How to best implement a sorted list of JSON data accessible for all players to submit to multiple times?

I am working on a webGL game where anyone that plays the game (anonymously) can submit a piece of text/content to be placed in the world for everyone to see. When a new piece of text is submitted, any player that is close enough to see will see a spawning animation of that text being placed. All submitted texts are stored on the server.

I am using Nakama as a backend for storing the placed text objects using a json containing {x, y, z, text} through the leaderboard system, but I am not sure if this is the best approach.

Currently, every text object placed by a player is a leaderboard score submission with the json in the metadata and the submission time as score (so that the list remains sorted in time).

However, Nakama does not have a leaderboard update method for including multiple submissions for a player. The old submissions get overwritten by the “higher” score.

To circumvent this, I am creating a new session for every object that is placed, but this is probably not very efficient since this means every text object receives its own random user account etc. Imagine that the amount of text objects will easily exceed 10 000.

Ideally, a single user can submit multiple scores(=text objects in the world) and they will all be stored. So what I am looking for with Nakama, is a single big, list of JSON to which multiple users can read and submit simultaneously at high frequency, sorted by submission date.

How can I best implement such a data structure for my game using Nakama?
(See attached picture for the game)

  1. Versions: Nakama 3.5, Linux Docker, Godot 4 Client Nakama
  2. Server Framework Runtime language (If relevant) X
{code or log snippet}

:tv: Media:

Hello @Arceryz,

Is there a particular reason why you’re using a leaderboard instead of the Storage Engine?

I think the best way to achieve this would be to split the map into a grid, each of the coordinates where you place a text blob (object/column) should then fall into one of the squares of the grid.

The size of each square will depend on how granular you want the grid to be, but each square should be able to contain multiple objects (as per your image example - I’m also assuming that the columns may not overlap).

Each of these squares would map into a collection of the Storage Engine, this allows you to use the StorageList to fetch all the entries in a square, and you can then sort them in the client by create_time if needed.

Each of the actual text objects would map to a Storage Engine entry key (you can create a unique key by using the actual coordinates if there cannot be multiple entries with the same coordinates, otherwise use some unique identifier).

This will allow a user to submit multiple objects into the world, and should allow you to fetch objects efficiently as the user approaches and moves to different squares.

Hope this helps.