A classic 2048 game clone built on Godot 4.7+, designed for PC desktop in landscape (1280×720). Merge matching numbers until you reach 2048 — simple rules, addictive gameplay, and an elegantly structured Godot learning template with thorough comments.
The entire project is built purely in code: main.tscn is only 6 lines (root node + script reference). Theme styles are generated in pure code by ThemeBuilder (replacing .tres files), and UI nodes are constructed at runtime by ViewBuilder — no .tscn / .tres resource black boxes. Reading the .gd files tells you everything.
ThemeBuilder replaces .tres, ViewConfig is the single source of truthGridView listens directly to keyboard/touch and emits move_requested signals, no Controller mediation neededGridView reuses TileView instances via _dead/_live arrays, avoiding frequent node creation/destructionFollowing the same Logic-View separation as Block Fall, Block Blast, and the mobile 2048 — replacing the common MVC pattern. main.gd is a thin 95-line coordinator:
| Layer | Responsibility | Key Files |
|---|---|---|
| logic/ | Pure game logic. Game / GameGrid / GameTile all extend RefCounted, no scene-tree dependency, unit-testable. SaveData handles high-score JSON persistence. |
game.gd game_grid.gd game_tile.gd save_data.gd |
| view/ | Pure rendering + input handling. GridView listens to keyboard/touch → emits move_requested. Three animation states (spawn/move/merge) via Tween. |
grid_view.gd tile_view.gd view_config.gd theme_builder.gd view_builder.gd board_sizer.gd |
| main.gd | Thin coordinator. ViewBuilder.build() constructs the UI → wires Logic ↔ View signals → Game.start() kicks off the game. |
— |
Key insight: The entire Logic layer is RefCounted, so you can instantiate and test it directly without a scene tree — Game.new() + a fixed random seed = a reproducible test board.
The project ships with a lightweight test framework (no plugin dependencies), matching the mobile edition’s coverage:
tests/test_*.gd) — covers Game (movement/merging/scoring/win/lose/dead board), GameGrid (grid access), GameTile (data constraints), SaveData (score formatting)tests/smoke_test.gd) — instantiates the real main scene and verifies the full flowover signalRun them with:
godot --headless --path . --script res://tests/test_runner.gd # Unit tests
godot --headless --path . --script res://tests/smoke_test.gd # Smoke test
board_sizer.gd auto-fit board: keeps the board square and centered within available space999 / 1.0k / 1.0m), high score persisted as JSONThe project includes tools/auto_demo.gd: starts a game with a fixed random seed, plays 80 moves using a simple greedy strategy, then exits — so you can record a 60fps clip in one command (fully reproducible).
godot --path . --write-movie frames/frame.png --fixed-fps 60 res://tools/auto_demo.tscn
ffmpeg -y -framerate 60 -i frames/frame%08d.png -c:v libx264 -preset slow \
-crf 18 -pix_fmt yuv420p -movflags +faststart -an demo.mp4
godot-2048-pc/
├── resources/ # Static assets
│ └── fonts/ # JetBrainsMono font (regular + bold)
├── logic/ # Game logic layer (Logic)
│ ├── game.gd # Game: movement/merging/scoring/win-lose (RefCounted pure logic)
│ ├── game_grid.gd # 4×4 grid data structure
│ ├── game_tile.gd # Single tile data (value, position, merge sources)
│ └── save_data.gd # High-score JSON persistence (format_score formatting)
├── view/ # Rendering layer (View)
│ ├── grid_view.gd # UI grid + object pool + Tween animations + input handling
│ ├── tile_view.gd # Tile drawing (bit-operation colors + auto font sizing)
│ ├── view_config.gd # View config constants (sizes, colors, fonts)
│ ├── theme_builder.gd # Theme factory (builds Theme in pure code)
│ ├── view_builder.gd # Scene builder (builds node tree in pure code)
│ └── board_sizer.gd # Board square auto-fit + centering (PC-exclusive)
├── tests/ # Tests (no plugin dependencies, covers full Logic layer)
│ ├── test_runner.gd # Unit test runner
│ ├── smoke_test.gd # Smoke test
│ ├── test_base.gd # Assertion base class
│ ├── test_game.gd # Game core logic tests
│ ├── test_game_grid.gd # Grid data tests
│ ├── test_game_tile.gd # Tile data tests
│ └── test_save_data.gd # Score formatting tests
├── tools/ # Helper tools
│ └── auto_demo.gd # Auto-demo script (fixed seed + greedy 80 moves)
├── docs/ # Project documentation
│ ├── intro.md # This document (Chinese)
│ └── intro_en.md # English introduction
├── main.gd # Main coordinator (LV thin layer: 95 lines of signal wiring)
├── main.tscn # Main scene (only 6 lines: root node + script reference)
├── project.godot # Engine configuration
├── export_presets.cfg # Export preset configuration
└── LICENSE.md # Paid license (see LICENSE_en.md for English version)
godot --path .)export_presets.cfgThis project uses a paid custom license. After purchase you may modify the code and ship derivative games, but you may not redistribute the source code or sell it commercially. See LICENSE.md (or LICENSE_en.md for English) for the full terms.