colyseus / colyseus-defold

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

Help with getting data from room state #50

Closed bedryck closed 9 months ago

bedryck commented 9 months ago

It's not a bug, I am in the process of learning Colyseus. One thing with which I have a problem now is that room.state has a lot of additional internal data. Example: If I call - pprint(self.room.state.players) I get:

{ --[[0000019FBDB59290]]
  items = { --[[0000019FBDB59350]]
    65a24ee976d0a46c2988a1bf = { --[[0000019FBDB59C10]]
      __refid = 3,
      nickname = "test2",
      __callbacks = { --[[0000019FBDB5A700]]
        score = { --[[0000019FBDB5A750]]
          1 = function: 0x019fbc2b0da0
        }
      },
      id = "65a24ee976d0a46c2988a1bf"
    },
    659884a1b6f3d582d7e9fea0 = { --[[0000019FBDB583D0]]
      __refid = 7,
      nickname = "test",
      id = "659884a1b6f3d582d7e9fea0"
    }
  },
  props = { --[[0000019FBDB59240]]
    __refid = 2,
    __callbacks = { --[[0000019FBDB56530]]
      0 = { --[[0000019FBDB56580]]
        1 = function: 0x019fbc347080,
        2 = function: 0x019fbdb56cf0
      },
      128 = { --[[0000019FBDB56E40]]
        1 = function: 0x019fbc2a0f20
      }
    },
    _child_type = { --[[0000019FBDB55AB0]]
      _context = { --[[0000019FBDB96F90]]
        types = { --[[0000019FBDB97070]]
          0 = { ... } --[[0000019FBDB55AB0]],
          1 = { --[[0000019FBDB55C60]]
            _context = { ... } --[[0000019FBDB96F90]],
            _schema = { --[[0000019FBDB55CB0]]
              players = { --[[0000019FBDB55E30]]
                map = { ... } --[[0000019FBDB55AB0]]
              },
              gameStage = "string",
              ownerId = "string"
            },
            _fields_by_index = { --[[0000019FBDB55D00]]
              1 = "players",
              2 = "ownerId",
              3 = "gameStage"
            },
            __index = { ... } --[[0000019FBDB55C60]],
            _typeid = 1
          }
        },
        schemas = { --[[0000019FBDB96FE0]]
          1 = { ... } --[[0000019FBDB55AB0]],
          2 = { --[[0000019FBDB55C60]]
            _context = { ... } --[[0000019FBDB96F90]],
            _schema = { --[[0000019FBDB55CB0]]
              players = { --[[0000019FBDB55E30]]
                map = { ... } --[[0000019FBDB55AB0]]
              },
              gameStage = "string",
              ownerId = "string"
            },
            _fields_by_index = { --[[0000019FBDB55D00]]
              1 = "players",
              2 = "ownerId",
              3 = "gameStage"
            },
            __index = { ... } --[[0000019FBDB55C60]],
            _typeid = 1
          }
        }
      },
      _schema = { --[[0000019FBDB55B00]]
        nickname = "string",
        score = "number",
        id = "string"
      },
      _fields_by_index = { --[[0000019FBDB55B50]]
        1 = "nickname",
        2 = "id",
        3 = "score"
      },
      __index = { ... } --[[0000019FBDB55AB0]],
      _typeid = 0
    }
  },
  dynamic_indexes = { --[[0000019FBDB593F0]]
    1 = "65a24ee976d0a46c2988a1bf",
    2 = "659884a1b6f3d582d7e9fea0"
  },
  indexes = { --[[0000019FBDB593A0]]
    1 = "65a24ee976d0a46c2988a1bf",
    5 = "659884a1b6f3d582d7e9fea0"
  }
}

What I need. I want to get pure state example: pprint(self.room.state.players)

 { --[[0000019FBDB59350]]
    65a24ee976d0a46c2988a1bf = { --[[0000019FBDB59C10]]
      nickname = "test2",
      score = 1,
      id = "65a24ee976d0a46c2988a1bf"
    },
    659884a1b6f3d582d7e9fea0 = { --[[0000019FBDB583D0]]
      nickname = "test",
      score = 1,
      id = "659884a1b6f3d582d7e9fea0"
    }

Why I need it. I have a room controller that sends messages to needed components and in one case I need to send room.state.players, but such as room.state.players have functions I get error that msg.post in Defold cannot send data.

I think I can avoid this error just iterating by room.state.players and accumulating data which I need, and then send data through msg.post

Or I can use singleton where I save instances of room and then from component get state from singleton without using msg.post

But maybe I missed something and there is a way to get a pure state. Thank you!

endel commented 9 months ago

Hi @bedryck, thanks for the feedback - we could perhaps implement this as an instance method, e.g.: room.state.players:to_message()

I'm afraid returning the clean structure directly is not going to be possible due to how the de-serialization works internally.

bedryck commented 9 months ago

It will be very useful for me, also it will be helpful in debugging as well. Let me know if you do something like that. I think I'll solve my problem using a singleton for now. Thank you for your reply!

endel commented 9 months ago

Thanks @bedryck, I've just released 0.15.7 adding a :to_raw() method on all schema instances. 🙌

This now outputs more easily-readable output:

pprint(room.state.players:to_raw())
bedryck commented 9 months ago

You are amazing. I just tested and it is exactly what I need! Thank you a lot!