Object would be remained after command "deleteObject"

Hi I’m new at JS, and i met a problem in development.
This is a simple example for showing it:

In the beginning, I create 2 buttons for creating/deleting some cards which could be pick up in below gray zone
image

and I press space on the ‘create button’, some cards would be created as following
image

and I press space on the ‘delete button’, the cards would be deleted as following
image

It seems perfect but in fact,
when I go to the last be deleted card’s position and press space,
I found it will still trigger the card id,
image

I have log the closestObject

This is my code of delete Objects


function deleteCards():void
{
    let timeCounter = 0;

    // Delete cards
    for(let index = 0; index < allCards.length; index++)
    {
        let objId = "CARD_" + index;
        if(game.getObject(objId, MAP_ID) != undefined)
        {
            setTimeout(() =>
            {
                game.deleteObject(MAP_ID, objId);
            }, timeCounter*100);
        }
        timeCounter += 1;
    }
}

Could you please help me to solve this problem, thanks a lot!

Hi,

I got the exactly same issue here! Does someone know how to fix it? Thanks!

Few things:

How are you generating the objects in the first place? It is possible you are adding multiple copies of an object, or otherwise creating mangled objects that do not display correctly. If you have a github link, or a code file I can take a look at, the cause might not be proximal to the symptom.

Also, try checking the game.completeMaps[MAP_ID].objects contents. If there is another object that has the same name as your target object, the deleteObject function might be going after the wrong object.

Let’s start with that, and see where we can get.

Hi @Bill_Uncork-It ,

Thanks for reply.
The following is the code how I generate the objects:

const PICS:string[] =
["https://cdn.gather.town/storage.googleapis.com/gather-town.appspot.com/uploads/1tETsmYZSOjnNz0y/niNp15h1mjZ2LdYeg76qRk",
"https://cdn.gather.town/storage.googleapis.com/gather-town.appspot.com/uploads/1tETsmYZSOjnNz0y/0FwmaXqDyGB6z3qLQlBXlN",
"https://cdn.gather.town/storage.googleapis.com/gather-town.appspot.com/uploads/1tETsmYZSOjnNz0y/JE8uTkGQ3CSGtM9xCC9WX0",
"https://cdn.gather.town/storage.googleapis.com/gather-town.appspot.com/uploads/1tETsmYZSOjnNz0y/THBxmWLT0OZMxFXsrJtrvC",
"https://cdn.gather.town/storage.googleapis.com/gather-town.appspot.com/uploads/1tETsmYZSOjnNz0y/ft4ax63kmANwnlalYgkrzX",
"https://cdn.gather.town/storage.googleapis.com/gather-town.appspot.com/uploads/1tETsmYZSOjnNz0y/foanLdcahzHmpsMw3V6f4h",
"https://cdn.gather.town/storage.googleapis.com/gather-town.appspot.com/uploads/1tETsmYZSOjnNz0y/cttvBBa0jZYFfcMcE33X4b"];

function createCards():void
{
    allCards = [];
    let timeCounter = 0;

    let x = 10;
    let y = 10;
    // Init cards
    for(let index = 0; index < PICS.length; index++)
    {
        let objId = "CARD_" + index;
        let obj =
        {
            id: objId,
            normal: PICS[index],

            x: x + index*2,
            y: y,
            type: 5,
            width: 2,
            height: 2,
            distThreshold: 0,
            previewMessage: "Space",
        };
        allCards.push(objId);
        setTimeout(() =>
        {
            game.setObject(MAP_ID, objId, obj);
        }, timeCounter*100);
        timeCounter += 1;
    }
}

And I have tried check the game.completeMaps[MAP_ID].objects contents as following:

just two objects in it:

{
  '0': {
    x: 10,
    y: 6,
    normal: 'https://cdn.gather.town/storage.googleapis.com/gather-town.appspot.com/uploads/1tETsmYZSOjnNz0y/ZY9gGj3i7fFN9Zy0QfTW26',
    type: 5,
    width: 2,
    height: 2,
    previewMessage: 'Space',
    distThreshold: 0,
    id: 'BUTTON_CREATE',
    objectPlacerId: 'zGuziCXsQnSIp123pH7ERqFiLYS2',
    properties: {},
    key: 0
  },
  '1': {
    x: 14,
    y: 6,
    normal: 'https://cdn.gather.town/storage.googleapis.com/gather-town.appspot.com/uploads/1tETsmYZSOjnNz0y/xebaGrEsNolThsQwM1UAem',
    type: 5,
    width: 2,
    height: 2,
    previewMessage: 'Space',
    distThreshold: 0,
    id: 'BUTTON_DELETE',
    objectPlacerId: 'zGuziCXsQnSIp123pH7ERqFiLYS2',
    properties: {},
    key: 1
  }
}
CARD_6

I will send you the code in message,
Thank you!

Ah, got it. I think.

So, a few things are happening, which may be combining to get this issue.

In the player object, there are new fields (closestObject, closestObjectTemplate) which stores the information that playerTriggersItem pulls in. However, these fields are not overwritten with undefined in the event that you are not close to an object. So when you are far enough from any other object, and get the player.closestObject, it returns the last object you were close enough to when you pressed space.

Now, I realize your code is not pulling player.closestObject, but instead is pulling playerTriggersItem.closestObject. I worry that the websocket is somehow providing the stale player data, instead of providing the data the event returns. I have run a MPV test on prod through the console, and I do not see your error, suggesting something in prod has fixed or avoided the issue, but the WS API we have access to does not. This can sometimes happen if prod is using a newer version of the Websocket API and there is a translation issue.

To summarize, the object array does not have any mangled or invisible objects, which is good. Your code is probably pulling stale player data for some odd websocket reason. I would add a check to see if the object exists (game.getObjectById should work) and if it does not exist, you can assume it is the stale data.

Final note, code review stuff: your timeouts might (actually, are likely) to get you in trouble. Promises, and awaiting the promises to then catch error states will be a much more robust way of implementing your code. If you pass ‘true’ as a 4th parameter on deleteObject, for example, it will return a promise you can await. Hopefully that helps!

Hi @Bill_Uncork-It ,

Thanks for giving me a lot of suggestions.
I spent some times to figure out them and I really appreciate for that!

In my application, I also use game.getObject to check if the triggered item is exist, if not I will use filterObjectsInMap to find if any other object on the same position so that the user can pick up the object if there is something new.

It seems solve this problem, however, I found that when user go to another room and come back the room again, the mangled object which was invisible will become visible, and this really make user confused.
It’s visible but cannot be picked up.

image

If the condition happen, the user have to reconnect to the room to solve it.

Finally, thanks for your code review suggestions.
I’m trying to figure out and modify the code.
Thanks.

Just to clarify, when the user leaves the room and returns, they are able to see an object that does not appear on game.completeMaps[{MapID}].objects? (I would specifically check the browser console, not just console.log from your code)

I ran into an issue a few months ago when I was toying around with adding and removing objects. One of the big issues I found was with ‘key’ field mismatches. In theory, built in functions like deleteObject or setObject, etc, should guard against any mismatches, but I am not sure if they actually do. This could cause issues where the client side data has different data than the game server, leading to ‘invisible’ objects, or objects appearing/disappearing as users load/reload rooms.

It is just a theory, though. I am hoping the next @gathertown npm release will have a better way of handling object creation and deletion.

Yes, that’s what I mean.(when the user leaves the room and returns, they are able to see an object that does not appear on game.completeMaps[{MapID}].objects?)

Surprisingly, I cannot duplicate the bug today!
Although I don’t know is there anything update.
Thanks for your help and advice!