50 điểm bởi namyunwoo 2026-05-17 | 24 bình luận | Chia sẻ qua WhatsApp

Port mã nguồn cho Forgotten Saga (game RPG DOS Hàn Quốc năm 1997)

Động lực

  • 30 năm trước, trò chơi đóng gói đầu tiên tôi mua khi còn học tiểu học là Forgotten Saga
  • Đây là game RPG đầu tiên trong đời, và tôi tự nhiên bị cuốn rất sâu vào nó
  • Sau hơn 20 năm sống mà quên mất nó, tôi mới biết rằng đến giờ vẫn còn rất nhiều người đang chơi
  • "Liệu có thể biến nó thành một game đa nền tảng không?"
  • Những gì còn lại chỉ là file thực thi PE32 từ năm 1997 + các file dữ liệu (đương nhiên là không có mã nguồn)

Cách tiếp cận

  • Có hai hướng lớn để tái hiện game gốc
    • Diễn giải lại dựa trên đặc tả — xem gameplay rồi làm lại tương tự
    • Phục dựng trung thực theo từng hàm của bản gốc — port nguyên mã đã được decompile
  • Tôi chọn cách thứ hai, để bám theo hành vi gốc đã được kiểm chứng thay vì suy đoán
  • Bản gốc là Windows MSVC năm 1997

Những gì đã phân tích

Decompile binary gốc

  • Dùng Ghidra 12 để xử lý PE32. Decompile thành công 100% của 937 hàm
  • 51.799 dòng pseudocode C

Phân tích định dạng dữ liệu (48 loại, đã kiểm chứng toàn bộ)

  • LZSS — chuẩn + biến thể FAM (khởi tạo ring 0x00, cách bố trí bit của ref_offset khác)
  • SPB — 256 màu + RLE, 1.155 ảnh
  • MOB — 2.699 frame hoạt ảnh nhân vật/NPC. header 0xA4 + pixel RLE + frame stride 20B
  • SCP — VM bytecode, hơn 128 opcode, 6.026 entry, 43.036 câu thoại
  • FAM — 292 bản đồ, 5 layer (base / overlay / collision / ...)
  • DAT — CHAR / ITEM 290 loại / MAGIC / ABILITY / MONSTER
  • SAV — struct actor 0x2A4 (676B), party + inventory + biến toàn cục

Tự xác minh trực tiếp đầu vào người dùng

  • Tự parse file save để xác minh offset của actor struct
  • Sửa các mapping sai trước đó (0x3C ATK→STR, 0x40 INT→TLT, v.v.)

Những gì đã tạo ra

  • 263 file Lua, 157.277 dòng
  • 3.760 asset
  • Bản build desktop bằng LÖVE 2D 11.5 + bản build web bằng love.js (emscripten)
  • Tự triển khai joystick ảo cho di động + IME tiếng Hàn
  • Kích hoạt SharedArrayBuffer (COOP/COEP qua coi-serviceworker)
  • Lưu trữ save bền vững bằng IndexedDB (môi trường trình duyệt)
  • 5 kênh phân phối — Web / iOS / Android / Windows / macOS

Phạm vi tái hiện

  • Tiêu đề / tạo nhân vật / field / hội thoại / cửa hàng / inventory / trang bị / bẫy / DETECT·UNLOCK / save — hoàn tất
  • Hệ thống chiến đấu — đang thực hiện

Ứng dụng công cụ AI

  • Chủ yếu dùng tính năng /goal của GPT 5.5, còn Claude Code dùng để hỗ trợ + debug thời gian thực

Vai trò của GPT 5.5 /goal — phân tích decompile / tích lũy chỉnh sửa

  • Tự động phân tích original function cluster / call graph / opcode reference
  • Deep dive vào định dạng dữ liệu (định dạng sav, actor offset, cấu trúc FAM, v.v.)
  • Tích lũy sửa mislabel trong bản decode tự động ban đầu (bản đã chỉnh sửa 51.799 dòng)

Vai trò của Claude Code — port Lua + chu trình kiểm chứng tức thời

  • Đọc hàm gốc → port sang Lua → chạy test verify.sh (hơn 100 chế độ test, hơn 1.000 assertion)
  • Debug môi trường trình duyệt (IDBFS / IME / SharedArrayBuffer, v.v.)
  • Khi nhận báo cáo từ người dùng thì debug → fix → deploy bản dev → kiểm chứng → deploy bản live

Thời gian thực hiện

  • Khoảng 1–3 tháng

Đây là sản phẩm như thế nào

  • Chơi thử (trình duyệt): https://forgottensaga-classic.blogspot.com/2026/05/…
  • Chạy được trên cả PC lẫn di động. Bản di động tự triển khai joystick ảo + IME tiếng Hàn
  • Tái hiện trung thực gameplay gốc — hành vi gốc được giữ 1:1 như Z-sorting, palette cycle, state machine của NPC, SCP VM, v.v.

24 bình luận

 
chinnotching 26 ngày trước

Tôi nhớ có một đứa bạn hồi tôi còn học cấp 2 đã từng đặt trước, điều mà thời đó còn khá hiếm, và nó cứ than thở với tôi vì Forgotten Saga liên tục không giữ đúng ngày phát hành. haha

 
namyunwoo 26 ngày trước

Chắc cũng bị dồn lại khoảng 2 năm rồi nhỉ? haha

 

Quá đỗi lãng mạn. Chúc dự án tuyệt vời này thành công!

 
namyunwoo 26 ngày trước

Cảm ơn bạn, giờ khó mà tìm lại được cảm giác lãng mạn đó.

 

Nếu không nhập tên thì trước đây game sẽ tự động đặt là Hiro Amy, nhưng giờ thì không được nữa nhỉ.
Đó vốn là một trò chơi đầy lỗi, nên tôi cũng tò mò không biết khi port sang anh có tái hiện luôn cả các lỗi đó một cách trung thành hay không.

 
namyunwoo 29 ngày trước

Thậm chí có lẽ còn nhiều lỗi hơn nữa.. tôi sẽ thử cải thiện dần từng chút một.

 
shakespeares 2026-05-18

Tuyệt quá.. wow

 
namyunwoo 26 ngày trước

Cảm ơn bạn 💪🏻

 
zz5414 2026-05-18

Dạo này tôi cũng muốn port một game kinh điển mà hồi tiểu học mình từng chơi rất vui lên web, thì đúng lúc lại có bài như thế này được đăng. Tôi tò mò không biết những bài về động cơ hay nội dung phân tích đó được lấy từ đâu để xuất hiện trên GeekNews.

 
namyunwoo 26 ngày trước

Haha, vì tôi là người đã đăng nó mà.

 
namyunwoo 26 ngày trước

❤️Cảm ơn bạn

 
gafani 2026-05-18

Tôi nhập sai tên rồi, có cách nào xóa không? Nút Esc ảo không hoạt động, phím Backspace trên bàn phím cũng không ăn. Hồi hộp quá.

 
namyunwoo 29 ngày trước

Cảm ơn bạn hu hu
Tôi đã sửa lỗi phím Backspace không hoạt động. Tuy nhiên, vấn đề khi nhấn Esc ở chế độ toàn màn hình thì chế độ toàn màn hình bị thoát vẫn đang được xử lý..

 
sam1287 2026-05-18

Thật tuyệt vời!

 
namyunwoo 26 ngày trước

Hehe, chỉ là một chút tình cảm của fan thôi..

 
teipub 2026-05-18

Thật tuyệt vời!

 
namyunwoo 26 ngày trước

Bạn quá khen rồi haha 😂

 
ifmkl 2026-05-18

Wow, thật sự quá tuyệt vời.

 
namyunwoo 26 ngày trước

Cảm ơn nhé~~👍🏻👍🏻

 
kaydash 2026-05-18

Wow, đúng là đỉnh thật.

 
namyunwoo 26 ngày trước

Cảm ơn bạn, mình sẽ từng bước nâng cao độ hoàn thiện.

 
mssmss 2026-05-17

Cảm ơn bạn. Cảm ơn bạn. Ủng hộ bạn.

 
namyunwoo 26 ngày trước

Cảm ơn bạn đã ủng hộ!