Bouncing an idea for determining bot behavior

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
togFox
Party member
Posts: 770
Joined: Sat Jan 30, 2021 9:46 am
Location: Brisbane, Oztralia

Bouncing an idea for determining bot behavior

Post by togFox »

I haven't quite thunk this through properly and sometimes voicing it out loud can cement or flush an idea. :)

I have an AI bot (agent) that needs to make intelligent decisions in a survival scenario (hypothetical). I want the bot to choose from a range of options that is somewhat random and somewhat intelligent. I squiggled a tree of possible behaviours my bot can perform

Image

Sorry for all the words but here is how to read it:

Workflow:
  • Start at the root node and immediately examine it's children
(find food, find shelter, gather resources, socialise)
  • Determine child randomly based on priority stored with each child
(find food = 4/12 = 33%)
(find shelther = 4/12 = 33% chance)
(gather resources = 3/12 = 25% chance)
(socialise = 1/12 = 8% chance)
  • If randomly chosen child is a leaf then search is over and that action is executed
(e.g find shelter)
  • If randomly chosen child is not a leaf (e.g. gather resources) then examine all children for this new node
(gather wood, gather clay)
  • Determine child randomly based on priority stored with each child
(wood = 3/5 = 60% chance)
(clay = 2/5 = 40% chance)
  • Randomly chosen child is a leaf (e.g. gather wood) so execute action

Long story short - I want a tree where I can insert nodes and give them a nominal priority. The priority only makes sense in the context of the nodes siblings and the priority is a simple mechanism to "weight" or favour some behaviors over others.

Furthermore, some nodes can be 'deconstructed' into more nodes of that same type and a different priority applies in that new context. In the diagram above, the bot has some chance of "singing" but it really isn't very high (1/12 * 1/4 = 1/48 = 2% chance) but every now and then, when you least expect it, that agent will start yodeling. :) I can also quickly adjust the priority of one node without upsetting the tree or recalculating percentages. Changing "socialise" to two (2) means singing is now 4% chance of being randomly chosen.

I can also add new leaf and sub-trees as I dream up new behaviors and the tree will simply cope.

Anyway. Lots of words. I'm going to assume I'm the first person to invent this device so I'll name it the "weighted Fox tree". :emo:

Obvious flaws? Design faults? Anything I overlooked?

If it looks sound then I guess I need to write "tree" code to make this work. I guess each node will be a table and that table can hold another table (which is a node). I can add a new child node with a simple table.insert(node, sub-node) I guess (or something).
Current project:
https://togfox.itch.io/backyard-gridiron-manager
American football manager/sim game - build and manage a roster and win season after season
User avatar
Gunroar:Cannon()
Party member
Posts: 1085
Joined: Thu Dec 10, 2020 1:57 am

Re: Bouncing an idea for determining bot behavior

Post by Gunroar:Cannon() »

togFox wrote: Thu Aug 19, 2021 11:26 am I haven't quite thunk this through properly and sometimes voicing it out loud can cement or flush an idea. :)
Haha, you said thunk (just wanted to say it quickly before you changed it. I haven't even read the whole thing :rofl: )

Edit:never mind that's correct. When I read it through again I was like"...wait, before he changes what?" :crazy:

Edit: Okay read it. Sounds pretty good :awesome: . Though that's kind of like a Behaviour tree(lua,Wikipedia). But I'm sure they're differences since I don't know it that well. But I could also say it seems like a baby of utility theory and behaviour trees. Just ... I don't think it's new :( ? But I guess implementing it yourself will help you understand and edit the AI more?
Last edited by Gunroar:Cannon() on Thu Aug 19, 2021 1:41 pm, edited 2 times in total.
The risk I took was calculated,
but man, am I bad at math.

-How to be saved and born again :huh:
User avatar
milon
Party member
Posts: 472
Joined: Thu Jan 18, 2018 9:14 pm

Re: Bouncing an idea for determining bot behavior

Post by milon »

togFox wrote: Thu Aug 19, 2021 11:26 am Obvious flaws? Design faults? Anything I overlooked?
Is this bot acting alone in the world? Are a bunch of individual bots doing this in parallel? Are a bunch of bots trying to work as a collective group? Is there a player character that can interact with them?

Answers to these questions will help me answer your own questions. Your use of the bot(s) will affect the nuances, etc involved. I know a tiny bit about this, but I'm by no means an expert. And I doubt you're the first to invent this approach, but I like the name "weighted Fox tree" :)
Any code samples/ideas by me should be considered Public Domain (no attribution needed) license unless otherwise stated.
User avatar
togFox
Party member
Posts: 770
Joined: Sat Jan 30, 2021 9:46 am
Location: Brisbane, Oztralia

Re: Bouncing an idea for determining bot behavior

Post by togFox »

I'm thinking there will be a bunch of bots (not s stupid amount) with their own table/tree doing their own thing. They wouldn't interact with each other directly but they would change the environment/world and the bots around them would be impacted by that. I'm not yet sure how the player/avatar would interact. I would decide that after/if I get this to look convincing.

It's like a behavioural tree but they have no room for randomness.

I'm trying to tell my bots there is some routine behaviors that are expected to happen routinely (priority 4 and 3) but if you want to mix it up with a priority 2 or 1 now and then then that's okay too.
Current project:
https://togfox.itch.io/backyard-gridiron-manager
American football manager/sim game - build and manage a roster and win season after season
User avatar
Gunroar:Cannon()
Party member
Posts: 1085
Joined: Thu Dec 10, 2020 1:57 am

Re: Bouncing an idea for determining bot behavior

Post by Gunroar:Cannon() »

Come to think of it, I think, from looking at their .json mob file, that minecraft uses something like this too.

Code: Select all

(cow.json)
...
      "minecraft:hurt_on_condition": {
        "damage_conditions": [
          {
            "filters": { "test": "in_lava", "subject": "self", "operator": "==", "value": true },
            "cause": "lava",
            "damage_per_tick": 4
          }
        ]
      },
      "minecraft:movement": {
        "value": 0.25
      },
      "minecraft:behavior.float": {
        "priority": 0
      },
      "minecraft:behavior.panic": {
        "priority": 1,
        "speed_multiplier": 1.25
      },
      "minecraft:behavior.mount_pathing": {
        "priority": 2,
        "speed_multiplier": 1.5,
        "target_dist": 0.0,
        "track_target": true
      },
      "minecraft:behavior.breed": {
        "priority": 3,
        "speed_multiplier": 1.0
      },
      "minecraft:behavior.tempt": {
        "priority": 4,
        "speed_multiplier": 1.25,
        "items": [
          "wheat"
        ]
      },
...
Seems pretty thought out. Fuzzy logic is usually used with utility theory for randomness. (I don't know how that helps :P)
The risk I took was calculated,
but man, am I bad at math.

-How to be saved and born again :huh:
User avatar
darkfrei
Party member
Posts: 1169
Joined: Sat Feb 08, 2020 11:09 pm

Re: Bouncing an idea for determining bot behavior

Post by darkfrei »

See how it's done in Factorio:
https://wiki.factorio.com/Prototype/Entity#Example

One prototype of one type of entities:

Code: Select all

{
    type = "container",
    name = "wooden-chest",
    icon = "__base__/graphics/icons/wooden-chest.png",
    flags = {"placeable-neutral", "player-creation"},
    minable = {mining_time = 1, result = "wooden-chest"},
    max_health = 100,
    corpse = "small-remnants",
    collision_box = {{-0.35, -0.35}, {0.35, 0.35}},
    fast_replaceable_group = "container",
    selection_box = {{-0.5, -0.5}, {0.5, 0.5}},
    inventory_size = 16,
    open_sound = { filename = "__base__/sound/wooden-chest-open.ogg" },
    close_sound = { filename = "__base__/sound/wooden-chest-close.ogg" },
    vehicle_impact_sound =  { filename = "__base__/sound/car-wood-impact.ogg", volume = 1.0 },
    picture =
    {
      filename = "__base__/graphics/entity/wooden-chest/wooden-chest.png",
      priority = "extra-high",
      width = 46,
      height = 33,
      shift = {0.25, 0.015625}
    },
See also: https://github.com/wube/factorio-data/t ... pes/entity
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
togFox
Party member
Posts: 770
Joined: Sat Jan 30, 2021 9:46 am
Location: Brisbane, Oztralia

Re: Bouncing an idea for determining bot behavior

Post by togFox »

Thanks all. Lots of material here.

Utility theory or utility points + a quazi behavioural tree = weighted Fox tree. lolz.

I researched utility theory and that is exactly what I wanted to adjust my tree with so Gun was on the money with that one. :) I'm kinda excited to implement this now with a single bot and watch it do random yet biased activities that reflect common human patterns with occasional whimsical departures. :)
Current project:
https://togfox.itch.io/backyard-gridiron-manager
American football manager/sim game - build and manage a roster and win season after season
User avatar
Gunroar:Cannon()
Party member
Posts: 1085
Joined: Thu Dec 10, 2020 1:57 am

Re: Bouncing an idea for determining bot behavior

Post by Gunroar:Cannon() »

Good luck!
The risk I took was calculated,
but man, am I bad at math.

-How to be saved and born again :huh:
User avatar
Xii
Party member
Posts: 137
Joined: Thu Aug 13, 2020 9:09 pm
Contact:

Re: Bouncing an idea for determining bot behavior

Post by Xii »

Ignoring one's environment is hardly intelligence. AI needs to look around and make decisions based on what they see. What you've described is simply random behavior (with some behaviors more likely than others, but not conditionally so).

If you add an evaluation function to each node instead of a flat weight, those functions can then evaluate the situation and output weights appropriate for the current state of things. Gathering wood evaluation function, for example, increases its weight if there's not enough wood gathered already.

This does mean you have to actually run the evaluation functions of all nodes recursively to add up their weights properly. Fortunately, this can be done entirely in parallel as the functions are read-only on world state.
User avatar
togFox
Party member
Posts: 770
Joined: Sat Jan 30, 2021 9:46 am
Location: Brisbane, Oztralia

Re: Bouncing an idea for determining bot behavior

Post by togFox »

What if I expand on my tree in the OP by building an 'activation' function into each node. If the activation function returns TRUE then the node is a valid option for the rng. If the activation function returns FALSE then the node is not included in the rng determination and it's children can not be traversed

For example: the first row in the OP has 12 'priorities' meaning 'find food' has a 4/12 chance of being randomly selected (based on priorities). Now if 'find food' has an activation function:

if agent.fullness < 25% then return true else return false end

then there is a possibility the node is not activated and does not become an rng option. The likely hood of "find shelter" is now elevated to 50% - assuming it is also activated.

Here is my pre-programmed tree so far (just an empty root and the first node/child):

Code: Select all

	tree.goal = "root"
	tree.priority = 1
	tree.child = {}
	tree.child[1] = {}
	tree.child[1].goal = enum.goalEat
	tree.child[1].priority = 4
How would I hard-code an activation function into the node so that it turns a boolean when traversing nodes in ipairs and recursively?
Current project:
https://togfox.itch.io/backyard-gridiron-manager
American football manager/sim game - build and manage a roster and win season after season
Post Reply

Who is online

Users browsing this forum: No registered users and 46 guests