If a Gadget involves unsafe behaviors, and runs on the first frame of sim, is the game host what determines what happens, do servers and clients reach agreement somehow (and what are the rules), or does instant desync occur?
I.E., I have a Gadget, it can create 20 random Units on Frame 0. The host's determination is that unit 1 is created, my machine decides that 5 is created. Who wins? Do both Units get created?
Or, I have a Gadget that I'm using for damage calculation in my "DnD in Spaaaaace" game. If the host rolls a natural 20, and I roll a 1... who's right?
If this has an easy answer, i.e. there's some way to say, "hosts are the only ones allowed to execute this", or if hosts always determine the "right answer", I'd like to know.
Looking at stuff like Fibre, I don't see indeterminacy being used- this is a biggie, with a lot of ramifications if it hasn't already been dealt with. I assume it has been, but I thought I'd ask, before I make a fool out've myself when I release the map demo, which is getting closer to non-vaporware, and ask people to test it...
Gadget code and indeterminacy
Moderator: Moderators
Re: Gadget code and indeterminacy
If you use a synced rng, I think all would be well, but an unsynced rng... not 100% sure about the placement scenario, depending on how it is done, but probably a desync, and certainly a desync in dice rolling.
Edit: Looks like the code automatically makes random calls in synced code safe:
Edit: Looks like the code automatically makes random calls in synced code safe:
Code: Select all
bool CLuaHandleSynced::SyncifyRandomFuncs()
{
// adjust the math.random() and math.randomseed() calls
lua_getglobal(L, "math");
if (!lua_istable(L, -1)) {
logOutput.Print("lua.math does not exist\n");
return false;
}
// copy the original random() into the registry
lua_pushstring(L, "random");
lua_pushstring(L, "random");
lua_rawget(L, -3); // math table
lua_rawset(L, LUA_REGISTRYINDEX);
// copy the original randomseed() into the registry
lua_pushstring(L, "randomseed");
lua_pushstring(L, "randomseed");
lua_rawget(L, -3); // math table
lua_rawset(L, LUA_REGISTRYINDEX);
// install our custom random()
lua_pushstring(L, "random");
lua_pushcfunction(L, SyncedRandom);
lua_rawset(L, -3);
// remove randomseed()
lua_pushstring(L, "randomseed");
lua_pushnil(L);
lua_rawset(L, -3);
lua_pop(L, 1); // pop the global math table
return true;
}
Re: Gadget code and indeterminacy
So, as long as all executes in sync, it should be ok? Sync requires the host to win?
<looks at code> Ok, that looks like it should be safe, then. I just have to require sync. Not like I was planning otherwise, it's already sync.
However, that leads right back to the frame 0 issues over in Dev- if we want to run mind-boggling code before we deliver a frame, yet stay in sync, how to go about this? I can probably write a crappy load-distributor, that spreads the load over multiple frames, but that'd be a custom hack, just for my specific application...
Oh, and this is probably a gimme, but LuaCOB is always sync, right? Or do I need to specify that, within my functions?
<looks at code> Ok, that looks like it should be safe, then. I just have to require sync. Not like I was planning otherwise, it's already sync.
However, that leads right back to the frame 0 issues over in Dev- if we want to run mind-boggling code before we deliver a frame, yet stay in sync, how to go about this? I can probably write a crappy load-distributor, that spreads the load over multiple frames, but that'd be a custom hack, just for my specific application...
Oh, and this is probably a gimme, but LuaCOB is always sync, right? Or do I need to specify that, within my functions?
Re: Gadget code and indeterminacy
Synced is called synced for a reason; even random numbers are synced.
In spring, the code is executed simultaneously on all computers playing; only unit commands and sync check hashes are transmitted...
The host doesn't win a dice roll because everyone gets the same result. Unsynchronized code can't affect the engine directly, it can only read the synced data, draw GUI elements, and send unit commands. Also makes it very hard to cheat without embedding cheats in the mod.
If a D20 is rolled, everyone rolls the same D20 and gets the same result.
Spring's networking model is just sending commands and simulating the entire game on each computer. If you ever get a different result than someone else, the engine starts spewing desync errors and the game can occur differently on other computers.
In spring, the code is executed simultaneously on all computers playing; only unit commands and sync check hashes are transmitted...
The host doesn't win a dice roll because everyone gets the same result. Unsynchronized code can't affect the engine directly, it can only read the synced data, draw GUI elements, and send unit commands. Also makes it very hard to cheat without embedding cheats in the mod.
If a D20 is rolled, everyone rolls the same D20 and gets the same result.
Spring's networking model is just sending commands and simulating the entire game on each computer. If you ever get a different result than someone else, the engine starts spewing desync errors and the game can occur differently on other computers.
Re: Gadget code and indeterminacy
Generally if it's not deterministic you aren't allowed to use it in synced code anyway.