EDIT 3-18-2015 SOLVED A little update due to the new nightly build, with good news. The new nightly did not have any changes to the broken lua file. On a different stroke, I figured out how to work with anchors, so now I don't need the extra groundpet.lua. Now, my pets use the same files as the ship pets, but the exact same problem persists. I edited only one pet right now for testing, and it does spawn; it just dies almost immediately after. Using the Bunny Pet (Avian starter pet) as a base. The petbunny.monstertype has "anchorName" : "aviantechstation", making the anchor as the Avian's tech station. The aviantechstation.object has the following code; Code: "scripts" : [ "/objects/spawner/shipPetSpawner.lua" ], "scriptDelta" : 20, "shipPetType" : "petbunny", "spawnOffset" : [12, -1] This code is copied over to my spawner, replacing the previous script that activated on clicking. The custom spawner item acts as an anchor with the custom pet as the shipPetType instead of petbunny. The custom pet references the custom spawner as the anchorName. Essentially, my pet is now a copy of the pet bunny, just with a different anchorName and shipPetType. This managed to work! I'm not sure why the lua kept trying to reference what wasn't there, but I don't code nor know how, so that wasn't an error on my part (for once!). I'll cut to the chase. This is exactly what happens; 1. Place a pet spawner down (from my mod, Assorted Crafting Things) 2. Summon the pet. 3. Pet despawns after a few seconds. On March 8th, I unpacked the files, and touched up my mod by copying the groundpet.lua, and removing all mentions of "anchor", much like I did for the mod currently on the site. It worked all fine and dandy, and then a new patch comes out for Nightly. I do the same thing, editing the files, and upon testing it out, knowing something may be off, my pet did what was posted above. So like the smart modder should, I go to my log file. Here's what was wrong; Code: [18:57:32.794] Error: Exception while invoking lua function 'update'. (LuaException) Error code 2, [string "/monsters/pets/campworks_groundpet.lua"]:270: attempt to call global 'findGroundPosition' (a nil value) 0000000038006BD0 000000000657D700 The file "campworks_groundpet.lua" is just the copy of "groundpet.lua", but renamed so that it doesn't clash with the one working with normal pets. The only mention of "findGroundPosition" is in the campworks_groundpet.lua, as is "groundPosition". The Lua is as follows: Code: function init() self.pathing = {} self.pathing.stuckTimer = 0 self.pathing.maxStuckTime = 2 self.jumpCooldown = 0 self.jumpMaxCooldown = 1 self.movementParameters = mcontroller.baseParameters() self.jumpHoldTime = self.movementParameters.airJumpProfile.jumpHoldTime self.jumpSpeed = self.movementParameters.airJumpProfile.jumpSpeed self.runSpeed = self.movementParameters.runSpeed self.stuckPosition = mcontroller.position() self.stuckCount = 0 self.scriptDelta = 5 storage.petResources = storage.petResources or entity.configParameter("petResources") self.petResourceDeltas = entity.configParameter("petResourceDeltas") setPetResources(storage.petResources) local states = stateMachine.scanScripts(entity.configParameter("scripts"), "(%a+State)%.lua") self.state = stateMachine.create(states) local actionStates = {} local actions = stateMachine.scanScripts(entity.configParameter("scripts"), "(%a+Action)%.lua") for _, action in pairs(actions) do table.insert(actionStates, 1, action) end self.actionState = stateMachine.create(actionStates) self.autoPickState = false self.actionState.leavingState = function(stateName) self.querySurroundingsTimer = 0 end self.followTarget = 0 self.behaviorName = entity.configParameter("behavior") self.behavior = _ENV[self.behaviorName] storage.knownPlayers = storage.knownPlayers or entity.configParameter("knownPlayers", {}) storage.foodLikings = storage.foodLikings or entity.configParameter("foodLikings", {}) self.querySurroundingsCooldown = entity.configParameter("querySurroundingsCooldown", 3) self.querySurroundingsTimer = 1 self.querySurroundingsRange = entity.configParameter("querySurroundingsRange", 50) self.standTimer = 0 self.debug = true if capturepod and capturepod.onInit then capturepod.onInit() end if self.behavior and self.behavior.init then self.behavior.init() end end function update(dt) self.actionState.update(dt) if self.actionState.stateDesc() == "" and not self.state.update(dt) then self.state.pickState() end if self.querySurroundingsTimer <= 0 then querySurroundings() self.querySurroundingsTimer = self.querySurroundingsTimer + self.querySurroundingsCooldown end tickResources(dt) decrementTimers(dt) if not self.moved then script.setUpdateDelta(self.scriptDelta) end if self.debug then script.setUpdateDelta(1) if self.actionState.stateDesc() ~= "" then world.debugText(self.actionState.stateDesc(), mcontroller.position(), "blue") else world.debugText(self.state.stateDesc(), mcontroller.position(), "blue") end drawDebugResources() end end function damage(args) if capturepod ~= nil and capturepod.onDamage(args) then return end end function die() if capturepod ~= nil then capturepod.onDie() end end function querySurroundings() local nearEntities = world.entityQuery(mcontroller.position(), self.querySurroundingsRange, { includedTypes = { "player", "itemDrop", "monster", "object" }, withoutEntityId = entity.id() }) --Queue up reactions for _,entityId in ipairs(nearEntities) do self.behavior.reactTo(entityId) end --Run actions self.behavior.run() return false end function emote(emoteType) entity.burstParticleEmitter("emote"..emoteType) end function itemFoodLiking(entityName) if not entityName or root.itemType(entityName) ~= "consumable" then return false end local foodLiking = storage.foodLikings[entityName] if foodLiking == nil then return nil end --How much does it like the food if foodLiking == true or foodLiking == false then if foodLiking == true then foodLiking = math.random(50, 100) elseif foodLiking == false then foodLiking = math.random(0, 50) end storage.foodLikings[entityName] = foodLiking end return foodLiking end function petResources() local resources = {} for resourceName, resourceValue in pairs(storage.petResources) do resources[resourceName] = status.resource(resourceName) end return resources end function setPetResources(resources) for resourceName, resourceValue in pairs(resources) do status.setResource(resourceName, resourceValue) end end function tickResources(dt) for resourceName, resourceDelta in pairs(self.petResourceDeltas) do status.modifyResource(resourceName, resourceDelta * dt) end end function drawDebugResources() local resources = storage.petResources local position = mcontroller.position() local y = 2 for resourceName, resourceValue in pairs(storage.petResources) do --Border world.debugLine(vec2.add(position, {-2, y+0.125}), vec2.add(position, {-2, y + 0.75}), "black") world.debugLine(vec2.add(position, {-2, y + 0.75}), vec2.add(position, {2, y + 0.75}), "black") world.debugLine(vec2.add(position, {2, y + 0.75}), vec2.add(position, {2, y+0.125}), "black") world.debugLine(vec2.add(position, {2, y+0.125}), vec2.add(position, {-2, y+0.125}), "black") local width = 3.75 * status.resource(resourceName) / 100 world.debugLine(vec2.add(position, {-1.875, y + 0.25}), vec2.add(position, {-1.875 + width, y + 0.25}), "green") world.debugLine(vec2.add(position, {-1.875, y + 0.375}), vec2.add(position, {-1.875 + width, y + 0.375}), "green") world.debugLine(vec2.add(position, {-1.875, y + 0.5}), vec2.add(position, {-1.875 + width, y + 0.5}), "green") world.debugLine(vec2.add(position, {-1.875, y + 0.625}), vec2.add(position, {-1.875 + width, y + 0.625}), "green") world.debugText(resourceName, vec2.add(position, {2.25, y - 0.125}), "blue") y = y + 1 end end function decrementTimers(dt) self.querySurroundingsTimer = self.querySurroundingsTimer - dt self.jumpCooldown = self.jumpCooldown - dt self.standTimer = self.standTimer - dt end function setMovementState(running) if not mcontroller.onGround() then if mcontroller.liquidMovement() then entity.setAnimationState("movement", "swim") else setJumpState() end else if running then entity.setAnimationState("movement", "run") else entity.setAnimationState("movement", "walk") end end end function setIdleState() local currentState = entity.animationState("movement") if currentState ~= "idle" and currentState ~= "stand" then self.standTimer = entity.configParameter("idle.standTime", 2) end if not mcontroller.onGround() then setJumpState() elseif self.standTimer < 0 then entity.setAnimationState("movement", "idle") else entity.setAnimationState("movement", "stand") end end function setJumpState() if mcontroller.yVelocity() > 0 then entity.setAnimationState("movement", "jumping") else entity.setAnimationState("movement", "falling") end end function boundingBox(force) if self.boundingBox and not force then return self.boundingBox end local collisionPoly = mcontroller.collisionPoly() local bounds = {0, 0, 0, 0} for _,point in pairs(collisionPoly) do if point[1] < bounds[1] then bounds[1] = point[1] end if point[2] < bounds[2] then bounds[2] = point[2] end if point[1] > bounds[3] then bounds[3] = point[1] end if point[2] > bounds[4] then bounds[4] = point[2] end end self.boundingBox = bounds return bounds end -------------------------------------------------------------------------------- -- draw lines to display the specified rect {x1, y1, x2, y2} in the specified color, optionally offset by basePos function debugRect(rect, color, basePos) if basePos then rect = translate(rect, basePos) end world.debugLine({rect[1], rect[2]}, {rect[1], rect[4]}, color) world.debugLine({rect[1], rect[2]}, {rect[3], rect[2]}, color) world.debugLine({rect[3], rect[4]}, {rect[1], rect[4]}, color) world.debugLine({rect[3], rect[4]}, {rect[3], rect[2]}, color) end -------------------------------------------------------------------------------- --MOVEMENT--------------------------------------------------------------------- -------------------------------------------------------------------------------- function approachPoint(dt, targetPosition, stopDistance, running) local toTarget = world.distance(targetPosition, mcontroller.position()) local targetDistance = world.magnitude(targetPosition, mcontroller.position()) local groundPosition = findGroundPosition(targetPosition, -20, 1, util.toDirection(-toTarget[1])) if groundPosition then self.approachPosition = groundPosition end if self.approachPosition and targetDistance > stopDistance then if moveTo(self.approachPosition, dt, {run = running}) then mcontroller.controlFace(self.pathing.deltaX or toTarget[1]) setMovementState(running) else entity.setAnimationState("movement", "idle") end return false elseif targetDistance <= stopDistance then return true end end -------------------------------------------------------------------------------- function move(direction, options) if options == nil then options = {} end if options.run == nil then options.run = false end direction = util.toDirection(direction) local position = mcontroller.position() local boundsEdge = 0 local bounds = boundingBox() local tilePosition if direction > 0 then tilePosition = {math.ceil(position[1]), position[2]} boundsEdge = bounds[3] else tilePosition = {math.floor(position[1]), position[2]} boundsEdge = bounds[1] end --Stop at walls if world.lineTileCollision({position[1], position[2] + bounds[2] + 1.5}, { position[1] + boundsEdge + direction, position[2] + bounds[2] + 1.5}, true) then return false, "wall" end --Check if the position ahead is valid, including slopes local yDirs = {0, 1, -1} for _,yDir in ipairs(yDirs) do if validStandingPosition({tilePosition[1] + direction, tilePosition[2] + yDir}) then moveX(direction, options.run) return true end end return false, "ledge" end I'm unsure of why it's telling me this. The variable is there, but it's not finding it?
The error is telling you that the "findGroundPosition()" function is undefined. I can't tell you why, it's probably something to do with the nature of nightly builds. So you may want to compare this script with an older one that you know works. See why this function may not be defined.
It appears to be undefined because it's not there. No such function is defined anywhere in starbound. It also wasn't defined over a month ago, so it's not exactly a nightly thing. Confused this with a completely different issue, please ignore.