ニュース

Nix 導出でスーパーマリオブラザーズ3をプレイする

開発者がNixの遅延評価をプレイ可能なNESエミュレータに変えた。各ボタン押下が導出となり、ストアがセーブ状態の履歴となる。

August 15, 2026· 1 min read· 出典: Farid Zakaria’s Blog
Nix 導出でスーパーマリオブラザーズ3をプレイする

Nixの遅延性は両刃の剣だ。Nixpkgsを可能にする再帰的属性セットを支える一方、触れた属性だけが評価されることを意味する。開発者のfzakariaはこれを論理的な極限まで押し進め、属性パスをスーパーマリオブラザーズ3のボタン押下の連続に変えた。ツリーの各ノードがゲームの1フレームとなる。

核となるトリックは、各ボタン押下が独自の導出であり、前の押下のセーブ状態を入力として取ることだ。つまり、Nixストアがエミュレータのセーブ状態の履歴になる。100回押下した途中から分岐するのも、末尾に追加するのも1押下で済む。依存グラフ入力シーケンスそのものなので、Nixに問い合わせれば、どのボタンがどのフレームを生成したかを正確に確認できる。

.play属性はほぼノーオペレーションだ。パス上のすべてのフレームはすでにストアにあるため、録画は何も再エミュレートしない。フレームへのシンボリックリンクのディレクトリに過ぎず、ffmpegで連結する準備ができている。

これはどこまで行けるのか?Nixのデフォルトのmax-call-depthは10,000で、約2,400回の押下で限界に達する。しかし、ulimit -s unlimitedで10,000,000に引き上げると、約14秒で20,000回の押下が可能になる——1押下あたり約0.7ms。次のボトルネックはカーネルのargv制限で、作者のマシンでは21,845回の押下で上限に達する。

このプロジェクト、fzakaria/nes-nixは一般化されている。ROMはフレーク入力なので、任意のNESゲームを指定できる。遅延性とコンテンツアドレス型ストレージが、純粋関数型の方法で状態を持つ計算をモデル化できることを示す、楽しいデモンストレーションだ。

依存グラフは入力シーケンスそのものなので、どのボタンがフレームを生成したかをNixに問い合わせることができる。
Manul X 編集部