Bunny quest with telegraphing logic change
The quest for bone broth
The Quest to eradicate the undead infestation
Exploring a level: cabins, altars, caves, ruins and ... clubbing

A few things these past 2 weeks:

Adding complexity in quest behaviour

Entire day spent on enabling this scenario, which is really a mod on an escort quest. Previously, an entity aims towards a destination, and you need to protect. The new scenario allows this: the entity follows you, until it spots an exit, at which point it sets its new goal as the exit. It might sound obscure, but this expands the scenarios that can be portrayed in the game, so ... I like it. Also, to telegraph this "switch" from following the character to aiming for the exit, an exclamation mark pops up at the following creature. But no, that was not enough.

Telegraphing and cutscene animations

That exclamation mark on the bunny was not enough. I remember games like Shining Force 2, which used simple sprite transformations to communicate some actions and emotions, like surprise, looking around, and so on. So I thought that might be useful for cutscene animations as well as telegraphing a few things. For example, in the aforementioned quest, the bunny follows the player and when it discovers an exit, plays but the looking around (looking left and right) and the double jump (surprise) animations, then proceeds normally to that exit. I'll confess my approach to rendering has resulted in a really weird way required to achieve this, using shader code for all such animations and an integer per sprite to figure how to animate the sprite given its position and other standard rendering parameters.

More quest types/examples

I'm slowly trying to build up to a framework for procedural quests. There are some key "blueprints" that are missing:

  • Kill a boss or some other unique creature at some location: for this, I need to "edit" the location to include that boss/creature organically
  • Clear an area from some group of creatures, e.g. undead: for this, I need to "edit" the location to include that creature group as well
  • Find an item, e.g. some journal note or some relic. Similarly, need to edit the location specification to include that

Besides making the above happen, I also need to proceed onto quest brainstorming, which means reading a few RPG books : adventures, settings, adventure writing guides, etc.

Dungeons, prefabs and AI

So, basically I have a list of quest types I want to implement. Top of the list, is "kill some boss" and "find some treasure". Pretty simple, right? Ok, here's the question: how do we "augment" a map to contain a boss and treasure? That's a bit tricky when one dances the procedural dance. I've already done some work on that (surprise surprise) before the port to Godot. In particular, I had a class of prefabs that are purely boss lairs. Some info in the related blog post here. But what if a boss doesn't live in a lair?

At this point, I'll reiterate that Sigil of Kings uses for its maps: procedural generation, prefabs, connecting prefabs procedurally, procedurally generating prefabs, procedurally generating prefab features, procedurally generating general features, and a few other things. You get the idea. Duct tape, RNG, and lots of happy hours spent on that ... thing, made mostly of C++ and C# glue code. E.g. in a wilderness cabin we have a chair, a bed and a table that have rules for placing procedurally. In that same vein, I can use some special "boss" and "treasure" rules for creating placement spots for bosses and treasure (e.g. by a wall, etc). For prefab lairs, I'm including this boss/treasure info in the definition of the entire "zone" (the area specification). The prefab element placement rules are all stored in a database and I just use references for that.

Now going back to bosses/treasure in random areas that don't naturally support them, that's the bit I worked on. Effectively the zone specification allows some prefab element rules to be specified dynamically, in addition to the databased-provided ones. There is a bit of work for merging the rules both in the C++ side and in the C# side (the joys of this little plugin idea), but the result is that I can inject some boss/treasure rules (and any other rules really) at any existing ruleset that is applied to any zone. The reason for all this work is that I want the benefits of using lightweight references and the benefits of being able to dynamically extend them. It's a common "pattern" throughout the codebase really, and it's ... a bit of work to deal with.

Another bit I worked on was AI-related. The moment you entered a level, AI started doing stuff. But imagine everything being carefully placed in the dungeon generation process, only for the AI to start creating a mess the moment they start playing! E.g. creatures killing each other (when you don't want to just yet) or bosses taking walks away from their lairs, spoiling the discovery moments when you find them in their "natural" environment. The solution to this was simple: I already maintain a list of what zones the player has ever visited, and unless the player has been to a zone or they see the entity's position, the entity will not run its AI. This possibly needs some tweaking, but it does the trick.

That's it for now. Now more quest types to do. Until next time!