Jump to content


Photo

[blaxun] Online Engine/examples And Documentation


  • Please log in to reply
1484 replies to this topic

#1461 shadowman465

shadowman465

    GMC Member

  • New Member
  • 244 posts

Posted 22 December 2010 - 04:04 PM

I was just looking over the engine and the noticed in the Server.gmk the obj_login step event:
//Now that the Player object exists we will have to listen for incoming messages
if(!tcpconnected(socket))instance_destroy(); //Kill the instance if we loose connection
size = receivemessage(socket);

if(size < 0) 
break;

if(size == 0)
{
    instance_destroy();
    break;
}

There is an instance_destroy but there is no instance destroy event to close the socket.
If a player closed the game before getting past logging in wouldn't that socket never
get closed?
  • 0

#1462 sabriath

sabriath

    12013

  • GMC Member
  • 3147 posts

Posted 22 December 2010 - 09:44 PM

There is an instance_destroy but there is no instance destroy event to close the socket.
If a player closed the game before getting past logging in wouldn't that socket never
get closed?

When the DLL detaches, all sockets are closed and WSACleanup is called....although it _should_ be in the instance destroy event, so good catch.
  • 0

#1463 akash

akash

    GMC Member

  • New Member
  • 1 posts

Posted 17 April 2011 - 07:36 AM

I need your help..

Please add me in ym : akashbchandran


Thank you


Feedback : REALLY GREAT AND AWESOMEEEEEEEEEE TUTOR!!!!

Edited by akash, 17 April 2011 - 07:37 AM.

  • 0

#1464 raubaut

raubaut

    GMC Member

  • GMC Member
  • 15 posts

Posted 05 July 2011 - 03:47 AM

Hi,

I am having difficulties that were mentioned earlier but as far as I can tell no solution has been provided.

The problem is as follows. Let's say we have two players: Player 1 and Player 2. Both players login. Let's say Player 1 decides to log off. If Player 1 then logs back on his movement will no longer be updating on Player 2's screen. Essentially, a "ghost" of Player 1 is drawn, and then never updated. If Player 2 then leaves and then re-enters the room, this ghost of Player 1 disappears, never to return.

I will try to investigate the source of this problem, but in the meantime does anyone have any ideas or solutions? This is very much a critical bug.

I am using engine 1.0 without any modifications.

Edited by raubaut, 05 July 2011 - 03:48 AM.

  • 0

#1465 True Valhalla

True Valhalla

    ಠ_ಠ

  • Retired Staff
  • 4879 posts
  • Version:GM:Studio

Posted 05 July 2011 - 05:51 AM

There are still a few bugs left in this engine, and I don't think BlaXun has the time to support it anymore. There is also a GM8.1+ issue with MyINI.dll on Windows 64bit systems which will cause problems (the file remains fragmented).

If anyone is looked for bug-free, working examples, my site has them. I actually learned off BlaXun's engine, so my design is probably somewhat similar - but polished, well commented and working ;)

Hope it helps someone.
  • 0

#1466 raubaut

raubaut

    GMC Member

  • GMC Member
  • 15 posts

Posted 05 July 2011 - 02:20 PM

The problem is as follows. Let's say we have two players: Player 1 and Player 2. Both players login. Let's say Player 1 decides to log off. If Player 1 then logs back on his movement will no longer be updating on Player 2's screen. Essentially, a "ghost" of Player 1 is drawn, and then never updated. If Player 2 then leaves and then re-enters the room, this ghost of Player 1 disappears, never to return.


There is a second bug, which occurs when the second player to join is the one who leaves.

I have fixed both bugs. This post documents one fix, and the post below documents the other fix. Please see the below post for "patched" Game Maker files, a.k.a. Basic Engine v1.2!

Note: In the spirit of educating others I will leave the following documentation of my thought process for dealing with this bug. I would consider myself a novice/intermediate programmer so I'm not the most efficient, but reading this documentation might help others to contemplate similar problems, or problem solving in general.

Conditions that produce the bug:
Player 1 connects
Player 2 connects
Player 2 disconnects
The server-side list contains [Player2] but should contain [Player1]. In other words, the server still thinks that Player2 is connected when in fact Player1 is connected! This allows for multiple instances of Player1, which is very bad. Therefore, the server isn't correctly updating the list of players. I am not sure why it is deleting the first entry in the list...


UPDATE 1:

When the server deletes a player it uses the following code:

ds_list_delete(global._playernames,list_place)

The player which is deleted is determined by list_place. Each player object has a list_place variable. In theory, the first player to join should get 0, the second 1, the third 2. However as it is right now this variable is never changed so every player object inherits a list_place of 0. This appears to be the root of the problem.

UPDATE 2:

I found a solution to this problem. In the server's obj_player Create event, the code is as follows:

/*
This script will be executed once a new Player entered the game.
We'll now refresh some existing variables and inform other Players about this Player.
Also this new Player needs to get informed that other Players are currently connected to the game.
*/

global._playing +=1 //Increase the number of Players that are currently online to draw it on the Server Screen
playerid = iniReadReal(_accpth,'INFO','PlayerID',0) //Read the Id of the Player from his Account file

//The Player logged in and we add his name to the list of currently connected Players
//This is needed to prevent Players to login with the same account twice (Optionally you could use the Player ID to get the same effect)
list_place = ds_list_add(global._playernames,string_lower(_name))

If instead list_place assumes the value of global._playing before this variable is updated, then each object player will refer to the correct position on the array. For example:

list_place = global._playing
global._playing +=1 //Increase the number of Players that are currently online to draw it on the Server Screen
playerid = iniReadReal(_accpth,'INFO','PlayerID',0) //Read the Id of the Player from his Account file

Now the second player to login can log out and back in without any trouble. Unfortunately, users can now login twice with the same account.

UPDATE 3:

I've found a solution to the logging in problem, but it creates another problem. Using the following code:

list_place = global._playing
global._playing +=1 //Increase the number of Players that are currently online to draw it on the Server Screen
playerid = iniReadReal(_accpth,'INFO','PlayerID',0) //Read the Id of the Player from his Account file

//The Player logged in and we add his name to the list of currently connected Players
//This is needed to prevent Players to login with the same account twice.
ds_list_add(global._playernames,string_lower(_name))

The second player can now log in and out and back in. However, if the second player logs out, then the first player logs out, then Player 1 is still on the server list of players. There is still something wrong with list_place's value...

This only occurs when the following happens:

Player 1 joins.
Player 2 joins.
Player 1 quits.
Player 2 quits.
And it appears that this is because the server still thinks Player 2 is in list_place 1. Somehow, I need to decrement all players at a list place above a player that leaves. How would I do this? :blink:

UPDATE 4:

How? Elementary, dear Watson. The simple approach is to enter a loop for every instance of obj_player on the server-side where list_place is greater than the player who is exiting.

This can be done by entering the following code into obj_player's alarm[0] event (which is executed when a player quits).

k = list_place
if k < global._playing {
    do
    {
         i = (instance_find(obj_player,k+1))
         i.list_place -= 1
         k+=1
    }
    until (k = global._playing);
}

I have run some tests with up to 4 players and the variables are changing as they should be. Problem solved!

Edited by raubaut, 05 July 2011 - 10:56 PM.

  • 0

#1467 raubaut

raubaut

    GMC Member

  • GMC Member
  • 15 posts

Posted 05 July 2011 - 03:16 PM

The problem is as follows. Let's say we have two players: Player 1 and Player 2. Both players login. Let's say Player 1 decides to log off. If Player 1 then logs back on his movement will no longer be updating on Player 2's screen. Essentially, a "ghost" of Player 1 is drawn, and then never updated. If Player 2 then leaves and then re-enters the room, this ghost of Player 1 disappears, never to return.


Now, with respect to the ghosting bug I described in the quoted passage above...

On the client side, a ds_map (global._playermap) is maintained for other players in the game. When a player joins they are added to this array.

I have been watching this array by checking ds_map_size(global._playermap). When another player joins, the map size increases from 0 to 1. However, when that player then leaves, the map size does not then decrease back to 0. This seems to indicate that the array is not being correctly updated on the client-side. I don't know if this is the main reason for the ghosting bug, but it seems like a good lead.

Again, I'm not very good with arrays so I will see what I can do. If anyone has any advice that would be greatly appreciated. I am hoping to salvage what I've already developed on this engine for future use, so fixing this bug is pretty important to me. :whistle:

UPDATE:

So on the client side, other players are stored in a ds_map. When a new player enters, they are added to the global._playermap ds_map. When they leave, however, only the obj_other_player instance is destroyed. When Player 1 is logged on, and Player 2 logs on and then off, Player 2 is still in Player 1's ds_map. Somehow that ds_map entry has to be removed...

Easy fix!

We'll modify case_msg_leave as follows:

/*
This script will be performed once the server tells us that a Player is leaving the game
*/

player_id = readushort()

//First destroy the instance of the player
with remove_player(player_id)
instance_destroy()

//Then remove the player from our array of players
ds_map_delete(global._playermap,player_id)

And since we're calling remove_player instead of get_player we'll create that use the following code:

/*
This script is used to get the instance-id of a players object.
We use the Players Player Id which is sent by the server 
This one is slightly different than get_player as we've already processed the packet
*/

return (ds_map_find_value(global._playermap,player_id));

//this returns information about players in the game

Voila!

Bug fixes! :whistle:

Click to download Basic Engine v 1.2 !

Edited by raubaut, 05 July 2011 - 11:08 PM.

  • 0

#1468 EchoJerichoX

EchoJerichoX

    www.MetroidCoven.com

  • GMC Member
  • 501 posts
  • Version:GM8.1

Posted 23 July 2011 - 07:08 AM

This will prove to be very, very useful soon. Thank you very much!
  • 0

#1469 Hello-World

Hello-World

    GMC Member

  • New Member
  • 105 posts

Posted 06 October 2011 - 10:42 PM

@raubaut: I was having this EXACT same problem! I'm going to try your solution(s) and see if it works. :)

HOLY COW! EVERYTHING WORK PERFECTLY NOW! I can log in/out as much as I want on ANY char now and absolutely NO problems! Oh, and my engine has position saving, chat, collectibles, PvP system, trading system, hyperspace system, and other features so I've edited those segments of code a lot and your fix still works. :)

Edited by Hello-World, 06 October 2011 - 11:00 PM.

  • 0

#1470 BlaXun

BlaXun

    Slime Online Creator

  • GMC Member
  • 2607 posts
  • Version:GM:Studio

Posted 10 October 2011 - 07:19 PM

People are still using this... epic :)
  • 0

#1471 hanyunanodesudc

hanyunanodesudc

    GMC Member

  • New Member
  • 360 posts

Posted 02 November 2011 - 06:54 AM

People are still using this... epic :)

ofc, ofc...
  • 0

#1472 l1ttledand

l1ttledand

    GMC Member

  • GMC Member
  • 43 posts
  • Version:GM8

Posted 28 November 2011 - 05:33 AM

:thumbsup:

Edited by l1ttledand, 13 December 2011 - 03:22 AM.

  • 0

#1473 XTIDIA Games

XTIDIA Games

    GMC Member

  • GMC Member
  • 198 posts
  • Version:GM8

Posted 28 November 2011 - 07:35 AM

shouldn't this go to tutorials and examples ?
  • 0

#1474 Glen

Glen

    GMC Member

  • GMC Member
  • 840 posts
  • Version:GM:Studio

Posted 29 November 2011 - 12:40 AM

People are still using this... epic :)

Do you still use this engine in SO2 or have you completely redone the engine for your project?
  • 0

#1475 Rassym

Rassym

    GMC Member

  • New Member
  • 286 posts
  • Version:Unknown

Posted 15 December 2011 - 05:36 PM

I wonder how i can check a variable on the server, cause
when i start the server i want to have that the server owner can choose which map he wants.
And when a player connects to the server, the client get the map variable from the server
and go to the right room.

anyone..?
  • 0

#1476 hanyunanodesudc

hanyunanodesudc

    GMC Member

  • New Member
  • 360 posts

Posted 21 December 2011 - 05:15 PM

I wonder how i can check a variable on the server, cause
when i start the server i want to have that the server owner can choose which map he wants.
And when a player connects to the server, the client get the map variable from the server
and go to the right room.

anyone..?


Just have the server set a map variable to something.
and whenever a player logs on, send an additional info for that map value, and have the client start off on that room first.

for example, boot server, starting map value is 4. Use w/e interface you need to change it to like, let's say, 6.
When a player logs in, you send the client this value (6). Player then spawns in client room 6.
  • 0

#1477 Tebo

Tebo

    GMC Member

  • New Member
  • 1 posts
  • Version:GM8

Posted 27 December 2011 - 10:22 AM

I'm having trouble making the player disappear from other players screen when he warps. I just removed the mouse movement and changed it to keyboard movement so I removed MSG_NEW_CONTACT which is for using mouse movement. Does MSG_NEW_CONTACT have to do with making the player disappear from other players screen when he warps.


Also if a player gets an error the server also has an error which says that the variable list_place is not defined.

k = list_place
if k < global._playing {
    do
    {
         i = (instance_find(obj_player,k+1))
         i.list_place -= 1
         k+=1
    }
    until (k = global._playing);
}

  • 0

#1478 DaDiBoM

DaDiBoM

    GMC Member

  • New Member
  • 23 posts

Posted 21 January 2012 - 08:34 PM

The problem with players logging in and out again was that their ds_map values in the client wasn't removed when they left, therefore their saved "Id" variables in the map was linked to the old object id's, that were removed when they logged out.

This is a simple and correct fix, in case_msg_enter (in the client)
you do (for both case 1 and two!):
i.playerid=readushort()
ds_map_add(global._playermap,i.playerid,i) //Add the Player to a ds_map
instead of
ds_map_add(global._playermap,readshort(),i) //Add the Player to a ds_map
then in the destroy event of obj_other_player you do
ds_map_delete(global._playermap,playerid)
This bug was so annoying, and the solution was so simple ;_;

Edited by DaDiBoM, 21 January 2012 - 08:37 PM.

  • 0

#1479 marfin201

marfin201

    GMC Member

  • New Member
  • 170 posts
  • Version:GM8

Posted 10 May 2012 - 08:48 AM

Hold it !!..
And you're be cool :biggrin:
OMG !! I think you're the master for it ... :biggrin:
Good Job Blaxun !!
Thank u very much of your guide !! :smile:
  • 0

#1480 BlaXun

BlaXun

    Slime Online Creator

  • GMC Member
  • 2607 posts
  • Version:GM:Studio

Posted 14 May 2012 - 05:58 PM

And its still beein used.
Hooray me <3
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users