So I’m developing a side project in which NPCs are randomly placed around a randomly generated map in “tribes”. They will destroy environmental items to get resources, build houses, creating defenses against other NPCs, etc. It’ll all be autonomous and it’ll just be controlled by AI scripts.
Here’s an example of the ModuleScript I want to use to store and control the NPC inventories
(something I wrote up in about 5 mins, may not be 100% correct )
local NPCInventorySystem = {}
local NPCInventories = {} -- Inventory of all alive NPCs
local NPCTemplate = -- Template for new NPCs
{
Status = "Idle",
Team = nil,
Hunger = 100,
Thirst = 100,
Energy = 100,
Inventory =
{
Wood = 0,
Stone = 0,
Tools = {},
}
}
function NPCInventorySystem.AddNPC(NPC) -- Add a template
NPCInventories[NPC] = NPCTemplate
end
function NPCInventorySystem.ReturnNPC(NPC) -- Return an NPC inventory (if none, return nil)
return NPCInventories[NPC] or nil
end
return NPCInventorySystem
This is all well and good, but all of the NPCs are named based on their team color.
(i.e. Sand red NPC for Sand red team, Steel blue NPC for Steel blue team, etc)
I hypothesize that because all of the NPCs are named the same, separate inventories are not created, and their inventories are all linked (all five NPCs share an inventory, which I don’t want). Is there a way to prevent this?
Here are two (possible) solutions I’m trying to think of:
give every NPC a “key” value (Not what I prefer to do)
use NumberValues in a folder stored in an NPC (I don’t want to to do this either but I’m not fully opposed to it)
Is there any way to give each NPC a separate inventory while having them be named the same? Perhaps I’m totally understanding this wrong anyways. Thanks for your help
Since you’re setting every inventory identical to the Template therefore they will share the same properties even when one of them changes, What you have to do is run a for loop and basically get all the elements inside the Template and put it in a new table.
Your best/only option is to use an ID per NPC. This can be as simple as the current amount of NPCs in game +1 at the time of NPC creation (this could result in issues later on if NPCs despawn/respawn, etc…) Or you could go all out and use a GUID which will generate a guaranteed unique ID - this is overboard for this use-case… I would personally just use the last 12 digits of tick() or something as a unique ID.
As ObscureBrandon said, you need to essentially “clone” out the template table into a new table. Here’s some information on doing that: lua-users wiki: Copy Table
You might want to define a function for creating NPCTemplates instead of declaring one outright, since every assignment from this NPCTemplate will be a reference to the same table instead of creating a new one. Here is some code that basically does that:
--...
local function CreateNPCTemplate()
return {
--stats here
}
end
function NPCInventorySystem.AddNPC(NPC)
NPCInventories[NPC] = CreateNPCTemplate()
end
--...
This will guarantee that each table is a unique reference and not the same object over and over while still keeping your code clean.
Be warned that you can’t define the table beforehand and hand it down to the function, as this will give you the same referenced table again:
--Don't do this!
local NPCTemplate = {
--stats here
}
local function CreateNPCTemplate()
return NPCTemplate
end
--...
Instead of cloning or returning a new Table you could use JSON Encode and Decode to make a new copy as well, it’s just something fun that came to my mind.
I do believe that the decoded version will be a new Table rather than having the same address.
(Make sure they aren’t mixed tables or you’ll have problems)
Thanks for your help, guys. I seriously had no clue you had to copy the table, haha. Time to go update all of the other projects I’ve done this in… lol