Skip to content
··16 phút đọc

6 tháng, 3 dự án game, 0 game được ship

Tôi dành 6 tháng để học làm game developer trong khi vẫn làm full-time. Tôi xây ba dự án, viết 684 commit, và ship đúng 0 game. Đây là chuyện đã xảy ra, những gì tôi học được, và vì sao chưa có gì được ship.

Đáng lẽ tôi đã viết bài này vài tuần trước. Nhưng tôi nghĩ tôi vẫn hy vọng rằng đến lúc ngồi xuống viết, ít nhất một trong ba game tôi đang làm đã xong.

Không có cái nào xong cả.

Vậy nên đây là tình hình: 684 commit trên ba dự án trong sáu tháng, và chưa có gì để bạn download, chơi, hay gửi cho bạn bè. Nếu bạn từng học một thứ hoàn toàn mới ngoài công việc full-time — một thứ thật sự khó, một thứ bạn chưa giỏi sẵn — chắc bạn hiểu rất rõ cảm giác này.

Tôi vẫn viết bài này, vì tôi nghĩ câu chuyện vì sao không có gì được ship có ích hơn một bài thông báo bóng bẩy về một thứ đã xong.

Bối cảnh ban đầu

Trong 18 năm, tôi làm trong ngành advertising. Đó là một công việc tốt, khó, và tôi biết cách làm. Tôi đã ship campaign, xây team, viết sách, đứng trên sân khấu. Trong thế giới đó, tôi biết "done" trông như thế nào.

Rồi cuối năm 2025, tôi quyết định muốn học game development. Không phải game marketing. Không phải game strategy. Mà là thật sự làm game — code, art, systems, và cảm giác khi một nhân vật di chuyển trên màn hình.

Tôi không có kinh nghiệm với game engine. Tôi chưa từng rig một model 3D. Tôi không biết state machine nghĩa là gì trong bối cảnh animation. Tôi đã code vài năm, chủ yếu là web app và AI product, nhưng game là một discipline hoàn toàn khác. (Nếu tôi sai ở đâu, xin cứ sửa — tôi vẫn đang học.)

Điều đầu tiên tôi học được: ship một game rất khó. Điều thứ hai: bạn không thể suy luận trên document để tìm ra một game loop hay.

Bạn phải nhìn nó chuyển động. Bạn phải chơi nó, hoặc ít nhất đưa nó vào runtime của Godot và xem character, camera, controls, và feedback có thật sự tạo ra cảm giác gì không. Rồi bạn phải sẵn sàng build, delete, cut, và rebuild cho đến khi một thứ thú vị xuất hiện.

Đây là chuyện đã xảy ra.


Dự án 1: The AI Pet Sanctuary (288 commit)

Tháng 12, 2025 – Tháng 2, 2026

Dự án đầu tiên bắt đầu từ một ý tưởng đơn giản: nếu bạn có một pet sống trên máy tính và nói chuyện với bạn bằng AI thì sao? Không phải chatbot với avatar pet — mà là một pet thật sự, có hành vi, habitat, và personality.

Tôi xây một ứng dụng full-stack. React ở frontend, FastAPI ở backend, Supabase cho database. Tôi dùng Gemini cho conversation và Cloudflare Stream cho video.

Phần tham vọng nhất là animation system. Tôi muốn 18 loại pet trong sáu nhóm lớn — chó, mèo, chim, thú nhỏ, cá, bò sát. Mỗi con cần di chuyển, chớp mắt, và có cảm giác sống.

Tôi bắt đầu với Rive animations. Chúng không phù hợp với use case này. Vì vậy tôi thay bằng CSS và JavaScript pet animations. Sau đó tôi xây một pipeline dùng Google Veo 3.1 để tạo animation content — AI video generation cho các chuyển động của pet. Nó hoạt động, nhưng rất brittle. API có thể fail, ánh sáng không nhất quán, scale thay đổi giữa các lần generate. Tôi dành nhiều thời gian chiến đấu với generation pipeline hơn là thiết kế trải nghiệm pet thật sự.

Tôi cũng xây habitat system với môi trường full-screen immersive — một căn phòng tên "The Study" nơi pet sống. Care screens. Memory screens. Conversation integration. Một bản redesign "Quiet Luxury" hoàn chỉnh giữa chừng vì bản đầu nhìn như prototype. (Vì đúng là prototype.)

Rồi tôi pivot.

288 commit sau, tôi quyết định web app là nền tảng sai và bắt đầu lên kế hoạch cho bản iOS native. Đến giờ tôi vẫn không biết đó là quyết định đúng hay chỉ là sự chán nản đội lốt strategy. Một phần tôi tin rằng pet trên điện thoại thân mật hơn pet trong browser. Một phần khác nghĩ tôi chỉ mệt với React.

Nhưng nếu thành thật, lý do thật sự khiến tôi không ship nó đơn giản hơn: nó chán. Tôi đã xây tất cả — habitat, animation system, conversation integration — và khi đến lúc ngồi xuống tương tác với pet, tôi mất hứng trong vòng hai phút. Không có gì đủ compelling để giữ attention của tôi. Tôi chơi game từ hồi secondary school, nên tôi tin phản ứng đầu tiên đó, dù không phải lúc nào tôi cũng biết cách sửa. Tôi vẫn chơi Mobile Legends với gia đình và thường leo tới Mystic. Đó không phải game bạn chơi để thư giãn thụ động — nó đòi hỏi skill và attention. Pet sanctuary này không đòi hỏi cái nào.

Tôi cứ tự nói với tôi rằng vấn đề là platform. Web app không thể tạo ra trải nghiệm immersive mà tôi muốn. Có thể iOS sẽ khác. Nhưng sâu bên trong, tôi biết vấn đề không phải React — mà là design. Không có platform switch nào khiến một game loop không thú vị tự nhiên trở nên hấp dẫn.

Sai ở đâu

Nhìn lại repo, tôi không nghĩ bài học đúng là "288 commit mà không release là tệ." Nếu core loop không engaging, ship sớm hơn chỉ có nghĩa là ship một thứ chán sớm hơn.

Vấn đề thật sự là tôi cứ đổi container trước khi chứng minh loop. Dự án đi từ merge/order mechanics, sang pure companion, sang immersive habitats, rồi sang iOS. Mỗi pivot đều có lý do. Nhưng câu hỏi tôi không trả lời đủ rõ đơn giản hơn nhiều: tôi có muốn mở thứ này mỗi ngày không?

Tôi lẽ ra có thể validate điều đó với một pet, một room, một conversation, và một interaction care/play. Thay vào đó, tôi xây 18 loại pet trên 6 nhóm động vật với cả habitat system trước khi có runtime answer cho câu hỏi quan trọng nhất: pet này có thú vị để quay lại không?

Animation tạo bởi AI rất mạnh nhưng brittle. Khi nó hoạt động, rất ấn tượng. Khi không, bạn đang debug prompt và lỗi API thay vì product. Bạn cần fallback pipeline, và tôi đã không xây nó đủ sớm.

Tôi học được gì

Việc đầu tiên không phải là cut scope. Việc đầu tiên là tìm phần thú vị. Đôi khi điều đó nghĩa là build thêm. Đôi khi nghĩa là xóa thứ bạn vừa build. Sai lầm không phải là exploration. Sai lầm là explore quá lâu mà không có playable proof cho biết core experience có sự sống hay không.


Dự án 2: Con cáo trở thành một bước đệm (35 commit)

17 tháng 4 – 12 tháng 5, 2026

Sau khi pet sanctuary pivot sang iOS, tôi bắt đầu dự án mới trong Godot 4.6. Lần này tôi muốn build game từ đầu trong một game engine thật, không phải web app giả làm game.

Concept ban đầu: Spirit Fox Kit Sanctuary Sim. Một chú cáo nhỏ sống trong căn phòng ấm áp, và bạn chăm sóc nó. Đơn giản, ấm, gọn.

Tôi setup Godot project. Tôi cố thiết kế fox character với hidden tense silhouettes, twitch animations nhanh hơn, và micro-signals cho stillness.

Nhưng câu đó làm prototype nghe có vẻ legible hơn thực tế rất nhiều. Trên màn hình, con cáo không đọc ra cáo. Nó chỉ là một khối tròn nhỏ. Tôi không thấy được shape nào usable, chứ chưa nói tới việc đánh giá phần visual còn lại của căn phòng.

Tôi xây draft room loop với GUT test coverage. Placeholder audio. Hover cues cho interactables. Room scene layout. Cold-start playtest harness để tôi thật sự có thể chơi nó.

Rồi tôi chơi thử.

Sự thật thành thật là vấn đề này thiên về visual hơn là triết lý: con cáo fail ngay ở first read. Room prototype có một path được verify cơ học, và repo thậm chí ghi lại abbreviated solo gate pass cho placeholder-art build. Stillness, emergence beat, touch distinction, và room problem đều acceptable cho stage đó.

Nhưng acceptable cho một authored beat nhỏ không đồng nghĩa với đủ mạnh về visual để gánh cả game. Dự án này phụ thuộc vào việc con cáo gánh trải nghiệm. Nếu tôi không thấy shape, posture, và appeal của nó, sanctuary loop chưa có cơ hội.

Vì vậy ngày 20 tháng 4 — chỉ ba ngày sau khi bắt đầu — tôi viết một pivot spec đầy đủ. Fox sanctuary sim trở thành một thứ hoàn toàn khác: landscape action-adventure với safehouse ấm áp và vùng hostile để explore. Tôi pause kế hoạch fox-first và bắt đầu thiết kế hướng mới.

35 commit. Một beat được validate. Một pivot. Không có gì được ship.

Sai ở đâu

Vấn đề thật sự là tôi đối xử với animation signals như thể chúng có thể bù cho một base shape không đọc được. Không thể. Một twitch không quan trọng nếu body bên dưới không có silhouette.

Pivot không chứng minh công việc đầu tiên bị lãng phí. Nó biến công việc đầu tiên thành foundation. Điều tôi vẫn chưa có là evidence rằng hướng Hearthkeeper lớn hơn sẽ hoạt động, hoặc rằng tôi có thể làm core character đủ readable để người chơi quan tâm.

Tôi học được gì

Playtesting sớm cho bạn thấy prototype thật sự đang chứng minh điều gì. Room prototype chứng minh tone, pacing, và một relationship beat. Nó không chứng minh một game hoàn chỉnh, và nó phơi bày ngay vấn đề visual readability. Đó là thông tin hữu ích, nhưng nó chỉ sang bước tiếp theo khác: giải quyết character read và build loop nhỏ nhất safehouse -> run -> return trước khi polish con cáo tiếp.

Game 1 dạy tôi rằng một loop technically complete vẫn có thể chán. Game 2 dạy tôi rằng một character concept đã document và test vẫn có thể fail về visual trong vài giây. Hai thất bại đó là lý do Game 3 tiến bộ thực hơn: tôi chú ý nhiều hơn tới readability, motion, weapon feel, và liệu playable slice có hoạt động trên màn hình không.

Pivot dựa trên evidence khác với drifting. Con cáo không đọc được trong runtime, nên đổi hướng không tự động là thiếu discipline. Phần tôi cần cải thiện là feedback loop: đưa câu hỏi visual hoặc gameplay rủi ro nhất lên màn hình nhanh hơn, rồi quyết định bằng evidence thay vì ở mãi trong concept mode.


Dự án 3: Dự án mà pipeline bắt đầu chạy được (361 commit)

21 tháng 4 – 13 tháng 5, 2026

Đây là dự án tôi vẫn đang làm. Đây cũng là dự án mà bài học từ hai dự án đầu tiên cuối cùng bắt đầu compound.

Nó là một mech tactics game. Bạn điều khiển một squad mech trong combat, và sau mỗi battle, một LLM phân tích chuyện đã xảy ra rồi đưa cho bạn một debrief. Hãy tưởng tượng post-match analysis, nhưng được viết bởi AI có access vào toàn bộ game state.

Repo có ba track, nhưng giờ chúng không còn ngang nhau:

Track A — The LLM Debrief System: Đây là AI validation track ban đầu. Nó giúp tôi test structured debriefs, nhưng không còn là main product path.

Track B — The 2D Phone Prototype: Đây là nơi tôi cuối cùng tìm được một pipeline workable cho trải nghiệm player 2D tương đối immersive. Runtime Godot thật có lane-match combat loop, touch joystick, shop/modules, hero XP, ability cooldowns, VFX motifs đọc được trên phone, enemy punish zones, neutral relay objective, HUD feedback, và iOS export/testing flow. Art pipeline cũng bắt đầu chạy được: Nano Banana 2 (Gemini 3.1 Flash Image) tạo ra initial hero và character images usable, rồi MCP-based pixel cleanup workflow và Aseprite biến các candidate đã curate thành cleaned sprites, animation frames, và Godot-ready sheets. Nó chưa phải finished game, và phone acceptance vẫn pending, nhưng nó gần với cảm giác "cái này giống game" hơn nhiều so với hai dự án đầu.

Track C — The Campaign and 3D Path: Đây là product direction hiện tại. Nó giữ lại các bài học hữu ích của Track B, thêm campaign memory loop, và chuyển production combat về hướng 3D/2.5D. Đây là vấn đề khó hơn nhiều so với pipeline 2D. Ở 2D, tôi có thể kiểm soát readability bằng sprite sheets, HUD tuning, procedural VFX, và phone captures. Ở 3D, mọi decision đều đụng tới modeling, rigging, animation, camera, lighting, GLB export, weapon sockets, hit anchors, action timing, và runtime performance.

Tôi cũng tích hợp Blender cho custom rigging work, đưa Rokoko mocap data vào cho locomotion, và build hero mech character với full rig, animation tree, và weapon socket integration.

361 commit trong ba tuần. Một pipeline 2D thật sự. Một experiment 3D khó hơn rất nhiều. Vẫn ở prototype territory.

Sai ở đâu

Đây là điều tôi phải thừa nhận: pipeline 2D bắt đầu hoạt động, nhưng pipeline 3D có thể nuốt trọn cả project nếu tôi để nó làm vậy.

Với Track B, pipeline work không phải fake progress. Nano Banana 2 -> Aseprite workflow, touch controls, HUD, readable ability motifs, module feedback, phone captures, và export loop đều làm product playable hơn. Công việc đó dạy tôi player cần nhìn và cảm nhận gì trong từng khoảnh khắc.

Rủi ro bây giờ khác. Trong Track C, 3D cần rất nhiều pipeline trước khi nó có cảm giác là thứ gì đó: model import, rig quality, animation names, weapon attachment, muzzle position, hit center, camera angle, lighting, movement, jump timing, attack timing, VFX, và runtime inspection. Đó không phải optional details. Nếu character không đọc được, cả scene fail trong vài giây.

Nhưng playable encounter vẫn phải dẫn đầu. Nếu không, tôi có thể dành nhiều tuần để cải thiện weapon fit, jump compression, left-hand IK, và mocap cleanup của hero mech mà vẫn không trả lời câu hỏi đơn giản của player: điều khiển thứ này có vui không?

Tôi học được gì

Pipeline work chỉ hữu ích khi nó tiếp tục phục vụ playable slice. Track B dạy tôi rằng pipeline đúng có thể tạo trải nghiệm 2D immersive hơn. Track C dạy tôi rằng 3D làm chi phí của mỗi cải tiến tăng lên. Tôi phải giữ acceptance gate thật cụ thể: player có đọc được hero mech không, có move nó được không, có aim, fire, hiểu hit, và muốn làm lại không?

Tracks cần gates. Track A đã làm xong việc của nó. Track B tạo ra reusable lessons về 2D game feel và presentation. Track C là bet hiện tại. Vấn đề không phải là tôi explore nhiều path. Vấn đề là mở lại chúng mà không có runtime question rõ ràng và decision rule rõ ràng.

3D game development là một skill gap rất lớn. Rigging, animation, mocap data, asset budgets, weapon sockets, camera framing, và readable motion là những discipline tôi chưa từng có kinh nghiệm professional. Tôi học chúng trong lúc cũng đang học Godot, game design, và campaign architecture. Learning curve không phải steep — nó gần như dựng đứng. Tôi nghĩ đây là phần làm tôi ngạc nhiên nhất. Trong web development, tôi có thể build một thứ functional trong một ngày. Trong 3D game dev, tôi dành cả buổi tối chỉ để làm cánh tay character gập đúng cách. (Đây là kiểu câu mà sáu tháng trước tôi sẽ không hiểu.)


Ba dự án này có điểm gì chung

Nếu thành thật với chính tôi — và bài này chỉ có tác dụng nếu tôi thành thật — pattern không phải là "scope creep." Cách nói đó quá dễ, và trong trường hợp này tôi nghĩ nó sai.

Tôi không nghĩ game vận hành như business deck — ít nhất đó là điều ba dự án này dạy tôi. Bạn không biết một idea có tốt hay không chỉ vì premise nghe hay. Bạn biết khi bạn có thể chơi nó, hoặc ít nhất thấy nó chạy trong engine và cảm nhận character, camera, interaction, và feedback có đang làm được gì không.

1. Runtime là sự thật

Pet sanctuary nghe hay cho đến khi tôi tương tác với pet và thấy chán. Con cáo nghe hay cho đến khi tôi thấy nó trong Godot và không đọc được shape. Track B bắt đầu chạy được vì loop đi vào một phone-like runtime: touch controls, HUD, VFX, shop, XP, readable motifs, và capture feedback.

Đó là pattern thật. Sự thật hữu ích chỉ xuất hiện khi idea trở nên visible và playable.

2. Exploration là cần thiết, nhưng nó cần evidence

Tôi không nghĩ bài học đúng là "đừng thêm nữa." Game development cần exploration. Bạn build, thử, delete, cut, rebuild, và thử lại vì bạn đang tìm phần thú vị.

Phần cần discipline không phải số lượng công việc. Nó là evidence loop. Mỗi phần việc nên trả lời một câu hỏi: việc này có làm game readable hơn, engaging hơn, controllable hơn, đáng replay hơn không?

3. Pipeline tốt khi nó làm game playable hơn

Nano Banana 2 -> MCP cleanup -> Aseprite workflow không phải distraction. Nó giúp tôi đưa 2D characters và animation tốt hơn vào game. HUD và VFX work ở Track B cũng không phải fake progress. Nó làm runtime rõ hơn.

Rủi ro là khi pipeline ngừng trả lời player-facing question. Trong Track C, 3D tooling là cần thiết, nhưng nó phải luôn quay lại một điều: player có đọc được hero mech, move nó, bắn weapon, hiểu hit, và muốn làm lại không?

4. Khoảng cách không phải coding skill. Nó là playable judgment.

Tôi có thể build một full-stack application với Supabase, FastAPI, và React. Tôi có thể rig một 3D model, viết GUT tests, và build custom debugging tools. Điều tôi vẫn đang học là đánh giá xem một thứ có thật sự thú vị như một game hay không. Track B đưa tôi gần hơn ở 2D. Track C cho tôi thấy nó khó hơn bao nhiêu khi motion, camera, lighting, weapons, và animation đều phải phối hợp với nhau.

Tôi nghĩ đây là điều quan trọng nhất tôi học được. Code là phần tôi giỏi. Phần khó là quyết định game thật sự là gì, làm nó thú vị, rồi có discipline để liên tục quay lại runtime evidence cho đến khi nó đáng ship.


Tôi học được gì sau tất cả

Nếu tôi cố gói sáu tháng này thành điều gì đó hữu ích — cho tôi, hoặc cho ai đang ở vị trí tương tự — đây là những gì tôi nghĩ tôi biết bây giờ mà hồi tháng 12 tôi chưa biết:

  1. Version đầu tiên nên trả lời câu hỏi rủi ro nhất trong runtime. Pet sanctuary của tôi cần một pet interaction khiến tôi muốn quay lại. Game con cáo cần một silhouette readable trong blank room trước khi tôi lo micro-signals. Game mech cuối cùng tiến gần hơn qua Track B vì tôi có thể nhìn và cảm nhận loop trên màn hình.

  2. Playtesting không optional, và runtime review cũng tính. Khoảnh khắc tôi thấy con cáo như một shapeless mass, tôi biết project chưa hoạt động. Đó là 30 phút giá trị nhất của toàn bộ project. Tôi lẽ ra nên chạm tới visual truth đó sớm hơn.

  3. Learning là một outcome hợp lệ, dù không phải outcome bạn dự tính. Tôi bắt đầu với mục tiêu build game. Tôi không ship game. Nhưng tôi học Godot, LLM prompt engineering, Nano Banana 2 for character ideation, Aseprite animation cleanup, 2D phone readability, HUD and VFX feedback, animation pipelines, 3D rigging, mocap data, game feel, camera systems, visual readability, và sự khác biệt giữa building tools và building products. Điều đó không phải không có gì. Nó cũng là lý do Game 3 tốt hơn Game 1 và Game 2, dù vẫn chưa ship.

  4. Tôi vẫn cần định nghĩa một finish line thành thật. Một phần tôi muốn đẩy project này tới completion để có thể nói rằng tôi đã ship game. Một phần tôi nghĩ learning chính là product và tôi nên chấp nhận điều đó. Cả hai đều là câu trả lời thành thật. Tôi nghĩ sự thật nằm đâu đó ở giữa: ship một focused slice tôn trọng những gì tôi đã học, thay vì restart from zero thêm lần nữa.

Tiếp theo là gì

Tôi vẫn đang làm mech tactics project. LLM debrief concept thú vị, và tôi nghĩ có điều gì đó thật sự mới trong ý tưởng AI-powered post-match analysis cho tactics game.

Nhưng tôi đang cố đổi approach: runtime proof trước, polish sau, chỉ ship khi playable slice có lý do tồn tại. Hai dự án đầu không bị lãng phí. Chúng thay đổi những gì tôi nhìn ở Game 3: character có readable không, motion có feel tốt không, weapon có đúng không, và một người có hiểu encounter mà không cần tôi giải thích architecture không?

Nếu hôm nay tôi bắt đầu một game mới, tôi sẽ không bắt đầu bằng một architecture plan lớn. Tôi sẽ bắt đầu với runtime proof nhanh nhất có thể trả lời câu hỏi tôi thật sự quan tâm. Với Game 3 bây giờ, cùng discipline đó phải xảy ra bên trong project: một character, một weapon, một encounter, một acceptance test rõ ràng.

Tôi chưa biết liệu tôi sẽ đẩy một trong các dự án này tới completion, hay chấp nhận rằng learning là product. Có thể tôi sai về timeline, nhưng tôi nghĩ pattern quan trọng hơn bất kỳ dự án riêng lẻ nào.

Một câu hỏi cho bạn

Tôi muốn hỏi thật, không phải hỏi tu từ: bạn đã từng ở đây chưa? (Tôi nghi là nhiều builder từng ở đây hơn chúng ta thường thừa nhận.)

Bạn đã từng dành nhiều tháng xây một thứ mà cuối cùng không ship chưa? Bạn có hoàn thành nó không, hay bỏ đi? Và nếu bạn bỏ đi — đó có phải quyết định đúng không, hay bạn vẫn nghĩ về nó?

Tôi đã ship nhiều thứ trong sự nghiệp. Campaign, platform, product. Nhưng đó là domain tôi có 18 năm kinh nghiệm. Game development là mới, và khoảng cách giữa "tôi có thể build thứ này về mặt kỹ thuật" và "đây là một game hay" lớn hơn tôi tưởng rất nhiều.

Nếu bạn đã vượt qua khoảng cách đó, tôi rất muốn nghe điều gì giúp bạn không pivot away. Bạn có thể reply trên LinkedIn hoặc nhắn trực tiếp — tôi thật sự tò mò.


Vậy thôi, hết rồi. Tôi rất muốn nghe suy nghĩ của bạn — nhất là nếu bạn cũng từng trải qua chuyện tương tự. Bạn có thể liên hệ với tôi trên LinkedIn hoặc gửi note trực tiếp.

Thân mến,

Chandler

Đọc tiếp