GameMaker Client side draw bug in online multiplayer game.

half_cup

Member
Hi,

I've run into a rather mind-boggling bug with my game. I will try to post concise detail below.

The game is a turn-based tile placing game and the bug I'm experiencing is regarding a turn timer.


I am using GML's function draw_healthbar to display the remaining time on the host and client's screens.
The host and the clients all have an object instance running called obj_gameControl which is the object drawing these healthbars.

All game instances are using the following code in obj_gameControl's "step" event to control the timer.
Before you look at the code, I'll explain the variables.

timed - a true or false indicating whether or not there is a timer at all
start_timer - a player's turn has just begun, this variable gets set to true
my_time - the time remaining during my turn
game_timer_global - the amount of time per turn (set at the beginning of the game)
time_percent - used in obj_gameControl's "draw" event for the healthbar function
online - a true or false indicating whether or not we are using local play or online multiplayer (this is set to true as soon as you join the server).
can_place - set to true at the beginning of a players turn (allowing them to place a tile on the board)
forced_move - you'll see in the code, but set to true when the timer runs out.

**For debugging purposes, I am also drawing my_time, game_timer_global, and time_percent during game play.

Now, the code in the Step event:
Code:
    if(timed)
    {
        //Start timer
        if(start_timer && online)
        {
            my_time = game_timer_global;
            start_timer = false;
        }
 
        //Run the timer
        if(my_time > 0)
        {my_time -= 1;}
        else
        {forced_move = true;}
    }
 
    time_percent = (my_time/game_timer_global)*100;
And in the Draw Event:
Code:
    if(can_place && timed)
    {
        draw_text_color(32,300,"Turn Timer",c_white,c_white,c_white,c_white,1);
        draw_healthbar(32,320,100,340,time_percent,c_black,c_blue,c_aqua,0,true,true);
    }

    draw_text_color(50,220,my_time,c_white,c_white,c_white,c_white,1);
    draw_text_color(50,240,game_timer_global,c_white,c_white,c_white,c_white,1);
    draw_text_color(50,260,time_percent,c_white,c_white,c_white,c_white,1);
Now you should know, the timer itself is working flawlessly, both host and client side. Players will be forced to make a move if the timer runs out.

The host's code works as expected. All variables are shown correctly, the healthbar and drawn "my_time" and "time_percent" variables empty proportionately.

The client's "draw_text_color" that draws the words "Turn Timer" works while it is their turn (meaning that can_place & timed have to be set to true)
The client's "my_time" variable draws correctly, and goes down by 1 every tick, just like it says it should in the code.
The client's "game_timer_global" draws correctly, and is the same as the host's "game_timer_global" that is drawn on screen.

Here's the bug.

The client's "time_percent" variable shows 100 when it is not their turn, but instantly goes to 0 when it is their turn. (so basically as soon as start_timer and can_place are set to true which happens in another part of the step event)
As such, the clients healthbar always shows as empty.

I am not manipulating the "time_percent" code anywhere other than where you see above, in the Step event of obj_gameControl (well, time_percent is set to 100 in obj_gameControl's "create" event)
I scoured my code to make sure.

Please help, I am at my wit's end with why this isn't working.

Thank you,
half_cup
 
Last edited:

half_cup

Member
SOLVED - I found the solution on a different thread, not in the community here, so I will share.

The variable I was sending from the host to the clients was the variable game_timer_global. I was sending it as a buffer_u16.

It turns out, when you send numbers through a buffer, they are not "real" numbers.

The fix was to instead convert and send this number as a buffer_string, and then reconvert it to a "real number" once it reached the client.

This simple change fixed everything.

I hope this helps someone!
 
Top