How to make a mapping between clients and players in multiplayer games and shareable saves?

Godot Version

4.2.1

Question

I’m making a multiplayer game. But I don’t know how to make a mapping system.
These is current progress i made:

  • Serialization in saving and loading
  • Player system based player id
  • Player data saving and loading

I think the system need to have these features:

  • Mapping between clients and player ids.
  • In every save and multiplayer games, the client is hard to login as another player.
  • When saves are shared, someone can’t login as another player in other place hosted this save.
  • In multiplayer, clients can’t got another player’s private data.

I think this is hard for everyone. Thanks for answer.

You essentially want a full profile and login system, so you should approach it like that.
From what I get this is a large world in which multiple people can wander around across multiple gaming sessions?

So essentially you have to:

  1. establish a secure encryption protocol between the client and the server
  2. build a database system on the server that manages logins froom hashed paswords and usernames / userids
  3. link the players from this database with the information on player position and stuff inside a game
  4. store individual games data permanently on the server
  5. give players a way to join/create games on the server

Quite the undertaking haha

1 Like

I solved it by encrypt mapping in saving.
My solution:

Saving:

    stream.store_64(player_tokens.size())
    var aes_key = Global.configs.g("token-mapping-key")
    for token in player_tokens:
        var player_id = player_tokens[token]
        var token_buffer = token.to_ascii_buffer()
        token_buffer.resize(ceili(token_buffer.size() / 16.0) * 16)
        aes_context.start(AESContext.MODE_ECB_ENCRYPT, aes_key)
        var token_encrypted = aes_context.update(token_buffer)
        aes_context.finish()
        stream.store_32(token_encrypted.size())
        stream.store_buffer(token_encrypted)
        stream.store_64(player_id)
    aes_context.start(AESContext.MODE_ECB_ENCRYPT, aes_key)
    var buffer = aes_context.update(magic_number)
    aes_context.finish()
    stream.store_16(buffer.size())
    stream.store_buffer(buffer)

 

Loading:

    player_tokens = {}
    var aes_key = Global.configs.g("token-mapping-key")
    for _1 in range(stream.get_64()):
        var token_buffer = stream.get_buffer(stream.get_32())
        token_buffer.resize(ceili(token_buffer.size() / 16.0) * 16)
        aes_context.start(AESContext.MODE_ECB_DECRYPT, aes_key)
        var token_decrypted = aes_context.update(token_buffer).get_string_from_ascii()
        player_tokens[token_decrypted] = stream.get_64()
        aes_context.finish() 
    var buffer = stream.get_buffer(stream.get_16())
    buffer.resize(ceili(buffer.size() / 16.0) * 16)
    aes_context.start(AESContext.MODE_ECB_DECRYPT, aes_key)
    var buffer_decrypted = aes_context.update(buffer)
    aes_context.finish()
    if buffer_decrypted != magic_number:
        player_tokens = {}
        player_tokens[Global.configs.g("player-token")] = 1