In terms of lua processing, putting the information into a table (your first option) will be tons faster than using an "if elseif" chain. Lua can read the value for any given key extremely quickly, but it has to consider every "if" condition separately.
You seem to be thinking that it will take time for lua to "return" the table to whatever is asking for the information. However, lua won't be copying it at all - it will make the table once and then simply copy a reference to the table as needed (and a reference is as fast as anything, including a single number). Further, once a ModuleScript has been run, it won't run again - whatever it does is saved to memory for the rest of the server's life.
In terms of memory, the first option is better too -- it won't be making a lot of temporary tables. It will have a single larger table that will always be in use, but I don't think that'll be a problem unless each entry has thousands of variables (where-as you currently show 2 in your demonstration, ItemID and Image. Even having 100 variables for each of 1000 objects should be okay).
More important is how easy it will be for you to manage the data. If every object has the same fields, you might consider using a function:
local data = {}
local function Item(id, image)
local item = {ItemId = id, Image = image}
data[id] = item
return item
end
Item(1, "")
Item(2, "")
local sword = Item(3, "")
sword.Special = 5
local function Weapon(id, image, damage)
local item = Item(id, image)
item.Damage = damage
return item
end
local sword2 = Weapon(4, "", 5)
local betterSword = Weapon(5, "", 10)
return data
This set up lets you do some interesting things:
- You could give each of these item tables functions
- You could error if an argument was not provided or was the wrong type (which would help with data entry problems). ex:
local function Weapon(id, image, damage)
if type(damage) ~= "number" then error("Damage must be a number") end
local item = Item(id, image)
item.Damage = damage
return item
end
local sword3 = Weapon(6, "", "", 12)
There's also a more complicated option where you provide small tables into functions (sort of like named arguments):
local data = {}
local idKey = "ID"
local itemKeys = {[idKey]="ItemId", Image="Image"}
local weaponKeys = {dmg="Damage"}
local function Gen(keys, base)
return function(stats)
local item = base and base(stats) or {}
data[stats.ID] = item
for k, v in pairs(keys) do
if not stats[k] then error("Item did not have key " .. k) end
item[v] = stats[k]
end
return item
end
end
local Item = Gen(itemKeys)
local Weapon = Gen(weaponKeys, Item)
Item{ID=1, Image=""}
Weapon{ID=4, Image="", dmg=5}
return data
All this said, especially if you're not comfortable using what I've suggested, just using tables is perfectly fine. The only downside is that it might be more difficult to catch errors and it might be harder to change (if you ever need to change the name of a field or something) - but Find & Replace can help a lot too.
(This paragraph only applies if your script is downloaded to the client.) Though 5000 lines of information isn't necessarily too much of a strain, if you find that it does become an issue for clients (you should test this first, though), you could set it up so that the information stays on the server except for when needed. Doing so would mean that the client doesn't ever receive your 5000 line script, it just asks the server (through some RemoteFunction) for information on whatever object(s) it needs to know about. If any one player rarely needs information on many of your objects, this would save on start-up time (at the cost of a bit of latency when you do end up needing the information, since it would have to stop and ask the server for it instead of already knowing what it is).
1 comment
Why not do "ItemId = AssetId"?