Chơi Super Mario Bros. 3 với Nix Derivations
Một lập trình viên biến sự đánh giá lười biếng của Nix thành một trình giả lập NES có thể chơi được, nơi mỗi lần nhấn nút là một derivation và store trở thành lịch sử savestate.
Sự lười biếng của Nix là một con dao hai lưỡi: nó cung cấp năng lượng cho các tập hợp thuộc tính đệ quy giúp Nixpkgs có thể hoạt động, nhưng nó cũng có nghĩa là chỉ những thuộc tính bạn chạm vào mới được đánh giá. Một lập trình viên, fzakaria, đã đưa điều này đến cực điểm logic bằng cách biến một đường dẫn thuộc tính thành một chuỗi các lần nhấn nút trong Super Mario Bros. 3, với mỗi nút trong cây là một khung hình của trò chơi.
Thủ thuật cốt lõi là mỗi lần nhấn nút là một derivation riêng, lấy savestate của lần nhấn trước làm đầu vào. Điều này có nghĩa là Nix store trở thành lịch sử savestate của trình giả lập. Việc rẽ nhánh từ giữa một chuỗi trăm lần nhấn tốn một lần nhấn, cũng như việc thêm vào cuối. Đồ thị phụ thuộc là chuỗi đầu vào, vì vậy bạn có thể truy vấn Nix để xem chính xác nút nào đã tạo ra một khung hình.
Thuộc tính .play gần như là một no-op: mọi khung hình dọc theo đường dẫn đã có trong store, vì vậy bản ghi không bao giờ mô phỏng lại bất cứ điều gì. Nó chỉ là một thư mục chứa các symlink đến các khung hình, sẵn sàng cho ffmpeg ghép lại.
Điều này có thể đi xa đến đâu? max-call-depth mặc định của Nix là 10.000 sẽ cạn kiệt ở khoảng 2.400 lần nhấn, nhưng nâng nó lên 10 triệu (với ulimit -s unlimited) sẽ cho bạn 20.000 lần nhấn trong khoảng 14 giây — khoảng 0,7ms mỗi lần nhấn. Nút thắt tiếp theo là giới hạn argv của kernel, giới hạn ở 21.845 lần nhấn trên máy của tác giả.
Dự án, fzakaria/nes-nix, được tổng quát hóa: ROM là một flake input, vì vậy bạn có thể trỏ nó vào bất kỳ trò chơi NES nào. Đây là một minh chứng thú vị về cách sự lười biếng và lưu trữ nội dung định địa chỉ có thể mô hình hóa tính toán trạng thái một cách thuần hàm.
Đồ thị phụ thuộc là chuỗi đầu vào, vì vậy chúng ta có thể hỏi Nix nút nào đã tạo ra một khung hình.
Thảo luận
0 bình luận
Hãy là người đầu tiên thảo luận.