Multiplayer for a voxel-based game?

Hello everyone,
I’m in the process of creating a voxel-based game (not a Minecraft clone though :D), and I’m planning to incorporate sortof any random idea that pops up in my head. Like, for no reason, tanks in your medieval-ish village. Whatever.
The thing is, I would like to add multiplayer to the game and have no idea how to. I already implemented it into another game of mine, “Rusted Intelligence”, but that one had a hand-made map. This game doesn’t. It’s generated by a custom map generator that I wrote. I don’t think it’s possible to send the whole world over everytime, especially since it’s already 10.000 cubes for the map, plus a few thousand other objects, and npcs will also be there. So, my question is, how would I organize the multiplayer here to NOT rely on single packets that could get lost (e.g. when sending the world over once at the start and then only sending changes) and make it perfom halfway well?

Thank you in advance for any answers,

Robbi Blechdose

In my game more than 100k objects can be active at the same time, while map supports unlimited cound of object (millions). It based on 2D grid. Each object is a part of some cell. And game checks hashcode between server and client cells. Hashcode is based on id of object and time of object edition. So if you change object, it will update cell’s hashcode. And cell keep some data about deleted objects. So almost everything in my game sync is based on last update time of object. And cells keep last update time. So if something changes, client download only fresh data.
So this allows to keep unlimited count of objects. Client download them once and then download only changes or download it again if dissyncronization happens.
We tested it. And we played without any lags via hamachi, so it is not costful way.

That’s an interesting idea. Thanks!
There’s just the problem that buildings are permanently deleted from the arraylist they’re stored in, so this solution would require me to rewrite that…
Altough a separate table for the hashcode data might solve that. Hm.
How do you determine if the whole map has been sent over already?

EDIT: Also, how do you do it that only fresh data is downloaded? I imagine there must be both the data from the client and from the server on one of them to compare the hashcode…

  1. Don’t use arraylists. Use HashSets or HashMaps if you have a lot of objects.
  2. My deleted objects are removed from an objects set of a cell. And moved to set of deleted objects of a cell. If set of deleted objects become too big (100-1000 deleted id’s), then server clear it.

Server doesn’t send whole map. He only works with cells that close enough to player location. If hashcode of cells are equal on server and client side and update time of cell are equal, everything is right then.

Look example:
16:30:30 client want to get objects of Cell№1 (he has on his side 0 hashcode and 00:00:00 update time of that cell). Server has (133700 and 15:25:00 last update time of cell). So server send objects.
16:31:22 client downloaded all data of cell. He has on his side 133700 hashcode and 15:25:00 last update time of cell. Last update time of cell he determs by highest value of time (I use long type) of objects.
15:32:00 some object in this cell was deleted. Server has 132000 hashcode and 15:32:00 update time.
So client request to download information off all(including deleted) objects between 15:25:00 and 15:32:00. If he downloaded everything but hashcode or updatetime of cell are not equal he performs wipe and download objects again.

Each object has his time of last update.

You could also try to implement a seed that determines the world which is generated. So the same seed will always generate the same world. Then you just have to exchange seeds and then updates; you never have to send the whole world to other clients.

1 Like

Thanks for the answer.
But

16:30:30 client want to get objects of Cell№1 (he has on his side 0
hashcode and 00:00:00 update time of that cell). Server has (133700 and
15:25:00 last update time of cell). So server send objects.

This is exactly what I was asking and what still confuses me. Sorry if that wasn’t clear. Do you send all Hashes from the server to the client every frame to do the check?

Server sends hashcodes and last update times (2 values Longs + some additional data like id of cell) of nearest cells N millis. And it is UDP. If you need very fast reaction, you can make N like 30 or 60 ms. If response time is not very important, server could send it every 300-… millis.
If client find something wrong, he sends info about it. So the bottom line is that usually if nothing happens and everything is ok, then server sends only some values.