Terasology / Behaviors

Store for an assortment of behaviors that can be applied to creatures
https://terasology.github.io/Behaviors
6 stars 18 forks source link

Distinction for further Behaviours #108

Closed skaldarnar closed 2 years ago

skaldarnar commented 2 years ago

Nature of Monsters

Natures

The Natures would be Coded with:

Monster M - Actually unnecessary unless this kind of diversion gets added to another kind of Entity Peaceful (P) / Hostile (H) * Kind of unnecessary if you know which Dangerous meter which Kind extends. Trusting (Tr) / Timid (Ti) II Guarding (Gu) / Chasing (Ch) Solo (s) / Group (g)

Examples for Certain Natures would be

PTrs -> Sheep PTrg -> Dog PTis -> Rabbit PTig -> Deer HGus -> Bear HGug -> Wolf HChs -> Fox HChg -> Raptors

Differentiating Parameters could be identified with + identifier.

Example

A Monster Peaceful Trusting Solo which can fly would be Coded with:

MPTrs + f or PTrs + f or PTrs + flying

For further explanation:

The Dangerous meter

is distinct by the Damage they do to Entitys. So Peacfull Entitys shouldnt damage other Entiys while Hostile do.

The Kind Distinction

is based on their behaviour towards Entitys.

Timid: Runs Away from Entitys based on Action or Distance Trusting: Follows Entitys based on Action or Distance Guarding: Attacks Entitys based on Action or Distance maybe follows them for a certain length Chasing: Attacks Entitys based on Distance, no necessary Action needed.

The Parameters

adjust on every monster so theyre open for each to adjust. Therefore crossings from peacfull and hostile mobs is possible by switiching their hostility on event. The Current Parameters extend the .behaviour and its pre-made behaviours and nodes.

The Occurring differentiation

adjusts around spawning parameters. For right now we spawn mobs for testing by hand but they could be spawned in packs or solo entitys based on their kind.

The Wolf Problem

Wolves are kind of a weird pick to put. They usually hunt in Packs and they can guard around objectives. So its kinda hard to put them. I Usually would put them on Guard since they have that ability. Raptors from jurassic park for e.g. don't show this behaviour. So i think putting them into different groups is reasonable based on the abilities they show with priority on guarding.

So every Guard can be a Chaser but not every Chaser can Guard. At least that is my mentality towards these decisions.

Further Steps

It would be awesome to define behaviour trees as base for the 4 Kinds. Chaser , Guard, Timid and Truster. So every coming Mob can be assigned one of these base Natures and then get adjusted on the parameters by fly. Therefore not every Mob has to get its own Behaviour explored and programmed.... but!... Every Mob can be tweaked towards the experience the developer has in mind.

Exploring the Depth of Switiching Dangerous meters would also be welcomed... The Wolf in Minecraft it self is such a switching Entity and it would be a cool dynamic for players to find out if Hostile Mobs can become Trusting and Switch to the players side.

skaldarnar commented 2 years ago

❓ What is the purpose of the (short) codes you introduce (e.g., "MPTrs + f")? Is this intended to be used in prefabs and then parsed in some way to actually form the behavior trees? Or is it just a shorthand notation to categorize the different groups?

❓ Is the dangerous meter just the damage the mob would be dealing? Is it "damage per second", or are there other factors involved?

👍 I like distinction by kind, I think "timid", "trusting", "guarding", and "chasing" characterize entities pretty well.

ℹī¸ regarding occurrence of entities and where they are spawned we have some ideas, especially @casals. I think we do spawn groups of sheep and deer, but I may be mistaken, and improving on the environmental aspect is definitely a good idea (although I'm not sure how feasible addressing the spawning logic is right now). You can find a previous attempt on this in https://github.com/Terasology/Spawning/pull/7

Therefore crossings from peacfull and hostile mobs is possible by switiching their hostility on event.

👍 I really like this aspect - switching behaviors or characteristics in-game based on inputs and things happening around the entity is indeed essential. I think the idea with behavior trees is that you can just switch out (sub-)trees to give an entity a completely different behavior.

❓ This leads to the question how we can best model the kind and characteristic with our engine/framework so that it "just works" in the end...

So every Guard can be a Chaser but not every Chaser can Guard.

đŸ’Ŧ Although such restrictions sometimes seem useful, I'd recommend to be more careful with it. Think about whether there are any benefits or drawbacks with being more or less strict about something.

In this particular case, I don't see why we would need to restrict transitioning from one state to the other. Even though it might not be that common, I could think of some animal or monster that's primarily a "chaser" hunting pray, but if its lair is endangered it would stick to guarding that place instead of chasing the attacker very far.

it would be a cool dynamic for players to find out if Hostile Mobs can become Trusting and Switch to the players side.

👍 That's another good idea and does fit very well with the concept of luring mobs.

❓ One thing to follow up on here could be to experiment with different ways to lure an entity and how that could be implemented. Our first PoC was based on the player holding an item. Minecraft uses an additional mechanic to feed mobs to make them friendly towards the player (wolf) or trigger mating between already tame mobs (cows, sheep, ...)

Jacob-Rueckert commented 2 years ago

❓ What is the purpose of the (short) codes you introduce (e.g., "MPTrs + f")? Is this intended to be used in prefabs and then parsed in some way to actually form the behaviour trees? Or is it just a shorthand notation to categorize the different groups?

This was an Idea for quickly searching through our library of behaviours. Since its intended to use these behaviours kind of like a prefab and being able to make new behaviour "master" trees, the behaviour tree a entity has when finalized, fast and from scratch. I figured that if someone who isn't familiar with the concept of behaviours can look up a kind of behaviour he/she visualized.

E.g. : You want to make a Rabbit and you visualize it as a Peaceful Timid Solo Entity then you can look up any prefab behaviour "master" tree that consists of these behaviours and check if you just need to alter the configuration or add other parameters like jumping or eating carrot

❓ Is the dangerous meter just the damage the mob would be dealing? Is it "damage per second", or are there other factors involved?

No. The Damaging Kind would be a behaviour / action i think. The Dangerous Meter can be thought of like a scale with 2 indicators 1 and 0. Its basically just a differentiation if a Monster can Damage or is supposed to Damage a Player or not. If you think about it in this distinction is just a parameter like can_damage_player but this distinction is made in games all the time. Its not a restriction, furthermore an intention of the designer of the entity. In Minecraft for example there are 3 kinds of intention:

(0) Villagers -> Will never hurt the player (0.5) Iron Golems -> Can Hurt the player but will not necessarily (0.5) Spiders -> Only hurt player while night (1) Pillagers -> Will always try to hurt the player

*Pls don't be confused by the 0.5 this is just a made up indicator for changing behaviour on condition. Iron Golems and Spiders would switch between 1 and 0 for example.

The differentiation of the kind of damage it does, like attack speed, dot effects, damage values etc. would be distinct in an action given to the behaviour tree. Im still a bit confused around Action and Behaviours in this regard which might be why this is so complicated to clarify. For me an Action would be Stray. I know its a .behaviour, but simply put Stray is a RandomMoveBehaviour which does a find_path. So there is no decision level in the stray.behaviour it self. The behaviour gets started under a certain condition but thats not done in the "Stray"-Behaviour, but one level above. So when i talk about an action a entity can make i refer to these possible behaviours at the lowest point of decision an entity can have. (Its really tough with the wording I'm sry) When i refer to a Behaviour i mean a Behaviour Tree like Critter which makes decisions and goes through these base behaviours like flee or stray.

regarding occurrence of entities and where they are spawned we have some ideas, especially @casals. I think we do spawn groups of sheep and deer, but I may be mistaken, and improving on the environmental aspect is definitely a good idea (although I'm not sure how feasible addressing the spawning logic is right now).

You can find a previous attempt on this in https://github.com/Terasology/Spawning/pull/7

I looked through the ticket but i didn't saw an implementation for group spawning but one for day and night spawning. Which i think is redundant for the behaviours it self. I think the only real spawning behaviour to consider is group or solo spawning to indicate if a Mob is part of a "pack" or so. In Minecraft this reminds me the most of the wolfs which all get angry if you hurt one wolf. But actually that is restricted to an area not a distinct group of entities.

I don't know if this would be necessary and more of a useless restriction because iron golems for example attack you when you hit a villager. Say we have something similar then the iron golem would have to know his group of villagers that he's protecting, instead of just protecting every villager. If this feels unnecessary or to complicated / to restrictive then the distinction between solo and group in my example is useless and would be done in an behaviour instead of a configuration.

❓ This leads to the question how we can best model the kind and characteristic with our engine/framework so that it "just works" in the end...

We already discussed that in our meeting. I will prep a "master"-tree which i think could work for one example of a entity and we revisit it together. I think with the current framework we already have the tools to build more differentiated and complex behaviours. Although we probably need to extend the current existing (in my phrasing) base behaviours / actions like stray and flee.

đŸ’Ŧ Although such restrictions sometimes seem useful, I'd recommend to be more careful with it. Think about whether there are any benefits or drawbacks with being more or less strict about something.

You're completely right and since this was the first iteration of this concept / idea I didn't really spend a lot of thought on that i will include this consideration in further iterations more precisely reasoned.

how much simpler would the model be if there are less restrictions or dependencies between some aspects?

Thats something to be considered when determining how complex or how simple the prefabs for these final trees shall be. In a previous point i already made an e.g for such a maybe redundant aspect (Groups and Solo Spawning) but i believe at least considering an option is better then straight up canceling it.

what complexity is added by a rule? what problem does a rule solve? why does a restriction make your / another dev's / a player's life easier or better?

The complexity in behaviours, at least in my view, starts by not adding rules. The less actual options an entity has the less complicated it will be. Therefore rules simplifying the concept in itself makes the whole structure more stable and less complex on the costs of flexibility and possibility.

In this particular case, I don't see why we would need to restrict transitioning from one state to the other. Even though it might not be that common, I could think of some animal or monster that's primarily a "chaser" hunting pray, but if its lair is endangered it would stick to guarding that place instead of chasing the attacker very far.

In that case i would recommend doing a custom behaviour for an entity that way since its already very specific. I imagine that there could be a Hunter.behaviour adding a timer for days and nights and on like the 2nd night after a hunt they go hunting again. So the base construct would be a guarding entity with the addition of this hunting event like behaviour.

❓ One thing to follow up on here could be to experiment with different ways to lure an entity and how that could be implemented. Our first PoC was based on the player holding an item. Minecraft uses an additional mechanic to feed mobs to make them friendly towards the player (wolf) or trigger mating between already tame mobs (cows, sheep, ...)

There are a lot of examples other games do in this regard. In horrow games hunters get lured / are following sound or activity. Other Mobs can be like blind and only follow you if you're hurt. Piglins in Minecraft attack you if you don't have gold on yourself. And so on. This would be a Parametric Behaviour which catches conditions and alters the behaviour of the entity.

*Since I'm referring here to a parametric.behaviour i mean the parameters we can change to develop changing behaviour. Custom Behaviours so to say. If you take Cows and Sheeps in Minecraft for example. A custom behaviour / parametric behaviour would NOT be luring but can_be_sheered or can_be_milked. Both can be lured but only one can be sheered and on can be milked.

jdrueckert commented 2 years ago

Just a slight comment from me on the "size" / scope of actions:

simply put Stray is a RandomMoveBehaviour which does a find_path. So there is no decision level in the stray.behaviour it self [...] So when i talk about an action a entity can make i refer to these possible behaviours at the lowest point of decision an entity can have.

In my interpretation, an action is the smallest reusable building block of a behavior.

If we look at the stray behavior as you mentioned, this does some animation stuff around but mainly calls the doRandomMove behavior which performs a target a nearby block action and then calls the naiveMoveTo behavior which performs a find a path action and then the move along the path action(s).

While it can be argued that the path finding and moving along it do not need to be separate actions, it's still relevant that there are separate actions for finding a nearby block and finding/moving along a path. A sample behavior A might require to find a nearby block and make the AI only look at it while a sample behavior B might require to find a specific (potentially not nearby) block and make the AI move there. So the two actions need to be separate in order to allow being reused in combination with respective other actions to build a different behavior. Having stray as an action instead of a behavior would not allow this.