I had a lovely winter break working on Skymagi. After losing all of 2023 and half of 2024, momentum toward the latter half of the year felt re-invigorating.
A common bit of advice on gamedev forums is the importance of making small games first. And while Skymagi is not my first game, it is definitely my largest. It can be daunting to face everything left to finish from the original scope, and that’s after all the cuts. Working a full-time software job outside of the project sometimes forces progress to a crawl. It can be demoralizing.
But there’s a deep satisfaction that comes with inching towards a goal, learning from past mistakes, and realizing that I could built the current iteration so much better/faster than when I started.
So, let’s start 2025 strong.
Evocation Sigil
Back in 2022, I created the Evocation sigil, where mages can upcast spells into greater versions that can destroy castles. The intent is for evocation spells to be the main weapons of the castle.
However, the new sigil mana pool doesn’t affect evocation yet.
The Design
- Evocation spells cast at the sigil require sigil mana, similar to FTL’s energy for the weapon system.
- Mages have their own spellbook and select from spells they can cast.
- Spells using the sigil are continuously cast and require no individual mage’s mana.
This design allows mana to be flexibly spent at Evocation based on mage’s prepared spells. It also might require swapping mages depending on how mana elsewhere is spent and their spell list. The goal is to make it feel dynamic based on what circumstances require and strategy for fighting.
Here’s a shitty sketch of the Evocation Sigil UI.
Each slot represents a sigil slot where a mage can occupy. Each mage picks a spell to cast. In the sketch, Pyro has fire, Druid has rock. Each cost 1 mana, which draws from the sigil’s 2/3 mana. It’s out of mana now, so the battlemage can’t cast anything.
So I tried to mock it up properly:
Overall, I thought this design worked okay:
- Shows mana costs of spells next to total
- Mage icons for showing who is casting what
- Maximum slots and disabled states
- Dedicated buttons for casting, targeting, and cast bars
The next several hours were spent on iterating on alignment with the other sigils, since Abjuration and Teleport will have spells as well. One variation I called “The Stack”.
One Pixel Magic
While developing the spell cast bar, I kept switching between LibGDX’s ShapeRenderer
and SpriteBatch
for rendering the fill and frame respectively. Unnecessary draw-calls, flushes, and tedious boilerplate.
batch.begin(); // render textures to GPU...
batch.draw( ... ); // render casting bar frame
// uh oh, now i need casting %
batch.end();
shapes.begin(ShapeRenderer.ShapeType.Filled);
shapes.setColor(Orange);
shapes.rect( .... ); // casting bar fill
shapes.end();
// now back to textures
batch.begin();
Then it dawned on me. I could just use a 1x1 white pixel from my spritesheet and tint/size it. I felt like a genius. That clunky block turned into:
batch.begin(); // render textures to GPU...
batch.draw( ... ); // render casting bar frame
// BEHOLD
batch.setColor(Orange);
batch.draw(onePx, ...); // FILL!
I immediately rewrote all my health and mana bar code.
I googled it, and of course, it’s a well-known trick. But I didn’t know about it.
Implementation
Using one pixel magic, ImHud, 9 patches, and updateSigilLevel
from earlier.
Though I had a disabled
state, I didn’t have the grayscale icon. I could’ve opened up
photoshop and made it in 3 seconds… or… I could spend a few hours on…
S H A D E R S
Grayscale in two lines:
float luminance = dot(color.rgb, vec3(0.299, 0.587, 0.114));
FragColor = vec4(luminance, luminance, luminance, color.a);
Thanks to a helpful wikipedia page, I learned that humans do not perceive brightness identically between colors. The shader’s magic numbers come from the NTSC standards. Humans perceive green the brightest (0.72) compared to red (0.3) and blue (0.1).
There were a few more design questions that arose.
- Should a spell allocate mana when a mage starts using it? I said yes, to make swapping more convenient.
- If mana is lost, which spell should be deactivated? I chose the furthest slot, so players can order as desired.
- Click the spell to activate, right click to deactivate.
Autocast
A common gameplay pattern is to keep targets and spells consistent across multiple casts.
If the goal is to destroy the enemy’s wards, the same sigil might be targeted by 3-4 fireballs.
Rather than requiring the player to keep inputing the same target, there should be a togglable button for autocasting.
The talented designers I work with would say don’t make a toggle a button; make it a toggle. Well, they aren’t here to stop me.
The toggle simply enqueues an identical CastCommand
after the current finishes.
Now, the evocation sigil requires mana and spells can activate/deactivate to pull from the pool.
Bonus Update (1/18/2025)
Check it out, new evocation sigil artwork! Now it’s a spellbook with candles that opens/closes based on mana. -Kittems from the Future
Here’s some designs I decided not to use, including a black hole and a sword.