Lab
EdenCodeのコンセプトは「のっぱらから楽園を作る神様の真似事」だ。抽象的に見えて、実はゲームのストーリーとして読んでも違和感がない。それに気づいたとき、ちょっとした実験をしたくなった。
このコンセプトを、プレイヤーが直接体験できるショートRPGとして作ったらどうなるか。プレイ時間は5〜10分。難しすぎない。死なない設計。そして最後はちょっといい話になってる——そういうゲームを、1枚のHTMLファイルで作り切ることにした。
主役はエデニー(Edeny)、自称勇者で金の亡者。相棒はクラナ(Clana)、AIエルフでツッコミ専門。なんだかんだ二人でボスを倒して、気づいたら英雄になってた——というコンセプト。ゲームのタイトルは「Edeny Arcadia」〜のっぱらに楽園を〜。
最初に「骨格」から作ることにした。見た目を後回しにして、まず動く仕組みを完成させる。
20×24タイルのフィールドマップ、カメラ追従、壁判定、ターン制バトル——これらをCanvasとJavaScriptだけで組んだ。この段階でもっとも重要な判断を下した。全インタラクションを1つの関数 runScript() に統一することだ。
なぜこれが「最大の正解」だったか。ゲームの中に出てくるあらゆる会話・演出は、「テキストを1行ずつ表示して、終わったら次の処理を呼ぶ」という同じパターンに帰着する。それを1つの仕組みに収めておけば、後でNPCを追加するときも、バトルのエンディングを変えるときも、同じ場所を触るだけで済む。
骨格が動いたら「味付け」の段階へ。BGM・効果音・パーティクル・状況対応のNPCセリフを追加した。
BGMはWebAudioAPIで完全に自作した。ライブラリは使っていない。音符データの配列をルックアヘッドスケジューラ(80msインターバル・0.3秒先読み)で鳴らす仕組みで、フィールド曲・バトル曲それぞれを用意した。SEも同様にbeep()関数1本で全種類を合成している。
NPCのセリフはゲームの進行状況によって変わる。getLines()関数を使って、ボス出現前・バトル中・撃破後の3パターンを自動で切り替える設計にした。同じNPCがゲームの状態を反映して話す——これだけで、世界が生きているように感じられる。
最後の「磨く」フェーズで、ゲームが一気にゲームらしくなった。
ヒット時の画面シェイク(指数関数減衰でゆっくり収まる)、sin波による歩行アニメーション(足と腕が逆位相でスイングする)、そしてタイトル画面の全面刷新。都市シルエット・山・星・流れ星・浮遊パーティクル・キャライラスト——全部Canvas 2Dだけで描いた。
if (bt.victoryIdx >= bt.victoryLines.length) return; をフェーズの冒頭に追加。配列外アクセスを根本から防ぐ。問題は「インデックスが進みすぎること」ではなく「進みすぎたとき何も止まらないこと」だった。
foff で計算して、視線の先のタイルだけを判定する。「隣にいる」ではなく「見ている方向にいる」に変えるだけで、全部の問題が消えた。
このゲームを作って気づいたことは、「最初の設計判断が後のすべてを決める」ということだった。
runScript()を最初に作ったことで、セリフを追加するコストがほぼゼロになった。タイルをT.WALLやT.PATHと定数で管理したことで、マップを読み直すときに意図が一目でわかる。BGMをルックアヘッドスケジューラで鳴らすと決めたことで、リズムのズレが起きなくなった。
どれも「そうしなくても動く」設計だ。でも「そうしたことで、後から困らない」設計でもある。ゲームを作ることは、最終的には「後から変えやすい仕組みを最初に作ること」だと思う。
WebAudioAPIはライブラリなしで使える、という発見も大きかった。音符の周波数と長さの配列さえ用意すれば、自作シンセで全曲・全SEを鳴らせる。「外部依存ゼロ」で完結したことで、配布・デプロイが圧倒的にシンプルになった。
Canvas 2Dも同様だ。Painter's algorithm(後に描いたものが手前に来る)を理解するだけで、10レイヤーを重ねた複雑なタイトル画面も、clipMaskなしで描ける。道具が複雑でなくても、道具の使い方を理解することで、できることは増える。
EdenCodeのコンセプト「のっぱらから楽園を作る神様の真似事」を、HTML1ファイルのRPGとして形にした。骨格(タイルマップ・バトル)→味付け(BGM・パーティクル・NPC)→磨く(シェイク・歩行アニメ・タイトル)の3フェーズで積み上げたことで、バグは最小限に抑えられた。
鍵になったのはrunScript()による統一管理という最初の設計判断。全インタラクションを1つの仕組みに通すことで、追加コストがほぼゼロになった。WebAudioAPI・Canvas 2D・GamepadAPIをライブラリなしで使い切った1日——エデニーは英雄になったが、作り手も少し強くなった。