I noticed something troubling shortly after sitting down to work on my game – my new map generation code was working splendidly, but new players connecting to my server wouldn’t get any map data and would be stuck wandering a black void! Aside from the amusement factor of seeing other players and being able to apparently walk through walls (on the server’s end, since the client saw no walls there was no collision – one downside of a non-authoritative server) this represented a major issue.
I put off my plans for working on monster spawning and combat today and focused on fixing that particular snafu, and fix it I did! The solution didn’t come easily – at first I thought I could just attach a network view to my TileMap (a construct from the 2D Toolkit) but of course that didn’t do anything since there’s no good having something listening to you if you’re not saying anything, and I couldn’t pass along the TileMap data object to new players since as a GameObject datatype, it can’t be transmitted as an argument using remote procedure calls. RPCs will, however, accept more simple data types such as string, integer and most importantly, Vector3.
For the uninitiated, a Vector3 is three float values typically used to describe a position in 3d space; an X, a Y and a Z co-ordinate. Ultimately though they’re just a three element array and the numbers can be used for anything, which made me a very happy camper.
I created RPC versions of two methods my Dungeon Manager uses to build the map – SetTile and Build. SetTile accepts four integer arguments, X and Y co-ordinates, a layer number and a tile ID. Build is called after you’re done setting tiles with SetTile and will update the TileMap allowing you to see the results. Can you see where I’m going with this? Every time the server placed a tile it calls the SetTileRPC I created, using a buffered RPC mode. When it’s finished generating the map, it calls the Build RPC, again in buffered mode.
The important part here is making the RPC calls in buffered mode – as the name suggests, in this mode all rpc calls are recorded in a buffer, which played back to new players in the order they were received. Essentially, the server’s Dungeon Manager records every tile it places while generating the map and tells newly connected players’ Dungeon Managers to place all the same tiles, build the map and then pop the player into existence.
Wonderful stuff, wish it didn’t take so long to figure out. Networking is hard!
I didn’t have the energy or inclination to go back to the day’s planned work so instead I played around with adding lighting to the map – it looks pretty cool! For some reason player sprites aren’t being lit properly though, so there’s something to start on tomorrow!