Ai is fickle, but it yields good results.

Welcome to another brown background blog post!

I’ve been procrastinating on doing some sort of social media post recently, partly due to my half-assed sleep schedule. At one point I was gonna do a YouTube video about a good thought process to have when fixing bugs/errors in your game. And then there is this blog post, so I decided to do a blog post. Anyway, let’s get into it.

I’ve shown on our discord that we have started to use a Unity Asset called “Behaviour Designer” which gives you a visual interface for building game ai behavior through a branching tree structure called a “behavior tree.” The behavior tree works from top to bottom and left to right. Each node (or “Task”) on the tree can run some code that will result in a “success” or “failure” (or “not finished”) for that task. That simple information is used to direct the ai to choose which tasks to skip executing and which ones should execute. There are a variety of other ways in which the tree can be used to get the desired effect that you want. But the big idea is that you don’t have to think about the ai in a code-oriented way.

What my behaviour tree currently looks like. I have seperated the ai into 3 “parrallel branches” that run at the same time.

What my behaviour tree currently looks like. I have seperated the ai into 3 “parrallel branches” that run at the same time.

So why is this better than a fully coded ai?

I can’t say for sure if it’s better, at least in the context of Unity Engine. What I do know, is if I look at this ai tree ^ and try imagining how I would do that in code, it seems pretty difficult. It’s doable, but it is in no way as visual, and therefore easy to debug compared to this tree system.

I discovered very early on that this is basically visual coding, but in a very different way, and this made me rethink my original views on visual coding. By all means, “text-based-programming” should always be the starting point for computer systems. I can’t see it making any bit of sense to have a node-based C/C++ compiler. And all you have to work with are nodes. It just makes more sense for “framework level” code to exist in text form. And then that ground-level code can be used to build other systems that make interacting with a computer at higher levels more quick and intuitive (kinda like python, Lua, javascript, and even Basic from the ’80s). A visual programming system gives you a new way to build things, but it can’t be useful unless there is a way to extend that system with custom features (or nodes) by writing lower-level code that’s based on the code that powers the higher-level system. And Behaviour Designer does give you that ability, without that, it would basically be useless.

When I first started working with this tool, I did give it a little too much credit and assume that it would make ai design a whole lot faster. Which it did, but not as much as I might have hoped, but I think after getting used to its quirks, working with it will be a lot more smooth.

Like with regular code, there are many ways you can choose to code something, but one of them will be easier to read, and will probably withstand the test of time; Code that scales well with features. That doesn’t mean the other ways are bad, it just means that there is one that best suits your goals. And you don’t always know for sure if the current way is the best. And so you may hesitate to spend the time to refactor your code and let it go, and then continue to write code that will depend on that other code, and then make more refactoring work for yourself later on, etc, etc… 

But the moral here is not to idolize your code or try to confirm its divinity and be like: “This is the way the code was meant to be written. ALL THE PIECES FALL TOGETHER PERFECTLY. THIS IS THE WAY OF THE CODE!!!!!“

Please don’t do that, if you’re like me ಠ_ಠ

Anyway, my point is, the same thing applies to visual programming, of course!

This is the old tree. Unlike an old tree in the real world, it is not big and strong. It is weak, and I got rid of it.

This is the old tree. Unlike an old tree in the real world, it is not big and strong. It is weak, and I got rid of it.

So, why is this tree weak?

Excellent question, young cockroach!!! ヽ(☉ ͜つ☉)ノ

One thing I wondered while working on this tree (we will describe it as “old”) was how easy it would be to alter it for different AIs in the game. I do want most cave enemies to have basically the same ai behavior, but they might be customized in a specific way. Kinda like in Minecraft, all “Character Entities” have the ability to climb stuff, but that ability can be triggered to only happen in specific situations. For the player, those are climbable objects like ladders. For spiders, that's almost anything it touches. So I want to have behavior shareability across all NPCs, so I don’t end up writing the same code twice. Eventually, the behavior tree will be sectioned off into pieces that can then be shared amongst many different enemies and NPCs. And modularly customizable, so ai behavior will be overall consistent but can have a lot of variety.

The “old” tree that I am no longer using, that you see above, is taking a bunch of different tasks and mashing them together to get a working result. It’s probably totally fine. In fact, I might realize something about my new tree even, I don’t know,. My new tree at least seems to have better structure than the old one. You can see that the old one doesn’t look very symmetrical, but on my new one up at the top of the page, I am actually able to label the different sections and tell you what they are doing.

My new tree takes into consideration the fact that creatures can do multiple things at once. For example, we can choose to move our legs, and also at the same time, choose to move our arms. So there are 4 different “states” our bodies can be on (in this example). And our legs or arms don’t have to wait for each other to stop moving to do something. Some say, they can work IN PARALLEL.

The Parallel “decorator node” in Behaviour Designer is very special. At first, I was afraid to use it, but it seems to be crucial.

This node tells the tree that it’s “children branches” will all run in parallel. This is kinda like multithreading, but not exactly. Basically, they use Coroutines. And each branch of the tree doesn’t have to wait for another branch to reach its end for it to run. They all run simultaneously. This means I can have one branch who’s goal is to keep some information up-to-date that the other branches may need to function at any given point in time, but those branches can process that information in whatever way they desire. In my case, there is one branch that acts as the part of the kobold's brain that processes information from it’s “Eyes” to determine if it should follow something, or attack the thing it is chasing. The other 2 branches, as you may expect, control the “legs” and “arms”. One branch controls the attacking behavior, and the other controls the walking/chasing behavior. And any changes that happen in the vision branch can alter the state of the other branches accordingly.

I honestly hope that this is the right way to go about it. To me, this appears to make the most sense. Eventually, I will have to add a part for kobolds being able to use weapons. So the tree needs to be able to adapt based on whether the kobold is holding something. And I think this method will be better for that.

There have been a lot of slowdowns with doing things in this parallel way, but I think it’s just a matter of figuring things out. Either way, we are getting somewhere!

In other news! (╯⌐■ ͜つ■)╯︵ ┻━┻

Before I finish this post, I want to make sure everyone is in the know about what will be up next. Right now, I am just working on fixing some bugs that I have ignored for some time. I feel like it would be best to do that before moving on. Also, I will be working on implementing ARMOR for the first time, and mainly just trying to see how I am gonna tell the player: “hay, when you receive damage, you need to make that number a bit smaller first“.

And along with armor, I will also be seeing if I can start to revive character animations.

TLDW: Each wearable (armor, hats, clothing) has its own animation, but it’s all in sync. So I don’t want to have to create animation data for each damn sprite. DAT STUPID

So I have to make some system that aids that one quirk.

Also, I think our general goal is to add more content to the caves. In our roadmap, that’s not detailed as much, probably because the roadmap only focuses on major features, and not like: “ok let's start to actually add more stuff to the caves/biomes”. Which we can definitely start doing very soon (once animations are rock solid, *badum tssss*).

Also, here is our roadmap for those who haven’t seen. (but keep scrolling down, for my last message!)

Lastly,

A personal thank you to our new patron

(╭☞ ゚ᗜ ゚)╭☞ Blanktester!

Blanktester has recently joined our pantheon of patrons as a gold tier. And Mike and I would like to give em a big thank you for supporting us! People like Blank help us to not give up on our venture in making a quality indie game. And this is just one of the ways we want to pay him back. But not the only way.

We’ve been thinking about doing a limited time merch sale, and he would probably be one of the people who will get some free merch possibly. We are still discussing all of this, so nothing is confirmed. But for what our patrons have done for us so far, it makes sense to give back.

LASTLY, I would also like to thank Revyn for rejoining the pantheon this month. Every bit counts!

Also, go like his tweet! :P https://twitter.com/aseapup/status/1316193799148908546

Anyway, thanks for reading my ramblings. And I’ll cya guys later!

Previous
Previous

Layering Sprite Renderers In Unity

Next
Next

I might do a dev blog