• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Windows [UNSLOVED]ds_list returned as null, but actually exists? PLEASE HELP ME

BMatjasic

Member
Hello people,

I have a really strange problem here... I create a ds_lists with in which I store data about session (I create a map and add details) and in this map I create a section named "playerList" in which I call var List = ds_list_create(), so the pointer to that section should be a pointer to this list. But somehow, when I try to query and search for the session map, I get ALL the data, except "playerList", which is returned as null. In the bottom picture, you can see that the list is actually existing and created, but perhaps gets lost later, but I can't see a reason why.. In the picture bellow, I have an evidence, that the list is actually existing and it holds a map, but later can't be queried by the script that's giving an error.

Picture is in the spoiler:



Thanks in advance!
 

Weird Dragon

Wizard
GMC Elder
It is very confusing.
I assume that you doing the whole thing within the same script otherwise the declaration with the term "var" can not be applied.

You wrote "and in this map I create a section named "playerList" in which I call var List = ds_list_create(),"
so somewhere you create a ds_list stored in the variable List which means that the index for that list is List,
but I can not find that index appearing in your code. It is hard to read so I could have missed something.
 

BMatjasic

Member
Allright so, When I create a list for this session I call a script session_create(), which is the following:

Code:
var Socket = argument0; //pass the socket id to the first argument
var MaxPlayers = argument1; //The second argument hold the maximum ammount of players in one single session

var playerList = ds_list_create();//Here we will create a list which will hold information about players INSIDE the session
var Session = ds_map_create(); //Let's create a session map and pass all the information we need to it
//Adding needed information to the session
ds_map_add(Session, "socket", Socket);  //add socket to session database NOTE: If you don't want to set master socket, just leave socket argument -1
ds_map_add(Session, "name", client_find_info(Socket, "name")); //add name of the room owner
ds_map_add(Session, "max_players", MaxPlayers); //add ammount of max players
ds_map_add_list(Session, "playerList", playerList); //Create list of players
ds_map_add(Session, "id", ds_list_size(global.sessionList)); //Add the id of this session
ds_list_add(global.sessionList, Session); //adding session to the current session list
//ds_list_mark_as_map(global.sessionList, ds_list_size(global.sessionList));
show_debug_message("PlayerList size for session: "+string(ds_list_size(global.sessionList)) + " is: "+string(ds_map_find_value(Session, "playerList")));

return ds_list_size(global.sessionList)-1; //Return id of the session
You can notice at the third line of the code, var playerList = ds_list_create() and "ds_map_add_list(Session, "playerList", playerList); //Create list of players" line. So there is the part when it's actually created.

Now we have a script session_join which is executed AFTER session is actually created.

Code:
var Socket = argument0; //Pass socket argument
var SessionJoin = argument1; //Pass session argument

if(session_exists(SessionJoin) == true) {

    for(var i = 0; i < ds_list_size(global.sessionList); i ++) { //query for session data
    
        var sessionMap = ds_list_find_value(global.sessionList, i);
        var sessionId = ds_map_find_value(sessionMap, "id");
        
        if(sessionId == SessionJoin) { //Checks whether we found the correct session
            
            var playerList = ds_map_find_value(sessionMap, "playerList");
            var maxPlayers = ds_map_find_value(sessionMap, "max_players");
            
            //Now we need to encode a map with players who are in this session and send those info over
            
            
            if(ds_list_size(playerList) < maxPlayers) { //whether there is a free slot
                var playerName = client_find_info(Socket, "name");
                
                //Add values to a map
                var pMap = ds_map_create(); //Creates a dictionary for a player
                ds_map_add(pMap, "name", playerName);
                ds_map_add(pMap, "socket", Socket);
                ds_map_add(pMap, "x", -1);
                ds_map_add(pMap, "y", -1);
                ds_list_add(playerList, pMap);
                ds_list_mark_as_map(playerList, ds_list_size(playerList)-1);
                
                show_debug_message("List: "+string(ds_map_find_value(sessionMap, "playerList")));
                var def = ds_map_create();
                ds_map_add_list(def, "default", playerList);
                
                
                var json_playerList = json_encode(def);
                show_debug_message(json_playerList);
                ds_map_destroy(def);

Note(I did not copy the whole code part because of the page height reasons)

Okay with all that going pretty well and echo the correct list and the correct pointer, the script session_broadcast_message is where the pointer gets lost:

session_broadcast_message()

NOTE: Please read code comments to find the line which outputs an error

Code:
var Socket = argument0; //Pass the socket argument


var SocketsSession = client_find_info(Socket, "room_id"); //Finds in which session the socket is

        var sessionMap = session_find(SocketsSession); //Finds a map pointer correctly
        
        var playerList = ds_map_find_value(sessionMap, "playerList"); //Finds a list of players > !!!!THATS THE PART WHERE THE ERROR APPEARS!!!
            show_message(ds_list_size(playerList)) {
            for(var j = 0; j < ds_list_size(playerList); j ++) { //Queires trough all of them
                
                
                var pMap = ds_list_find_value(playerList, j); //Finds each sockets map
                var socket = ds_map_find_value(pMap, "socket");
                
                if(socket != Socket) { //Except the sending one!!
                
                    network_send_packet(socket, m_buffer, buffer_tell(m_buffer)); //And finnaly sends info to each socket
                }
                }
                
                
            
            }
Cheers!
 

Weird Dragon

Wizard
GMC Elder
Here is the part where you refer to the error:
Code:
       var sessionMap = session_find(SocketsSession); //Finds a map pointer correctly
       
        var playerList = ds_map_find_value(sessionMap, "playerList"); //Finds a list of players > !!!!THATS THE PART WHERE THE ERROR APPEARS!!!
In the above code "sessionMap" is applied in two different ways.
In the first line it is the value returned by session_find(SocketsSession),
in the second line it is a ds_map id.
So you have created some ds_maps which all have a key called "playerList" and then the value returned by session_find(SocketsSession) will determine which map will be applied.
Since all the ds_maps created in the former scripts are created with local script variables I would guess that there is a problem there. Normally such a local variable will only work within the script where it exists but I guess that if you run another script inside a script then those local variables are existing within the whole code block, but is the script session_broadcast_message() part of that code block?
 

BMatjasic

Member
Well I have changed all local variable in the scripts, but the problem seems to be remaining.... I don't have a clue why...
 

Weird Dragon

Wizard
GMC Elder
OK, so that was not the problem.

Well, the error message was about a non-exsisting ds_map. Here is the code in question:
Code:
       var sessionMap = session_find(SocketsSession); //Finds a map pointer correctly
     
       var playerList = ds_map_find_value(sessionMap, "playerList"); //Finds a list of players > !!!!THATS THE PART WHERE THE ERROR APPEARS!!!
Somehow the variable "sessionMap" stores a number that doesn't refer to a ds_map index. That means that "session_find(SocketsSession)" returns a number that doesn't fit.

Are you sure that the possible return values from "session_find(SocketsSession)" are aligned with the possible index numbers of the ds_maps?
 

BMatjasic

Member
I have found out that the easiest way of checking this up is to json_encode a map to see full database. This is an screenshot of encoded json map which is returned as a value of session_find(SocketsSession), as you can see every value there is correct except the playerList value is null... I'm not sure about that one...



***

UPDATE:

I have figured out that that list is only accessible in the script session_join in any other case the ds_list of the map section "playerList" is null.
 
Last edited by a moderator:
P

ParodyKnaveBob

Guest
So what happens in that script to cause its value to vanish afterward? Is it by chance pointing to the async_load map while in an Async Event but not copying it for later use?

Regards,
Bob

P.S. Just a side tip. You might not be aware of DS accessors which can greatly clean up / simplify your code:
Code:
var sessionMap = ds_list_find_value(global.sessionList, i);
var sessionId = ds_map_find_value(sessionMap, "id");
ds_map_add(pMap, "socket", Socket);
...can become...
Code:
var sessionMap = global.sessionList[| i];
var sessionId = sessionMap[? "id"];
pMap[? "socket"] = Socket;
 

TheouAegis

Member
In your one code you create sessionList but don't populate it with anything. Maybe ds_map_add_list() only works with a list that actually has something in it.

(or i misread the code)
 
S

Spikehead777

Guest
The scripts you have provided do not appear to be the problem. It appears you are creating lists and storing them in a map correctly (I am not 100% familar with ds_map_add_list, though). I would look at your other scripts (especially ones that are called after session_join(...) and before the erroring line in session_broadcast_message(...).

Do you have other scripts where you replace (ds_map_replace) or destroy (ds_map_destroy) ds_maps? If you do, it may be possible you have a subtle error in one of your other scripts that's somehow dereferencing or destroying your playerList ds_map.
 

BMatjasic

Member
@ParodyKnaveBob: I don't know, that's the point... It isn't vanished anywhere it just gets lost...

@TheouAegis: TheouAegis it doesn't... belive me I've tried... I am adding things later which is visible and also the list HAS a content. The pointer to that list gets lost when using any other script but session_join

@Spikehead777:
As you can see only in disconnect case the map and lists are destroyed. NOTE: "def" is a test map for json and it doesn't have any function here.

 
Top