Jump to content

Recommended Posts

Hi friends,

 

So for this project I'm working on, I need a monster to pick a flower. I've come really really close, I swear that my code is right on the cusp. I think I'm missing something really dumb, so I think I can spare you guys the details.

 

My problem is: My monster will run up to the closest flower and stand on it, but that's it. How do I make it actually "Pick" the flower?

 

Note that I've modeled my custom behavior after the "findflower" behavior that the bee uses. This is what my buffered action thingy looks like. 

local action = BufferedAction(self.inst, self.inst.components.flower_picker.target, ACTIONS.PICK, nil, nil, nil,  0.1)self.inst.components.locomotor:PushAction(action, self.shouldrun)

My creature has an inventory component (seemed like a good idea), a custom "flower_picker" component, and the all-important locomotor. 

Let me know if you need anymore details!!

-BBox

Edited by BlackBox

**UPDATE**

 

Out of curiosity, I wondered if I was having problems because the engine didn't want to allow monsters/creatures to use the "PICK" action. So I went ahead and duplicated the way the spider's EAT action works

local function EatFoodAction(inst)local target = FindEntity(inst, 10, function(item) return inst.components.eater:CanEat(item) end)if target thenreturn BufferedAction(inst, target, ACTIONS.EAT)endend//Then in the actual brain....DoAction(self.inst, function() return EatFoodAction(self.inst) end ),

This STILL results in my monster simply running up to the nearest piece of food and simply standing on top of it. It's obviously missing something but what? Does it need to have a thoroughly implemented state graph? If that is the case, then I'm somewhat confused - as I imagined the stategraph only cared about playing the right animations and the right sounds at the right time - having 0 impact on the actual gameplay. 

 

Let me know if you have anymore questions! Help me, help you, help me  :-)

Brains are used to define monster behavior. Check out perdbrain.lua's PickBerriesAction function to see how the gobbler (named 'perd' in code) picks berries.

To debug your code, I'd do something like this:

local LocoMotor = require "components/locomotor"local LocoMotor_PushAction_base = LocoMotor.PushActionfunction LocoMotor:PushAction(bufferedaction, run, try_instant)    LocoMotor_PushAction_base(self, bufferedaction, run, try_instant)    print("Locomotor of "..tostring(self.inst).." got "..tostring(bufferedaction).." pushed to it")end
so that you can keep track of when buffered actions get pushed and you can see if yours is being overwritten by something somewhere.

You can also enable debug rendering (BACKSPACE) and then use the console command c_select() (if you use Better Console this will set the debug entity to whatever you're hovering over; without Better Console, you'd have to provide the prefab instance as a parameter to c_select()) to set your monster as the debug entity. Each component of the debug entity will show up in the debug rendering readout (top left) and provide some information about itself.

Edited by squeek

Brains are used to define monster behavior. Check out perdbrain.lua's PickBerriesAction function to see how the gobbler (named 'perd' in code) picks berries.

To debug your code, I'd do something like this:

local LocoMotor = require "components/locomotor"local LocoMotor_PushAction_base = LocoMotor.PushActionfunction LocoMotor:PushAction(bufferedaction, run, try_instant)    LocoMotor_PushAction_base(self, bufferedaction, run, try_instant)    print("Locomotor of "..tostring(self.inst).." got "..tostring(bufferedaction).." pushed to it")end
so that you can keep track of when buffered actions get pushed and you can see if yours is being overwritten by something somewhere.

You can also enable debug rendering (BACKSPACE) and then use the console command c_select() (if you use Better Console this will set the debug entity to whatever you're hovering over; without Better Console, you'd have to provide the prefab instance as a parameter to c_select()) to set your monster as the debug entity. Each component of the debug entity will show up in the debug rendering readout (top left) and provide some information about itself.

 

 

@squeek thanks, as usual, for all of your help! I ended up being unable to figure out what was wrong - but you gave me a bunch of really useful debugging tools that I've been using extensively the whole time.

 

I ended up just coding around my problem. My creature now runs up to the target and then simply removes it - although it'd be better if action actually worked, some things just can't be helped when you're on a deadline :) 

btw squeek, sometimes betterconsole dont show whole log, but only few last strings.

while log.txt is much larger. What may cause it? "huge" log size (mine is about 100k-170k) or some illegal chars?

 

next time i get it, i try to turn off addon and look if it helps or attach log here.

Edited by iWitch

@squeek thanks, as usual, for all of your help! I ended up being unable to figure out what was wrong - but you gave me a bunch of really useful debugging tools that I've been using extensively the whole time.

 

I ended up just coding around my problem. My creature now runs up to the target and then simply removes it - although it'd be better if action actually worked, some things just can't be helped when you're on a deadline :-)

I poked around a bit. Here's what's happening:

The locomotor moves the entity to the target, then calls EntityScript:PushBufferedAction with the buffered action you gave to the locomotor component. In that EntityScript function, it'll run down to line 855 (elseif not self.sg:StartAction(bufferedaction) then) which, if self.sg:StartAction returns false, will fail the action. The StartAction function will return false if the stategraph of the entity has no method to handle the action you are trying to perform. So, you need to make sure to add an ACTIONS.PICK handler to the stategraph of your monster. Here are the relevant parts of SGperd.lua:

local actionhandlers = {    ActionHandler(ACTIONS.PICK, "pick"),}CommonStates.AddSimpleActionState(states, "pick", "take", 9*FRAMES, {"busy"})return StateGraph("perd", states, events, "idle", actionhandlers)

btw squeek, sometimes betterconsole dont show whole log, but only few last strings.

while log.txt is much larger. What may cause it? "huge" log size (mine is about 100k-170k) or some illegal chars?

next time i get it, i try to turn off addon and look if it helps or attach log here.

Not everything that gets outputted to log.txt uses the Lua print function, so it's not added to the ingame console (for example, the function TheSim:LuaPrint will print to log.txt without printing to the console). Also, the console log gets reset when Better Console is loaded, so you'll only see the things that get printed after Better Console gets loaded.

The console and log.txt are meant to serve different purposes, though. log.txt is for when you need all the information you can possibly get. The console is for immediate feedback about what's currently happening.

Edited by squeek

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...