Submissions by saluk tagged behaviors

A submission for Make games. 328

Forgot to submit last night. I spent a couple hours starting to implement an npc for this example quest. It was enlightening. There are still many many npc path and ai bugs that I need to either find nice workarounds for or fix properly. My goal was to have a simple dialog tree that ended with the npc walking off and hanging out in a specified area.

The behavior tree nodes setup for pathing feel much more complicated than I think they need to be, and I am pretty limited in the kinds of behavior I can easily implement. I didn't have a pre-defined behavior handy, and trying to come up with a "hanging out" behavior was taxing my brain. Editing behavior trees is hard, because I always have to remember what all of the nodes mean, which means either better naming or an editor may be in order.

I also still have a weird disconnect between the dialog system and events. I think I have talked about this before, and it's possible I need to redesign the whole thing. To implement this simple situation, I have to:

  • Add the npc to the map in tiled
  • Create a section in characters.json for that npc specifying their name and sprite
  • Add a dialog tag to the end of characters.json that makes the right conversation start when you use the "greet" action on this specific npc
  • Create the conversation script, which ends with launching an event
  • Create the event script which sets the npc behavior
  • Create the behavior and debug it with all of the other behaviors

Last night I basically stopped when I got to that last step. I couldn't really think of The first set of steps took about an hour. Not terrible but not great either. There are some fairly well behaviors that are defined now that make some things easy. Picking up or doing something with an item takes only a few lines (once I remember how to do it). But anything else is a bit confusing. I think an editor would help a lot. But I think I need to redesign how behaviors, conversations, and events work in a wholistic way, because this isn't going to scale. It would be really nice if I could just open a new file, and put all of those things together line by line in a simple way:

"I'm going to go off by myself now"
char1 behavior = 
  if char1.distance(region(x)) < 500:
    char1.movetoward(region(x))

Definitely need to spend some time creating a more cohesive and complete grammar for everything before I can get to something clean like that. But it will help so much in experimenting with such highly experimental gameplay!

I also had a bug with the response interface where the player chooses what to say. After getting fed up with behaviors, I tried to fix this and couldn't narrow down why it wasn't working, so I went to bed frustrated. I hate going to bed frustrated!

A submission for Make games. 296

I've been experimenting with building a planner for the AI. For now, the idea is to be able to dynamically generate a behavior tree for acquiring a specific item. Now that we have a rudimentary crafting system that the player can interact with, I thought it might be a good idea to see if the AI characters could interact with it as well. This isn't just to give me something to tinker with - one of the earliest ideas I had for a puzzle in the game involves slipping some poison into the castle kitchen at a point in the process where it will go undetected. At that time it would have been a very scripted event, but now that I am moving towards simulation something more reactive and flexible makes more sense.

So I wrote a function called get_item_tree, which basically walks through all of the recipes, and builds a tree to acquire that item. At each level of the tree, we first determine if we already have the item or can just pick it up somewhere. If not, we recursively search for the ingredients that make up the item, and call get_item_tree on those.

Here's an example of one of these generated trees:

{
  "type": "P",
  "name": "Get item from combo",
  "children": [
    {
      "btf": "_interact_object",
      "type": "SUB",
      "args": {
        "action": "get",
        "object": "poisoned_meat",
        "dist": 50
      }
    },
    {
      "type": "S",
      "name": "Collect ingredients",
      "children": [
        {
          "type": "P",
          "name": "Get item from combo",
          "children": [
            {
              "btf": "_interact_object",
              "type": "SUB",
              "args": {
                "action": "get",
                "object": "meat",
                "dist": 50
              }
            }
          ]
        },
        {
          "type": "P",
          "name": "Get item from combo",
          "children": [
            {
              "btf": "_interact_object",
              "type": "SUB",
              "args": {
                "action": "get",
                "object": "poison",
                "dist": 50
              }
            },
            {
              "type": "S",
              "name": "Collect ingredients",
              "children": [
                {
                  "type": "P",
                  "name": "Get item from combo",
                  "children": [
                    {
                      "btf": "_interact_object",
                      "type": "SUB",
                      "args": {
                        "action": "get",
                        "object": "poisonberry",
                        "dist": 50
                      }
                    }
                  ]
                },
                {
                  "type": "P",
                  "name": "Get item from combo",
                  "children": [
                    {
                      "btf": "_interact_object",
                      "type": "SUB",
                      "args": {
                        "action": "get",
                        "object": "masher",
                        "dist": 50
                      }
                    }
                  ]
                },
                {
                  "items": "poisonberry,masher",
                  "type": "COMBINE_ACTION"
                }
              ]
            }
          ]
        },
        {
          "items": "meat,poison",
          "type": "COMBINE_ACTION"
        }
      ]
    }
  ]
}

Note that we first try to get "poisoned_meat", which if that fails we search for both meat and poison. At the end of all the searching, we make a call to combine the meat and the poison (which will access the crafting function). I can build as complicated a crafting tree as I want (though I probably won't go very deep with it in the actual game) and I can easily set up scenarios where npcs are involved in a crafting process of some kind.

I haven't actually tested the generated tree in-game yet, so there's still quite a bit to do here. Also missing is that most npc crafting will be much better for the player if you can actually see the crafting happen. Weaponsmiths will need anvils to work on, cooks will need an oven to cook meat over, weavers will need a loom, etc. I will need a much more descriptive list of recipes for npcs which includes not just the items used but the device needed, and whatever resource that device needs to function (i.e. coal for a furnace/stove).

For the player I have so far just been hardcoding these actions, such as stoking the firepit with logs. So I'll need to decide if the extra crafting info npcs need is just a markup for their benefit, or if I want to change how the player actions are coded as well to generate them from the same data. Making things more data oriented would be very cool I think.

A submission for Make games. 191

Added a referencing system to behavior trees to make it easy to replace nodes with other nodes. I created a behavior for being in the bed, which basically does nothing until it's time to wake up. The interaction command for the bed now handles adding that behavior into the tree when he uses the bed; and then when he uses the bed to wake up, it clears that behavior. This will hopefully be one more piece of the puzzle for dynamic interactions that don't grow out of proportion, and while the bed behavior is not attached, none of those nodes have to be processed.

I may change some of the existing subtrees to use this attach-detach mechanism.