Garlictos - a wave survival roguelike for Android, made solo in Godot 4

I released my first game last week. Garlictos, a Brotato-style wave survival roguelike for Android, built alone in Godot 4 over about a year between classes. It’s free.

What it is

Weapons fire on their own, you only control movement and positioning. Twenty waves, with a level-up and a shop between each one. The mechanic I built the game around is weapon merging: you carry six weapons max, and two identical weapons fuse into a stronger tier. Once the bag is full the game starts merging on its own, so every shop visit becomes the same decision - buy the third pistol to force the merge, or break the build for the shotgun that just appeared. There are four characters with different starting gear, a permanent upgrade temple between runs, and an endless mode after wave 20.

The Godot parts that were actually hard

Since this is the Godot forum, the engine-specific war stories are probably more interesting than the game description:

Shader instance uniforms. I had random screen flashing on device that never reproduced in the editor and never showed up in the profiler. adb logcat -s godot on the actual phone finally gave me “Too many instances using shader instance variables, max 4096”. My pooled enemies each carried a per-instance uniform for their hit flash, and a big wave blew straight through the limit. Worth knowing that this error is device-only - if you’re debugging mobile in Godot and not reading logcat, you’re working blind.

2D batching. Draw calls sat at 204 on a busy wave. The two culprits were a shadow sprite using show_behind_parent = true, which silently breaks batching for everything around it, and a Label with outline_size = 8, which costs roughly three times what a 2px outline does. Fixing both took it to 67 draw calls with no visual change worth mentioning. The Monitors tab with remote debug over USB is what found it - the editor’s own numbers were useless because the desktop never struggled.

Physics interpolation ghosting. At 30Hz physics with interpolation enabled, fast-moving enemies smeared. The cause was that I was repositioning some of them outside _physics_process, so interpolation had two unrelated positions to blend between. Obvious in hindsight, invisible while it was happening.

I went with the Compatibility renderer for old device coverage and I’d make the same call again.

On monetisation, since people usually ask

There are no forced ads. No interstitial between waves, no banner, no energy system, no timers. There is one optional rewarded ad you can choose to watch in the shop if you want extra gold, and a single optional purchase that unlocks nothing. I was told repeatedly that this is financially stupid and it probably is, but I didn’t want to ship something I’d uninstall myself in the first minute.

Details

Godot 4, Compatibility renderer, GDScript. Around 117 MB, Android 7.0+, works fully offline. English and Turkish for now.

If anyone tries it, the single most useful thing you can tell me is which wave killed you the first time. I’ve played it so many times I’ve completely lost the ability to judge whether it’s hard. Happy to go deeper on any of the technical bits above.

You should add some screenshots to your post.

2 Likes

yeah fair, my bad. kept meaning to and then just didn’t.

tried to embed a couple straight from the store page and this forum won’t let a new account do it - first it said one media item max, then it choked on the url length. so for now they’re here:

the shop one is the interesting screen, that’s where the whole merge decision lives. i’ll get proper images into the post itself once i’m back on the machine that has them. if there’s something specific you’d rather see - the Monitors draw call overlay, or what wave 15+ looks like with six merged weapons all firing - tell me and i’ll grab that one.

Finally back with proper images (and honest news on the ads front).

1.7 shipped since my last reply. Freezes down ~90%, the wave 6 wall got smoothed out, revives went 1 → 3, item descriptions are all real now (157 of them), text is bigger everywhere.

The part I need to correct from the original post: I added two interstitials (after wave 8, and on death-to-menu, capped at once per 3 min). The rewarded ad for revive is still opt-in, no banner. A supporter pack skips the interstitials entirely. Wanted to say that here rather than let the old “no forced ads” line stand uncorrected.

New trailer, shows the merge/shop loop and a few late waves: https://www.youtube.com/watch?v=3GNlJ_Z0nb4