Fablewoods 04
How not to build a spell crafting system
three times
[Shape] + [Element] + [Mods]
Start simple, a few crafting bits, combine and done! Right? Right...? Oh, no.
Shape
- Information on the spawn, movement, collision
- Bolt (normal projectile)
- Beam (channeled projectile/raycast)
- Nova, wave, cone, etc
Element
- Apply and match to status effects and visuals, mod speed, aoe, impacts
- Ice, Fire, Physical, Lightning, etc.
Modifiers
- Wildlands! Strategy pattern to allow for combinations and interesting emergent behaviors
Easy enough, hack into the current AttackData, insert the behaviors spawn and let it mange itself...

---- one month later ---
it's fine... I'm fine,. Everything is fine.

The bouncing and orbit modifiers are great, they work well with the projectiles but they broke my art brain to get working on beams or other shapes. Early on I added a block to crafting to just not allow mods that aren't compatible with the other shapes -- I likely should have stopped there.
But, I wanted beams that bounce, orbit, split, chain, etc.
[CastSpell] -> [SpellFactory] -> [SpellShape] -> [SpellElement] -> [SpellMods]
-> New Duplicate runtime only [AttackData]Attack hits terrain -> MaybeSplash / AOE damage
Attack hits entity -> MaybeRecast -> Split -> Etc.
Attack dupes from mod -> track current state for limiting chain/reducing speed, etc. Test Arena
Alright... Add test area, debug marathon later...
It works! A few bugs for sure, but it's pretty fun to play with, components are dropped randomly in the dungeon and the regular play through lets you upgrade a house in town to unlock the spell crafting bench to experiment with new combinations.
Crafting, Stats, Horrible Bugs
Not done, but we are out of the valley of despair! I'll take that. Some bloopers and testing videos.

Dungeon Branching
Prefab snapping with branching, separating the generation from visuals until the path is solved.
Mobs - States
Trying three big ones, Tank, Ranged, Fodder. These behaviors are component based and can be mix and matched, but the bases should be solid. No path issues, attack pauses, etc. They need to work well, then we branch from those main states to create bosses and alternates.
Give the mobs the ability to queue up actions based on their position, abilities and goals.
- Idle / Wander
- Alert
- Follow
- Return to spawn (out of ability distance, time out)
- StateSequence - Sort of a internal FSM, running in sequence with exit interrupts
- Gather AbilityData (Abilities are assigned on the Entity components)
- Charge Up
- Cast/Use - Attack!
- Recover
- Exit State
Nothing novel or new, but seeing the mobs start to come to life is fun, i'll save this for the next post.

Player
Another less visual change, but the player state machine was split into a movement FSM and an ability FSM, this lets you layer move, jump, sprint animations and state as well as casting, cast-charge, attack and any other animation based input.
I want the player to feel responsive for that action-rpg feel. This seemed like the way to go.
[Player]
- [StateMachineMovement] - Sprint, Run, Jump, Dash
- [StateMachineAction] - Quick Cast, Attack, Attack Combo, Channel
Component shift
It all started with InventoryData... A fever dream and the save state. I was sharing InventoryData (base resource with a stack of inv slots, holding ItemData, quantity) on props like chests, the player, the mobs etc. Then you add LootTables and things get wonky. All the sudden I need to update multiple save functions and I get annoyed, lil turnip dude just save yourself.
I shifted to multiple components with a simplified entity glue, which also allowed for stat tracking, achievements, etc. Mostly from the PersistComponent which gathers up the entity it's attached to and dumps the save.
Build CI
Pretty boring, but adding CI to the build process that injects versioning information and allows for uploading to steam with tags is a big step for actually releasing bits. Previous iterations were purely local builds with manual tagging and zipping for steam uploads.
Now, make a push with a tag or not and the LAN based Gitea instance will plop out the binaries for steam deck and windows. Generally takes a few minutes and easy to toss into steam or locally push to the steam deck for testing.
This also does some of the dirty work, dumping in the steam-app ID and adjusting any env vars that might be useful later. (save game versioning is terrifying)

Awkwardly this means I have two apps on the steamdeck, one local build pushed directly to the device for non-tagged quick test builds. Similar to nightly releases and the official Fablewoods app it's not updated automatically and needs a tagged version with certificate signing to be pushed to steam users.

Web View
I have a few servers scattered in the cloud that use different OS platforms and web servers, don't ask why, I don't know either. I wanted to track the data over long periods of time. This includes slurping up all the NGINX, lighttpd logs as well as the OS specific logs and tossing them into a sqlite3 DB for caching and long term storage with deduplication. Could have used a million different libraries to do this but continuing on my self hosted, one person dev journey for better or worse.
The blips of activity were generally related to social media posts and that's good to track for some reason, probably.
I'm always impressed by devlogs like https://www.factorio.com/blog/ they are such a fun time capsule of dev efforts. I want to have something similar with fablewoods.com eventually tracking the releases and change logs. This let's me push those sort of blog posts and get see what happens from those efforts.

