Review on data structure for game appreciated!

Hey everyone, so I’m learning MongoDB to build the structure to my game and as I get closer to completing M320 - Data Modeling (MongoDB University) I’ve built the first version of my data structure. I was wondering if the community could give their opinion.

This is a very simple structure used to represent items owned by a player in a game. I wanted a way to make it so that there was never any stale data and that any items that are updated are immediately reflected in future queries.

So I came up with a structure where there is three collections with different types of documents.

The Item Prototype which contains static information about an item. Things like name, description, type, requirements and so on. These are things that are going to be read often, but written very rarely.

The Item is basically an instance of the Item Prototype this is an item that actually exists in the game. It contains some data specific to the item such as who owns it, who’s created it, the durability, etc.

The Character is nearly irrelevant here, but needed as the parent to the Item.

So here I will layout my structure…

Item PrototypeFormatted Code Link

{ 
      _id: ObjectId("..."),
      name: "Rusty Shortsword", 
      type: "weapon",
      subtype: "sword",
      description: "It looks like it hasn't been used in awhile.",
      stackable: false, 
      maximum_carry_limit: 2147483647,  // int32 max safe value 
      merchant_value: 0,
      requirements: {
        { k: "strength", v: 3 },
        { k: "quest", v: 17 }
      },
      modifiers: {
        { k: "accuracy", v: 1 }
      }
}

ItemFormatted Code Link

{
      _id: ObjectId("..."),
      item_id: ObjectId("..."),    // Item Prototype _id
      owned_by: ObjectId("..."),   // Character _id
      durability: 100.0, 
      created_by: ObjectId("..."), // Character _id 
      created_at: new Date()
}

CharacterFormatted Code Link

{
  _id: ObjectId("..."),
  ...
}

Item Prototype → Item will be a One-to-Zillions setup, where Item → Character will be a many-to-one.

Hi @Christian_Tucker,

Welcome to MongoDB community.

Happy to discuss thus data design.

Thinking in relationship ways for MongoDB is good but shouldn’t be the main aspects.

I think the main questions is how is your application access the data and what are the critical paths for its performance (reads of character data and its items or updating items)

My assumption is that reads will favor writes in this use case and you rather get the character and its inventory, at least first amount of items as quick as possible. Correct me if I am wrong.

In this case wouldn’t it make sense to keep last added items inside the character? Including the immutable items shown on the screen like its “name” and “description”

If user has a large amount of items you should outsource them to items collection by pulling a document out of a character and placing them in the items collection for when user clock on next items for example.

You can still keep the prototype collection for the extended information, but it feels a waste to query it for every time an item needs to project its name so this could be placed in every character array.

Let me know what you think.

Best
Pavel

Hey @Pavel_Duchovny thanks for the response… I will provide some information about the way the data is used below…

When information about the character is read, we do not need to access any of the items that belong to the character, it’s only when a character is “selected” from our game interface that the character’s inventory (items) are loaded. Because of the way we’ve decided to setup our inventory system, a character can have an “infinite” amount of items at any given time. This means that there can be thousands of items that belong to a given character.

Item reads will only happen during login, but writes will happen throughout the user’s session.

One of the reasons I wanted to seperate out the item documents into being their own non-duplicated data was for tracking. Based on other data that is not shown here I am able to determine where a specific item came from, every character that has ever possessed the item and where the item was removed from the game. (Destroyed, Consumed, Sold to a vendor, etc.)

Because of wanting to keep track of all this data, this means that I need to keep item information for every item instance in the game, instead of just having a subdocument of item-id, amount in a characters document / seperate inventory collection.

The prototype collection doesn’t need to be queried every time a user wants to get item information, instead, this data will sync’d to a memory database at runtime. The collection in this case is simply used to form a relation for memory-lookup and an easy way to allow our creatives to balance, design, and make changes to existing items for future updates. It will never be used in a $lookup and has a primary use-case of just being the raw-storage for a caching mechanism.

Hi @Christian_Tucker,

If you are confident that this schema is best design for you data access go for it.

Thanks,
Pavel