Hello, everyone.
To test my Lua abilities, I set out on creating a self-replicating, semi-intelligent, and thrilling hive system reminiscent of the Faro Robots from Horizon: Zero Dawn. A few bumps were encountered, but I mostly got everything up to speed on my own. I have a Queen, a spawning system, resource collection, outside response, etc. etc.
The problem occurs in the Queen's Resources NumberValue, defined as "Resources." The Queen script has no issue keeping track of this value when it comes to spawning the robots, nor when it reaches zero and stops drone production. The issue occurs when the Robots return to the Queen to deposit their harvested resources; Instead of increasing from the zero resources that warranted the collection, the Queen suddenly regains the 500 resources within her NumberValue, and the robots add onto it. In addition, this value has no effect on the value within the Queen's script, as the Production function does not resume even though it has surpassed the threshold.
local Queen = script.Parent local SpawnPart = script.Parent:WaitForChild("SpawnPart") local Resources = Queen.Resources.Value local IsCreatingDrone = false local WorkerControl = game.Lighting:WaitForChild("WorkerControl") local QueenSerial = Queen.QueenSerial.Value local Crown = Queen.Crown if QueenSerial == 0 then QueenSerial = math.random(1, 9999999999) print("Queen " .. tostring(QueenSerial) .. " is now online.") Queen.Name = QueenSerial end function SpawnDrone(dronetype) if dronetype == "Worker" and IsCreatingDrone == false then IsCreatingDrone = true Resources = Resources - 50 local Worker = Instance.new("Model", Queen) Worker.Name = "Worker Drone" local WorkerHead = Instance.new("Part", Worker) WorkerHead.Name = "Head" WorkerHead.Size = Vector3.new(2, 1, 2) WorkerHead.Material = Enum.Material.Neon WorkerHead.BrickColor = BrickColor.new("Lime green") WorkerHead.Position = SpawnPart.Position + Vector3.new(0, 4, 0) local Weld = Instance.new("WeldConstraint", WorkerHead) Weld.Part0 = WorkerHead local WorkerBody = Instance.new("Part", Worker) WorkerBody.Name = "HumanoidRootPart" WorkerBody.Size = Vector3.new(2, 1, 2) WorkerBody.Material = Enum.Material.Metal WorkerBody.BrickColor = BrickColor.new("Dark stone grey") WorkerBody.Position = WorkerHead.Position + Vector3.new(0, -1, 0) Worker.PrimaryPart = WorkerBody Weld.Part1 = WorkerBody local Humanoid = Instance.new("Humanoid", Worker) local IsActive = Instance.new("BoolValue", Worker) IsActive.Name = "IsActive" local ResourceLoad = Instance.new("NumberValue", Worker) ResourceLoad.Name = "ResourceLoad" local WorkerControl = WorkerControl:Clone() WorkerControl.Parent = Worker WorkerControl.Disabled = false local HomeQueenSerial = Instance.new("NumberValue", Worker) HomeQueenSerial.Name = "HomeQueenSerial" HomeQueenSerial.Value = QueenSerial local DroneSerial = Instance.new("NumberValue", Worker) DroneSerial.Name = "DroneSerial" DroneSerial.Value = math.random(1, 9999999999) WorkerHead.Anchored = true WorkerBody.Anchored = true wait(2) WorkerHead.Anchored = false WorkerBody.Anchored = false print("Drone " .. tostring(DroneSerial.Value) .. " is now online.") print("Queen " .. tostring(QueenSerial) .. " has " .. tostring(Resources) .. " resources remaining.") IsCreatingDrone = false end end function Dormant() Crown.BrickColor = BrickColor.new("New Yeller") if Resources >= 50 then Production() else wait(1) Dormant() end end function Production() Crown.BrickColor = BrickColor.new("Lime green") if Resources >= 50 then SpawnDrone("Worker") wait(4) Production() elseif Resources == 0 then print(("Queen " .. tostring(QueenSerial) .. " has no resources. Activating Dormancy Protocols.")) Dormant() end end Production()
And now for the Drones.
local PathfindingService = game:GetService("PathfindingService") local DroneSerial = script.Parent:WaitForChild("DroneSerial").Value local dronepart = script.Parent.HumanoidRootPart local humanoid = script.Parent:WaitForChild("Humanoid") local WorkerHead = script.Parent:WaitForChild("Head") local HomeQueenSerial = tostring(script.Parent:WaitForChild("HomeQueenSerial").Value) local resourceload = script.Parent.ResourceLoad.Value local isactive = script.Parent.IsActive.Value local target local HarvestingOrganicMatter = false local OrganicMatterDirectory = game.Workspace:WaitForChild("OrganicMatterDirectory") local QueenDirectory = game.Workspace:WaitForChild("QueenDirectory") local Queens = QueenDirectory:GetChildren() function ReturnToHive(targethive) local HomeQueen local QueenTitle = tostring(HomeQueenSerial) for _, i in pairs(Queens) do if QueenTitle == i.Name then HomeQueen = i end end print("Worker Drone " .. DroneSerial .. " is returning to Queen " .. QueenTitle .. " at " .. tostring(HomeQueen.SpawnPart.Position)) WorkerHead.BrickColor = BrickColor.new("Lime green") local ReturnPosition = HomeQueen.SpawnPart.Position - Vector3.new(0, 2, 0) local path = PathfindingService:CreatePath() local waypoints local currentWaypointIndex local function followPath(destinationObject) path:ComputeAsync(dronepart.Position, ReturnPosition) waypoints = {} if path.Status == Enum.PathStatus.Success then waypoints = path:GetWaypoints() currentWaypointIndex = 1 humanoid:MoveTo(waypoints[currentWaypointIndex].Position) else humanoid:MoveTo(dronepart.Position) end end local function onWaypointReached(reached) if reached and currentWaypointIndex < #waypoints then currentWaypointIndex = currentWaypointIndex + 1 humanoid:MoveTo(waypoints[currentWaypointIndex].Position) end end local function onPathBlocked(blockedWaypointIndex) if blockedWaypointIndex > currentWaypointIndex then followPath(ReturnPosition) end end path.Blocked:Connect(onPathBlocked) humanoid.MoveToFinished:Connect(onWaypointReached) followPath(ReturnPosition) WorkerHead.BrickColor = BrickColor.new("New Yeller") for i=1, 50 do resourceload = resourceload - 1 wait(1) HomeQueen.Resources.Value = HomeQueen.Resources.Value + 1 end print("Worker Drone " .. DroneSerial .. " has deposited resources at Queen " .. QueenTitle .. " and is returning to harvesting.") print("Queen " .. QueenTitle .. " now has " .. tostring(HomeQueen.Resources.Value) .. " resources.") WorkerHead.BrickColor = BrickColor.new("Lime green") IdentifyTarget() end function RetrieveResource(targetresource) print(targetresource.Position) local path = PathfindingService:CreatePath() local waypoints local currentWaypointIndex local function followPath(destinationObject) path:ComputeAsync(dronepart.Position, targetresource.Position) waypoints = {} if path.Status == Enum.PathStatus.Success then waypoints = path:GetWaypoints() currentWaypointIndex = 1 humanoid:MoveTo(waypoints[currentWaypointIndex].Position) else humanoid:MoveTo(dronepart.Position) end end local function onWaypointReached(reached) if reached and currentWaypointIndex < #waypoints then currentWaypointIndex = currentWaypointIndex + 1 humanoid:MoveTo(waypoints[currentWaypointIndex].Position) end end local function onPathBlocked(blockedWaypointIndex) if blockedWaypointIndex > currentWaypointIndex then followPath(targetresource.Position) end end path.Blocked:Connect(onPathBlocked) humanoid.MoveToFinished:Connect(onWaypointReached) followPath(target.Position) end function IdentifyTarget() print("Identifying target!") local directory = OrganicMatterDirectory:GetChildren() local randomtarget = math.random(1, #directory) target = directory[tonumber(randomtarget)] print(target.Name) RetrieveResource(target) end function Harvest(part) if part.Name == "OrganicMatter" and HarvestingOrganicMatter == false then local OrganicMatterAmount = part:WaitForChild("Matter").Value print("Harvesting!") HarvestingOrganicMatter = true WorkerHead.BrickColor = BrickColor.new("New Yeller") for i=1, 50 do OrganicMatterAmount = OrganicMatterAmount - i wait(1) resourceload = resourceload + 1 end print(resourceload .." units have been harvested.") WorkerHead.BrickColor = BrickColor.new("Lime green") ReturnToHive(HomeQueenSerial) end end wait(5) IdentifyTarget() script.Parent.Head.Touched:Connect(Harvest)
Some coding in these blocks are inefficient, and though I realize and lament that, I respectfully ask all direction be focused on the question. This was a project of possibility, not precision.
All help (besides the aforementioned) is greatly appreciated. If you need something clarified, let me know.
Turns out that affixing .Value to a :WaitForChild("NumberValue") conjures up some weird phantom value that doesn't affect the actual instance. All I had to do was assign :WaitForChild("NumberVariable") to a variable and then refer to it as Variable.Value for it to work properly.