• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM Better Way to Sync Object Destructions in Multiplayer

Anixias

Member
Currently, my method is to have the server send a list of all objects close to a client twice per second. I don't like sending lists of objects, and I am about to see how this effects performance:
buffer_write number of objects near the client
loop through them writing their IDs

client receives, repeats loop for the number read from the buffer
add the ID to a temporary list
when all are added, delete any object not appearing on the list
destroy the list

What is your method of syncing destructions?

Also, how long should timeout disconnects be? I'm using UDP. I currently have 5 seconds of no input causes the server to put the player into a safety mode to prevent deaths and stuff. After 30 seconds, it removes the player entirely. The client-side pulls up a disconnect message after 5 seconds of no info received. After 30 seconds, it disconnects.

Anyway, original question, how should I sync object destructions?
 

sp202

Member
I haven't tackled multiplayer myself but this seems a wholly inefficient way to go about it. Assuming instance IDs would be different between the two instances of the game you could just send the object_index of the instance being destroyed and its position and use instance_nearest in the client if the margin of error is too high to do a simple instance_place.
 

Anixias

Member
How I handle IDs is to send the ID of an object, and a bunch of position stuff, from the server to each client. The client checks all objects of that type to see if their variable "object_id" is the same as the ID of the server object. If so, it updates it's stats. Otherwise, it spawns a new object, sets "object_id" to the ID on the server, then updates its stats. Since I'm using UDP, I can't be 100% sure that sending a message on instance destruction would actually reach the client, and that was why I was sending a list of all objects every so often. Then, the client would be 100% sure whether something should be there or not. However, as you said, it is super inefficient. I could attempt a dumbed-down version and every so often, send a list of all the objects within a client's view, like I have been, but sending those messages WAY less frequently (once every three seconds maybe) and sending instance destroy messages, too. I think that'd help.
 

FrostyCat

Redemption Seeker
Sending keyframes every now and then is exactly what UDP-based multiplayer games do, stop thinking of it as dumb. There are ways to send the list one chunk at a time to prevent congestion when the time comes to send a keyframe (e.g. by attaching a sequence ID to each chunk), but it has to be done.
 
Hello!

If I need 100% correct sync (I mean if it's game breaking if objects are not synced) i use 2 ds_list (one with shared ID and one with the local object ID) for each object type like players, projectiles, enemies etc...
The whole lists are only sent when someone connects.

Example of destroying a spell for a client, this is from the "main switch" in the network event:
Code:
case 11: // Destroy spell
tmp_id = buffer_read(t_bfr, buffer_u16)
tmp_id = ds_list_find_index(spell_id, tmp_id)
if tmp_id != -1
{
from_o = ds_list_find_value(spell_object, tmp_id)  
client_spell_destroy(from_o)
}
break
Code:
///client_spell_destroy(spell)
var o = argument0, tmp_id;

tmp_id = ds_list_find_index(obj_ctrl.spell_id, o.my_id)
ds_list_delete(obj_ctrl.spell_id, tmp_id)
ds_list_delete(obj_ctrl.spell_object, tmp_id)
with o instance_destroy()
This is ment to be used for TCP or guarantied UDP so I'm not sure this is what you are after. Hope it can be somewhat usefull! :)
 
Top