Generic progress report go!
OK I know I said this month would be slower because I'd be traveling and
taking some time off and I swear I did (thought I had to cancel going
to Ireland because of a Covid scare) but still found time to add... actually
quite a lot of stuff. I mostly focused on adding features to the battle
engine.
(it should go without saying: since we've been mostly focusing on the engine and UI design, all these graphics are still only a step past being placeholders)
Line of sight: I was able to re-use a lot of code from the
demo, which itself borrowed
this algorithm
from the rougelike community. I spent a weekend trying to optimize it enough
to use in gdscript instead of c#, but it ended up being too slow. To calculate
for an entire map, the gdscript version took around ~25 seconds to run as
opposed to the ~2 seconds in C#. This means that there's not going to be
another web version of the game until Godot 4 is able to export C# code to
html5 — which I've seen a few mentions that it's being worked on so a browser
demo remains possibly possible eventually.
Pathfinding: Godot's built-in A* algo is not set up to have
multiple possible movement costs to enter the same tile (such as the
difference between climbing a cliff and stepping there from the same
elevation) so I had to come up with a sorta-weird hack where I stacked a bunch
of pathfinding nodes at the same tile; one for every possible movement cost
that could enter that tile. It now is smart enough to use ramps and step up
cliffs gradually using shorter climbable objects as stepping stones.
Attack animations: Although we haven't been focusing on the
fancy graphical juice of the game, I still needed to set up the structures
that would contain the animation data. Not much to say here besides we've done
so and will probably flesh it out more once we start focusing on game feel.
Destructible terrain: terrain tiles now can transform
into another specified tile when they are damaged (half health) or destroyed.
I also added support for multi-tile terrain objects (like large rocks) that
share a single health pool.
Enemy AI: I've added a draft of a controller that gets the
enemy to run around and use their weapons. I've tried to make it a little more
robust than the version in the demo where they just run at you until they're
in range and then shoot, but of course this means there's now more room for
strange behaviors. For instance, some of them are currently doing a weird
little dance before and after they shoot.
Weapon profiles: it's a very strange experience playing Baldur's Gate 3 while working on a video game adaptation of a different TTRPG. I feel like I have a little peek behind the curtain having dealt with many of the same challenges inherent in doing so. One such challenge is how to wrangle the many, many actions available to a character and deal with those actions contextually becoming available and unavailable.
For example, in BG3, when you cast the Hex spell on someone, you become able to re-apply that Hex to a different enemy without spending another spell slot. One way to approach this would be to give some kind of discount on the Hex action so using it again doesn't cost a slot — but what they've done instead is a far more flexible, modular, and stateless solution: they simply make an entirely separate second version of the action which does not cost a spell slot show up in your action bar. Having abilities be able to just in general hide and show various versions of actions means you can use that same system for weapon profiles, charged and uncharged modes, and temporary bonus actions like the re-application of hexes.
So we've copied this for LT. Here's the Drake's assault cannon, which has two
modes: regular and spinning. Using the "spin up" action hides itself and the
regular attack, then shows the spinning and "spin down" actions. This is also
a glimpse at the direction Mark has been going for the player interface —
we're taking some more pages out of BG3's book and making an
icon-and-tooltip-rich action bar instead of the demo's nested radial menu
system which was stylish but we think would end up being too impractical.
Contextual actions: Sometimes you need to take an action that
comes from your environment instead of from your own abilities. Since we've
done a good job keeping the code for the actions stateless (they
don't know anything about where they are or who they belong to beyond what we
tell them when they're activated) it was just a matter of asking a unit's
neighbors if they have any actions they'd like to share. Here's an example of
that in action: a restock drone giving an adjacent ally an action to consume
the drone.
Finally, I don't have a good gif for it, but I expanded the Buff/ongoing
status condition system to have the ability to run custom snippets of code in
reaction to events, just like legit Reactions do. This will give us the
ability to do strange one-off things like handle the Witch's Chain ability
that monitors how far the unit it is applied to moves and do nasty stuff when
triggered.
Next month we're planning be shifting away from the battle engine somewhat and
working on more character sheet + pilot portrait maker stuff.