Syncing custom variables

Before you start

In this post I'll explain how custom variables (anything other than direction, x, y, sprite_*, for example) should be synced. This tutorial assumes you already have a basic game that shows a login box and has a "player object" and an "other player object" set up. If you don't, the getting started tutorial covers the basics of creating a new game.

Clothing

Let's assume there's some kind of variable, I'll call it "clothing_sprite", that stores which sprite is drawn on top of the player sprite, like this:

draw_self();
draw_sprite(clothing_sprite,0, x, y);

We also want that sprite to appear on the other player object, and it should be the same sprite as the player is currently using. For the purposes of this tutorial, I'll assume sprites can be switched by pressing 1, 2, or 3. Add this code to the step event of the player object:

if(keyboard_check_pressed(ord('1')))clothing_sprite =spr_clothing_1;
if(keyboard_check_pressed(ord('2')))clothing_sprite =spr_clothing_2;
if(keyboard_check_pressed(ord('3')))clothing_sprite = spr_clothing_3;

Parent-object

I like to keep the amount of duplicate code in my projects to an absolute minimum. I don't want to have to update the drawing code twice if I decide I want to change it. Create a new object, and name it something like "par_players". It'll be the place where code for both the player object and the other player object can be placed.

Add the code for drawing the clothing to the draw event:

draw_self();
draw_sprite(clothing_sprite,0, x, y);

Initialize the variable in the create event:

clothing_sprite= spr_clothing_1

Set the parent of both the player object and the other player object to this new "par_players" object. If you've already got a draw or create event added to the player or other player object, make sure to invoke the inherited event as well:

event_inherited();

Synchronizing the variable

Lastly, the variable's value will need to be sent to the other clients. You won't need to take care of sending the variable to new players that connect, or making sure you only set the variable when changing it.

Add this code to the step event of the player object:

gms_self_set(“clothing_sprite”,clothing_sprite);

This piece of code will tell the extension that there is a variable named clothing_sprite that will need to be sent to the other players. The extension will then do all the hard work of deciding the best way to send the variable and when to send the variable.

Note: If you know a variable is not an integer value, make sure to round(...), floor(...) or ceil(...) the value if you only use the integer part of the number. If GameMaker Server will use less bandwidth if the variable is an integer. If you're sending a number as a string, convert it to a real fist. Strings generally use more bandwidth than numbers when sending them. gms_self_set_precision(...) can also be used to specify how precise the value needs to be sent.

Add this code to the draw event of the other player object:

clothing_sprite= gms_other_get(player_id, “clothing_sprite”)
event_inherited();

This will obtain the variable's value and store it in "clothing_sprite". Then, it calls the inherited draw event, which will draw the player's sprite and the clothing sprite on top. The player_id variable is automatically created by the extension, and is used to identify other players. It'll exist in every instance of the other player object created by the extension.

Replies (35)

Last message on 22 Jun 2016

innominato on 10 Jan 2016, 11:43:43
Why this code works on Windows and not on android?

if (GMS.master == false ){
seed = (gms_other_get(player_id, "seed")); //on Android, the seed isn't received
random_set_seed(seed);
}
Size43 (Administrator) on 11 Jan 2016, 12:15:48
Are you properly connected to the server on android? What do gms_info_isconnected and gms_info_isloggedin return?

Also note that GameMaker does not guarantee that a seed will generate the same set of numbers on different platforms.
Forgeio on 5 Jul 2015, 16:38:31
Hey Size, in my game when the player presses spacebar, it creates a sword depending on the direction he is facing. I have everything set up, and it looks great, except I have it so that in case he attacks while moving, the sword will jump to the players position. This messes the whole game up, so that when you attack the other player attacks and when the other player attacks you attack. Please help! I cant figure out which way to sync this!
Size43 (Administrator) on 7 Jul 2015, 15:07:32
Are you using something like "with" (=applies to object in D&D) to move the sword?
Forgeio on 7 Jul 2015, 16:19:42
no, I just tried doing this example except having it jump to obj_player1.x obj_player1.y
Forgeio on 8 Jul 2015, 02:48:29
sorry forget what I just said, inside of the step event of the sword object it has it jump to the obj_player1.x and obj_player1.y
Size43 (Administrator) on 14 Jul 2015, 21:58:17
Check if gms_instance_is_owner(id) is true before making the instance jump to the position of the player :)
Forgeio on 17 Jul 2015, 00:18:48
can you give me an example code? sorry but I tried it and it didn't really work :/
Size43 (Administrator) on 19 Jul 2015, 22:28:07
if gms_instance_is_owner(id)
{
    x = obj_player1.x
    y = obj_player1.y
}

should work.
Forgeio on 20 Jul 2015, 21:36:53
so I should just keep (id) as id? nothing has to go there?
Size43 (Administrator) on 24 Jul 2015, 15:34:45
If you're syncing the instance with the is_full flag - Yes, you can just keep id there.
Forgeio on 24 Jul 2015, 18:32:27
can you just give me the full code for it? I just cant seem to figure it out. What all should go in the step event of the object for the sword? also, how would I have it sync its rotation and sprite change etc.
Size43 (Administrator) on 28 Jul 2015, 20:13:08
That is the full code, it should be in the step event. You can sync other variables using gms_instance_set(...) and gms_instance_get(...).
Forgeio on 29 Jul 2015, 00:04:10
it didn't work though, on the other player the sword does not follow the player. Maybe its just lag though...
Size43 (Administrator) on 9 Aug 2015, 14:19:53
Apologies for my delayed responses. As you may know, Outlook is blocking all GameMaker Server mails which means I don't get notified when you post a reply.

What does your instance syncing code look like? (the part where you call gms_instance_sync(...))
Forgeio on 9 Aug 2015, 19:19:31
gms_instance_sync(id,is_full,'x','y');
if gms_instance_is_owner(id)
{
x = object0.x
y = object0.y
}

that's the whole code I have in the create event of the sword
Size43 (Administrator) on 12 Aug 2015, 20:02:09
Try moving this part to the step-event instead of the create-event:

if gms_instance_is_owner(id)
{
    x = object0.x
    y = object0.y
}
Forgeio on 13 Aug 2015, 01:02:35
thanks
Forgeio on 15 Sep 2015, 03:53:11
it still doesnt work... sorry for being such a bother ;-;
Size43 (Administrator) on 21 Sep 2015, 19:29:25
Hey,

Sorry for my late reply. I don't have as much free time as I expected, so I haven't been able to even touch any GameMaker Server code in almost a month. If I recall correctly you've sent me a mail with an example of what's not working. I had a quick look at it and there are indeed some bugs that need to be fixed. I'm hoping for things to slow down a bit so that I can fix it next weekend.
Forgeio on 5 Mar 2016, 08:14:30
Did you forget about me? Lol
Size43 (Administrator) on 6 Mar 2016, 17:11:29
Oops, sorry. To be honest, I've got no idea if I actually fixed what I found, or what the bug actually was. There have been 3 updates since I posted that, please check if you're still having this problem on update 1.8.8.

If it's still not fixed, let me know and I'll promise to fix it within a week or so :)
Forgeio on 20 Sep 2015, 05:32:27
hello??
Forgeio on 6 Jul 2015, 03:26:51
sorry about so many questions, but also, how do I make commands? like /spawn and admin commands like /ban?
Size43 (Administrator) on 7 Jul 2015, 15:06:12
You can use gms_script_set_chat_verify to see a chat message before it's sent. You can intercept the commands using normal string functions and then return false to prevent the message from being sent.
Forgeio on 8 Jul 2015, 15:27:37
can you give me an example code?
Size43 (Administrator) on 14 Jul 2015, 22:02:17
Something like this:

if string_pos("/ban", argument0) == 1
{
    // Handle command using normal GM functions
    return false;
}// Check for other commands
return true;
Forgeio on 16 Jul 2015, 02:55:19
thank you so much :D
kaikalii on 14 May 2015, 03:23:38
What do I need to do in order to sync changes in the player's sprite?
Currently, I have certain conditions that change the player's sprite via "sprite_index = spr_new_sprite;"
Do I need to implement it as a draw function in order to sync it?
Without syncing, you cannot see other players' sprites change.
Size43 (Administrator) on 14 May 2015, 17:49:41
Make sure you're not drawing a specific sprite in the draw event of the other player. If that's not the case, please try adding gms_optimize_variables(true, true) right below the gms_settings call.
SaitoZero on 20 Sep 2014, 16:45:03
Hey Size, may you turn everything in Documentation into a file( html help, txt, docx, ect...) and upload it? I can't always be online 'cause my net isn't very good and my laptop has such low RAM that browser takes about 40%, so it's lagging and I can't use Game Maker when browsing the internet.
Size43 (Administrator) on 20 Sep 2014, 16:46:44
I'll see what I can do :)
namlunthkl on 3 Nov 2014, 16:46:34
I will help you to make some example but.... You have to create a page to post Example first!!! :)
LightVelox on 18 Aug 2014, 16:55:35
how i get the player id?i put

if team=1{player_id=p1 other_player_id=p2}
if team=2{player_id=p2 other_player_id=p1}


sorry for that questions i have a little problem with id and instance syncs
Size43 (Administrator) on 19 Aug 2014, 20:22:22
There's gms_self_playerid for the playerID of the player object, and a variable named player_id is created automatically for all other player objects. You don't need to add any other code for that.