Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Best and efficient way to store rarity of an object?

So a lot of games now contain items that you collect, often along with a rarity for example, a standard dog pet has a rarity of common whilst a dragon pet has a rarity of legendary. I plan to adopt to this method and plan to use tables and dictionaries. But is it best to create stats of the object and have the rarity in it for example:

Dog = {Damage = 50, Rarity = Common}

Now the problem with this method is that if I were to have a system where players buy an egg or loot box with an allocated rarity, how would the loot box or egg know which pet rarity is what without cycling through all of them and adding them up again, to then cycle this new rarity specific table. But to get around this is to create a table for rarities for example:

Common = {Dog, Cat}

But now the problem here is that let’s say the player opens their inventory and each item will be highlighted in a different colour depending on the rarity, how would the client side know if an item is common unless it cycles through the table above until it matches the name, and finds at which rarity the cycle has stopped at.

The last way that I see to do this is by implementing two different tables, a stats table and a rarity table, but I feel there is a more efficient way. How do the big games such as pet sim do this?

2 answers

✓ Accepted answer

You can do both at the same time. You can do this manually, but it is error prone; use functions to automate it instead (below).

Also note that whenever you are thinking in terms of searching through a list to match a specific string, use a dictionary.

Code:

local function RarityGroup(name, color)
	return {
		Name = assert(name, "Rarity groups must have a name"),
		Color = assert(color, "Rarity groups must have a color"),
	}
end
--Rarities
local common = RarityGroup("Common", Color3.new(1, 1, 1))
local legendary = RarityGroup("Legendary", Color3.new(1, 1, 0))

local items = {} -- List<item>
local itemsByRarity = {} -- Dictionary<rarity, List<item>>
local function Item(stats)
	assert(stats.Rarity, "All items must have a rarity")
	local item = stats
	items[#items + 1] = item
	-- Get (or create) the list of items for this rarity level
	local list = itemsByRarity[stats.Rarity]
	if not list then
		list = {}
		itemsByRarity[stats.Rarity] = list
	end
	list[#list + 1] = item
	return item
end
--Items
local dog = Item({Name = "Dog", Damage = 50, Rarity = common})
local dragon = Item({Name = "Dragon", Damage = 200, Rarity = legendary})
local cat = Item({Name = "Cat", Damage = 50, Rarity = common})

--Demo: items by rarity
local commonItems = itemsByRarity[common]
for i = 1, #commonItems do
	print(commonItems[i].Name, commonItems[i].Damage)
end
--Demo: can get rarity name and color from any item:
for i = 1, #items do
	print(items[i].Name, items[i].Rarity.Name, items[i].Rarity.Color)
end

-- Say you want to look items up by name (ex maybe you store the name of an object in the datastore):

--Manual version
local itemsByName = {}
itemsByName.Dog = dog -- equivalent to: itemsByName["Dog"] = dog

local name = "Dog"
local item = itemsByName[name]
print(item.Name, item.Damage) -- will print Dog 50

-- You could expand on the 'Item' function to add items to the 'itemsByName' dictionary automatically

(Note that the assert commands are just there to make sure you don't forget information when adding groups or items.)

Doing things this way is a bit more complicated to set up (as you can see) and will use slightly more memory (though the difference will be very very little - you won't notice), but lets you look up whatever list you need without going through all your items each time.

1 comment

0

I somewhat actually understand this and makes me feel good about my coding capabilities, I feel I can use the source code and manipulate relatively easily. Thank you so much!

This discussion is preserved as it was. New answers, comments, and votes are closed.