Best way to handle versioning?

Overall, what’s a good way to go about handling versioning?

Lets take one example from my game. Equipment information, such as stats:

Equipment template:

{
  "id": "weapon_iron_sword",
  "type": "weapon",
  "baseStats": {
    "attack": 10,
    "attackSpeed": 0,
  },
  "levelScaling": {
    "baseMultiplier": 1,
    "multiplierPerLevel": 0.1
  },
}

For players actual inventory, it’s just:

{
  "id": "1bdca98f-e1e4-4988-826f-10fa70b5f748",
  "level": 1,
  "rarity": "epic",
  "templateId": "weapon_iron_sword"
}

Lets say the game is v1.0, and in the new v2.0, I decided to rework that weapon stats completely differently.

I believe most mobile games allow a ~1 week extra time when a new game version comes out before forcing the player to update, especially since Apple App Store can take a while to approve update and roll it out fully to all users.

I want it so players still on v1.0 app continue using the old v1.0 version of the equipment stats, while players who’ve updated to v2.0 app now use the v2.0 version of the equipment stats.

One additional requirement is still being able to hot fix: say I made a mistake in v1.0 and the equipment stats are too overpowered, in such case I should be able to adjust the v1.0 equipment stats without any app update needed.


My current approach:

  • client always sends clientVersion which is the app version
  • for equipment templates, use version appendix for collection name (e.g. equipment_templates_v1_0_0)
  • my code uses helper function when ever fetching equipment template, get the collection based on clientVersion

Notes:

  • I should make a clean up method to delete super old equipment template collection versions that are for a clientVersion that is no longer supported.
  • Not sure the best way to do this, I don’t think there’s any Nakama API for getting all collection keys in the database. Instead, I have a separate collection called equipment_templates_versions with an array of the active version numbers. Let me know if there’s a better alternative way.
  • Then I have an admin RPC for this, or will consider a CRON job.

Data migrations is also one of my concerns which I need to learn the best way to deal with. For example, changing the way the player data is stored. I’m assuming I should do something like in player object store dataVersion, and compare with some sort of migrations collection like player_data_migrations which sequentially runs some custom defined migration functions up until the latest version needed, then set dataVersion to latest if successful.

I assume it’s best to do this during an authentication hook.


Appreciate any advice on how to approach these sort of things, and if I’m doing it the right way or not.