| General | Hosted Sites | Civ5 | CivRev | Civ4Col | Civ4 | Civ3 | Civ2 | Civ1 | Misc | Marketplace |
![]() |
|
|
Welcome to Civilization Fanatics' Center. You are currently viewing our site as a guest which gives you limited access to our site features. By joining our free community, you will be able to participate in the discussions, search the forum, send private messages, vote in polls, upload your own screenshots to the gallery, and access many other special features. Registration is fast, simple and absolutely free, so sign up today! If you have any problems with the registration process or your account login, please contact support. |
|
|||||||
![]() |
|
|
Thread Tools |
|
|
#1 |
|
Chieftain
Join Date: Dec 2008
Location: Mannheim, Germany
Posts: 49
|
Random number generation OOS error - is there a solution?
Hi - I've seen a lot of discussion that using the random number generator in python causes MP OOS errors. Has anyone found a solution to this? Is it related to the getSorenRand function, or random numbers in general (i.e. if you created a mathematical function from scratch that generated random numbers does the problem persist?
|
|
|
|
|
|
#2 |
|
Deity
|
As long as you use getSorenRand, AND you do it in a way that doesn't rely on the activeplayer's condition, you won't have sync issues.
SorenRand ensures that everyone uses the same algorithm for their random numbers, so as long as everyone makes a random number, they all get the same result. If you use a local function to make a rand, then each person's seed is different, and each OS's algorithm is different, so the results won't match.
__________________
Fall from Heaven: - Random Stories and Fragments - Trivia Thread - The Complete FfH Manual - Lore Compendium - The Erebus Project - #erebus - The Mega Story General Information: Mod Details, World Information Resource, Easter Eggs, Quick-Guide, Empyrean/Esus & Guilds Information, The Other Religions, Mana Chart, Religous ThemesSpecific Details: FfH Wikia, FfH Wiki, FF Wiki, World Spells, FoL Guide, Council of Esus Guide, Magic Comparison, Potential Fix for MAF issues |
|
|
|
|
|
#3 | |
|
Tsar
Join Date: Nov 2007
Location: Samara, Russia
Posts: 1,557
|
Quote:
how can i use random numbers and not to cause oos - is it enough just to use sorerand? Is it applicable for python or sdk as well?
__________________
CIV5 MODS: Emigration v4; Food Resources; Happines per populationCIV4 MODS: Commanders, Defender withdrawal, Gold for disbanding, Occasional Promotions, Caveman mod launcher, Supply Lines (no mod, just an idea) |
|
|
|
|
|
|
#4 |
|
Deity
Join Date: Mar 2007
Location: Mountain View, California
Posts: 9,624
|
An OOS error occurs if the game state on one machine differs from any other machine.
One way this can happen is if one machine calls getSorenRandNum() without any other machine doing it too. The Soren random number generator is part of the game state, and it must be used identically by every machine. Another way is to have some game-state-altering code run only for the active player without telling the other machines what it did. If you want to add 10 to the active player's treasury every turn, make sure you send a network message to add the gold so every machine does it.These issues can crop up in the SDK and Python.
__________________
Monkeys killing monkeys killing monkeys over pieces of the ground. Silly monkeys, give them thumbs they make a club and beat their brother down. BUG Mod - BTS Unaltered Gameplay [ Forum | Download | FAQ | Known Issues | Troubleshooting | Modding Tutorial ] |
|
|
|
|
|
#5 |
|
Deity
|
ActivePlayer refers to the guy behind the computer. So in a multiplayer game, each human is their own ActivePlayer.
If you have a python routine that does something like: if (getActivePlayer) == CIVILIZATION_ROME getSorenRand() ... Then this will cause an OOS, because only one of the humans is Rome, so he grabs an "extra" random number, making him not agree with everyone else. Same issue if you base it on keypresses or mouse clicks/movements. Like having a random number generated when someone does a mouseover of a building to choose from a variety of flavorful text to supply with the stats. Seems harmless enough, but since not all players will mouse over the building at the same time, they will each be continuously shifting their Randoms so that they can no longer agree with one another. As long as you avoid these and similar mistakes, using getSorenRand solves all of your issues. Technically you could also use getMapRand, but there is little need to do so, and it'll just confuse people who try to use your work and don't know about the second function.
__________________
Fall from Heaven: - Random Stories and Fragments - Trivia Thread - The Complete FfH Manual - Lore Compendium - The Erebus Project - #erebus - The Mega Story General Information: Mod Details, World Information Resource, Easter Eggs, Quick-Guide, Empyrean/Esus & Guilds Information, The Other Religions, Mana Chart, Religous ThemesSpecific Details: FfH Wikia, FfH Wiki, FF Wiki, World Spells, FoL Guide, Council of Esus Guide, Magic Comparison, Potential Fix for MAF issues |
|
|
|
|
|
#6 |
|
Chieftain
Join Date: Dec 2008
Location: Mannheim, Germany
Posts: 49
|
OK, I am using the function within a button which I created according to the button tutorial. And it is conditional on the player being active: ie if the unit is active and the unit is in a certain position... But the button has to tie to this unit and conditions - so how would this work? I assume the getSorenRand gets a seed from somewhere - can you set this manually?
Lets say we've gotten to the point where the button has been pushed - can I somehow jump to a global, or grab a global instance? Or maybe just save the fact that the button has been pushed, but wait for the end of the round or the beginning of the next round to do the action? |
|
|
|
|
|
#7 |
|
Deity
Join Date: Mar 2007
Location: Mountain View, California
Posts: 9,624
|
It sounds like you want a player to be able to initiate a game action--just like attacking or moving a unit--via the interface (button), and all players' machines should perform the same action for that player's unit. For this you want to send a mod net message which is a network message containing a custom command with some data.
For an example, see BUG's CvStrategyOverlay.py module. Each message requires code that sends it and code that receives and handles it. It's not terribly complicated once you get the hang of it. If you provide more specifics we might be able to help you better.
__________________
Monkeys killing monkeys killing monkeys over pieces of the ground. Silly monkeys, give them thumbs they make a club and beat their brother down. BUG Mod - BTS Unaltered Gameplay [ Forum | Download | FAQ | Known Issues | Troubleshooting | Modding Tutorial ] |
|
|
|
|
|
#8 |
|
Deity
Join Date: Apr 2008
Location: California
Posts: 4,727
|
I highly recommend this guide to learn about oos.
__________________
Come see the Fury Road sub-forum! Everybody wants post-apocalyptic desert warfare with crossbows! |
|
|
|
|
|
#9 |
|
Chieftain
Join Date: Dec 2008
Location: Mannheim, Germany
Posts: 49
|
Oopsies
Ah-hem
**nonchalant whistling** After reading the guide to multiplayer modding I now suspect that the problem is not related to the sorenrand function, but rather to problems with global vs. local reference. I am enclosing the code below. Actually just one function, but the others are similar, so if I can fix this one I should be able to fix the others. PHP Code:
Thanks! PS: I suspect my variable naming still needs some work... but in my defence, my work keeps getting in the way of me spending more time modding... |
|
|
|
|
|
#10 |
|
Deity
Join Date: Apr 2008
Location: California
Posts: 4,727
|
In general, if you are displaying information only and not changing any game state, you can do anything you want. But, if you are changing game state, you need to call modnetmessage as soon as possible, and do all your actual work in the function which receives the modnetmessage. Otherwise we can guarantee your code will cause oos.
__________________
Come see the Fury Road sub-forum! Everybody wants post-apocalyptic desert warfare with crossbows! |
|
|
|
|
|
#11 |
|
Deity
Join Date: Mar 2007
Location: Mountain View, California
Posts: 9,624
|
The problem is that your code runs only on the machine of the player that clicked the button (or whatever triggered your code). This means only one player calls getSorenRandNum(), and that causes the sequences to go out of sync.
As davidallen says, you need to detect your UI event and then send a mod net message so every players' machine runs the code. Everything starting with the line Code:
jRnd = gc.getGame().getSorenRandNum(100, "Trade") In your code, BTW, both the use of Soren rand num and changeGold() cause OOS.
__________________
Monkeys killing monkeys killing monkeys over pieces of the ground. Silly monkeys, give them thumbs they make a club and beat their brother down. BUG Mod - BTS Unaltered Gameplay [ Forum | Download | FAQ | Known Issues | Troubleshooting | Modding Tutorial ] |
|
|
|
|
|
#12 |
|
Chieftain
Join Date: Dec 2008
Location: Mannheim, Germany
Posts: 49
|
Ok, cool, I wanted to define a lot of that stuff as commands anyway, as I have some duplication in my mod. But how exactly does the mod net message work? Is there a mod somewhere that uses this command so that I could see how to use it?
|
|
|
|
|
|
#13 |
|
Deity
|
Fall from Heaven and Fall Further use it a few times each. Mostly you just need to figure out a way to condense any action you want to perform into 5 integer values.
__________________
Fall from Heaven: - Random Stories and Fragments - Trivia Thread - The Complete FfH Manual - Lore Compendium - The Erebus Project - #erebus - The Mega Story General Information: Mod Details, World Information Resource, Easter Eggs, Quick-Guide, Empyrean/Esus & Guilds Information, The Other Religions, Mana Chart, Religous ThemesSpecific Details: FfH Wikia, FfH Wiki, FF Wiki, World Spells, FoL Guide, Council of Esus Guide, Magic Comparison, Potential Fix for MAF issues |
|
|
|
|
|
#14 |
|
Deity
Join Date: Apr 2008
Location: California
Posts: 4,727
|
I learned about modnetmessage from the Gods Of Old mod which is part of the BTS release. The Great Priest of each religion has an action button to cause a meteor strike, or tsunami, or whatever, and these use modnetmessage. I never wrote a proper guide. I just looked through the "python action button" tutorial in the tutorial subforum, written by TC01, but this actually has exactly the same problem you started with -- it does not use modnetmessage, so it is not MP-safe.
My older mod Fury Road also uses modnetmessage (see my sig), but it is based on the way Gods Of Old does it. Dune Wars also follows the same model. So there are a few places to look.
__________________
Come see the Fury Road sub-forum! Everybody wants post-apocalyptic desert warfare with crossbows! |
|
|
|
|
|
#15 |
|
Deity
Join Date: Mar 2007
Location: Mountain View, California
Posts: 9,624
|
BUG uses it in its StrategyOverlay.py module (see my sig). Specifically, search for onModNetMessage to see how to receive the message and sendModNetMessage for sending. Also, the Python API shows the details:
CyMessageControl.sendModNetMessage(int iData1, int iData2, int iData3, int iData4, int iData5)
__________________
Monkeys killing monkeys killing monkeys over pieces of the ground. Silly monkeys, give them thumbs they make a club and beat their brother down. BUG Mod - BTS Unaltered Gameplay [ Forum | Download | FAQ | Known Issues | Troubleshooting | Modding Tutorial ] |
|
|
|
|
|
#16 |
|
Chieftain
Join Date: Dec 2008
Location: Mannheim, Germany
Posts: 49
|
OK, let me see if Ive got this straight (and I'm not a programmer, so I am probably not using the correct terminology)
If you start with the gods of old mod: The "action trigger" if you will, is within the CyMainInterface file. It basically watches for the widget that indicates a button has been pushed, then defines the five integer values that will be passed via the net message to the actual command, which will be executed (hopefully) identically on all networked computers. CyEventManager is where the "action" takes place - it watches for the action to be triggered, then uses the 5 integers to perform the action. Is there any other file that comes into play? I assume that the tricky part will be converting everything to integer values to pass to the command, the converting back into pointers for actions that require pointers rather than integers as arguments. One more question - why 5 integer values? Couldn't you define NetMessage to accept more? (Not that I need it, just curious) |
|
|
|
|
|
#17 |
|
Deity
Join Date: Apr 2008
Location: California
Posts: 4,727
|
That is a good explanation. It is not hard to pass integers; pPlayer.getID() returns the int for a player which you convert back with with gc.getPlayer(), pUnit.getID() returns the int for a unit which you convert back with pPlayer.getUnit(), etc. I am sure that modNetMessage originally passed three ints, then the civ engine authors had one application which needed four, then they had one which needed five.
__________________
Come see the Fury Road sub-forum! Everybody wants post-apocalyptic desert warfare with crossbows! |
|
|
|
|
|
#18 |
|
Deity
|
The actual communication between the computers happens in the EXE, or at least in one of the DLLs we don't have access to. As such, we cannot change this message from 5 integers to some other set of values. What they gave us is all we get.
__________________
Fall from Heaven: - Random Stories and Fragments - Trivia Thread - The Complete FfH Manual - Lore Compendium - The Erebus Project - #erebus - The Mega Story General Information: Mod Details, World Information Resource, Easter Eggs, Quick-Guide, Empyrean/Esus & Guilds Information, The Other Religions, Mana Chart, Religous ThemesSpecific Details: FfH Wikia, FfH Wiki, FF Wiki, World Spells, FoL Guide, Council of Esus Guide, Magic Comparison, Potential Fix for MAF issues |
|
|
|
|
|
#19 |
|
Deity
Join Date: Mar 2007
Location: Mountain View, California
Posts: 9,624
|
But you can use CvMessageData to define your own net messages containing other data types. Look at CvMessageData.cpp and you'll see a bunch of subclasses for passing messages. Each one takes a specific set of data, e.g. for founding a religion:
Code:
CvNetFoundReligion::CvNetFoundReligion(PlayerTypes ePlayer, ReligionTypes eReligion, ReligionTypes eSlotReligion) : CvMessageData(GAMEMESSAGE_FOUND_RELIGION),
m_ePlayer(ePlayer),
m_eReligion(eReligion),
m_eSlotReligion(eSlotReligion)
{
}
Code:
void CvNetFoundReligion::PutInBuffer(FDataStreamBase* pStream)
{
pStream->Write(m_ePlayer);
pStream->Write(m_eReligion);
pStream->Write(m_eSlotReligion);
}
void CvNetFoundReligion::SetFromBuffer(FDataStreamBase* pStream)
{
pStream->Read((int*)&m_ePlayer);
pStream->Read((int*)&m_eReligion);
pStream->Read((int*)&m_eSlotReligion);
}
Code:
void CvNetFoundReligion::Execute()
{
if (m_ePlayer != NO_PLAYER)
{
GET_PLAYER(m_ePlayer).foundReligion(m_eReligion, m_eSlotReligion, true);
}
}
Code:
void CvNetFoundReligion::Debug(char* szAddendum)
{
sprintf(szAddendum, "Non-simultaneous found religion notification");
}
Code:
void CvMessageControl::sendFoundReligion(PlayerTypes ePlayer, ReligionTypes eReligion, ReligionTypes eSlotReligion)
{
gDLL->sendMessageData(new CvNetFoundReligion(ePlayer, eReligion, eSlotReligion));
}
Code:
case BUTTONPOPUP_FOUND_RELIGION:
CvMessageControl::getInstance().sendFoundReligion(
GC.getGameINLINE().getActivePlayer(),
(ReligionTypes)pPopupReturn->getButtonClicked(),
(ReligionTypes)info.getData1());
__________________
Monkeys killing monkeys killing monkeys over pieces of the ground. Silly monkeys, give them thumbs they make a club and beat their brother down. BUG Mod - BTS Unaltered Gameplay [ Forum | Download | FAQ | Known Issues | Troubleshooting | Modding Tutorial ] |
|
|
|
|
|
#20 |
|
Deity
Join Date: Mar 2007
Location: Mountain View, California
Posts: 9,624
|
Yay!
It works and wasn't too hard to do. [Edit: Turns out passing a string is easy too since there are Read/WriteString() functions on the stream.]Note you only need to do this if you need to pass arguments that you cannot squish into 5 integers (e.g. a string).
__________________
Monkeys killing monkeys killing monkeys over pieces of the ground. Silly monkeys, give them thumbs they make a club and beat their brother down. BUG Mod - BTS Unaltered Gameplay [ Forum | Download | FAQ | Known Issues | Troubleshooting | Modding Tutorial ] Last edited by EmperorFool; Jan 30, 2010 at 08:23 PM. |
|
|
|
![]() |
| Bookmarks |
| Tags |
| oos, random number |
|
| Thread Tools | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| [BTS] OOS On Multiplayer Random Events | Ed_ | Civ4 - Technical Support | 2 | Dec 10, 2010 10:53 AM |
| Windows 7/Random Events = OOS | Moineau | Civ4 - Multiplayer & PBEM | 3 | Apr 04, 2010 08:51 PM |
| random map generation | oawiefga | Civ4 - General Discussions | 13 | Apr 25, 2009 10:24 PM |
| OoS errors should be your number one priority | DioBrando | Civ4 - Fall from Heaven | 7 | Oct 11, 2008 02:28 AM |
| Random world generation? | IloveV | Civ4 - General Discussions | 1 | Nov 04, 2005 08:53 AM |