19 điểm bởi GN⁺ 2025-08-25 | 4 bình luận | Chia sẻ qua WhatsApp
  • Một kỹ sư phần mềm 15 năm kinh nghiệm chia sẻ trải nghiệm phát triển một trò chơi bài thời thơ ấu bằng Go
  • Khi phát triển “Truco” mà không có LLM (mô hình ngôn ngữ lớn), tác giả phải tự giải quyết thủ công mọi vấn đề như thiết kế UI và triển khai serverless, nên mất 3 tháng
  • Khi làm “Escoba”, tác giả dùng LLM để chuyển đổi mã backend và tăng mạnh tốc độ triển khai, phần lớn đã hoạt động chỉ sau 1 lần prompt
  • Ở phần sau, bài viết cung cấp hướng dẫn từng bước để bất kỳ ai cũng có thể làm game, thông qua ví dụ Tic-Tac-Toe cùng backend Go, chuyển đổi WASM và tích hợp React
  • Tuy nhiên, frontend React và việc quản lý trạng thái game dựa trên WASM vẫn cần tự debug và triển khai trực tiếp

Giới thiệu

  • Một kỹ sư phần mềm có 15 năm kinh nghiệm nhận ra rằng mình chưa từng thật sự tự làm và triển khai một trò chơi nào
  • Tác giả quyết định phát triển bằng Go một trong những trò chơi bài mà mình từng chơi cùng bạn bè thời nhỏ ở Argentina

Truco: 3 tháng không có LLM

  • Từ ngày 18/06/2024, tác giả bắt đầu phát triển trò chơi bài Truco với backend Go. Phần frontend được viết với kiến thức React chỉ ở mức tối thiểu
  • Việc triển khai UI là thử thách lớn nhất; để không phải cung cấp máy chủ, tác giả dùng TinyGo để transpile sang WASM (WebAssembly) rồi triển khai các tệp tĩnh lên GitHub Pages
  • Vì khi đó chưa dùng LLM, tác giả phải tự tìm hiểu mọi chi tiết và lặp đi lặp lại quá trình thử sai, nên mất khoảng 3 tháng để hoàn thành
  • Mục tiêu không phải quảng cáo hay kiếm tiền mà chỉ đơn giản là hoàn thiện trò chơi; ngay cả sau 1 năm phát hành, trò chơi vẫn được chơi đều đặn

Escoba: 3 ngày cùng LLM

  • Một năm sau, trong chuyến về Argentina thăm gia đình, tác giả dạy cho cháu mình trò chơi bài phổ biến thứ hai có tên Escoba
  • Lần này, tác giả dùng LLM (Claude), sao chép backend của Truco rồi mô tả luật của Escoba trong prompt và yêu cầu refactor mã
  • Ngay ở prompt đầu tiên, phần triển khai đã gần như hoàn hảo; chỉ còn một vài lỗi nhỏ và một số tính năng bổ sung cần chỉnh tay
  • Frontend vẫn cần nhiều ngày tự triển khai/debug. Giới hạn của LLM, kỹ năng React và môi trường đặc thù khi trạng thái game được quản lý trong WASM đều là các yếu tố gây khó khăn
    Quảng cáo

Từng bước: cách tự làm game của riêng bạn

Phát triển backend

  • Backend cho game theo lượt có thể được thiết kế chức năng một cách rõ ràng
  • Để giữ kiến trúc serverless, việc tránh mô hình hai người chơi trực tiếp với nhau là lựa chọn thực tế nếu không có máy chủ thương mại

Phát triển frontend

  • Frontend cần thực hiện các việc sau
    • Yêu cầu backend tạo GameState mới
    • Hiển thị trạng thái trên UI
    • Cung cấp giao diện để chọn hành động hợp lệ
    • Gửi command tới backend khi áp dụng hành động
    • Nếu đến lượt bot thì gửi yêu cầu tới backend
Quảng cáo

Chuyển backend sang WASM

  • Để build mã Go thành WASM, dùng GOARCH=wasm GOOS=js go build
  • Có thể gặp vấn đề kích thước binary quá lớn, nên tác giả dùng TinyGo để giảm dung lượng
  • Để export các hàm kết nối với frontend, cần viết một entry point riêng trong Go (ví dụ: main_wasm.go) và tách nhánh khi build
  • Trong hàm main, cần chặn bằng select {} để chương trình không kết thúc ngay lập tức

Liên kết dữ liệu backend - frontend

  • Các struct linh hoạt của Go như GameState không thể serialize/deserialize trực tiếp trong WASM
  • Vì vậy, cần trao đổi toàn bộ dữ liệu bằng định dạng JSON
  • Theo tài liệu TinyGo, cả đầu vào và đầu ra đều được truyền nhận bằng JSON serialization

Giao diện frontend - backend

  • Ở frontend, các hàm backend được gọi trực tiếp
  • GameState chỉ được quản lý bên trong WASM và frontend không thể mutation; backend luôn là nguồn chân lý duy nhất
  • Sau khi biên dịch lại WASM, cần thay thế tệp tương ứng; bài viết cũng đưa ví dụ tự động hóa bằng Makefile

Môi trường chạy WASM

  • Để chạy được, cần đưa wasm_exec.js vào phần head, rồi dùng script đó để tạo instance và chạy

Kết luận

  • Làm game là một trải nghiệm thú vị, và tổ hợp Go, WASM, React là một cách tiếp cận mà ai cũng có thể thử
  • Sự hỗ trợ của LLM giúp năng suất tăng mạnh, nhưng năng lực frontend và kinh nghiệm debug vẫn rất quan trọng
  • Bất kỳ ai cũng có thể tự thử thách bản thân với việc phát triển game theo cấu trúc này, nên hãy thử xem

4 bình luận

 
codong 2025-08-27

Nếu đoạn mã được tạo ra mà lại dùng document.getElementById trong React, thì đã dùng LLM nào vậy....

 
onetoday 2025-08-27

Gần như có cảm giác như một kiểu câu view giật tít..
"Nếu làm từ đầu thì mất 3 tháng, còn nếu lại làm một thứ tương tự thì mất 3 ngày"

 
savvykang 2025-08-27

Có lẽ tác giả gốc là kiểu người còn chẳng biết bình thường mình làm gì.

 
GN⁺ 2025-08-25
Ý kiến trên Hacker News
  • Điều tôi thấy hay ở bài đăng này là nó chỉ ra một điều mà nhiều lập trình viên thường bỏ qua. Trong phát triển game, bản thân việc viết code hiếm khi là điểm nghẽn. Ngay cả người làm một mình cũng có thể tạo cơ chế nhanh mà không cần AI. Phần thực sự khó là nhiều lớp vô hình ở phía trên, như cân bằng game loop, tinh chỉnh độ khó, làm asset không bị lạc tông, hay polishing đủ để giữ sự chú ý của người dùng hơn 5 phút. Đó cũng là lý do sau thời LLM, Steam vẫn chưa tràn ngập những game xuất sắc. Công nghệ đã hạ thấp một rào cản, nhưng các rào cản lớn hơn vẫn còn nguyên. Thời Unity trỗi dậy trong thập niên 2010 cũng vậy. Engine đã dân chủ hóa việc làm game, nhưng thứ tăng vọt không phải số game hay mà là số lần thử. LLM với code, và mô hình ảnh với art, đều đang tạo ra hiện tượng tương tự, nhưng các công cụ này không thể nói cho bạn biết game nào thực sự vui. Câu hỏi khiến tôi thấy thú vị là điều gì sẽ xảy ra nếu AI không chỉ triển khai mà còn playtest. Tức là nếu nó tiến tới mức chạy hàng nghìn vòng lặp và cho biết cơ chế nào giữ được người chơi mô phỏng ở lại, thì vai trò của nó sẽ mở rộng từ hack năng suất sang đối tác thiết kế. Chúng ta chưa ở giai đoạn đó, nhưng bài này cho cảm giác như một data point ban đầu theo hướng ấy

    • Về ý kiến thắc mắc tương lai sẽ ra sao nếu AI không chỉ triển khai mà còn playtest, chạy hàng nghìn vòng lặp để đo xem người chơi bị cuốn hút hơn bao nhiêu, tôi lại thấy tò mò AI sẽ mô phỏng người chơi bằng cách nào và vì sao nó có thể đánh giá đúng thứ mà con người thật sự sẽ thấy cuốn hút

    • Tôi muốn phản biện ví dụ về sự trỗi dậy của Unity trong thập niên 2010 rằng số lượng game thật sự hay không nhiều đến vậy. Thực ra nếu so với thời XBLA, khối lượng game khổng lồ mà chúng ta có hiện nay sẽ là bất khả thi nếu không có các công cụ như Unity, Godot, Gamemaker, Renpy, RPG Maker. Nghĩa là đã có bước nhảy vọt rõ rệt không chỉ về chất mà cả về lượng

    • Với tôi, bài kiểm tra litmus cho AI tạo sinh là liệu nó có thể tạo ra trọn bộ spritesheet cho game hành động pixel art 2D hay không. Ví dụ mục tiêu chỉ là tạo thật hoàn hảo chuyển động của xe tăng hoặc nhân vật chính thôi, nhưng đến giờ tôi vẫn chưa thấy ca thành công nào

    • Tôi nghĩ nhận định "AI không thể nói cho bạn biết game của bạn có thực sự vui hay không" là insight cốt lõi. AI không thể trải nghiệm game như con người thật, hay bất kỳ trải nghiệm nào khác theo cách của con người. Nó chỉ có thể dự đoán ở mức nào đó bằng cách nhìn vào dữ liệu đánh giá của con người về các game tương tự. Nghĩa là AI không thể tự thưởng thức game của bạn. Bản chất này sẽ định nghĩa vai trò của lao động trong thời đại AI về sau. AI có thể viết tài liệu hay code theo kiểu giống con người ở một mức độ nào đó dựa trên dữ liệu quá khứ, nhưng điều đó chứng minh rằng vẫn có những sự tích hợp và trải nghiệm có ý nghĩa mà chỉ con người thật mới làm được. Có một điểm mà giá trị riêng của con người không thể bị thay thế, chỉ là chúng ta cần tiếp cận khác đi về cách nhìn nhận giá trị ấy

    • Mẫu hình này cũng đúng với các lĩnh vực khác ngoài phát triển game. Như ai cũng kỳ vọng, coding dựa trên agent có tiềm năng rất lớn, nhưng hiện tại nó chỉ giải quyết vượt trội một số tác vụ nhất định (demo webapp nhanh, nối các thư viện nhỏ, v.v.), còn với phần mềm quy mô lớn thực tế thì vẫn chưa áp dụng tốt. Cả cách mô hình được huấn luyện lẫn know-how mà chúng ta dùng đều vẫn còn thiếu. Điều này không có gì đáng ngạc nhiên. Ngay cả git sau khi ra đời cũng phải 5 năm đầu chỉ có các công ty tinh hoa triển khai cho ra hồn, rồi thêm 5 năm nữa mới phổ biến rộng. Rốt cuộc bây giờ thì ai cũng quen, nhưng tôi cho rằng LLM còn khó dùng cho đúng cách hơn cả git. Nếu mỗi sản phẩm, OSS, blog post đừng cường điệu kiểu "giờ là xong rồi, mọi thứ đã bị cách mạng hóa" thì có lẽ nó còn phát triển nhanh hơn. Chúng ta vẫn đang trong giai đoạn thử sai và thử nghiệm, và điều đó cần thời gian. Không nên kết luận quá sớm. Nếu thật sự mọi thứ đã được giải quyết thì ít nhất chúng ta đã phải bị chôn vùi trong phần mềm vượt trội hơn rất nhiều, nhưng hiện giờ mới chỉ là mức vừa cố cân bằng. Chừng này đã là thành quả khá ấn tượng chỉ sau 1~2 năm kể từ khi công nghệ mới xuất hiện

  • LLM có lợi thế dẫn trước 3 tháng là nhờ code, dùng game trước đó làm template, và trên hết là dựa trên toàn bộ kinh nghiệm lẫn sai lầm tích lũy khi từng hand-code

    • Ban đầu tôi tưởng đây sẽ là một tiêu đề giật gân, nhưng thật sự thấy bất ngờ ở đoạn "sao chép backend của Truco rồi giải thích dài dòng luật Escoba cho Claude và để nó refactor code". Tôi tự hỏi nếu con người trực tiếp refactor thì sẽ mất bao lâu. Có cảm giác sẽ mất hơn 3 ngày, nhưng cũng có thể không

    • Một điểm nữa là đây là game đầu tiên của người tham gia. Nghĩa là ở lần thử đầu tiên bạn phải đối mặt với vô số biến số chưa biết, nhưng nếu đã từng trải qua một lần và có sẵn insight cùng know-how rồi bắt đầu lại, thì ngay cả không có LLM cũng có thể làm trong thời gian ngắn hơn nhiều so với 3 tháng

    • Thực tế tôi cũng từng trải nghiệm rằng khi lặp lại cùng một dự án lần hai, lần ba, thứ từng mất vài tháng ban đầu sẽ giảm xuống còn khoảng 1/3 ở lần sau

  • <i>khụ khụ</i> Tôi từng phát triển trong vòng 24 giờ, có ví dụ tại nordicgamejam.com. Tôi chỉ muốn nói rằng thời chưa có LLM, GenAI hay cả Unity thì lựa chọn tốt nhất là Microsoft XNA và C#. Art khi đó phần lớn cũng chỉ ở mức vẽ tay bằng Paint. Dù vậy, mỗi năm vẫn có rất nhiều game thú vị ra đời, và đôi khi có những cái được công chúng biết đến như Baba is You hay Braid. Code không phải là điểm nghẽn, và cá nhân tôi tin chắc nút thắt cổ chai thật sự là giao tiếp giữa các thành viên

    • Nói thêm về ý kiến cho rằng giao tiếp trong nhóm là điểm nghẽn quan trọng, tôi muốn nhắc rằng ngay cả "giao tiếp" với chính mình trong đầu đôi khi cũng khó đến ngạc nhiên
  • Nhìn luồng bình luận này thì có vẻ nhiều người chưa có kinh nghiệm phát triển game. Thực ra các dự án dùng LLM ở đây đều là loại đã xuất hiện rất nhiều trong dữ liệu huấn luyện. Ví dụ đó cũng là dạng dự án trong các môn nhập môn lập trình, và ở các nước Nam Âu có rất nhiều game tương tự trò bài mà blog này nói tới. Tôi cũng từng là sinh viên năm nhất đại học, không có kinh nghiệm gì mà tự làm Moon Patrol bằng Python từ đầu, mất 2~3 tháng, thức đêm code 3 ngày mỗi tuần. Làm game bài thậm chí còn dễ hơn thế. LLM rõ ràng hữu ích ở những chỗ nhất định, nhưng các ví dụ đơn giản thế này không phù hợp để benchmark năng suất code hay độ hữu dụng của LLM

  • Tôi đã làm kiểu việc này với LLM trong vài ngày, ngắt quãng: stacky. Tổng cộng chắc cỡ hai ngày làm thật. Ban đầu viết từ ground up, sau đó theo kiểu brownfield, và cũng không định hoàn thiện thật nghiêm túc. Nhưng rồi cứ thêm dần chi tiết và tính năng nên ý tưởng lại nảy ra liên tục (super rotation, DAS, v.v.). Nó vẫn còn dang dở, mới khoảng 10~20% của toàn bộ game. Bản WebGL cũng chạy được. Nhưng nếu cố làm một bản Tetris tối thượng thì e là sẽ bị kiện, mà tôi cũng không có tiền trả phí license kiểu đó nên dừng lại. Cuối cùng thứ tôi có được là sự tự tin và kinh nghiệm. Gần đây thấy một link trên HN về hàm tham số nên tôi cũng thử làm playground graphy trong 1~2 giờ. Lại vẫn cứ đổ thời gian vào các chi tiết. Nếu bạn biết rõ mình muốn gì, thì làm kiểu này với LLM khá là thú vị

    • Bản tái tưởng tượng Tetris rất ngầu. Xin lưu ý là với MacBook Pro M4 Max mới và Firefox, nó đẩy mức dùng core lên 100% và quạt quay rất dữ
  • Tôi làm game như hobby khá đều đặn ở mức tương đối nghiêm túc và cũng đã hoàn thành nhiều game. Nhưng nhìn tổng thể luồng bình luận này thì có vẻ không nhiều người có kinh nghiệm phát triển game thực tế. Tôi không thể đồng ý với nhận định rằng code là phần dễ trong phát triển game. Nghĩ ra ý tưởng mới hay cơ chế biến tấu theo thể loại còn dễ hơn, còn phần code để hiện thực hóa mới là khó hơn nhiều. Ví dụ tưởng tượng chuyện thêm tùy biến battlemech vào một Vampire Survivors multiplayer thì dễ, nhưng triển khai nó chỉ bằng LLM thì gần như bất khả thi. Trường hợp này chỉ là luật của một game bài đã được biết đến hoàn toàn, nên đơn giản cỡ game rắn. Không phải tôi chê trách tác giả bài viết, chỉ là muốn chỉ ra rằng nhiều người đang phán xét việc phát triển mà không có trải nghiệm làm game thực tế

    • Tôi không đồng ý rằng code là phần khó trong phát triển game. Tất nhiên nó có thể khó, nhưng thứ thực sự khó là nghĩ ra những ý tưởng mới mẻ và thú vị. Khi đã có ý tưởng tốt thì bạn có thể chia nhỏ ra rồi lặp dần và cuối cùng sẽ triển khai được. Trở ngại thật sự là khoảnh khắc đứng trước trang giấy trắng và quyết định sẽ làm gì. Hãy đi dạo, thử đủ thứ, đây là vấn đề đã lặp lại hàng nghìn năm trong nghệ thuật. Trong khi đó code rốt cuộc là công việc mang tính kỹ thuật. Tôi cũng đang học phát triển game gần đây, kèm theo học toán, và thấy học vector hay quaternion còn dễ hơn nhiều so với việc quyết định "mình muốn làm game gì?"

    • Về cơ bản tôi đồng ý, nhưng với tôi thì ngược lại, phần nghĩ ra ý tưởng mới hay thử nghiệm sáng tạo lúc nào cũng khó hơn. Hầu như cơ chế game nào tôi cũng có thể code được, nhưng phần viết lách/sáng tạo thì cực kỳ vất vả. Nếu ai thấy phần đó dễ thì đúng là quá may mắn. Không phải chuyện tự nhiên với tất cả mọi người

  • Nếu định làm một game hoàn toàn client-side thì tôi thắc mắc vì sao lại viết kiểu như cần một "backend", và vì sao chỉ riêng backend lại dùng công nghệ khác thay vì toàn bộ app

  • Tôi có cảm giác trong ngành phần mềm, những vùng mà ý tưởng có thể được hiện thực hóa nhanh và dễ gần như đã biến mất. Cạnh tranh giờ đã quá khốc liệt, đến mức dù bạn nhắm vào một thị trường nhỏ đến đâu thì cũng đang cạnh tranh trực tiếp với VC toàn cầu, AI toàn cầu. Ngày xưa ít nhất còn có thể tìm ra những ngách mà tập đoàn lớn không thèm để ý. Giờ thì dù là VC lớn hay ngách nhỏ gì cũng đều phải cạnh tranh toàn cầu, nên rốt cuộc chỉ còn các thị trường nhỏ đòi hỏi công nghệ cực kỳ phức tạp, hoặc các lĩnh vực lợi nhuận thấp, xác suất thất bại cao và vòng đời ngắn (phần lớn game nằm đúng nhóm này). Với loại đầu tiên, bạn cần marketing kiểu đi gõ cửa từng nơi để giới thiệu sản phẩm. Theo kinh nghiệm của tôi trong ngành game, ngay cả một ca gọi là trúng lớn trước khi bước vào giai đoạn phát triển cũng chỉ ở mức "đạt một triệu lượt xem rồi 6 tháng sau chết hẳn". Vì gần như không có doanh thu lặp lại nên việc bắt đầu đã cực kỳ làm nản chí. Làm ra được một game như Minecraft gần như chẳng khác gì trúng số. Nhưng ngành game dù sao vẫn mang tính meritocracy hơn các ngành phần mềm khác. Chất lượng và độ vui thật sự có liên hệ với việc có được đón nhận hay không. Các ngành khác thì như mê cung của quy định, độc quyền do network effect, hay sự kiểm soát của chính phủ. Đôi khi tôi chỉ ước lúc đầu nhà nước nói thẳng rằng "lĩnh vực này công ty kia đã thống trị rồi, đừng startup ở đây, đi chỗ khác đi" để khỏi phí một năm cuộc đời

  • Tôi tự hỏi đến bao giờ người ta mới nhận ra rằng các dự án greenfield (hoàn toàn mới) là trường hợp tệ nhất để benchmark năng lực agent coding

  • Tôi thích LLM vì nó giúp tôi làm việc với code theo cách gần hơn với cách tôi trừu tượng hóa chương trình trong đầu. Khi đọc code, tôi hiểu nó gần như một AST, biến hàm và lời gọi hàm thành các nút trừu tượng đầu vào và kết quả. Nhờ LLM, việc hiện thực hóa ngược lại điều đó thành code trở nên cực kỳ đơn giản. Không còn phải lục tìm ví dụ code phù hợp với ý tưởng hay cố nhớ lại nữa, chỉ cần bảo LLM viết những đoạn lặp đi lặp lại như khởi tạo WiFi. Kết quả là tôi có thể lắp ráp chương trình như xếp các khối Lego. Trước thời LLM cách này vẫn làm được, nhưng tốn công hơn rất nhiều. Nhờ đó dạo này tôi phát triển khá dễ dàng qua nhiều ngôn ngữ khác nhau. Tôi không học được nhiều về cấu trúc nội tại hay cú pháp của từng ngôn ngữ, nhưng đó chính là mấu chốt. Ngôn ngữ và cú pháp chỉ là chi tiết thứ yếu, không liên quan đến luồng logic của chương trình. Cuối cùng, cũng như đã tiến hóa từ mã máy sang assembly, C, rồi các ngôn ngữ cấp cao hơn, chúng ta sẽ ngày càng tiến gần hơn không phải tới việc "viết code" mà là chính "lập trình". Không ai biết hình thái cuối cùng sẽ ra sao, nhưng chắc chắn theo thời gian chúng ta sẽ dành nhiều thời gian hơn cho "lập trình" và ít thời gian hơn cho việc "viết"

    • Đồng ý. Trước đây cũng từng có người lo rằng nếu viết bằng C thì không hiểu thật sự tầng assembly và rồi sẽ có ngày trả giá, nhưng thực tế là sự tiến bộ của công cụ năng suất cho lập trình. AI cũng vậy, ưu điểm lớn nhất là tách bớt những việc lặp đi lặp lại quá hiển nhiên khỏi tay lập trình viên. Ngày xưa ta từng phí thời gian săn memory leak và segmentation fault trong C. Giờ với ngôn ngữ hiện đại thì nhu cầu đó đã biến mất, và tương tự, việc tìm ví dụ cho các chi tiết triển khai vụn vặt hay lục tài liệu cũng sẽ dần biến mất. Cuối cùng lập trình viên sẽ có thể tập trung vào những phần sáng tạo hơn