-
-
Omenfall app icon — original 1024 × 1024 PNG.
-
RevenueCat-powered Cinder purchases with a Guest Wallet; linking Game Center is optional.
-
Omen bargains: choose a gain, accept its cost, and shape your run as Dread rises.
-
Ritual evolution: combine weapon ranks and matching Omens to unlock Funeral Star.
-
Four Keepers with distinct weapons, personal abilities and tradeoffs; Florinel is available from the start.
-
Lantern Memory on iPad: permanent progression across the Flame, Ward and Path branches.
-
Survival on iPhone: dodge the night horde with one-thumb movement and automatic attacks.
Inspiration
I love the "one thumb, pure chaos" loop of survivor-likes, but most of them look and feel the same: bright fantasy, endless stat stacking and runs that go on until you're tired. I wanted something darker and more deliberate for iPhone and iPad.
Omenfall started from one idea: "Protect the lantern until the final bell. Every powerful omen carries a price." Instead of every level-up being a free upgrade, what if each power came with a cost you have to weigh in the middle of a fight? I set that inside a dark folk-horror world: a ruined village, a lone lantern and a supernatural night that grows worse every minute.
What it does
Omenfall is a top-down survival roguelite built for short, intense sessions.
Gameplay
- One-thumb control: a floating joystick moves your Keeper, and attacks fire automatically. Your skill is in positioning, herding enemies, reading telegraphs and choosing your build.
- 8-minute Survival runs: each night has a clear arc. Ashlings teach movement, Night Hounds introduce charge telegraphs, Pale Moth swarms and Bell Wraith projectiles build pressure, an Elite Guardian arrives at 4:00, and the Horned Keeper boss appears at 7:15. Kill it before the final bell at 8:00, or the night wins.
- Endless Night: a separate mode, open from the start, with recurring bosses, shifting threats and a Game Center leaderboard.
- Omen Bargains: every level-up offers three cards, and each card clearly shows its Boon, its Price and its sigil (Ash, Moon or Thorn). Choices raise Dread (0–100), which makes the night more dangerous but increases your Cinder reward. The risk is always your choice, never hidden adaptive difficulty.
- Ritual Evolutions: reach rank 3 on the matching weapon and choose three Omens of its sigil to unlock one of three rituals: Funeral Star, Pale Eclipse or Briar Crown.
- Four Keepers, all sidegrades: Florinel, Rosaline, Lunaris and Kagehito each have their own signature weapon, two personal abilities, and a real advantage paired with a real drawback. A more expensive Keeper is never strictly stronger.
- Permanent progression: Lantern Memory offers 12 meta upgrades across Flame, Ward and Path. Additional relics and charms are discovered through gameplay milestones; they are not sold individually.
Art direction
Omenfall is dark folk-horror pixel art. The world is built from cool charcoal, moonlit blue, subdued teal, worn iron and aged wood, while warm amber lantern light, coral and ember highlights are reserved for what matters: the Keeper, attacks, XP embers and danger.
Readability drives every visual decision. Backgrounds stay quieter than enemies, projectiles and telegraphs, and each enemy has a subtle colored rim so its silhouette separates from the ground even in the densest waves. Every moving character has side, toward-camera and away-from-camera animations, mirrored for smooth eight-direction movement. Elite and boss attacks use larger, clearer telegraphs, so the screen can be chaotic without ever feeling unfair.
The UI follows the same mood: carved-wood and iron chrome, Omen cards color-coded by sigil, and an authored illustration for the lantern-rekindling revive moment.
Fair monetization that fits a roguelite, powered by RevenueCat
Omenfall is free, with unlimited runs: no energy, no tickets, no forced ads, no gacha and no subscription.
- Cinder packs (consumables): Cinder can be earned by playing and can optionally be purchased in four packs. It unlocks Keepers and Lantern Memory upgrades.
- Nightbound Wardrobe and Lost Places (non-consumables): outfits with matching attack visuals, and scenery. Both are purely cosmetic.
- Optional revive: once per run, the player can spend 150 Cinder or watch an optional rewarded ad.
This model fits the genre. A roguelite lives on "one more run", so run starts are never gated. Purchases only speed up the progression players already earn by playing, or change how the game looks. Since every Keeper is a sidegrade, spending never buys a stronger character, and skill and build choices still decide every night.
RevenueCat handles all in-app purchases. Every player gets a verified server account UUID, which I use as the RevenueCat App User ID. Purchases never grant Cinder on the device: RevenueCat and Apple provide proof, and my server credits Cinder exactly once through an idempotent ledger.
How I built it
Omenfall is a solo project. I designed, built, balanced and shipped it myself.
Building solo with AI
AI coding agents (Claude Code and OpenAI Codex) worked as my pair programmers throughout development. I connected them to Xcode through MCP, so they could build the project, run the test suite, read compiler issues and search Apple's documentation directly. I owned the product vision, game design, balance, art direction and every final decision.
To keep AI-assisted development under control, I wrote a binding project guide covering theme, architecture, monetization rules, performance constraints and a strict checkpoint workflow. Nothing was committed until I had manually playtested and approved it. AI image generation helped me create concept and source art, which I then processed into clean, runtime-ready pixel-art atlases with documented prompts and provenance.
Tech stack
- Swift, SpriteKit and SwiftUI. SpriteKit runs the world, HUD and joystick. SwiftUI powers every menu, the Level Up and Ritual screens, Results, Revive and the Store, all inside a UIKit app shell that runs natively in landscape on iPhone and iPad.
- Deterministic, testable game logic. Offer generation is deterministic for a given seed. Balance numbers live in focused balance models instead of scene code. Rewards and damage are pure functions covered by unit tests.
- Performance by design. A shared texture cache, three-direction sprite atlases, object pooling and a spatial grid for enemies are built to hold a 60 FPS target. On capable displays the game can start at 120 FPS, with an automatic fallback that reduces cosmetics but never gameplay density or telegraphs.
- Backend: Supabase (Postgres plus Edge Functions) stores the player's wallet and progress. Separate functions handle RevenueCat webhooks, Apple server notifications, purchase processing and account deletion. Offline runs store a durable receipt and sync when the device is back online, without paying out twice.
- Guest Wallet: players can buy without signing in. A per-device guest account is secured with a Keychain secret, and players can optionally link Game Center later, with a clear merge flow if they already have an account.
- Game Center: an Endless Night leaderboard and 14 achievements.
Challenges I ran into
- App Review and purchases: an early build required Game Center before checkout, and App Review rejected it. I rebuilt the flow around an automatic Guest Wallet so anyone can browse prices and buy immediately, with Game Center as a purely optional upgrade.
- Never paying twice: callbacks, webhooks, retries, offline runs, refunds and account merges can all overlap. Making every reward and purchase idempotent across devices and connection states was the hardest engineering problem of the project.
- Readable chaos: a screen full of enemies must still show every charge line, projectile and escape route. I tuned telegraphs, enemy rim lighting and background values so the danger stays readable even at peak density.
- Performance: I tracked down atlas texture bleeding, unnecessary environment chunk rebuilds and expensive profile copies that caused frame drops during heavy fights.
- Universal landscape: supporting every iPhone and iPad size, including notches, the Dynamic Island and new iPadOS windowing, without black borders or stretched UI.
- Directing AI at scale: AI agents are fast, but without clear rules they drift, mixing architectures, scattering tuning numbers or reintroducing removed features. I learned to write precise specifications and keep a living project guide as the single source of truth.
Accomplishments that I'm proud of
- A complete, polished game built by one person: two modes, four Keepers with eight personal abilities, seven enemy types including an elite and a multi-pattern boss, three Ritual Evolutions and a 12-node meta tree.
- A monetization model I'm proud to defend: optional, transparent and never pay-to-win. Every run is fully playable without spending.
- Production-grade purchase handling: server-verified, idempotent and account-safe, with purchases available without mandatory sign-in.
- Accessibility: Dynamic Type, VoiceOver, Reduce Motion and 44-point touch targets across the menus.
What I learned
- A small tradeoff is more interesting than a big number. Showing the Price as clearly as the Boon made level-ups feel like decisions instead of routine.
- Monetization is part of game design. Selling Cinder that players also earn through play, plus purely cosmetic items, fits a roguelite far better than energy systems or paid power.
- "Grant once" is hard. Trusting the server ledger and treating client callbacks only as hints saved me from a whole class of duplicate-reward bugs.
- AI multiplies a solo developer, but it doesn't replace judgment. With AI agents I could ship a scope that would normally need a team, but taste, game feel and final decisions still had to come from me.
- Ship early, listen to App Review. Each rejection made the purchase flow simpler and friendlier for real players.
What's next for Omenfall: Roguelike Survival
- Weekly Endless challenges and social Game Center features.
- More Nightbound Wardrobe outfits, Lost Places scenery and new enemy variants for Endless Night.
- Audio and atmosphere improvements.
- Using RevenueCat data to tune pack value and the Store experience based on real player behavior.
Built With
- admob
- claude
- codex
- deno
- gamekit
- postgresql
- revenuecat
- sprite-kit
- supabase
- swift
- swiftui
- typescript
Log in or sign up for Devpost to join the conversation.