Clone of the classic arcade game Battle City (NES, 1985), built with Go.
See the codeA modern remake and tribute to the classic arcade game Battle City (NES, 1985), built with Go and Ebiten. This project combines a passion for the original game with learning Go, Clean Architecture principles, and game development.
Play online: https://shpaker.github.io/tnk9x/
Stage 1 with normal graphics: headlights, bullet tracers, lit bricks and steel, tube TV filter.
WebAssembly build in a mobile browser — touch controls are auto-detected.
Playable now:
game.shot_cooldown)game.enemy_bonus_pickup, on by default): the enemy nearest to a dropped bonus races for it; helmet and boat go to the enemy itself, star and pistol make it stronger, grenade blows up the players, timer freezes them, shovel strips the HQ walls, tank adds an enemy to the reserveassets/levels/main.bccamp): stage select screen with a minimap preview, enemy composition and 3-star time; stages open one after another, packs open for collected starsconfig.yml (app.players, app.effects, app.fullscreen)app.fullscreen); toggle with F (desktop and browser)config.yml): 2D ray-traced lighting and shadows from tanks, bullets, explosions and bonuses, bloom, water/ice/steel glints, tube TV filter; switch to classic graphics without effects with F2 or the GRAPHICS item of the pause menu (keyboard and touch)
Under the hood:
Requirements: Go 1.24+, optionally — Just.
git clone https://github.com/shpaker/tnk9x.git
cd tnk9x
just deps # Install dependencies (or go mod download)
# Run the game
just run # or go run cmd/main.go
# Build binary
just build # binary will be in ./tnk9x
# Checks
just fmt
just lint
just test
The project follows Clean Architecture principles with clear separation of concerns. Dependencies point inward: outer layers depend on inner layers through interfaces. The composition root (internal/app) is the only place that assembles the object graph — all dependencies are injected via constructors, layer boundaries are enforced by depguard.
┌─────────────────────────────────────────────────────────┐
│ Composition Root (internal/app) │
│ game loop · state transitions · object graph assembly │
└───────────────────┬─────────────────────────────────────┘
│ (builds & wires)
┌───────────────────▼─────────────────────────────────────┐
│ Presentation Layer │
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ States │ │ Adapters │ │
│ │ │ │ │ │
│ │ StageState │ │ Renderer │ │
│ │ StageSelect │ │ Input │ │
│ │ │ │ Sound │ │
│ │ │ │ Scripting (Lua) │ │
│ └──────┬───────┘ └───────┬──────────────┘ │
│ └─────────┬────────┘ │
│ │ (depends on) │
└───────────────────▼─────────────────────────────────────┘
│
┌───────────────────▼─────────────────────────────────────┐
│ Application Layer │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Use Cases │ │ Services │ │
│ │ │ │ │ │
│ │ TankActions │ │ Collision │ │
│ │ Collision │ │ Animation │ │
│ │ Sound │ │ Braking │ │
│ └──────┬───────┘ └──────┬───────┘ │
│ └─────────┬───────┘ │
│ │ (manipulates) │
└───────────────────▼─────────────────────────────────────┘
│
┌───────────────────▼─────────────────────────────────────┐
│ Domain Layer │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Entities (Tank, Bullet, Block, HQ, etc.) │ │
│ │ Value Objects (Position, Size, Direction) │ │
│ │ Session Entities (GameSession, StageSession) │ │
│ └───────────────────────────────────────────────────┘ │
│ ▲ │
└───────────────────┼─────────────────────────────────────┘
│ (reads/writes)
┌───────────────────▼─────────────────────────────────────┐
│ Infrastructure Layer │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Repositories │ │ Raw Files │ │
│ │ │ │ │ │
│ │ Game │ │ FileSystem │ │
│ │ Processed │ │ │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
This project is licensed under the MIT License - see the LICENSE file for details.
288 followers · starred Aug 2026
83 followers · starred Aug 2026
Go
96.2%
Lua
2.6%
Clone of the classic arcade game Battle City (NES, 1985), built with Go.
See the codeA modern remake and tribute to the classic arcade game Battle City (NES, 1985), built with Go and Ebiten. This project combines a passion for the original game with learning Go, Clean Architecture principles, and game development.
Play online: https://shpaker.github.io/tnk9x/
Stage 1 with normal graphics: headlights, bullet tracers, lit bricks and steel, tube TV filter.
WebAssembly build in a mobile browser — touch controls are auto-detected.
Playable now:
game.shot_cooldown)game.enemy_bonus_pickup, on by default): the enemy nearest to a dropped bonus races for it; helmet and boat go to the enemy itself, star and pistol make it stronger, grenade blows up the players, timer freezes them, shovel strips the HQ walls, tank adds an enemy to the reserveassets/levels/main.bccamp): stage select screen with a minimap preview, enemy composition and 3-star time; stages open one after another, packs open for collected starsconfig.yml (app.players, app.effects, app.fullscreen)app.fullscreen); toggle with F (desktop and browser)config.yml): 2D ray-traced lighting and shadows from tanks, bullets, explosions and bonuses, bloom, water/ice/steel glints, tube TV filter; switch to classic graphics without effects with F2 or the GRAPHICS item of the pause menu (keyboard and touch)
Under the hood:
Requirements: Go 1.24+, optionally — Just.
git clone https://github.com/shpaker/tnk9x.git
cd tnk9x
just deps # Install dependencies (or go mod download)
# Run the game
just run # or go run cmd/main.go
# Build binary
just build # binary will be in ./tnk9x
# Checks
just fmt
just lint
just test
The project follows Clean Architecture principles with clear separation of concerns. Dependencies point inward: outer layers depend on inner layers through interfaces. The composition root (internal/app) is the only place that assembles the object graph — all dependencies are injected via constructors, layer boundaries are enforced by depguard.
┌─────────────────────────────────────────────────────────┐
│ Composition Root (internal/app) │
│ game loop · state transitions · object graph assembly │
└───────────────────┬─────────────────────────────────────┘
│ (builds & wires)
┌───────────────────▼─────────────────────────────────────┐
│ Presentation Layer │
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ States │ │ Adapters │ │
│ │ │ │ │ │
│ │ StageState │ │ Renderer │ │
│ │ StageSelect │ │ Input │ │
│ │ │ │ Sound │ │
│ │ │ │ Scripting (Lua) │ │
│ └──────┬───────┘ └───────┬──────────────┘ │
│ └─────────┬────────┘ │
│ │ (depends on) │
└───────────────────▼─────────────────────────────────────┘
│
┌───────────────────▼─────────────────────────────────────┐
│ Application Layer │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Use Cases │ │ Services │ │
│ │ │ │ │ │
│ │ TankActions │ │ Collision │ │
│ │ Collision │ │ Animation │ │
│ │ Sound │ │ Braking │ │
│ └──────┬───────┘ └──────┬───────┘ │
│ └─────────┬───────┘ │
│ │ (manipulates) │
└───────────────────▼─────────────────────────────────────┘
│
┌───────────────────▼─────────────────────────────────────┐
│ Domain Layer │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Entities (Tank, Bullet, Block, HQ, etc.) │ │
│ │ Value Objects (Position, Size, Direction) │ │
│ │ Session Entities (GameSession, StageSession) │ │
│ └───────────────────────────────────────────────────┘ │
│ ▲ │
└───────────────────┼─────────────────────────────────────┘
│ (reads/writes)
┌───────────────────▼─────────────────────────────────────┐
│ Infrastructure Layer │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Repositories │ │ Raw Files │ │
│ │ │ │ │ │
│ │ Game │ │ FileSystem │ │
│ │ Processed │ │ │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
This project is licensed under the MIT License - see the LICENSE file for details.
288 followers · starred Aug 2026
83 followers · starred Aug 2026
Go
96.2%
Lua
2.6%