Jump to content

Adding behaviors to creatures in DST


Recommended Posts

Hello, everyone. I've been poking around a bit, and I'm interested in taking a stab at making a mod for DST that adds or modifies some of the behavior for creatures (like making a Pigman hide in his house if a certain character comes near), but I'm not really sure  how I can implement this. I've looked at a mod I liked that did have some custom behaviors, but the author implemented them by copying the original Lua files wholesale and writing their code into them, which doesn't seem like a good idea at all.

 

So my question is this: how can I add behaviors to creatures in DST in a clean way, so it won't break every update? Additionally, would it be possible to only run functions for certain characters (e.g. spoken lines from some creatures that only players using a specific character can see)?

 

I should probably mention that I'm new to DST modding, and Lua in general, but I've been looking around and reading the guides I could find for modding, as well as looking in some of the game's scripts.

Link to comment
Share on other sites

  • Developer

To do this you could override the brain's OnStart function, then call the original and modify the returned Behaviour Tree before returning it back up.

PigBrain._OnStart = PigBrain.OnStartPigBrain.OnStart = function()    local your_node = --add your behaviour node here    local bt = PigBrain:_OnStart()    table.insert(bt.root.children, your_node )end

I haven't tried this though, so there may be some issues that I'm overlooking.

Link to comment
Share on other sites

Is it really that simple? I didn't realize the brains work like a binary tree (if I'm understanding this right). And this will just take the original behavior and insert my node into it at runtime?

 

And about checking which character the player is using for running the behavior, I'm a little confused by this new ThePlayer object. I saw it mentioned in the guide to changes in DST that ThePlayer can refer to more than one player, so how does this affect an if statement for running a behavior in the brain? For example, if I write my behavior to run when Wilson gets near a Pigman, and Wendy goes near Pigmen with a Wilson on the server, will the check still come up as true? Or to put it another way, how can I determine which player ThePlayer will reference?

 

Thanks a ton for your help so far!

Link to comment
Share on other sites

but the author implemented them by copying the original Lua files wholesale and writing their code into them, which doesn't seem like a good idea at all.

Someone else realizing this makes me happy ^_^

 

If I actually knew anything about brains I'd offer to help, but it looks like Peter got you pointed in the right direction, so good luck and happy modding!

 

I can clarify about ThePlayer, though. ThePlayer refers to the player instance that is being controlled by the computer the code is running on. For a given computer (and session), ThePlayer will always refer to the same player, but the tricky part is that when you write the code in a mod, it could be running on any of the computers. Often this will either result in ThePlayer getting the right player (if your code is running separately on each computer), or only getting the host player (if your code if just running on the host).

 

In most cases you actually want to avoid using ThePlayer at all. In your case, I'm not sure if there are inst parameters that you can check, but if not, you can just comb through AllPlayers-- something like this:

for k,v in pairs(AllPlayers) do    if v.prefab == 'wilson' do        --check if he's close enough and do the thing    endend 
Edit: And brains only run on the host, so ThePlayer will always refer to the host player in a brain. Edited by rezecib
Link to comment
Share on other sites

Okay, so using ThePlayer won't work if I want to do something with brains. Got it.

 

Now, for this part of the code you suggested

 

for k,v in pairs(AllPlayers) do
Could you let me know if I'm on the right track as to what these variables are? I can infer that v refers to the value of the current item in AllPlayers. Is k referring to the index of the current item? And I assume pairs() is a function to iterate through AllPlayers? Loosely-typed languages always throw me for a loop because I can't tell what's what at a glance.
 
By the way, what does inst refer to? Is it something broad, like the current game, or does it refer to something more specific, like the player?
Link to comment
Share on other sites

I can infer that v refers to the value of the current item in AllPlayers
 That's correct. Usually "k" and "v" are used to represent "key" and "value" -- tables in Lua are essentially hash maps. I wrote a few examples of the way for loops work in Lua in my guide to getting started with modding.

 

By the way, what does inst refer to? Is it something broad, like the current game, or does it refer to something more specific, like the player?
inst is just a common variable name (abbreviation of "instance"). Usually it refers to the instance of whatever entity is most relevant, e.g. if its the argument in a component's method, it will generally refer to the entity that the component is attached to. Players are sometimes passed as inst, but often also passed as things like doer, target, etc. It depends on the context.
Link to comment
Share on other sites

To do this you could override the brain's OnStart function, then call the original and modify the returned Behaviour Tree before returning it back up.

PigBrain._OnStart = PigBrain.OnStartPigBrain.OnStart = function()    local your_node = --add your behaviour node here    local bt = PigBrain:_OnStart()    table.insert(bt.root.children, your_node )end
I haven't tried this though, so there may be some issues that I'm overlooking.

Just one issue: the behaviour tree isn't actually returned by the brain's OnStart callback, it's just set in the brain's 'bt' field. Also, @Ipsquiggle implemented brain postinits a fair while back doing exactly what you did above. So it should read:

AddBrainPostInit("pigbrain", function(brain)    local your_node = --add your behaviour node here    local bt = brain.bt    your_node.parent = bt.root    table.insert(bt.root.children, your_node )end)
Edited by simplex
Link to comment
Share on other sites

  • Developer
Just one issue: the behaviour tree isn't actually returned by the brain's OnStart callback,

 

You're right! I misread the "return PigBrain" when I looked at it before. Either way, thanks for pointing out the better solution! 

Link to comment
Share on other sites

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
 Share

×
  • Create New...