Hi, my friend and I are currently working on our first-ever shooter party-type game. I was wondering what type of data would be necessary to include in a table for Datastores.
I’ve looked around, and I can’t seem to find specifically anything on what type of data would be valuable to store. I understand that you could obviously add more data in the future or on updates, but I would like to know the gist of info that would be ideal to store before the release of our game.
If you’re going to store items in the inventory, ensure it’s typically index / id based. You don’t want any data like descriptions or anything that’ll unnecessarily use up the datastore such as static data. For example, if your guns have a leveling system, you would save the itemName, level. Then you can use this data to tie into a separate modulescript that contains all of the other information such as descriptions, firerate, etc.
I’m also just gonna recommend since you’re new, profile store is my goto since they handle session locking for you. There’s always potential for weird bugs using roblox’s default dataservice framework with limited validation
In the comments I have above there, I already state that Enums are used for the inventory and stuff like that to save up on static data with a number instead of a string, and in fact use the system you already describe.
I am also already using the ProfileStore module from loleris already for data (ever since I lost my data when playing my game once lol).
I just need some recommendations of what could be included, like maybe like a hasSeenTutorial or hasSeenNewUpdateLog boolean or a playerFirstTimePlayDate or something like that.
Ooooh, I like that, I’m not sure what it could be used for rn but it sounds useful for the future.
Rounds lost might be a bit redundant since you have totalMatches and the Wins already but idk if that cuts down on time calculating that everytime on the server or something.
For a shooter game I wouldn’t really worry about it, you’d be surprised how much data you can hold on a single key.
I’ve worked on a roleplay game and we had a lot of data we saved and barely scrapped any data limit off a single key. We saved purchased vehicles, vehicle customizations, purchase history etc.
Personally I would recommend to start doing tracking stuff early on so you already have the data in place when you decide to build on it later, I’m not saying things like region or age but how long a player has been playing the game, favorite weapon, and other things.
This data looks fine, however, I would remove level. You should derive that on runtime using their current XP. Doing this makes future changes to the system easier to maintain, otherwise, you will need to backfill.
If you store a list of timestamps when loses and wins happen, you could extract a ton of data out of that! That’d include:
Winrate
Total plays
Total wins
Total losses
Winstreak
Winrate over time
Winstreak over time
Wins per month, week, day, etc
Loses per month, week, day, etc
Winrate sampled from a time period
etc
Anything like that you could generate out of just those two lists of timestamps. You don’t need to use all of these, but I find it cool how you can get all that data out of just those two lists.
I’ll add those types of entries to my datastore now.
That does sound pretty cool to add for the player; it could definitely be added as a feature post-release with its own UI for the player to see.
I didn’t realize just how little each individual key took in size. I was worried about surpassing that if we had an influx of players or a lot of updates/content to store.
Hi, thanks for the feedback since I’ve never seen anything online about storing that specifically before, this sounds very interesting. I am pretty curious on how would this work, can you tell me more?
Like assuming an array is filled with Unix timestamps. You would be able to get the total wins and total losses from using an integer counter and a for loop through the arrays. That information could go through math operations and be manipulated to figure out winrate ((total wins / total plays) * 100%), total plays (total wins + losses), winstreak (the last Unix timestamp being either a win or loss to start/end), etc.
My only concern though is that if someone had like a couple hundred or thousand wins/losses, would the code still be efficient to iterate through the for loop over and over again every single time for Unix timestamps when that player joins the game compared to just simply calling an integer value from the datastore from like “Wins”, “Losses”, “TotalGames”, etc.
Hmm, well at that scale it wouldn’t really be efficient. I’d limit the tracking to 14-30 days only, anything beyond that should just be merged into one total wins/losses value! It could depend on how long it takes to get a win. If it’s only a minute or two, 30d might be too long. Each unix timestamp is just one float to store, but in datastores it’s converted to JSON which uses strings to represent numbers.
I see, personally, I feel like that would make the whole timestamp system a bit redundant than just using simple integer counters, maybe in the future I would implement something like that though.
Glad it helped! That same info completely shifted how I approach building data systems and working with large datasets, It’s been a game changer.
A year from now I’m sure we’ll have even better tools and options available. Other creators in the space keep blowing my mind with what they’re doing.
Kills and Deaths — K/D is the first thing players check in any shooter. Without it, your game feels bare.
BestKillStreak — separate from WinStreak. A player can go 20-0 in a losing round.
Losses — lets you compute W/L ratio client-side without extra logic. Cheap to store, painful to retrofit later.
PlayTime — total seconds in-game. Useful for loyalty rewards, badges, and analytics down the line.
Loadout / persistence:
EquippedWeapons — a small table (e.g. primary/secondary slots) tracking what the player has selected, not just owned. Otherwise on rejoin they lose their loadout.
Meta / account info:
JoinDate — store once on first join (os.time()). Lets you do “OG player” badges, loyalty events, etc. You cannot reconstruct this later.
LastSeen — useful for detecting returning players and triggering welcome-back bonuses.
Economy:
If you ever plan a premium currency (Robux-purchased), add a separate key for it now — e.g. Gems = 0. Mixing it with earned currency causes accounting headaches later.
Cosmetics:
If Inventory is already meant to cover skins/trails/etc., you’re fine. But if Weapons and Inventory are both gear, consider splitting out Cosmetics = {} explicitly so the schema stays readable.