Flappy Bird

Flappy Bird là một hiện tượng trong làng game indie vào năm 2013. Mặc dù lối chơi đơn giản nhưng dễ gây nghiện và ức chế, có phần giống với series Dark Souls của From Software, nên mặc dù đã bị chính tác giả Nguyễn Hà Đông khai tử nhưng Flappy Bird vẫn để lại nhiều ảnh hưởng trong làng game.Một năm sau đó (2014), nó được một người ngoại quốc port sang hệ máy 8 bit của Nintendō là NES (Famicom/FC). Phiên bản này có lối chơi cũng tương tự như bản gốc trên điện thoại.

Phiên bản nhái của Flappy Bird này cũng xuất hiện dưới dạng băng vật lý, được kê giá 45 USD trên ebay. Đến năm 2022, chúng ta lại thấy một phiên bản băng vật lý khác được người Việt Nam sản xuất.

Tác giả của băng này là anh Huỳnh Hữu Ân trong hội người yêu thích game cổ (Retro Gaming Group). Anh là người Việt đầu tiên chế thành công các dòng băng Famicom/FC (NES) và Super Famicom/SFC (SNES) dựa trên mạch của băng gốc của Nintendō. Ta có thể cắm băng này vào máy Famicom/NES thật và chơi bình thường. Nội dung bên trong cũng chính là Rom do Nioreh code lại từ ý tưởng của Nguyễn Hà Đông.Điều đặc biệt ở cuốn băng này chính là dòng chữ "Cuốn băng này của Nguyễn Ngọc Phục" được viết bằng tiếng Việt ở màn hình khởi động của game. Anh Nguyễn Ngọc Phục trong nhóm game cổ đã đặt hàng anh Hữu Ân chế tác phiên bản vật lý với dòng chữ trên, vốn được thay thế từ dòng chữ của Nioreh.

Có thể coi như đây là một phiên bản "Việt hóa" của Flappy Bird mặc dù game này không có lời thoại, và tác giả của nó cũng là người Việt. Điều khiến tôi chú ý chính là dòng chữ tiếng Việt. Do đại đa số game Famicom/NES sử dụng font chữ là mảng (tile) có kích thước 8 x 8 pixel nên không thể vẽ dấu tiếng Việt một cách trọn vẹn được. Hầu hết các bản game Famicom/NES được dịch trước đây đều không vượt khỏi hạn chế này. Người dịch thường cố vẽ lại phần chữ và dấu tiếng Việt một cách khiên cưỡng trong ô vuông 8 x 8 nói trên. Đây là vấn đề đặc hữu của ngôn ngữ Việt mà hacker các nước khác không gặp phải.Tuy nhiên ta vẫn có thể giải quyết vấn đề bằng kiến thức về phần cứng của máy, cũng như kiến thức về ngôn ngữ Assembly của nó.

Tôi thử nhìn vào cấu trúc của game này bằng cách debug thì thấy game rất đơn giản. Memory của game chỉ gồm có 2 phần là PRG ROM chứa nội dung chương trình, và phần còn lại là CHR ROM chứa đồ họa trong game. Đồ họa của game này chỉ gồm sprite của con chim, một vài ống cống và một bộ font chữ.Tôi đã thử code lại dòng chữ trên chứ không "vẽ tay" như cách truyền thống. Ý niệm rất đơn giản. Một dòng để thể hiện phần chữ chính, và một dòng ngay phía trên nó thể hiện các dấu tiếng Việt nằm trên chữ cái như dấu sắc, huyền, hỏi, ngã, mũ, móc,... và một dòng nằm ngay dưới phần chữ chính để thể hiện dấu nặng. Với cách này, mỗi hàng chữ chiếm 3 dòng, gấp 3 lần so với cách vẽ nhồi nhét dấu vào trong 1 ô 8 x 8 pixel, nhưng kết quả thật mãn nhãn. 

Ý tưởng cũng rất đơn giản. Tìm thời điểm khi game đang định dạng ban đầu để chèn vào routine vẽ chữ này, sau đó nhảy đến routine chính. Đối với mỗi byte tương đương với một chữ cái, ta sẽ kiểm tra xem đó có phải là chữ cái có dấu không. Nếu là chữ cái có dấu thì sẽ được vẽ thêm dấu bên trên và bên dưới. Nếu chữ cái chỉ có một phần dấu bên trên (ấ, ầ, ẳ, ũ,...) hoặc một phần dấu bên dưới (ạ, ị, ẹ, ọ) thì vẫn vẽ đủ cả 3 dòng, nhưng dòng nào không có dấu thì vẽ ô trắng. Tuy nhiên cái game Flappy Bird này cực kỳ đơn giản, con chữ trên màn hình chỉ là một ma trận các mảng (tile) trong Nametable (Tile-map của NES) nên cách làm còn đơn giản hơn. Chỉ cần bố trí các tile tương ứng với ký tự lên màn hình là được. 

Kết lại bài này bằng một ý kiến lạc đề.Phần cứng ngày nay phát triển rất nhanh, cộng với sự ra đời của nhiều ngôn ngữ bậc cao giúp cho lập trình viên làm việc nhanh hơn trước rất nhiều. Tuy nhiên nó cũng có mặt trái là khiến cho người ta không còn hiểu được bản chất của vấn đề nữa. Ngay cả việc gõ bàn phím, chuyện rất đơn giản, nhưng không phải ai cũng hiểu rõ bản chất của nó. Người ta mặc định rằng khi gõ phím chữ "a" thì trên màn hình sẽ hiện ra chữ "a" tương ứng mà không hiểu tại sao lại như vậy. Đó cũng là lý do khiến ta rất hay gặp những câu hỏi trong làng dịch/Việt hóa game Việt là: tại sao tôi gõ dấu tiếng Việt nhưng trong game lại không hiển thị được dấu. Cốt lõi nằm ở chỗ anh có hiểu được bản chất của vấn đề hay không. Những người hỏi câu trên đều là người không hiểu bản chất của vấn đề. Chỉ biết nếu làm như vầy thì sẽ ra như vầy mà không hiểu tại sao lại như vậy. Những người chuyên sâu vào phần cứng và ngôn ngữ bậc thấp như Assembly sẽ tránh được những lỗi cốt lõi như vậy. 

Tôi sẽ đề cập đến kỹ thuật trình bày dấu tiếng Việt cho game Famicom/NES trong những bài viết khác.