1.7 KiB
Solutions to Hard Problems
Saving the Game: This is accomplished by serializing the lua state using eris, and serializing the rest of the C++ data structures the usual way.
Snapshotting for Client-Side Prediction: we serialize the synchronous world model (using the save-game serialization code) to save it. Then we apply predictive commands, and it becomes the asynchronous model. When necessary, we roll it back to its synchronous state.
Solutions we Didn’t Use
Snapshotting Lua: the function lua_newstate accepts a memory allocation function as a parameter. Using this hook, we can keep track of every block of memory that lua allocates. To snapshot lua’s state, it’s sufficient to memcpy all its memory blocks into a temporary buffer. To restore lua’s state, memcpy everything back, and also restore the heap to the state it was in. We built a proof-of-concept of this and it works. We could use this on the client side for asynchronous/synchronous work, instead of using eris serialization.
Collision Detection: We could have a function that is a bit different on the client vs. server. On the server:
bool TryEnter(Location OldLoc, Location NewLoc)
And on the client:
void TryEnter(Location OldLoc, Location NewLoc, Location &NewLocMod)
// NewLocMod will always be set to a value where the server version of this call will
// succeed, or to OldLoc.
We could have a data structure that is a pancake stack of heightfields. The area between odd and even heightfields is enterable. Given an x,y,z coordinate, it is easy to find the x,y,z’ coordinate that represents the floor. The resolution on the client will be higher of course.