OpenGame: Agent tự code, tự debug game cho đến khi playable

9 phút đọc English
Featured image for leigest519/OpenGame — OpenGame: Agent tự code, tự debug game cho đến khi playable

⚡ TL;DR

  • Vấn đề: LLM viết game hay bị màn hình đen, nhân vật không chết đúng lúc, scene chuyển là crash
  • Giải pháp: Agent tự chạy game trong sandbox, bắt lỗi và fix vòng lặp đến khi playable end-to-end
  • Dành cho: Dev muốn thử nhanh một web game mà không cần học Phaser hay game engine nào
  • Điểm khác biệt: Game Skill hai tầng, Template Skill scaffold kiến trúc trước khi viết một dòng logic
  • Verdict: Early release, chưa có npm package, nhưng 6 demo nặng đô đã chứng minh concept

Nhờ Claude viết một mini game quiz, code về sau vài giây. Mở trình duyệt: màn hình trắng. DevTools không có một lỗi đỏ nào. Code hợp lệ, TypeScript im lặng, không có gì chạy cả.

Ba lần thử, ba lần màn hình trắng. Lần thứ tư tôi tắt chat đi và tự viết tay.

LLM viết code game rất nhanh. Vấn đề là phần lớn code đó không chơi được.

Tại Sao LLM Thường Thất Bại Khi Viết Game

Game state không sống trong một file. Nó trải qua player.ts, scene.ts, gameState.ts, collision callback, event emitter. Khi LLM sửa một chỗ, nó không nhìn thấy mảnh ghép xung quanh.

Đội CUHK MMLab ghi lại ba kiểu vỡ cứ lặp đi lặp lại.

Cross-file inconsistency. LLM thêm một field mới vào playerData nhưng quên cập nhật function đọc nó ở file khác. Code hợp lệ về syntax, TypeScript không báo lỗi, logic bị đứt giữa hai file.

Broken scene wiring. Phaser bắt buộc asset phải load trong preload(), scene phải đăng ký đúng key trước khi chạy. Bỏ sót một bước là màn hình đen, không exception nào được throw. LLM không nhớ lifecycle này đủ chắc để giữ đúng trong suốt một project nhiều file.

Logical incoherence trong game loop. Game loop đòi nhất quán về thời gian: physics tick, collision callback và win/loss state phải ăn khớp nhau. Hình dung như bánh răng đồng hồ, mỗi bánh chạy đúng nhưng không ăn vào nhau thì kim vẫn không chạy. LLM hay tạo ra code không lỗi, nhưng nhân vật không chết khi va chạm, điều kiện thắng không bao giờ trigger.

Các agent thông thường sau đó patch từng lỗi riêng lẻ thay vì sửa lớp integration. Game build được, nhưng không playable.

Game Skill: Hai Tầng Cốt Lõi

OpenGame giải quyết bằng Game Skill, gồm hai phần làm việc tuần tự.

Template Skill chạy trước, trước khi viết một dòng logic nào. Thay vì để LLM tự quyết kiến trúc, agent chọn template phù hợp (Phaser 3, plain canvas, three.js…), scaffold ra project structure chuẩn, đặt đúng lifecycle hooks (preload, create, update), đăng ký đúng scene key. Kiến trúc xây trước, logic điền vào sau. Giống xây nhà: không ai đặt ống điện rồi mới vẽ bản thiết kế. Template library tích lũy mỗi khi một game build thành công.

Debug Skill chạy sau khi code xong. Agent launch game trong sandboxed browser, bắt console errors, integration errors, broken interactions. Tự fix và chạy lại. Vòng lặp đó tiếp tục cho đến khi game chơi được end-to-end. Không phải đến khi code trông đúng, mà đến khi ai đó thực sự chơi được. Giống anh tester ngồi chơi đến khi chết xong mới trả về “passed”.

Model mặc định là GameCoder-27B, 27B tham số được train chuyên cho game dev theo ba giai đoạn: nạp vào Phaser docs và game engine APIs, SFT trên trajectory game dev được tuyển chọn, và execution-grounded RL với reward signal từ chính OpenGame-Bench. Nhưng đây là tùy chọn. OpenGame dùng OpenAI-compatible API, nghĩa là swap GPT-4o, Claude hay bất kỳ model nào qua OpenRouter đều được.

Cài Đặt Và Chạy Thử

npm package đang chuẩn bị. Hiện tại cài từ source:

git clone https://github.com/leigest519/OpenGame.git
cd OpenGame
npm install
npm run build
npm link
# opengame giờ có trên PATH

Tạo game đầu tiên:

mkdir my-game && cd my-game
opengame

Agent hỏi prompt. Gõ vào:

Build a 2D platformer where a cat collects yarn balls while avoiding dogs.

Agent plan architecture, scaffold template, viết code, launch trong sandboxed browser, debug cho đến khi playable. Muốn chạy headless, không cần hỏi thêm:

opengame -p "Build a Snake clone with WASD controls and a dark theme." --yolo

Flag --yolo cho phép agent chạy shell commands, cần thiết cho vòng lặp sandbox của Debug Skill. Nếu dùng trong CI hoặc với prompt không tin tưởng, nên dùng GEMINI_SANDBOX=docker để isolate hoàn toàn.

LLM mặc định cấu hình qua biến môi trường:

export OPENAI_API_KEY="sk-..."
export OPENAI_BASE_URL="https://api.openai.com/v1"   # tùy chọn
export OPENAI_MODEL="gpt-4o"                         # tùy chọn

Session cũ muốn tiếp tục:

opengame --continue   # tiếp tục session gần nhất
opengame --resume     # chọn từ danh sách session cũ

OpenGame Build Được Gì?

Sáu demo trong repo là bằng chứng tốt hơn bất kỳ mô tả nào.

DemoThể loạiĐiểm đáng chú ý
Marvel Avengers: Infinity StrikeSide-scrolling platformer3 nhân vật, 3 màn, boss Thanos, pixel art Capcom 90s
Harry Potter: Arithmancy AcademyTurn-based card battleQuiz tích hợp vào cơ chế bài, combo Magic Resonance
K.O.F: Celestial ShowdownFighting quiz 2 ngườiHai player trên cùng bàn phím, trả lời đúng gây dame
Hajimi Defense: The Tuna CrisisTower defenseMèo cute chặn dưa leo và máy hút bụi robot
StarWars: Mandalorian ProtocolTop-down twin-stick shooterBlaster, Beskar Spear, Jetpack Dash, cơ chế cover
Squid Game: Red Light, Green LightSurvival reflexCơ chế run/freeze, xác chồng chất lên nhau

Chạy thử demo có sẵn:

unzip demo_*.zip && cd demo_*
npm install
npm run dev
# Mở http://localhost:5173

KOF Quiz Fighter ấn tượng nhất theo tôi. Hai người chơi trên cùng bàn phím, quiz tích hợp vào cơ chế đánh nhau. Không phải thứ tôi nghĩ ngẫu nhiên xây được từ một prompt trong một session. Hajimi Defense với mèo cute cũng vậy: tower defense chạy được, có wave enemy, có win condition.

OpenGame-Bench: Đo Lường Playability

Build xong không có nghĩa là playable. OpenGame-Bench đánh giá theo ba trục:

TrụcCâu hỏi
Build HealthGame có compile và chạy không lỗi không?
Visual UsabilityGame có render ra thứ tương tác được không?
Intent AlignmentGame có khớp với mô tả ban đầu không?

Cơ chế: launch game trong headless browser, chạy scripted interactions, dùng VLM judge để verify. Benchmark chạy trên 150 game prompts đa dạng.

GameCoder-27B được train qua vòng tròn khép kín: benchmark sinh model, model chạy benchmark, lỗi từ benchmark feed ngược vào training. Execution-grounded RL với reward signal từ chính playability thực tế, không phải từ code review.

Những Gì Chưa Hoàn Thiện

npm package chưa có. Hiện phải build từ source. Thêm một bước, không vấn đề lớn, nhưng cản người muốn thử nhanh trong 5 phút.

Settings directory vẫn tên .qwen. OpenGame fork từ qwen-code, là fork của Gemini CLI. Khi cài, thư mục cấu hình vẫn tên .qwen. Nếu thấy tài liệu nhắc .qwen thì đúng chỗ rồi, không bị nhầm sang chỗ khác.

Benchmark pipeline TBD. OpenGame-Bench được mô tả chi tiết trong paper nhưng pipeline đánh giá đầy đủ chưa công bố kèm repo. Các con số trong paper là kết quả nội bộ, chưa reproduce được độc lập.

Asset providers BYOK. OpenGame có thể sinh ảnh, video, audio nếu có key riêng. Nhưng mỗi modality cần cấu hình asset provider riêng biệt, không phải out-of-the-box.

Repo phát hành ngày 21/04/2026, chưa đầy ba tuần tính đến lúc bài này viết.


1.916 sao sau chưa đầy ba tuần. Đó là số, không phải nhận xét. Game Skill là ý tưởng đúng hướng và KOF Quiz Fighter với Hajimi Defense là bằng chứng đủ thuyết phục. Từ “demo ấn tượng” đến “tool production-ready” còn là một đoạn đường, đặc biệt khi npm package và benchmark pipeline vẫn TBD. Cũng như cái game quiz của tôi dạo nọ: code trông đúng, nhưng chạy được hay không là chuyện khác.

Nếu muốn thử: github.com/leigest519/OpenGame.

Hoang Yell

Hoang Yell

Một nhà phát triển phần mềm và là người kể chuyện kỹ thuật. Tôi dành thời gian để khám phá những repository mã nguồn mở thú vị nhất trên GitHub và trình bày chúng dưới dạng những câu chuyện dễ hiểu cho mọi người.