31 Assets, Zero Hardcoded Values: How ScriptableObjects Changed Everything


This is devlog #2 for Backfire. Last time I talked about where the idea came from and what the core loop feels like. This time I want to talk about something less glamorous but just as important: how the game’s content is structured, and why a Unity feature called ScriptableObjects made a solo developer’s life dramatically easier.

The problem with hardcoding

In the first prototype, my combat manager had this sitting in the code:

monsterName = "Stone Golem"
monsterMaxHP = 6

That works when you have one monster. I have 6+. Each has different HP, different abilities, different trigger intervals, different sprites, and two of them are bosses with phase transitions at 50% HP. If I hardcoded all of that, every time I wanted to tweak the Naga Guardian’s HP from 12 to 14, I’d have to open the script, find the right line, change it, save, wait for Unity to recompile, and test again. Multiply that by every monster, every grimoire page, every relic, and I’d spend more time editing code than designing the game.

ScriptableObjects as a content database

ScriptableObjects are Unity’s answer to this. They’re data containers that live as files in your project. You define the structure once in code — “a grimoire page has a name, a formula, a damage value, a rarity, and a bonus effect” — and then you create individual assets for each piece of content by filling in fields in the Inspector. No code touched. No recompilation. Just click, type, drag a sprite, done.

I created five ScriptableObject types for Backfire:

GrimoirePageSO defines a spell formula. Each one specifies which rune combination triggers it, how much damage it deals, and what bonus effect fires on cast. The formula is a list of slots where each slot is either a specific rune type or a wildcard “any” slot. This is how Frost Chain knows that Ice + Ice + Any is valid, while Fusion Bolt requires the specific combination of Fire + Ice + Storm.

MonsterSO defines a dungeon creature. HP, portrait, abilities with trigger intervals, elemental resistance, boss phase transitions. All in one asset. The Naga Guardian has Curse Tiles every 5 picks in Phase 1, then adds Tray Corruption in Phase 2 when it drops below 50% HP. All of that is configured in the Inspector, not written in code.

RelicSO defines a passive or active item. Iron Will is a passive that prevents your first overflow each floor. Purging Flame is an active with a 5-cast cooldown that lets you destroy one rune from your casting circle. Both use the same data structure. The relic type field switches between passive and active, and the effect type tells the game what to actually do.

PlayerClassSO defines a starting loadout. The Runesmith starts with 7 casting circle slots, no grimoire page, and the Iron Will relic. When I eventually add the another class, it’ll be another asset: 6 slots, Shadow Hex as a starting grimoire page, Hex Sight as a starting relic. Different file, same structure.

BoardTemplateSO defines a board layout. Tile positions, layers, and blocking relationships. Right now I have a hardcoded board, but the structure is ready.

The content database

All of these individual assets feed into a single master asset I called ContentDatabase.

This means adding new content to the game is a three-step process: create the ScriptableObject asset, fill in the fields, drag it into the ContentDatabase list. No code changes. No recompilation.

Why this matters for a solo developer

The reason I’m writing about data architecture in a game design devlog is that for a solo developer, the line between “design” and “engineering” doesn’t exist. Every structural decision is a design decision. Choosing to make grimoire pages data-driven instead of hardcoded means I can balance the game ten times faster. I can play a run, think “Frost Chain’s delay should be 3 picks instead of 2,” switch to the Inspector, change the value, and play again in under ten seconds. No code. No compilation. Just iterate.

It also means that when I eventually want community feedback on balance, I can share exact numbers. Every value is visible, every value is tweakable, and none of it is buried in source code.

What’s next

The data is ready. The grimoire draft system that actually presents these pages to the player between floors is the next build target. That’s where the game goes from “tile-matching with a monster HP bar” to “roguelite with real build variety.”

More soon. Peace.

Files

Backfire_EarlyPrototype.zip 36 MB
50 days ago

Get Backfire

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.