Gadget code and indeterminacy

Gadget code and indeterminacy

Discuss Lua based Spring scripts (LuaUI widgets, mission scripts, gaia scripts, mod-rules scripts, scripted keybindings, etc...)

Moderator: Moderators

Post Reply
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Gadget code and indeterminacy

Post by Argh »

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...
User avatar
lurker
Posts: 3842
Joined: 08 Jan 2007, 06:13

Re: Gadget code and indeterminacy

Post by lurker »

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:

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;
}
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Gadget code and indeterminacy

Post by Argh »

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?
User avatar
aegis
Posts: 2456
Joined: 11 Jul 2007, 17:47

Re: Gadget code and indeterminacy

Post by aegis »

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.
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Re: Gadget code and indeterminacy

Post by KDR_11k »

Generally if it's not deterministic you aren't allowed to use it in synced code anyway.
Post Reply

Return to “Lua Scripts”