DEV Community

Tse Xaiver
Tse Xaiver

Posted on

Duck Evac: a complete extraction-shooter game whose code and art are 100% open-weight generated

Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle Submission 💸

Hacktoberfest Open-Source AI Challenge — Week 2: Side Hustle submission*

Duck Evac (鸭鸭大撤离) is a complete, playable 2D top-down extraction shooter: drop in, loot, fight enemy ducks, extract alive. Every line of its code was generated with DeepSeek V4.1 (open weights, MIT license); every sprite was generated with MiniMax (open weights). No human drew a pixel, no human hand-wrote the engine — one person directed two open models and shipped a real game. It's now heading to TapTap (China's indie mobile store) for commercial release.

  • Code: key systems pasted in the Code section below (a GitHub repo will follow after the deadline rush)
  • Demo: 67 seconds of real gameplay, captured from the running web build
  • Art: 100% original duck IP — zero copyrighted assets, zero takedown risk

The problem: one person, a whole game

I wanted to ship a commercial indie game solo. The math every solo dev knows:

  • Code: a real game engine is thousands of lines — game loop, 8-direction sprite rendering, enemy AI, HUD, minimap, mobile touch controls. Months of work for one person.
  • Art: 42 sprites (3 playable duck skins, 6 bosses, soldiers, guns, menu art) in one consistent flat-cartoon style. Commissioning that costs more than the game will ever earn; drawing it myself was never an option.
  • The trap: closed models could do it, but per-token pricing turns "iterate 200 times on the boss fight" into a budget meeting. Open weights remove the meter: iterate forever, pay nothing per token.

The bet: open-weight models are now good enough that one person can direct them like a team — a coder and an art department — and ship.

What I built

Duck Evac is a 2D top-down search-strike-extract shooter:

  • 搜 (Loot) — scavenge buildings for weapons and supplies, backpack with 6 slots
  • 打 (Fight) — WASD + mouse aim on desktop; virtual joystick + fire/skill/melee/slide buttons on mobile; enemy ducks patrol and attack, bosses guard the extraction zone
  • 撤离 (Extract) — reach the extraction point before the timer runs out, or lose everything

Tech: Vite + React 19 + TypeScript, Canvas rendering with auto-resolution scaling, ~6,300-line game engine, 8-direction sprite system with runtime chroma-keying (AI art ships on white/green backgrounds; the engine cuts it out at load). Runs in the browser today; Android APK build in testing, TapTap submission in progress.

How the open models built it

Code — DeepSeek V4.1 (open weights, MIT). The entire codebase: the engine, the sprite pipeline, the HUD/minimap, the mobile control layer, the build scripts. The sprite system below is a good example of what it produced unprompted — region-growing background removal with separate tolerances for JPEG noise, gradient backgrounds, and enclosed white regions, plus per-sheet frame-order correction so a mislabeled sprite sheet doesn't need regeneration:

/** 抠除颜色容差平方(JPEG 压缩噪声余量) */
const CUT_TOL2 = 52 * 52;
/** 区域生长局部色差容差平方:背景渐变相邻像素色差极小,可一路传播;轮廓线深色跳变被挡住 */
const LOCAL_TOL2 = 15 * 15;
/** 区域生长全局约束平方:局部传播只允许发生在与背景参考足够近的像素上,
    防止穿过轮廓断口漏进角色身体(浅色身体脱色 bug 根因) */
const GROW_BOUND2 = 90 * 90;
Enter fullscreen mode Exit fullscreen mode

That's not boilerplate — that's a model reasoning about failure modes (light-colored bodies desaturating through contour gaps) and engineering around them.

Art — MiniMax (open weights). All 42 assets: 3 player duck skins (beret + backpack, steel helmet, red cap), 6 bosses (chicken, cat, dog, goose, weasel, fox — each with 8-direction sheets), soldier/ghost variants, guns, menu background. One flat-cartoon style, dark olive + beak-yellow tactical palette, held across every sheet:

// 美术素材:生成的角色 / Boss 立绘与主菜单背景(暗橄榄 + 鸭喙黄战术风)
export const CHARACTER_ART: Record<string, string> = {
  balanced: '.../aadkwds4vvmpi_ve_miaoda',  // 阿黄:贝雷帽+背包
  tank:     '.../aadkwdtzotijo_ve_miaoda',  // 铁头:钢盔
  scout:    '.../aadkwdu52jwci_ve_miaoda',  // 快羽:红棒球帽
};
Enter fullscreen mode Exit fullscreen mode

My job was art direction and integration: prompt the style once, hold it across 42 assets, wire the sheets into the engine's 8-direction system. The models did the drawing and the coding.

Demo

🎬 Watch the 67-second gameplay demo: https://youtube.com/shorts/vcrDhp-KuGg?si=RlrnwNCgE5lc5Tkz

67 seconds of real gameplay from the running web build: WASD movement, mouse-aim shooting, duck-vs-duck combat with +20 kill popups, "press E to loot" prompts, full HUD (health/ammo/timer/minimap). No scripted trailer — this is the game playing.

Code

The full repo will be public after the deadline rush. The two systems above are the heart of it:

  1. Sprite pipeline (src/game/sprites.ts, 530 lines) — loads AI-generated 2×2 sprite sheets, chroma-keys white backgrounds and olive base discs via region growing, normalizes to 8-direction transparent sprites. Ships with per-sheet diagOrder correction: if the model mislabels frame order on one sheet, you fix four numbers instead of regenerating.
  2. Engine (src/game/engine.ts, ~6,300 lines) — game loop, enemy AI (patrol/chase/attack states), collision, HUD, minimap, desktop + mobile input layers.
  3. Art manifest (src/game/art.ts, 69 lines) — every AI asset indexed by character/boss/weapon id, with commented rollback URLs for each art revision. The whole visual history of the project in one file.

Everything above was generated by open-weight models. My commits are prompts, selections, and wiring.

Who would pay for this, and why

  • Indie devs who can't afford artists: 42 consistent sprites for $0 in marginal cost. The art department is now a prompt and a style bible.
  • Solo devs who can't afford a team: a 6,300-line engine written by an open model you can self-host. The per-token meter is gone, so iteration 200 costs the same as iteration 1.
  • The game itself: Duck Evac is heading to TapTap as a commercial release. The side hustle isn't the tooling — it's the game the tooling made possible.

The pitch: open weights turned a two-person studio (coder + artist) into one person with two models. Duck Evac is the receipt.

Top comments (0)