GMS 2 Losing connection after changing levels

demonipo

Member
Like the title says, both players lose connection when I change rooms.

Before hand, I'm new to networking and I'm spawning both of them on a setup room to verify if both players are working correctly.

However, going to the first level makes the buffers not reach the host and the clients.

I've been stuck the whole week trying to fix this myself, but I'm understanding this problem is out of my league.

Can anyone please help me?

Async Networking Code:

GML:
var type = async_load[? "type"]

switch (type)
{
    case network_type_connect:
        var socket = async_load[? "socket"]
      
        var buffer = buffer_create(2, buffer_fixed, 1)
      
        buffer_write(buffer, buffer_u8,    DATA.INIT_DATA)
        buffer_write(buffer, buffer_u8,    ds_list_size(clients))
      
        network_send_packet(socket, buffer, buffer_get_size(buffer))
        buffer_delete(buffer)
      
        var player = instance_create_layer(random(room_width), random(room_height), "Instances", obj_player)
        player.playerID = ds_list_size(clients)
        player.is_local = false
      
        ds_list_add(clients, socket)
        break;
  
    case network_type_data:
        var buffer = async_load[? "buffer"]
      
        buffer_seek(buffer, buffer_seek_start, 0)
      
        var data = buffer_read(buffer, buffer_u8)
      
        if (data == DATA.INIT_DATA)
        {
            var count = buffer_read(buffer, buffer_u8)
          
            obj_player.playerID = count
          
            for (var i = 0; i < count; i++)
            {
                var player = instance_create_layer(random(room_width), random(room_height), "Instances", obj_player)
                player.playerID = i
                player.is_local = false
            }
          
            players = instance_number(obj_player)
        }
        else if (data == DATA.PLAYER_UPDATE)
        {
            var pID = buffer_read(buffer, buffer_s8)
          
            with (obj_player)
            {
                if (pID == playerID)
                {
                    var XScale = buffer_read(buffer, buffer_s8)
                    image_xscale = XScale
                    x = buffer_read(buffer, buffer_s32)
                    y = buffer_read(buffer, buffer_s32)
                    element = buffer_read(buffer, buffer_u8)
                    hurt = buffer_read(buffer, buffer_u8)
                }
            }
        }
        else if (data == DATA.FIRE_BULLET_INIT_DATA)
        {
            with (instance_create_layer(buffer_read(buffer, buffer_s32), buffer_read(buffer, buffer_s32), "Instances", obj_fire_bullet))
            {
                bulletID = buffer_read(buffer, buffer_u8)
                playerID = buffer_read(buffer, buffer_s8)
                hspd = buffer_read(buffer, buffer_s8)
                vspd = buffer_read(buffer, buffer_s8)
                //image_angle = buffer_read(buffer,buffer_u8)
            }
            buffer_delete(buffer)
        }
        else if (data == DATA.FIRE_BULLET_UPDATE)
        {
            var bufferBulletID = buffer_read(buffer, buffer_u8)
            for (i = 0; i < instance_number(obj_fire_bullet); i++)
            {
                with (instance_find(obj_fire_bullet, i))
                {
                    if (bufferBulletID == bulletID)
                    {
                        x = buffer_read(buffer, buffer_s32)
                        y = buffer_read(buffer, buffer_s32)
                    }
                }
            }
        }
        else if (data == DATA.LEVEL_UPDATE)
        {
            var playerX = buffer_read(buffer, buffer_u8)
            var playerY = buffer_read(buffer, buffer_u8)
            var playerPlayerID = buffer_read(buffer, buffer_u8)
          
            with (instance_create_depth(playerX, playerY, -100, obj_player))
            {
                playerID = playerPlayerID
            }
        }
        else if (data == DATA.LEVEL_CREATION)
        {
            var level = buffer_read(buffer, buffer_u8)
            room_goto(level)
        }
        break;
      
        case network_type_disconnect:
        for (i = 0; i < instance_number(obj_player); i++)
        {
            with (instance_find(obj_player,i))
            {
                if (i != playerID)
                {
                    ds_list_delete(clients, playerID)
                    playerID = i
                }
            }
        }
        socket = noone
        break;
}
Room Start Code:

GML:
if (room == setup_room)
{
    var player = instance_create_depth(obj_player_1_spawn.x, obj_player_1_spawn.y, -100, obj_player)
    player.playerID = instance_number(obj_player) - 1
    playerID = player.playerID
  
    online = true
    if (is_server)
    {
        ds_list_add(clients, -1)
    }
}
else if (room == level_1 && online == true)
{
    var player = instance_create_depth(obj_player_1_spawn.x, obj_player_1_spawn.y, -100, obj_player)
    player.playerID = 0
  
    if (is_server)
    {
        var player = instance_create_depth(obj_player_2_spawn.x, obj_player_2_spawn.y, -100, obj_player)
        player.playerID = 1
        player.is_local = false
      
        var buffer = buffer_create(16, buffer_fixed, 1)
  
        buffer_write(buffer, buffer_u8, DATA.LEVEL_CREATION)
        buffer_write(buffer, buffer_u8, room)
  
        for (var i = 0; i < ds_list_size(obj_controller.clients); i++)
        {
            // get socket
            var soc = obj_controller.clients[| i]
      
            //skip if server itself
            if (soc < 0) continue
      
            //send
            network_send_packet(soc, buffer, buffer_get_size(buffer))
        }
        buffer_delete(buffer)
    }
    else
    {
        player.is_local = false
      
        var player = instance_create_depth(obj_player_2_spawn.x, obj_player_2_spawn.y, -100, obj_player)
        player.playerID = instance_number(obj_player) - 1

        player.is_local = true
    }
}
else if ((room == level_1) && (ds_list_size(clients) == 1 || online = false))
{
    with (instance_create_depth(global.spawnPoint.x, global.spawnPoint.y, layer_get_depth("player_layer"), obj_player))
    {
        playerID = -1
    }
}
else if (ds_list_size(clients) != 0 && room == title_menu)
{
    online = false
    is_server = false
    ds_list_clear(clients)
}
is_local is what makes player run or not

player buffer delivery:

GML:
var buffer = buffer_create(2048, buffer_fixed, 1)

    buffer_write(buffer, buffer_u8, DATA.PLAYER_UPDATE)
    buffer_write(buffer, buffer_s8, playerID)
    buffer_write(buffer, buffer_s8, bufferPlayerXScale)
    buffer_write(buffer, buffer_s32, x)
    buffer_write(buffer, buffer_s32, y)
    buffer_write(buffer, buffer_u8, element)
    buffer_write(buffer, buffer_u8, hurt)

    //send position to server
    if (!obj_controller.is_server)
    {
        network_send_packet(obj_controller.server, buffer, buffer_get_size(buffer))
    }
    //send position to clients
    else
    {
        //loop through clients list
        for (var i = 0; i < ds_list_size(obj_controller.clients); i++)
        {
            // get socket
            var soc = obj_controller.clients[| i]
      
            //skip if server itself
            if (soc < 0) continue
      
            //send
            network_send_packet(soc, buffer, buffer_get_size(buffer))
        }
    }
    buffer_delete(buffer)
 
Last edited:

FrostyCat

Member
Make the object(s) sending and receiving networking messages persistent. The connection is still live, your problem is that you've lost the listener while changing rooms.
 

demonipo

Member
I didn't mention that sorry.

I have them persistent from the moment the game starts. To make everything work i created the online variable so that the network controller will shut the online down whenever it goes back to the title menu, making it the transition between offline and online play.

1591029781985.png

It also seems odd that the server host will recognize it changed rooms and send that buffer to the other player, but both stop listening when the client goes to the corresponding room.

Also also, the second player is spawned in the host side of the game. However, instead of spawning it in the player 2 spawn coordinates, it instead locates him to 640x480.

This issue does not happen with in the client side, as both are positioned correctly, but the non local player doesn't even process collision code
(when hit with a bullet, it isn't knocked back as it normally does. It's strange since the only place im doing exit if it isn't local is on the step event)
 
Top