UYLLII

Blog › Postmortems

Postmortems

Postmortem: Eldritch Survivors, the 3D survivors-like that crashed older phones

By David5 min read
UYLLII games

This is a post about a game you can't play. Eldritch Survivors is shelved, and it will stay that way until it runs on older phones without crashing. I think the failure is more useful written down than hidden.

The game

A Vampire Survivors-style roguelite set in 1920s cosmic horror. You're a lone investigator with a lantern in a fog-bound harbour town. Each run is a ten-minute night. Weapons fire automatically, you choose upgrades as you level, and waves of fish-men close in.

The twist was sanity as a currency. Every level-up offers Mundane cards and Forbidden cards. Forbidden ones are much stronger and cost sanity. As sanity falls through four madness tiers you deal more damage and earn more XP, but the screen warps, phantom enemies appear that aren't really there, and eventually the invisible "Unseen" become visible. At zero sanity you get a 20-second Revelation, and the fourth one ends the run.

The pitch was a five-second clip: a tiny figure with a lantern, a screen full of fish-men, the picture tears, and tentacles burst through.

Every name came from Lovecraft's public-domain stories. "Call of Cthulhu" and "Arkham Horror" are trademarks, so I stayed well away from both.

Why this genre

Survivors-likes had the biggest search demand of any genre I checked: a top-ten median of about 4.2 million installs on Google Play, with three apps less than a year old in that top ten.

Before designing anything I read about 24,650 Play reviews of 28 survivors-likes. Only two still held around 4.2 stars in recent reviews: Vampire Survivors and Magic Survival. Both have optional rewarded ads, no energy system, and work offline. The gacha and energy-timer games had sunk to 2 to 3.4 stars. The most common complaints:

So the design promised: rewarded ads only, autosave every five seconds and on hide ("never lose a run"), and a one-time No Ads purchase.

From pixels to 3D

The first build was pixel art. I hated it. I wanted smooth top-down 3D. The sprite's walk was a code bob that made the investigator look like he was squatting, and the shots spawned from the sprite's origin, i.e. his feet. So I rebuilt the renderer in three.js on the same simulation.

The lesson there is cheap: decide 2D or 3D, pixel or smooth, before building a renderer, and write the art direction into the design doc first.

The asset pipeline

A survivors-like needs hundreds of monsters on screen. That rules out ordinary skinned meshes, where each enemy pays for its own skeleton. The pipeline I built:

  1. concept art for each creature,
  2. a model in Blender,
  3. CC0 textures (from ambientCG and Poly Haven) baked on,
  4. decimated to a strict triangle budget: 800–1,500 for swarm enemies, 1,500–3,000 for grunts, 3,000–6,000 for elites, 10,000–20,000 for bosses,
  5. rigged, animated, and exported as a vertex animation texture (VAT), so every monster of a kind renders as one instanced draw call.

In a couple of days that produced 9 investigators, 11 monsters and allies, two sub-bosses, a final boss (Father Dagon, 13,600 triangles, with a rise-from-the-ground clip), 29 graveyard props and the weapon props. A one-row VAT for Dagon came out 16,000 pixels wide, beyond phone texture limits, so it wraps to 2,048. Raw exports of 109 MB were compacted to 52 MB with half-floats, 8-bit normals and JPEG.

For the title screen I also built a 41,000-triangle "showcase" detective with a 2,048-pixel texture, because the in-game model looked poor close up.

The crash

Every test so far had run on a desktop or an emulator. Then I opened the preview on an Oppo R17, a mid-range phone from 2018 with an Adreno 512 GPU. While it loaded, the canvas turned into the browser's crash image: the WebGL context was lost.

Adding it up afterwards, the full look needed:

Any one of those is fine on a flagship. Together, on a GPU from 2018, they were fatal.

I built a "lite" tier that auto-selects on older GPUs and on phones with 4 GB of memory or less: textures capped at 512 px, no HD menu model, no MSAA, a pixel ratio of 1.5, and fewer lights. A context loss reloads once in lite mode, and there's a "Low-power graphics" switch in Settings. But I only ever tested it by forcing a context loss on a desktop. The real root cause on that phone is still a guess: memory, or the float render target.

Why it's shelved

I decided to stop. Not because the game was bad (the core loop was fun, and I'd got far enough to break it: level 83 at 8:54 with full health, which led to a pile of balance fixes). It's shelved because a game that crashes on an older mid-range phone can't be released to the audience I'm making games for, and finding out why is open-ended work with no guaranteed end.

What I'd do differently

Parts of it live on. The asset pipeline (concept, Blender, CC0 bake, triangle budget, VAT) is reusable, and the review research shaped the ad design of everything I've built since. But no, you can't play it.