Notes on Behaviour Trees #
This is a Next-Level Godot Project by Firebelley Games
- Highlight a node in the scene tree and press f to focus in the editor window.
- Composition for characters, for the world inheritance often makes more sense because all levels will have mostly the same components.
- Scene inheritance?! I haven’t even touched this.
- Test scenes. Just put whatever you need into the test scene so you can run it (F6).
- Beehave behaviour tree plugin. What’s a blackboard?
- Behaviour trees are great for no-code game designer to collaborate. Otherwise probably overcomplicates it.
- Node-based state machines and behaviour trees raise the problem of injecting dependencies into each state. Firebelley uses a CallableStateMachine that takes Callables for tick, enter, and exit.
- Use groups instead of recursing over all children to find specific nodes. Uses a hashmap so it’s faster.
Timers vs. Timestamps #
I’ve been measuring delays wrong. I have lots of code that saves the value of Time.get_ticks_msec() and then later, compares that against the current ticks. Now I see the problem with that. When paused, Timers will pause but Time.get_ticks_msec() will continue on. So any cool downs can be waited out within the pause menu.
Right now I only noticed it with the trail that follows the player around. If I pause and wait a few moments before unpausing, the trail expires and it all disappears at once.
That’s a good lesson.
I’ve a bunch of those to learn, reckon.
Shopping #
I got a scene for a shop working. Right now it’s just three buttons that notify that the shop is closed once the player has made their choice. Looks more like a rogue like deck builder right now than a shop.
The hard part was getting it to work with the level system in Maaack’s game template.
First, I tried putting the shop inside the level.
Level1
- TheGame
- Shop
Level2
- TheGame
- Shop
Level3
- TheGame
- Shop
I figured I would hide TheGame while the player was shopping then queue_free() the shop and start TheGame once they were done. But then I had to pause TheGame and that was breaking the buttons in the shop. I fought with that for a while then tried a different approach.
Next was to tell the level loader from Maaack’s game template to alternate the shop with the levels. I modified the SceneLister’s array of level paths.
res://content/game/shop/shop.tscn
res://content/game/levels/level_1.tscn
res://content/game/shop/shop.tscn
res://content/game/levels/level_2.tscn
res://content/game/shop/shop.tscn
res://content/game/levels/level_3.tscn
The problem with that was the SceneLister uses the file name to track which level we’re on, not the index in the array. Reckon it works better that way for non-linear levels but for my purposes it didn’t work. The result was I would go to the shop after level one, then repeat level one, then back to the shop… forever.
So, finally I put the shop back into the level scenes just like above. But I load them in GDScript. So the level is a Node2D containing the music for that level (I guess I’ll need to have shop music as well, hmm). When it first loads, the shop is instantiated and displayed. Then when shopping is done it gets freed and TheGame is instantiated and displayed.
I think I would’ve preferred the second option but this is working and seemed better than wrangling the game template / SceneLister / LevelLoader into doing what I wanted.