colyseus / colyseus-defold

⚔ Colyseus SDK for Defold Engine
https://docs.colyseus.io/getting-started/defold-client/
MIT License
58 stars 10 forks source link

I don't think on_remove callbacks are working on ArraySchema when using splice #58

Open mrosati84 opened 1 week ago

mrosati84 commented 1 week ago

Hi and first of all THANK YOU for this great project. i love it!

I might have encountered an issue.

I'm running a Defold project, and I'm experiencing an unexpected result when trying to remove an item from ArraySchema using the splice method, as suggested in the documentation.

Here's a snippet of my code of my room state class:

remove_projectile(seq: number) {
    console.log("REMOVE PROJECTILE");
    console.log(seq);

    const index = this.projectiles.findIndex((p) => p.seq == seq);
    this.projectiles.splice(index, 1);
}

this code works like a charm when inspecting the state in Colyseus, however this is not triggering the on_remove on my Defold code:

room.state.projectiles:on_remove(function(projectile, session_id)
    print("PROJECTILE ON REMOVE")
end)

but strangely, this callback in Defold actually works if i use for instance the pop() method in Colyseus (here's the modified code)

remove_projectile(seq: number) {
    console.log("REMOVE PROJECTILE");
    console.log(seq);

    const index = this.projectiles.findIndex((p) => p.seq == seq);
    this.projectiles.pop();
}

of course i can't use pop() for my intent because i need to remove a specific item.

Have i found an issue or am i doing something wrong here?

Thanks! Matteo

endel commented 1 week ago

Hi Matteo 👋 Thank you for the kind words 💙

I've just tried splicing a single item and it seems to be working. Do you mind sharing a reproduction scenario? There are a few known issues regarding ArraySchema, you may be experiencing one: https://github.com/colyseus/colyseus/issues/641

I'll go ahead and suggest a workaround:

this.state.projectiles.splice(index, 1);
this.broadcastPatch(); // consume/broadcast the changes immediately

There's a major refactoring of schemas going on https://github.com/colyseus/colyseus/issues/709, I'm currently finishing one last issue before releasing Colyseus 0.16 and v3 of schemas. Initially, only the JavaScript SDK will be supported, and as things are stable, other SDKs will be implemented as well!

Cheers!

mrosati84 commented 1 week ago

hey endel,

you should be able to access the game repo here: https://gitlab.com/mrosati/defold-real-time-multiplayer

to reproduce, you need to perform a few steps:

  1. checkout the projectiles branch
  2. open the defold project and do Project -> fetch libraries
  3. you need to bundle first the authority game server so from defold, choose "project -> bundle" then pick your platform, and build it headless
  4. start colyseus, it's in the server directory
  5. start the authority game server from the command line
  6. now you can start the game choosing "build" command from defold.

the parts you might want to look are:

again, the callback works if i don't use splice and i use something like pop in Colyseus.

Also, i have tried the this.broadcastPatch() method, and it seems to solve the issue, but I understand it should not be invoked under normal circumstances right?

EDIT: even by using this.broadcastPatch() the callback is invoked very inconsistently, so it's not very reliable either.

Thanks! Matteo