hathora / builder

Multiplayer game framework

Home Page:https://docs.hathora.dev/#/builder/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How do you safely change the HathoraConfig types?

Strikeskids opened this issue · comments

I'm new to the hathora project and didn't see any documentation talking about the upgrade process for your HathoraConfig types. Did I miss it?

I'm wondering about questions like:

  • What if my client is running an older version of the types than the server I'm connecting to?
  • What if I deploy a new server, it breaks, and I need to roll it back but some clients already have downloaded the new version of the types?
  • How do I make sure that the clients and the servers are able to talk to each other?

The coordinator process described in the architecture docs indicates that clients should be able to seamlessly transition between backends.

  • How do we make sure that all of the backends are running the same version of the software?
  • What if a client gets migrated from a backend from one version to a backend of a different version?

There's a similar issue with the transaction log of all method calls being used for persistence.

  • What if the types of method calls changes?
  • How do I make sure that all of my old message calls can be read and handled by the new version of my software?

Hey @Strikeskids, all great questions. I'll admit we haven't thought very deeply on this topic, so would be interested in getting your thoughts on what you'd like to see in a solution here.

On the client <> server communication part: right now the model is just to update clients and servers at the same time whenever there are breaking changes to the API. If you want to update client and server separately, the only thing I can think of is defining a more generic userState, for example using union types. Something like this:

types:
  PlayerStateV1:
    foo: string
  PlayerStateV2:
    bar: string
  PlayerState:
    - PlayerStateV1
    - PlayerStateV2

userState: PlayerState

On the persistence side: we plan on implementing a migration system. The first step towards this is implementing a snapshotting feature, which would serialize/compact the replay log into a snapshot file using a user defined serialization function (InternalState -> byte array). Once we have this place, we would add a feature which lets users define migration functions which read the serialized byte array and deserialize it into the upgraded InternalState representation. This way, impl.ts doesn't need to be aware of any migrations and always has the most recent InternalState definition.