For the networking for Realm of Mankind we have decided to go for a throwback to how it used to be in the late 90s, early 2000s with the likes of Doom and Age of Empires II. The method is simultaneous deterministic lockstep simulation. The basic principle is that the game engine and AI should be deterministic, meaning that if give the same exact input it should produce the exact same results. This means that all the networking has to do is give the clients the same inputs and they should all produce the same results meaning that there is no need to sync anything else.
To do this we need a way to make sure that they all process the inputs at the same time, as some computers will be slower or on a slower network, this is where lockstep comes into play. Lockstep is a structure which all aspects of the simulation work with, it splits the game into turns which is where the game wait till it has received the new commands before it can continue. This means that all users receive the inputs at the same time in the game.
Another benefit of this system is the ability to recreate a replay system very quickly. If all the commands are saved in a database then all the game has to do in order to replay it is to run the game and renter the inputs for the database at the correct time. With the AI, also being deterministic it would simply play the game as if it was a real game rather than a replay and it should produce the exact same results!
The beauty of this system is that very little information has to be sent to each client meaning that it does not require an expensive server system, which as a small company we simply would not be able to afford, in order for users to get a smooth multiplayer experience for our users.
Please try out our Pathfinding Example project
H: Generates a hexagon graph
D: Destroys current graph
B: Starts a Breadth First Search
J: Runs Dijkstra’s algorithm
T: Traces path after BFS is complete
A: Runs A* algorithm
Clicking on a Hexagon changes its movment cost as follows:
– White = 1
– Pink = 4
– Yellow = 10
– Black = impassable
One of the fundamental aspects of the game that we needed to address first of all was the random terrain generation in which the game would be played. We chose to create a map using hexagons, as this allowed us effectively 6 directions of motion from each hexagon and would make the map look more natural. We decided that the map should be different every time, so no two games are the same, and so we needed to create an algorithm that would draw us a map which looks random, but also has some predictability about it, in that it has a basic shape to it and will not be toosmall or too large. As well as this, the algorithm also had to be dynamic, so that if we wanted to create a much larger game area for several players then the same code could be used. I decided that the best way to go about doing this would be to use RNG (Random Number Generation) to create a border between the land and sea, and then define the area on the outside of the border to be sea, and inside of it to be land. However this border needed to represent the shape of a coastline, with varying amounts of indents and extensions of land etc. therefore the RNG used determined the direction the the border would continue in from each hexagon tile, weighting the probabilities using the relative closeness of the border to the centre of the map area. This made sure that the map was not too small and had a vague consistent shape to it, however it maintains some variety. The border would continue up to an indent generated from each side, at which point it would move to another part of the algorithm to generate the next side of the map. Unfortunately this could not be used for the entirety of the map as the randomly created indent only represented an x or a y value, rather than a specific coordinate to draw to, and so, in order to make sure that the border created would connect with itself we used the A* pathfinding algorithm to generate the last small section of the border. Once the border had been generated we then needed to assign all of the hexes outside of the border as a ‘sea hex’, and in order to do this we used a variant of BFS (breadth first search) from a point on the map that was guaranteed to always be outside of the land area.