Pokémon Emerald là một tựa game kinh điển đã gắn liền với tuổi thơ của nhiều thế hệ game thủ Việt Nam. Nỗi nhớ về những cuộc phiêu lưu, bắt Pokémon, và khám phá vùng đất Hoenn vẫn còn đọng lại mạnh mẽ. Điều thú vị là, ngày nay, cộng đồng modding game Pokémon cũ vẫn hoạt động vô cùng sôi nổi, liên tục tạo ra những bản sửa đổi (mod) thú vị, kéo dài vòng đời của chúng. Tuy nhiên, ít ai có thể ngờ rằng, cảnh modding này còn mở ra một khả năng hoàn toàn mới: lưu trữ một file dữ liệu bên trong chính trò chơi Pokémon Emerald! Cụ thể, bạn có thể lưu trữ một file có dung lượng lên đến 10.8 KB, và điều này đã được kiểm chứng qua dự án mon-fs đầy sáng tạo.
Để hiểu rõ hơn về khả năng phi thường này, hãy nhớ lại cách máy tính của bạn hoạt động. Khi bạn mở một file, dù là tài liệu văn bản, hình ảnh, hay thậm chí trang web này, bạn đang tương tác với một tập hợp các cấu trúc dữ liệu mà máy tính của bạn biết cách diễn giải để hiển thị thông tin mong muốn. Ví dụ, với một trang web, bạn có thể xem mã nguồn để thấy các thẻ HTML mà trình duyệt đọc và hiển thị. Tương tự, máy tính hiểu dữ liệu trong một file JPG để hiển thị hình ảnh.
Khái niệm này mở rộng ra một chân lý đơn giản: bất cứ thứ gì đều có thể hoạt động như một “vật chứa” file, miễn là có một cách thức có cấu trúc để dữ liệu có thể được lưu và truy xuất về sau. Đó chính là lý do tại sao việc lưu trữ dữ liệu trong Pokémon Emerald trở thành hiện thực, và tất cả là nhờ vào mon-fs – một công cụ độc đáo mã hóa dữ liệu của bạn thành chính những con Pokémon! Mặc dù quy trình này khá chậm và phức tạp, đây lại là một cách vô cùng thú vị để minh họa cách dữ liệu được lưu trữ và làm thế nào mà thực tế bất kỳ thứ gì cũng có thể được dùng làm phương tiện lưu trữ.
Pokémon Emerald Chứa Dữ Liệu Như Thế Nào?
68 Bit Dữ Liệu Cho Mỗi Pokémon
Màn hình PC trong Pokémon Emerald hiển thị các Pokémon đã được "tiêm" dữ liệu bằng mon-fs
Hãy nhìn vào hình ảnh trên, được chụp từ quá trình mã hóa một file vào file save của Pokémon Emerald. Bản thân Pokémon, biệt danh của nó, giới tính, OT (Original Trainer – người huấn luyện gốc), các dải băng (ribbons), loại bóng dùng để bắt, và điểm kinh nghiệm – tất cả đều là những giá trị mà người chơi có thể thay đổi. Và đó chính xác là cách mon-fs hoạt động. Công cụ này cung cấp hai chế độ chính: “Full” (Toàn phần) và “Lite” (Tối giản).
- Chế độ Lite: Cho phép lưu trữ một file có dung lượng lên tới 3.2 KB. Điều đặc biệt là bạn có thể bắt và đặt tên cho mỗi Pokémon mà không cần bất kỳ công cụ bên ngoài nào khác, làm cho việc này trở nên dễ tiếp cận hơn cho người chơi thông thường.
- Chế độ Full: Nâng giới hạn lưu trữ lên tới 10.8 KB, tuy nhiên, chế độ này yêu cầu bạn phải sử dụng một trình chỉnh sửa file save (save editor) để có thể hoạt động hiệu quả.
Sự khác biệt giữa hai chế độ này nằm ở lượng dữ liệu dễ dàng truy cập được bởi người dùng. Ví dụ, có tổng cộng 386 loài Pokémon trong Emerald, về mặt lý thuyết có thể mã hóa 8 bit dữ liệu. Tuy nhiên, chỉ có 202 loài có thể bắt được, và con số này còn giảm nữa khi tính đến các Pokémon chỉ có thể bắt một lần hoặc nhận qua trứng. Sau khi loại bỏ những Pokémon này và tính đến sự tiện lợi, con số này được rút gọn xuống chỉ còn bốn loài Pokémon riêng biệt, cho phép lưu trữ 2 bit dữ liệu. Bốn Pokémon này bao gồm:
- Poochyena
- Whismur
- Taillow
- Nincada
Cả bốn loài Pokémon này đều có thể tìm thấy ở Tuyến đường 116 (Route 116), và tất cả đều có tỷ lệ xuất hiện từ 20% trở lên. Chúng cũng có tỷ lệ giới tính đực/cái ngang nhau khi gặp, cung cấp thêm 1 bit dữ liệu bên cạnh 2 bit mà bản thân loài Pokémon mang lại.
Cách tiếp cận này có thể khiến bạn không lưu trữ được nhiều dữ liệu bằng chế độ Full, nhưng nó lại dễ dàng hơn đáng kể cho một người thực sự bắt những Pokémon này, đặt tên đúng cách và đưa cho chúng đúng vật phẩm để biểu thị dữ liệu. Về phần tên, biệt danh của Pokémon cung cấp 60 bit dữ liệu và sử dụng mọi ký tự tiếng Anh cùng hầu hết các ký hiệu. Dấu cách được loại trừ để việc nhập tên thủ công dễ dàng hơn. Cuối cùng, vật phẩm giữ (held items) cung cấp 5 bit dữ liệu, vì có 32 vật phẩm có thể mua rẻ trong game và đưa cho Pokémon giữ.
Tổng hợp lại, chúng ta có các điểm dữ liệu sau cho mỗi Pokémon:
- Loài (Species): 2 bit
- Tên (Name): 60 bit
- Giới tính (Gender): 1 bit
- Vật phẩm giữ (Item Held): 5 bit
Điều này mang lại tổng cộng 68 bit dữ liệu cho mỗi Pokémon. Với 419 ô trống có sẵn (ô cuối cùng cần dùng để đệm), chúng ta có tổng cộng 28488 bit dữ liệu khả dụng, tương đương với 3.561 KB.
Quy Trình Mã Hóa File Thành Pokémon: Thử Nghiệm Thực Tế
Giao diện website mon-fs khi tạo danh sách Pokémon cần thiết để mã hóa dữ liệu ở chế độ Lite
Có một tiện ích web đi kèm với mon-fs sẽ nhận một file và hiển thị cho bạn những Pokémon cần thiết, vật phẩm cần đưa cho chúng và tên để đặt. Bạn có thể lưu một file “pc.json” để phác thảo những yêu cầu này, và file này có thể được tải lên lại cùng trang web để nhận lại file đầu ra. Như bạn có thể thấy ở hình ảnh trên, nó đưa ra các yêu cầu sau:
- Poochyena: Giới tính đực, không giữ vật phẩm, tên “baaaaaaaaa”
- Nincada: Giới tính đực, giữ X Accuracy, tên “aaaaaaaaaa”
- Poochyena: Giới tính đực, giữ Full Heal, tên “aaaaaaaaaa”
- Nincada: Giới tính cái, giữ Awakening, tên “g6n?Gizsvr”
- Whismur: Giới tính đực, không giữ vật phẩm, tên “pRh/vBaCaa”
- Poochyena: Giới tính đực, giữ Revive, tên “aaaaaaiwg6”
- Whismur: Giới tính cái, không giữ vật phẩm, tên “qBcxefviaa”
Vậy, giả sử tôi đã bắt được tất cả những Pokémon này, điều gì sẽ xảy ra tiếp theo? Làm thế nào để ai đó có thể lấy thông tin này, chuyển cho người khác và nhờ họ giải mã? Họ có thể sử dụng công cụ mon-fs đọc dữ liệu từ ảnh chụp màn hình bằng công nghệ OCR để xuất ra một file pc.json, hoặc người dùng khác có thể tải file save của bạn lên, nhập thủ công các chi tiết vào trang web và giải mã ngay tại đó.
Giao diện website mon-fs để giải mã hộp PC Pokémon từ dữ liệu nhập vào
Dù bằng cách nào, bạn cũng sẽ phải trải qua quá trình tái tạo file một cách tỉ mỉ. Chưa kể đến việc đi bắt Pokémon cũng sẽ mất một khoảng thời gian đáng kể, vì vậy đây không phải là một cách thực tế để truyền tải file cho người khác.
Có một số hạn chế được áp dụng để làm cho việc này dễ dàng hơn cho một người “bình thường” thực hiện trong game với các công cụ có sẵn. Tuy nhiên, chế độ “Full” nâng cao đáng kể khả năng lưu trữ. Ở chế độ này, dung lượng lưu trữ tăng lên 211 bit cho mỗi Pokémon, tương đương khoảng 11.05 KB. Tài liệu trên kho lưu trữ GitHub không nêu rõ lý do, nhưng chế độ “Full” trên trang web mon-fs khẳng định rằng các file dưới 10.8 KB được đảm bảo hoạt động. Điều này có thể liên quan đến các giá trị đệm một lần nữa, mặc dù không được giải thích chi tiết.
Tôi đã thử nghiệm với một bản mon-fs được xây dựng cục bộ để chèn Pokémon và đọc chúng trở lại từ file save game, và mặc dù quá trình chèn hoạt động, việc đọc lại thì không. Chương trình không đọc được luồng dữ liệu từ file save, và tôi cũng không thể làm cho công cụ đọc ảnh chụp màn hình bằng OCR và chuyển đổi chúng theo cách đó hoạt động. Tuy nhiên, việc nhập thủ công trên trang web mon-fs lại hoạt động, và một người thực sự tận tâm với việc chuyển file qua Pokémon có thể làm điều đó một cách thủ công.
Tính Ứng Dụng Và Ý Nghĩa Của Dự Án mon-fs
Các khối len nhiều màu trong Minecraft, minh họa khả năng lưu trữ dữ liệu
Mặc dù dự án mon-fs này chắc chắn không thực tế cho hầu hết mọi người, nhưng nó vẫn là một ý tưởng vô cùng thú vị. Bất kỳ trò chơi nào cho phép người dùng kiểm soát dữ liệu đều có thể được sử dụng theo cách này. Chúng ta đã thấy các kỹ thuật tương tự cho phép thực thi mã tùy ý trong nhiều trò chơi trước đây, bao gồm cả Pokémon Diamond và Pearl. Đương nhiên, những kỹ thuật đó phức tạp hơn đáng kể so với việc chỉ tạo ra một cấu trúc được nhận dạng từ dữ liệu người dùng và diễn giải nó từ bên ngoài giới hạn của trò chơi.
Toàn bộ dự án này vừa điên rồ, vừa thú vị, và nó có thể dạy bạn rất nhiều về cấu trúc dữ liệu và cách bất cứ thứ gì cũng có thể là một phần của cấu trúc dữ liệu nếu bạn có thể kiểm soát thứ tự và một số tham số của các mục được sử dụng để xây dựng mỗi “khối” dữ liệu. Để kết thúc với một ví dụ khác dễ hình dung hơn, bạn có thể làm điều này trong một trò chơi như Minecraft. Có 16 màu len trong Minecraft, và bạn có thể ánh xạ 0-F (hệ thập lục phân) cho những màu đó. Với log_2 của 16, chúng ta sẽ nhận được 4 bit lưu trữ cho mỗi khối len. Chỉ với 100 khối, bạn có thể biểu diễn 0.05 KB dữ liệu; con số này không nhiều, nhưng nó là một khái niệm tương tự với việc lưu trữ dữ liệu trong Pokémon Emerald. Một khối len trắng có thể biểu thị 0000, len xám nhạt 0001, v.v.
Nếu bạn quan tâm đến việc thử nghiệm dự án độc đáo này, hãy ghé thăm kho lưu trữ mon-fs trên GitHub và xem qua trang web mon-fs. Cả hai nguồn này sẽ hướng dẫn bạn cách thiết lập và cấu hình, đồng thời có thể mang đến cho bạn những ý tưởng mới về những nơi kỳ lạ khác mà bạn có thể lưu trữ dữ liệu, ẩn mình ngay trước mắt.