Sessions

Sessions can be used to separate groups of players into different 'instances' of the game. For example, in a 4-player game sessions could be used to make sure each group only sees each other, and nobody else. Another use-case is separating players into different 'worlds', where each world is user-generated.

Each session has 3 attributes: an ID, type and a tag.


  • ID: The primary way to identify a session. It's unique and will never change.

  • Type: A way to 'group' sessions. For example, the type can be used to differentiate between a lobby (where other players can still join), and the game in progress (where players can no longer join). A type can be any number between 0 and 255

  • Tag: Introduced in version 2.0, the tag can carry additional information about the session in a single string. For example, the tag might contain a user-friendly name for the session, or information about which world is played in the sesison.



You can create or join sessions at any point. However, you should always check whether the session ID is still valid before joining a session, since the server can delete empty sessions at any point.

Default login location


By default, all players will log in to any session with type 0. When connecting, the server will look through all sessions and find a session that has type 0. The player will be put into this session directly after logging in. You should not use type 0 for sessions where you want to fully control who enters the session.

Note: The VS mode will interfere with normal session usage. If you're using the VS mode, you cannot use session functions.

Communication between sessions


The following things are shared between sessions:

  • PlayerINIs

  • GameINIs

  • Binary Data Blocks

  • p2p messages sent with gms_p2p_all_in_game

  • p2p messages sent to a player in a different session



Anything else (player variables, global variables, instances) is separate for each session. If possible, you should try to use p2p messages for communication between sessions. If p2p messages do not fit your use case, you should use either the GameINI or binary data blocks for communication.

Asynchronous behaviour


When you call gms_session_join or gms_session_create, the player will not immediately move to the session. It takes some time for the command to be sent to the server, and for the server to send back the response (or an error). You cannot make any assumptions about how long this takes. Instead, you should set a script using gms_script_set_session_change. The script will be called every time a session change is finished. When the script is called, player information, global variables and synced instances will already have been updated.

Deciding which session to join


The server will decide what ID to give to any session, so you cannot use the ID to determine which session to join. A simple way to choose, is to use types. For example, if your game has 3 different 'modes' you could give each mode a different type. A script to join a session with a certain type might look something like this:

///join_session_with_type(type)

var type = argument0;
for(var i = 0; i < gms_session_count(); i++)
{
    if gms_session_type(gms_session_id(i)) == type
    {
        gms_session_join(gms_session_id(i))
        return 0;
    }
}
gms_session_create(type)


You can then use this script like this (where st_* are macros with values 1, 2, 3, etc.):

// Click 'Play normal mode'

join_session_with_type(st_mode_normal)
// Click 'Play slow mode'

join_session_with_type(st_mode_slow)
// Click 'Play fast mode'

join_session_with_type(st_mode_sonic)


If it's important for your game to wait until the join is successful before moving to the next room, you can add something like this to your session change script (see 'Asynchronous behaviour'):

///on_session_change(new_id)

var new_id = argument0;
if room == rm_choose_mode and 
    (gms_session_type(new_id) == st_mode_normal or 
     gms_session_type(new_id) == st_mode_slow or 
     gms_session_type(new_id) == st_mode_sonic)
{
    room_goto(rm_play)
}


Using tags


To store any additional information that does not fit in the type, which only accepts values ranging from 0 to 255, you can use the session tags. To create a session with a tag, use gms_session_create_ext. Once created, session tags cannot be changed, so this is only useful for storing information that you already know when creating the session.

For example, you can use the tag to store session names. This way, you can allow players to enter any session name, instead of requiring them to use IDs.

There are also a million different ways to combine multiple strings into one, so that you can store more than one thing in the tag. For example, you could use something like this script:http://www.gmlscripts.com/script/string_extract However, I will not dive into specifics here, since this is mostly GameMaker stuff, and GameMaker Server has very little to do with it.

Replies (48)

Last message on 10 Oct 2016

Arcadian on 27 Sep 2016, 22:17:42
I get this error inside a 1vs1 session, and using VS mode:
___________________________________________
############################################################################################
FATAL ERROR in
action number 1
of Step Event0
for object GMS:

Variable GMS.value(100060, -2147483648) not set before reading it.
at gml_Script_XGms_ve_writeValue
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Script_XGms_ve_writeValue (line 0)
gml_Script_XServer_writevariable
gml_Script_XServer_step
gml_Script_gms_step
gml_Object_GMS_Step_0
Size43 (Administrator) on 10 Oct 2016, 18:44:08
Would you be able to mail me your project at gamemakerserver@outlook.com?
Arcadian on 17 Sep 2016, 13:30:53
Communication between players is impossible at sessions, ok, but if you change a global variable using gms_global_set_string() is it visible for the other players? Or only for those inside the same session as you?
Size43 (Administrator) on 20 Sep 2016, 17:08:56
I believe it's actually possible to send p2p messages to other players if you know their id, but don't quote me on that.

Global / instance variables are bound to a specific session. Game / player INIs are not, so you could use those to share information between sessions.
Arcadian on 16 Sep 2016, 13:22:48
Hi Size43:

What are the differences between use VS mode or not? I asume there are some advantages, or games where using VS mode is more neccesary, but why?
Size43 (Administrator) on 16 Sep 2016, 13:24:55
VS mode handles the matchmaking for you. This can also be implemented manually using sessions, so the main advantage is that it saves time.
Aaron13ps on 28 Nov 2015, 06:19:08
Sorry if this is already answered, but how do you leave a session and re-join the main one? (The one automatically assigned when the player logs in)
Size43 (Administrator) on 7 Dec 2015, 11:44:34
The main session is simply a session with type 0. The example script in gms_session_type might be useful here. If there's no session with type 0, just create one and the server will put new players into that one as well.
Aaron13ps on 7 Dec 2015, 17:31:06
When I join a session (type 2) and use the script below, I get the error message provided within another reply adjacent to this one (character limit)

///leave_server()
global.IN_SESSION = false
global.HOSTING = false;
if (gms_session_type(gms_session_current_id()) != 0)
{
var i = 0;
while (i<10000)
{
if (gms_session_exists(i) && gms_session_type(i) = 0)
{
gms_session_join(global.lobbyserver)
exit
}
}
gms_session_create(0)
}
Size43 (Administrator) on 7 Dec 2015, 17:33:34
You can ignore my previous post :)

What does "global.lobbyserver" contain? Shouldn't it be gms_session_id(i)?

Also, note that you can just check "i < gms_session_count()" instead of 10000.
Aaron13ps on 7 Dec 2015, 17:39:01
OMG Forgot the i++... So now I am wondering why I did not go in an infinate loop. This is somewhat embarrassing. I rushed to ask the question without double checking my code :C

///leave_server()
global.IN_SESSION = false
global.HOSTING = false;
if (gms_session_type(gms_session_current_id()) != 0)
{
var i = 0;
while (i<gms_session_count())
{
if (gms_session_exists(i) && gms_session_type(i) = 0)
{
gms_session_join(i)
exit
}
i++
}
gms_session_create(0)
}

Still get same error message
Size43 (Administrator) on 7 Dec 2015, 18:30:27
Try replacing "gms_session_join(i)" with "gms_session_join(gms_session_id(i))".

Referencing a session by index is deprecated (because it's inconsistent with the gms_session_join, which does require a session_id instead of an index). You should use the id whenever possible. ;)
Aaron13ps on 7 Dec 2015, 18:55:10
Totally worked. Thank you for the assistance. :D
Aaron13ps on 7 Dec 2015, 17:30:00
############################################################################################
ERROR in
action number 1
of Step Event0
for object GMS:

SERVER ERROR:Session does not exist

Please note: This is a server-sided error message. To disable all GameMaker Server-errors, call gms_debug_hide_errors().
at gml_Script_XServer_error (line 3) - show_error(argument0, false);
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Script_XServer_error (line 3)
called from - gml_Script_gms_step (line 167) - XServer_error(gms_action_get_argument_string(0));
called from - gml_Object_GMS_StepNormalEvent_1 (line 1) - gms_step();
Size43 (Administrator) on 7 Dec 2015, 17:31:16
Could you post the code you're using?
Aaron13ps on 7 Dec 2015, 17:32:37
Yea I was doing that :) Had a character limit so I made two separate posts.. Man you were quick with the reply, I expected that I was going to have enough time to write the other reply XD.
Aaron13ps on 7 Dec 2015, 17:33:28
Oh crap, just realized I left some old code in it
global.lobbyserver was suppost to be I let me retry and see if it works
Aaron13ps on 7 Dec 2015, 17:35:05
Nope still get the same error message.

I had to re-write this code twice... that's my excuse for the slip-up :)
Forgeio on 2 Oct 2015, 21:39:13
how do you save sessions, for instance if someone is in session 2 and logs out, then someone else logs in to session 2, it will load it so that all the blocks are still edited as they were by the first player?
Size43 (Administrator) on 3 Oct 2015, 19:15:55
Sessions are not permanent. You'd have to write the blocks to a GameINI and load them back in when entering the session.
Forgeio on 5 Oct 2015, 01:26:26
oh :/ is there some way you could add permanent sessions in the next update? it would be really useful for me in Fortune
Size43 (Administrator) on 7 Oct 2015, 15:26:07
It seems like you're using sessions in a way they're not intended to be used. You can use either the GameINIs or the Binary Data Blocks to store level data (with the BDBs allowing for much more space). Adding a generic save mechanism would not help much in this case, I think.
Forgeio on 7 Oct 2015, 21:05:59
No I don't want them to save, I want them to stay active the entire time the server is running.
Size43 (Administrator) on 9 Oct 2015, 14:50:56
Sorry, that's not possible. A session will freeze when all players leave it, and it will be cleaned up shortly after it. Sessions are inteded to be used in a matchmaking system: A few players will join it, play a match, and then leave it again. If you want anything permanent you'll have to save it in some way -- even if it's only for a few minutes.
Forgeio on 10 Oct 2015, 19:28:23
is it possible that you could make something that would be permanent, almost like letting the players host their own servers except that its using the GM Server?
Size43 (Administrator) on 12 Oct 2015, 11:58:41
I'm working on something like that, but it won't be finished any time soon.

I don't get what you're trying to do with this. What prevents you from temporarily storing the game state in a global variable/INI?
Forgeio on 12 Oct 2015, 16:08:05
That would be too complicated, I would have to store the exact position of a ton of blocks and objects and exactly what each variables current value is.
Size43 (Administrator) on 17 Oct 2015, 15:26:00
That is the only way to do this if you want persistent rooms. I'd recommend using the BDBs if you want to store more than a few thousand bytes of data, though.
littlecoolpug on 16 May 2015, 06:35:36
Can Someone help me, my problem may just be that I just don't understand, but
every time I try to make a server it says ERROR, this server all ready exists! (I made it say this though, but only if the server all ready exists) but when I try to join a server I get this error:___________________________________________
############################################################################################
ERROR in
action number 1
of Step Event0
for object GMS:

SERVER ERROR:Session does not exist

Please note: This is a server-sided error message. To disable all GameMaker Server-errors, call gms_debug_hide_errors().
at gml_Script_XServer_error (line 3) - show_error(argument0, false);

stack frame is
gml_Script_XServer_error (line 3)
called from - gml_Script_gms_step (line 167) - XServer_error(gms_act
Size43 (Administrator) on 16 May 2015, 13:53:38
What code are you using?
littlecoolpug on 16 May 2015, 15:26:18
ok this is in the enter button, also the select var. is for when you push up or down it changes select to +1 or -1
session = get_string("Type your server number...","")
if(select = 0) {
if(session = "No Server") {
room_goto(room0)
}
else {
if(gms_session_exists(session)) {
gms_session_join(session)
}
}
}
if(select = 1) {
if(session = "No Server") {
room_goto(room0)
}
else {
if(gms_session_exists(session)) {
room_goto(room0)
gms_session_create(session)
}
}
}
littlecoolpug on 16 May 2015, 15:28:38
oh I forgot I made it when you type "No Server" when it asks to type your server its suppose to just not make a server and just play the game offline.
Size43 (Administrator) on 16 May 2015, 16:03:25
The session variable is a string, you should convert it to a number before passing it to any of the gms_session_* functions.
littlecoolpug on 16 May 2015, 15:40:47
I got another problem, I don't know how it happened, but every time i try to go to the login room my game freezes I think it may be from this: FreeType :: unable to find font file Arial Black
plz help thx
Size43 (Administrator) on 16 May 2015, 16:03:41
What version of GameMaker are you using?
littlecoolpug on 16 May 2015, 16:07:24
never mind I fixed the problem, it was caused by the room not the extension! thx for your help though
littlecoolpug on 16 May 2015, 16:17:41
thank you for your help! I've fix all my problems! THANK YOU SO MUCH.
Size43 (Administrator) on 16 May 2015, 16:18:50
No problem :)
littlecoolpug on 16 May 2015, 21:17:45
I got another problem! sorry about having so many! lol
I made a chat room, and I wanted it to enable chat when I enter the room and disable it when I exit the room, but it's not working please help me codes:
create:
enable = true //create also has the drag and drop show chat room
step:
if(enable = true) {
gms_chat_toggle ( true )
}
if(enable = false) {
gms_chat_toggle ( false )
}
Press esc:
control = false
goto_room(RM_menu) //this is how you leave the room
littlecoolpug on 16 May 2015, 21:38:48
Ok so I fixed the first problem it turns out i just didn't put the obj. in the room lol, but now it won't go away it just stays in the veiw!
littlecoolpug on 16 May 2015, 21:45:34
never mind I just made it where when you return to RM_menu it inputs the code:
gms_chat_toggle ( false )
instead of the push esc!
amkgames on 5 Apr 2015, 21:52:41
Is this like changing channel?
Size43 (Administrator) on 6 Apr 2015, 11:24:07
You could look at it that way, yes.
peril94 on 10 Dec 2014, 16:02:37
Never mind I think I've figured it out! :)
This is awesome btw
peril94 on 10 Dec 2014, 14:22:33
I'm using gm studio 1.3, + I've gone for a different approach now, gms_server_current_id returns all servers and not just mine so I've gone for a different angle using INI's.
The only problem I have is I can't set the server_id in the gms_create_session. What I'm trying to do is hard to explain, but basically when logging in it searches through the global INI to see how many worlds there are. if world 0 (server 0) has 32 people living there it will check world 1 and so on until it finds a world with a spare place so that you can live there, and then that will be your dedicated server, thats the one it will always attempt to join or create when you log in. Then when you have joined that server_id it will load the assosciated INI file.
peril94 on 10 Dec 2014, 01:53:47
is there any way to check the amount of sessions associated with just my game, when I use "gms_session_count" before I join or create a session it returns 0, but when I've created a sessions "gms_session_count returns" 925, which makes what I'm tryin to do impossible.
Size43 (Administrator) on 10 Dec 2014, 12:00:22
What version of GameMaker are you using?
Size43 (Administrator) on 10 Dec 2014, 11:21:35
gms_session_count should return 2 after creating a session. It should also return 1 after logging in (not sure what it returns when no one is logged in, but it should still be accurate). I'll make sure to fix this bug in 1.8.