Inspiration

Two games inspired this one. Oaken Tower is a tower autobattler where you stack items and watch them fight. Once Upon a Galaxy is an autobattler where you play against other people's builds with no turn timer. I wanted both ideas in one mobile game that I could play in short breaks.

Six Hollows started on July 8, 2026 as a 48-hour prototype called Slotfall. It shipped on the App Store on August 18. Version 1.1.0 came out on September 28 and added monthly seasons with rewards.

What it does

Six Hollows is an autobattler. You build a tree, and the tree fights on its own.

Starting a run. A run puts you in a room with five rivals. The rivals are ghosts. A ghost is a tree that another player built near your rank, saved round by round. Bots fill any seats that are left.

You start with 10 lives and an empty tree. The tree has six hollows, and each hollow holds one item. Before round one you pick one of three Spirits. A Spirit is a bonus that lasts the whole run, like extra tree health or an extra re-roll in every shop. The game has seven Spirits.

Each round has two parts.

  1. Shop. You see five items and get one free re-roll. You pick one item. You can put it in an empty hollow, swap it for an item you already hold, or pick a second copy of an item to level it up. There is no gold. One pick per round is your whole budget. A level-up gives you a fresh set of items, so you keep picking until you place or swap something.
  2. Fight. Your tree fights one rival's tree, and you don't tap anything. Items fire on their own timers, from the bottom hollow to the top. They deal damage, burn, poison, bleed, freeze, shield and heal. Where you put an item matters, because many items boost or react to the item next to them. If a fight lasts past 15 seconds, both trees start taking damage that keeps growing, so every fight ends.

After the fight you see how everyone in the room is doing. Then the next round starts, and you fight a different rival.

Getting stronger. Your tree starts with 1,000 health and gains more every round. Rare, epic and legendary items show up more often in later rounds. The 64 items belong to eight families, and each family does one thing. Cinder burns, Blight poisons, Deadeye crits, Rend bleeds, Salvo fires again, Clockwork speeds up, Frostbite freezes and Zap chains down the tree. You can stack one family or mix several.

An item that reaches level 3 gets a crown. Each crown lets you pick one of two boons. A boon is a bonus for the rest of the run, like stronger burns or a shield at the start of every fight. There are 22 boons.

Winning and losing. A lost fight costs one life in the early rounds, two in the middle rounds and three from round 9 on. A close loss costs less. At zero lives you are out. The last tree standing wins.

Your ghost. The game saves your tree after each round. Those saves become ghosts in other players' rooms. The tree someone fights in round 7 may be your real round 7 tree, with the same items, levels and boons.

Ranked play. Ranked play starts with your first run. There are six ranks, from Sapling to Elder.

Seasons. A new season starts every month and resets the rankings. Each season changes one rule for everyone. October is Blood Moon, and every bleed hit adds 10 extra bleed. Every ranked run you finish earns season XP. XP unlocks rewards like portraits, borders, titles and battle backgrounds. Blood Moon also has a new Spirit, the Pumpkin Lantern. It sets every enemy tree on fire at the start of each fight.

How I built it

The fight engine is a separate Swift package with no UI code. It takes two trees and a seed number. It gives back a list of everything that happened in the fight. The SwiftUI app plays that list back on screen. Two Metal shaders draw the holo foil effect and the ripple at the end of a fight.

The same trees and the same seed always give the same fight. Ghosts, replays, balance testing and the tutorial all depend on that.

The backend runs on Convex and is written in TypeScript. It saves ghosts, fills rooms, keeps the rankings, runs the seasons and checks purchases with RevenueCat. Players sign in with Game Center, and the server checks each sign-in.

Item numbers live on the server. Each run keeps the numbers it started with, so they never change in the middle of a run.

When an update changes the fight rules, old versions of the app show an update screen. That way everyone in a room plays by the same rules.

Accessibility

You can play Six Hollows with VoiceOver on every screen.

AppleVis is a community of blind and low-vision Apple users. One of the players listed the game there and said it was their most played game in recent weeks. They rated it fully accessible with VoiceOver and easy to use, with every button clearly labeled.

Two sets of tests run on every build. Apple's accessibility audit checks every screen for missing labels and small tap targets. Other tests save what VoiceOver reads as plain text, so a broken label shows up as a changed line.

Monetization

You can't pay to win. Nothing for sale changes a fight, the shop or the rankings.

The game is free and has no ads. There are two purchases. Both are cosmetic, and both go through RevenueCat.

The Supporter Pack costs $4.99 once. It gives you name colors, a gilded portrait and border with a holo foil effect, a title and a battle background.

The premium season track costs $4.99 per season. Every season has a free track and a premium track. The premium track holds only cosmetics. The one reward that changes a run, the Pumpkin Lantern Spirit, is on the free track. You can buy the premium track on the last day and still get every premium reward you already earned.

Challenges

Performance. Early fights stuttered because the whole battle screen redrew on every tick. I split the screen so only the cooldown bars and damage numbers update each tick. Sounds now load before the fight starts. Music plays in the background so it won't cause frame stutters. Images load once and stay in a cache. On the server, one rankings query recounted the whole board every time any score changed. Version 1.0.2 removed that query and skips saves that change nothing.

Art. Every item, portrait, border and background started as an AI image. I generated hundreds of variations and kept only a few. Python scripts clean up the generated assets, then send each pick through Retro Diffusion, which redraws it as pixel art. All the art uses the same 64-color palette, so pieces made weeks apart still look like one game.

Item balance. With 64 items, one strong combo can ruin ranked play. I built a command-line tool that runs thousands to millions of fights between bots and/or player ghosts. It shows how much each item changes the win rate, early and late in a run. Balance changes now come from the server, so this type of fix doesn't wait for App Store review. The latest one lowered the Blight and Cinder numbers.

What I learned

Making fights repeatable was the best early choice. One seed gave me replays, ghosts, balance testing and a tutorial that plays the same way every time.

I also learned to test accessibility on every build. Apple's accessibility audit and a custom suite of accessibility tests run on every screen.

Built With

Share this project:

Updates

Submission history