- OUO là dự án đã đảo ngược kỹ thuật hoàn toàn máy chủ demo
Ultima Online năm 1998, giải mã khoảng 5.000 hàm từ nhị phân MSVC x86 và chuyển sang C99 có tính di động
UoDemo.exe là bản demo độc lập đi kèm bản phát hành đầu tiên của Ultima Online: The Second Age, đồng thời chứa cả client lẫn toàn bộ mã và dữ liệu máy chủ đã được port sang Windows
- Mỗi hàm được đối chiếu với nhị phân gốc ở cấp độ từng lệnh, rồi được chuyển đổi thủ công để khớp hệ phân cấp lớp và bố cục vtable, đồng thời giữ nguyên luồng điều khiển, bố cục struct và các nhánh như bản gốc
- Bản phục dựng rất gần với mã máy chủ
Ultima Online đang vận hành thực tế vào giữa năm 1998, nhưng đã sửa các vấn đề ổn định như crash, tràn bộ nhớ, biến chưa khởi tạo, cùng các vấn đề gameplay như tăng kỹ năng và mật độ spawn, kèm tag đánh dấu
- Bản demo gốc chỉ hỗ trợ client 1.25.33, nhưng bản phục dựng hỗ trợ các client từ 1.25.30 đến 5.0.9.1 bất kể có mã hóa hay không, đồng thời đang tìm thêm các file dữ liệu máy chủ giai đoạn 1997~2003
Nguồn gốc và phạm vi của các file demo
- Mỗi hàm được đối chiếu với nhị phân gốc ở cấp độ từng lệnh, và sau 10 năm làm việc gián đoạn, dự án gần đây mới có thể hoàn tất nhờ sự phát triển của LLM
UoDemo.exe mang ngày 1998-09-02, còn dữ liệu máy chủ được trích xuất từ máy chủ vận hành ngày 2 tháng 6 năm 1998
- Một số tính năng đã được stub hóa cho bản demo và bản đồ có thể chơi bị thu gọn còn đảo Ocllo, nhưng phần còn lại vẫn là mã máy chủ sản xuất thực sự đang chạy trên
Ultima Online vào giữa năm 1998
Ultima Online là game MMORPG ra mắt năm 1997 do Origin Systems Inc. phát triển, và là một trong những MMORPG đầu tiên thành công về mặt thương mại
- Client chạy trên Windows, còn các máy chủ “shards” chạy trên nhiều máy Solaris, với bản đồ được chia theo từng khu vực
- Bản demo cung cấp một nhiệm vụ đơn giản là giết rồng trên đảo Ocllo, cho phép người chơi trải nghiệm các cơ chế cơ bản như hội thoại, giao dịch và chiến đấu
- Nhiều trình giả lập máy chủ
UO đã tái sử dụng một phần bản demo này, nhưng cho đến nay chưa có trường hợp nào đảo ngược kỹ thuật hoàn toàn
UoDemo.exe được biên dịch bằng Microsoft Visual C++ 5.0, tức Visual Studio 97, và nhắm tới một biến thể C++ trước thời C++98
Phương pháp đảo ngược kỹ thuật
-
Giải mã disassembly và suy đoán symbol
- Dùng radare2 để disassemble
- Tên symbol được suy ra từ client
UO 1.25.37 là bản port Linux thử nghiệm có chứa symbol C++
-
Chuyển đổi thủ công sang C99
- Mỗi hàm được dịch tay sang C99 sao cho giữ nguyên luồng điều khiển, bố cục struct và các nhánh như nhị phân gốc
- Những chỗ có khác biệt là phần sửa bug thực tế của bản demo hoặc điều chỉnh theo nền tảng, và đều được đánh dấu trong mã nguồn
-
Cách xác minh
- Bản build C được disassemble lại bằng
r2 để so sánh với bản gốc
- Chỉ khi hai kết quả khớp nhau thì hàm mới được đánh dấu là hoàn tất
- Các hàm helper chỉ được dùng cho những mẫu inline lặp lại, và chỉ khi helper có thể bung lại thành đúng đoạn mã như bản inline
-
Khôi phục hệ phân cấp lớp
- Công việc quan trọng nhất ở giai đoạn đầu là khớp chính xác hệ phân cấp lớp
- Hệ phân cấp cốt lõi là
CEntity (0x10) -> CResourceEntity (0x1C) -> CItem (0x50) -> CContainer (0x5C) -> CMobile (0x37C) -> CPlayer (0x458)
- Dispatch ảo được thực hiện qua các slot vtable; ví dụ
vtable[0x18] là IsPlayer, [0xD0] là IsMobile, [0xE4] là IsNPC
- Khi bố cục này đã được xác định, phần lớn nhị phân có thể được dịch lại khá trực tiếp
Kết quả phục dựng và khác biệt so với bản gốc
- Kết quả là một bản sao gần như hoàn hảo của máy chủ
Ultima Online năm 1998, dù vẫn có một số khác biệt
- So với mã gốc, các vấn đề ổn định như crash, tràn bộ nhớ và biến chưa khởi tạo đã được sửa
- Các vấn đề gameplay như tăng kỹ năng, hướng fame/notoriety và mật độ spawn cũng đã được chỉnh lại
- Mỗi chỉnh sửa đều được gắn tag trong mã nguồn để người đối chiếu với
UoDemo.exe có thể biết chính xác điều gì đã thay đổi và vì sao
- Một số tính năng như hệ thống spawn và hệ thống decay bị hỏng, có thể đã bị vô hiệu hóa một phần hoặc stub hóa để phát hành bản demo
- Mã của các tính năng đó vẫn còn, nhưng các điểm gọi trong luồng chạy thực tế không thể chạm tới; chỉ cần decompile riêng rồi nối lại dispatch là có thể làm chúng hoạt động
- Dữ liệu của một phần bản đồ bị thiếu, chẳng hạn game map chỉ chứa đảo Ocllo
- Tác giả đã tạo cả bộ công cụ để thao tác định dạng dữ liệu máy chủ, và tái dựng hoàn chỉnh cửa, biển hiệu, đồ trang trí, teleporter, bẫy, rương và vị trí spawn của phần còn lại của thế giới
Hệ sinh thái vẫn còn sót lại
- Hệ ecology system nổi tiếng nay đã bị loại bỏ vẫn còn tồn tại trong mã dù các lời gọi hàm đã bị ngắt
- Việc nối lại hệ thống thú săn mồi, con mồi và động vật ăn xác cho phép thấy sói đuổi thỏ hoặc quạ ăn đồ vật
- Tuy vậy, do thiếu dữ liệu chính xác nên chưa triển khai toàn bộ hệ thống tài nguyên và sản xuất
- Tài liệu nền liên quan gồm bài về ecology system của Raph Koster cho
UO và loạt bài về hệ thống tài nguyên UO 1, 2, 3
Tính năng bổ sung và khả năng tương thích client
- Các kỹ năng Meditation, Stealth và Remove Trap do OSI bổ sung vào tháng 2 năm 1999 đã được thêm mới
- Một phần dấu vết ban đầu của các tính năng này đã có sẵn trong mã
- Phần lớn tính năng mới có thể bật hoặc tắt lúc khởi động bằng tham số
-features
- Do máy chủ demo hoàn toàn không có hệ thống tài khoản, tác giả đã suy đoán cách các nhà phát triển gốc có thể đã triển khai và tái hiện lại theo hướng hơi hiện đại hóa
- Máy chủ demo gốc chỉ hỗ trợ client 1.25.33, nhưng nay đã được mở rộng để hỗ trợ mọi client từ 1.25.30 đến 5.0.9.1, tức 2007-03-27, bất kể có mã hóa hay không
- Vì trong nhiều năm đã tồn tại năm cơ chế mã hóa hoàn toàn khác nhau, từng cơ chế đều phải được đảo ngược kỹ thuật từ nhị phân client
Bản gốc 32-bit và bản build mặc định 64-bit
- Nhị phân gốc là 32-bit, nhưng bản build mặc định hiện tại nhắm tới 64-bit
- Hệ phân cấp lớp được tái hiện bằng cách nhúng struct C để mô phỏng kế thừa C++ ban đầu
- Nhờ cách này, có thể truyền
CMobile* vào nơi cần CContainer*
- Vì độ rộng con trỏ tăng lên trên 64-bit có thể đẩy lệch vị trí các trường kế thừa, một số struct được chèn padding có chủ đích để bố cục kế thừa và vtable khớp với nhị phân trên cả 32-bit lẫn 64-bit
Tài nguyên công khai
- https://github.com/draxinar/ouo: mã nguồn
- https://github.com/draxinar/rundir: dữ liệu dựa trên
UoDemo.dat, các chỉnh sửa, dữ liệu hoàn thiện và tính năng mới
- https://uo.serpent-isle.com/: Test Center, không phải shard thực, mà là môi trường để thử bản tái hiện rất trung thành với máy chủ
Ultima Online năm 1998
- UO:98: dự án của Batlin và Derrick, nguồn cảm hứng khiến công việc này bắt đầu từ năm 2016
OUO vẫn còn ở giai đoạn đầu và có thể vẫn tồn tại vấn đề
- Có thể báo lỗi đã phát hiện qua issue, và mọi đóng góp đều được hoan nghênh
Lời kêu gọi tới cộng đồng Ultima Online
- Nếu ai còn giữ các file
dynamic0.mul, dynamic0.bkp, regions.txt, resbank.mul của máy chủ Ultima Online gốc vào khoảng 1997~2003 thì tác giả mong được chia sẻ
dynamic0.mul và dynamic0.bkp là file lưu trạng thái máy chủ, regions.txt là định nghĩa spawn, còn resbank.mul là file định nghĩa tài nguyên
- Có vẻ khả năng các file
dynamic0.mul hoặc dynamic0.bkp gốc đã biến mất hoàn toàn là khá thấp
- Tác giả đã có sẵn công cụ để loại bỏ dữ liệu người chơi khỏi file
dynamic0.mul nhằm bảo vệ quyền riêng tư trước khi phân phối
- Những file này có giá trị rất lớn trong việc tái hiện nội dung thế giới
Ultima Online với độ chính xác rất cao
1 bình luận
Ý kiến trên Hacker News
Nếu ai đó có các tệp dynamic0.mul, dynamic0.bkp, regions.txt, resbank.mul của máy chủ Ultima Online gốc thì thật sự rất mong được gửi cho mình
Đây là các tệp lưu trạng thái game trên máy chủ, định nghĩa spawn và tài nguyên vào khoảng 1997~2003, và đặc biệt dynamic0.mul hay dynamic0.bkp hẳn đã được sao lưu ở nhiều nơi an toàn nên khó có thể xem là đã biến mất hoàn toàn
Những tệp này cực kỳ có giá trị để tái tạo nội dung thế giới Ultima Online với độ chính xác rất cao
Quá tuyệt. Thật lạ là mình vừa đang nghe nhạc nền game Ultima cũ thì lại nhìn thấy bài này
Mình tự hỏi liệu họ có cân nhắc viết kết quả disassembly bằng phương ngữ C++ trước C++98 từng được dùng trong bản gốc và nhắm tới đúng trình biên dịch ban đầu hay không
Mình từng disassemble các binary chạy trên hệ thống cổ, và nếu có thể thì hẳn mình cũng sẽ nhắm tới đúng toolchain gốc. Đây là một câu hỏi mang tính triết học khá thú vị
Với tư cách là nhà phát triển còn sống sót cuối cùng của eqclassic, mình đọc rất hứng thú, nhưng vẫn mong có một câu chuyện sâu hơn về cách họ dùng công cụ và toàn bộ quy trình diễn ra ra sao. Dù vậy đây vẫn là một bài viết hay
Khi đó chưa có LLM, nhưng có vài debug symbol còn sót lại trong binary PowerPC của 3 năm sau nên cũng giúp được đôi chút
Những tên tệp như packet_handler hay entitylist nghe quen một cách kỳ lạ :D
Cửa ải cuối cùng là phải có mã mạng gần như hoàn hảo trước khi mài giũa phần còn lại, và mình đã đốt hàng trăm giờ vào đây rồi
Mình chỉ lướt qua mã nguồn một chút thôi, nhưng có vẻ tất cả đều chạy trên TCP nên không giống như họ chồng thêm một cơ chế đảm bảo độ tin cậy riêng ở phía trên. Nếu đúng vậy thì đây là một lựa chọn khá “chậm” đối với MMO thời đó, nên khá thú vị
Nếu ai muốn thử UO thì đây vẫn là một game còn cộng đồng người chơi hoạt động. Các máy chủ bên thứ ba như UO Outlands gần với gameplay gốc hơn, nhưng theo tiêu chuẩn của những người quen MMO hiện đại thì khá khắc nghiệt
Người chơi khác có thể tới gank bạn và bạn cũng có thể mất trang bị
Hiện giờ vẫn có hơn 2500 người đang online trên máy chủ đó nên vẫn rất sôi động
Thành tựu lập trình thực sự đầu tiên của mình là làm website cho shard Ultima Online
Mình viết bằng PHP và HTML khá tệ, nhưng nó vẫn chạy suốt hơn 20 năm sau đó. Kỷ niệm đẹp thật
Mình ngạc nhiên vì quanh UO đến giờ vẫn còn một cộng đồng sôi động, và dù sao thì dự án này cũng thật sự rất ngầu
Lúc đó mình mới 12~13 tuổi, vào cuối thập niên 90 đến đầu những năm 2000. Giờ không còn nhớ tên emulator nữa nhưng rất có thể là POL
Mục tiêu của shard là làm sao giống máy chủ chính thức trước thời UO:Renaissance nhất có thể, nên bọn mình đã làm khá nhiều để nó trông và mang cảm giác như T2A
Mình học được rất nhiều, rồi sau này khi RunUO xuất hiện và ổn định hơn vào khoảng 2003, mình cũng giúp chuyển những gì đã làm trên POL sang mã C# cho RunUO, và để theo kịp thì phải học thêm rất nhiều
Những người mình làm cùng trên shard đó đều đang học khoa học máy tính ở đại học hoặc đã là lập trình viên rồi, còn mình chỉ là một đứa nhóc biết viết vài script
Mình xem trải nghiệm đó là yếu tố quyết định để sau này trở thành dân chuyên nghiệp. Công việc đầu tiên ở một công ty công nghệ thật sự của mình cũng là nhờ một trong số họ giới thiệu khi có vị trí thực tập
Theo một nghĩa nào đó, chính UO và các shard private đã tạo ra sự nghiệp của mình như bây giờ
Mình bắt đầu lập trình hoàn toàn vì nhu cầu thực tế
Mình quên tên game rồi, nhưng hình như là City of Heroes, đã đóng cửa nhiều năm rồi mà một ngày nào đó lại có người dựng lại máy chủ private
Cả những game online Shockwave ngày xưa cũng có các cộng đồng ngách đang dựng lại máy chủ, làm runtime Shockwave và cả decompiler
Vì cùng giải những bài toán tương tự nên cộng đồng giữa các game cũng chồng lấn lên nhau ;)
Việc thứ hai là sửa bản đồ, như xóa vật thể tĩnh, thêm đảo mới và công trình mới
Việc thứ ba là chỉnh verdata.mul để thêm animation mới và đồ họa vật phẩm mới
Chính nhờ chơi Ultima Online trên máy chủ POL không chính thức mà theo đúng nghĩa đen mình bước vào ngành IT. Trước đó mình đang học để làm kế toán
Nhờ đó mà lần đầu mình bước vào IRC, rồi sau này lan sang cả freenode
Cộng đồng emulator UO đã dẫn mình đến với lập trình mạng
Mình chưa từng thấy một game online nào khác nắm bắt được nhiều cơ chế gameplay phụ trợ, emergent và tình cờ đến vậy
Có vẻ như các MMO 3D về sau đã hạ thấp rất nhiều những yếu tố kinh tế, xây dựng và khám phá thú vị mà UO từng mang lại
PvP hay các dạng nhiệm vụ thì có thể những game khác làm tốt hơn, nhưng UO vẫn rất cuốn hút và bạn có thể tự nhiên chuyển đổi giữa chơi một mình, chơi theo nhóm, hoặc tương tác nhẹ với người lạ tùy theo tâm trạng
Phần lớn mọi người không muốn kiểu này mà thích được đặt trên đường ray định sẵn hơn
Và hai nhóm bị thu hút nhất bởi kiểu game này lại rơi vào một động lực mà nếu có nhóm này thì nhóm kia sẽ rời game. Trong khi đó nhóm thứ hai lại cần nhóm thứ nhất phải chơi
Ví dụ như Asheron's Call có cộng đồng mod rất sôi động và giờ cũng có cả cộng đồng emulator. Chỉ là độ nổi tiếng của máy chủ có vẻ không bằng UO
Shadowbane thì rất nặng về guild, nhưng cũng có cái thú của việc hơi sống ngoài vòng pháp luật một chút rồi PvP với người hay guild bất kỳ
Ngoài WoW, Old School RuneScape và Final Fantasy Online thì không có quá nhiều thứ thật sự đáng chơi
Mình rất ấn tượng với đoạn nói rằng sau 10 năm làm dự án này một cách ngắt quãng, gần đây nhờ tiến bộ của LLM mà cuối cùng họ cũng hoàn thành được một công việc từng tưởng như không có hồi kết
Mình cũng đang làm một dự án decompile MFC C++, và LLM hữu ích đến mức khó tin trong kiểu công việc này
Ngày trước mình từng rất thích Ultima Online
Gần đây mình đang vui vẻ với việc viết script Python trong client game TazUO. Dù là một phiên bản Python 3 hơi cũ, nhưng vẫn tốt hơn nhiều so với viết script trong Razor hay SteamUO
Nếu muốn thử đủ thứ trên một shard yên tĩnh kiểu chơi đơn thì Memento khá ổn
Mình từng tìm bản mobile đã được bản địa hóa sang tiếng Tây Ban Nha hoặc tiếng Pháp của Ultima 4 bản NES. Các phần khác cũng vậy
Mình muốn nó được xử lý kiểu như Pixel Remaster của series FF
Hiện tại chỉ có thể chơi bằng emulator
Những game nhập vai bản địa hóa có nhiều văn bản như vậy là cách rất dễ để “học ngoại ngữ khi chơi”, đồng thời cũng rất tốt để luyện đọc
Sẽ thật hay nếu có ai làm những thứ như vậy
À, UO… đúng là cả một trời kỷ niệm. Mình còn nhớ hồi chưa đủ tuổi để có thẻ, đã đạp xe tới Cybersmith ở Palo Alto để mua thời gian trả trước
Hồi đó mình chơi khá chăm trên shard Napa Valley. Không đủ can đảm để sang Catskills
Giờ thì mình nhớ trải nghiệm kiểu UO, nhưng thật sự không còn thời gian để dồn vào những game như thế nữa