Rustとwasmでスネークゲームを作りました

wasmを触りたかったのでwasmとRustを組み合わせた簡単なゲームを作りました

以下の記事を参考に実装しました(ほぼ写経) 🙏

https://medium.com/@geekrodion/snake-game-with-rust-javascript-and-webassembly-5e22b357ec7b

k8sにデモ用の静的ファイル配信Podもつくってデモも配置しました

コードはこちらに置いてあります

学んだこと

  • 最新のMIMEタイプの中にはまだwasmは存在していない
    • wasmファイルをnginxがブラウザにresponseするとき、 Content-Type: application/octet-stream としてresponseされる
    • そのためchromeだと「bootstrap.js:5 Error importing index.js: TypeError: Failed to execute ‘compile’ on ‘WebAssembly’: Incorrect response MIME type. Expected ‘application/wasm’.」と怒られる
    • nginx.confで対応できる
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
+   types {
+      application/wasm wasm;
+   }
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
  • wasmにはGCがないらしく、wasmのモジュールを簡単に出力できるのはC, C++, Rustぐらいらしい
  • wasmとRustについて
    • #[wasm_bindgen]でだいたいのRustの変数が渡せる
    • Rustでの想定する引数がOption<string> だった場合はundefinedやnullを渡せる
    • Rustのコードを修正した際、Rustコードのビルド→npmパッケージ再インストール→webpackビルドが必要なためPDCAがとても回しにくい
    • 長時間起動し続けるとセグメントエラーが出る(このゲームの実装が悪いと思われる)
    • Rustのエラー情報がjs側でほとんど表示されない(下記画像参照)
    • console_error_panic_hookクレートを使うことでより詳細な情報を表示することができる(下記画像参照)
  • 今回のゲームについて
    • 数学の知識が必要になって詰まった
      • パート8でのプレイヤーの頭部の射影をとってそれがプレイヤーの胴体(セグメント)に含まれるかどうかという実装(ゲームオーバーの判定)
  • その他
    • x.hypot(y) は (x^2+y^2)^(1/2) と同値
Rust  wasm  tech 

See also