How do I structure my shop?

Hello! I am in need of help on how to structure my shop.

Here’s an explanation of how it is currently structured.

Character 1’s requirements: 10 enemies killed.
The player’s data has 7, so it’s at 7/10.
this character existed when the player gained the 7 kills

Character 2’s requirements: 15 enemies killed.
the same thing happens.
this character existed AFTER when the player gained the 7 kills

The shop looks at the player’s data for total kills

How do I make it so that when something new gets added but with the same requirements such as kills, it would be 0? Like:

Character 3’s requirements: 20 enemies killed
The player’s data has 7, but the requirement is at 0/20.

I was thinking of adding another branch of data primarily for the shop, but i’m not really sure on how to make it. Here is an example of what I want to do:

PlayerData = {
  MainData = {
    ["Total Enemies Killed"] = 7
  }
  ShopData = {
    ["Character 1"] = {
      ["Total Enemies Killed"] = 7,
    },
    ["Character 2"] = {
      ["Total Enemies Killed"] = 0,
    },
  },
},

I would store the goal inside of an instance.
I am unsure on how to approach this, especially with non number requirements like having a character equipped or something like that. I also do not know a good way to add onto the character’s requirements when the main one gets added onto. Thank you!

I’m not here to solve the problem, but give feedback on the system.

I’m not sure why you would at all want a system like this, I personally think it would be more frustrating than anything.

(Assuming these characters are purely cosmetic, but if they’re not, that adds a new question on why you’re locking stuff like this)


Here’s a scenario:

  • Player 1 has been playing the game for a few weeks and has racked up 510 kills.
    Player 2 only started playing today, and only has 15 kills.

  • A new skin got added today, with a requirement of 550 kills.

  • Player 1 should expect to be able to purchase that new skin soon, as they already have 510 kills, however the system says they’re only at “5/550 kills”, causing Player 1 to assume that the game is bugged, or get extremely frustrated that they have to do all that grinding again.

  • Player 2 has no idea this mechanic exists. Every skin displays as having “15/x kills”.

  • Player 1 quits the game, never returns.

  • Player 2 keeps playing, and eventually the cycle repeats itself, with Player 2 now in this scenario, being Player 1.


Think of this system as resetting everyone’s progress in an RPG whenever a new area gets added.
Anyone who played prior to the update will be angry, meanwhile new players will just be confused to why everyone’s angry.


Alternatively, in a shooter scenario:
A new attachment gets released for the assault class, with a requirement of 500 kills. Players who already have 500 kills in that class do not own the attachment for some reason, only to figure out they have to get another 500 kills to unlock it.


Of course, bit of a stretch there with the RPG scenario, but point is, if someone already has the requirements to unlock something, they should just unlock it.

Extra grind is not fun, especially when you as the player feel you should already have the item.


Anyway, to answer your question, I do think that your thought out system would be one of the only way to do this, however a more optimal system would be to roll out skins in groups, and then save data for each group of “Characters” instead of for each skin separately.
Effectively, what you already have but instead of per character, its per group.

ShopData = {
    ["CharacterRollout1"] = 28,
    ["CharacterRollout2"] = 12,
    ["CharacterRollout3"] = 0,
}

--// searching character rollouts:
local folder = game.ReplicatedStorage.CharactersFolder
-- - CharacterRollout1: Folder
-- - - Character1: Model
-- - - Character2: Model

-- - CharacterRollout2: Folder
-- - - Character3: Model

-- - CharacterRollout3: Folder
-- - - Character4: Model
-- - - Character5: Model

for rollout, kills in ShopData do
    for _, character in folder[rollout]:GetChildren() do
        if character:GetAttribute("Kills") <= kills then
            --// Character is purchasable.
        else
            --// Character is not purchasable.
        end
    end
end

Hello, the characters aren’t cosmetic. The reason why I wanted a system like this, is purely because it would be way too easy to buy a new character for the old players who already have a lot. If I were to release a new character, I want the players to atleast grind just a bit for it, it would increase playtime and definitely annoy players.

But, it would benefit my game and my community (most of it); I believe that it’s most fun when my community interacts with each other, like asking ‘who already has this character? i wanna see what it does!’. I do not want the players to immediately get the character and try it out for a few minutes, before leaving. The requirements I would be putting won’t be too hard to achieve to the point that my players would get angry (hopefully).

I will try out what you suggested, thank you!