ゲームオーバーのないゲームを作る:終わりをなくすと何が起きるか
遊びをつくる執筆にClaudeを使用しています。

ミスをしても終了しないゲームを作る場面を考えてみます。落ちてくるものを逃しても、体力は減らず、画面が暗転することもありません。遊ぶ人は好きなときに始めて、好きなときにやめます。このとき遊びは、終わりがないぶん長く続くのでしょうか。それとも、緊張が消えて早く飽きるのでしょうか。 この問いは、頭の中で考えると両方の答えがもっともらしく見えます。「失敗がないから安心して続けられる」とも「失敗がないから目的が曖昧になる」とも言えるためです。決着をつけるには、同じゲームの「終わりあり版」と「終わりなし版」を用意し、人に遊んでもらって比べるしかありません。 この記事は、その比較実験の設計書です。結果は書きません。準備するもの、40行弱の試作コード、記録の取り方、結果の読み方、誤りやすい点を順に示します。自分で行えば、自分のゲームに当てはまる答えが出る形にしています。
「終わりをなくす」を分解して、問いを一つに絞る
「ゲームオーバーをなくす」には、少なくとも三つの別々の操作が含まれています。
- 強制終了をなくす(体力が尽きても画面が止まらない)
- 減点をなくす(ミスをしても数字が下がらない)
- ミスの見え方をなくす(失敗したと伝える演出自体を消す)
三つを一度に変えると、結果が出ても原因が分かりません。この実験では一つ目の強制終了だけを外し、他は固定します。
置く問いは次の二つです。
- 強制終了がないと、遊ぶ人が自分から止めるまでの時間はどう変わるか
- 遊ぶ人は、やめるときに何を理由に挙げるか
二つ目が重要です。時間の長短だけでは「続いた理由」は分かりません。やめた理由の言葉を集めることで、遊びを支えていたものが緊張なのか、手触りなのか、見た目の変化なのかを探ります。
公式作品に、終わりの作りを見比べる材料があります。「余白の庭」は時間制限なしの庭づくりで、戻す/やり直すがあり、置けるのは最大80個です。「こだまの森」は間違いが3回で終了します。「かたちのあいだ」は一手戻すを使っても手数が減りません。作品を開き、終わりの条件や失敗の扱いがどこに置かれているかを見てから試作に入ると、自分の設計の位置づけが見えやすくなります。どの作品がどう作られているかは、実際に開いて確かめてください。
準備するもの
次のものを用意します。
- 試作ファイル1つ(次の節のコード)
- 遊んでもらう人:最低4人。順序の入れ替えで2人ずつに分けられる人数です
- 記録用紙(紙でも表計算でも構いません)
- 時計(スマートフォンのストップウォッチで十分です)
- 1セッションの上限時間:10分を目安にします
遊ぶ人は、そのゲームを初めて見る人が理想です。作者本人が遊ぶと、仕様を知っているぶん結果がゆがみます。
試作:A版とB版を1つのファイルで作る
落ちてくる光の粒をクリックで拾うだけの最小のゲームです。冒頭の ENDLESS を切り替えると版が変わります。
- A版(false):粒を3回地面まで逃すと終了します
- B版(true):逃した粒は地面に小さな灯りとして残り、終了しません
B版では、逃したことが「罰」ではなく「地面に残る風景」に変わります。ただし、この仕掛けはB版の差を二重にします。終了がないことに加えて、見た目の変化も加わるためです。後述の「起こりやすい誤り」で、この点の扱いを説明します。
<!doctype html>
<meta charset="utf-8">
<canvas id="c" width="480" height="320" style="background:#123"></canvas>
<pre id="log"></pre>
<script>
const ENDLESS = true; // false なら3回逃したら終了
const c = document.getElementById("c"), g = c.getContext("2d");
let drops = [], lamps = [], miss = 0, taps = 0, got = 0, over = false;
const t0 = performance.now(), sec = () => Math.round((performance.now() - t0) / 1000);
setInterval(() => { if (!over) drops.push({ x: 20 + Math.random() * 440, y: 0, v: 40 + Math.random() * 40 }); }, 900);
c.onpointerdown = e => {
if (over) return;
const r = c.getBoundingClientRect(), n = drops.length;
const px = (e.clientX - r.left) * 480 / r.width, py = (e.clientY - r.top) * 320 / r.height;
drops = drops.filter(d => Math.hypot(d.x - px, d.y - py) > 24);
taps++; got += n - drops.length;
};
let last = performance.now();
function loop(now) {
const dt = (now - last) / 1000; last = now;
g.clearRect(0, 0, 480, 320);
for (const d of drops) d.y += d.v * dt;
drops = drops.filter(d => {
if (d.y < 310) return true;
if (ENDLESS) lamps.push(d.x); else if (++miss >= 3) over = true;
return false;
});
g.fillStyle = "#fd8";
for (const d of drops) { g.beginPath(); g.arc(d.x, d.y, 10, 0, 7); g.fill(); }
g.fillStyle = "#a96";
for (const x of lamps) g.fillRect(x - 2, 312, 4, 6);
document.getElementById("log").textContent =
`版:${ENDLESS ? "B(終わりなし)" : "A(3回で終了)"} 経過:${sec()}秒 タップ:${taps} 拾った:${got} 逃した:${ENDLESS ? lamps.length : miss}` + (over ? " 終了" : "");
if (!over) requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
</script>画面下の pre には経過秒、タップ数、拾った数、逃した数が出ます。これは観察者用の記録なので、遊ぶ人に見えると行動が変わります。遊んでもらう間は <pre id="log" hidden> のように hidden を付けて隠し、終了時に外して数字を読み取ってください。記録はこの画面の表示だけで、保存はされません。読み取る前にタブを閉じないよう気をつけます。
手順と記録の取り方
割り当てと順序
全員がA版とB版の両方を遊びます。半数がA→B、残り半数がB→Aの順にします。順序を入れ替えるのは、先に遊んだ版のほうが新鮮さのぶん長く遊ばれやすい、という影響を打ち消すためです。
1セッションの進め方
- 遊び方は一言だけ伝えます。「光の粒をクリックで拾うゲームです。やめたいときはいつでもやめてください」
- ストップウォッチを開始します。
- 遊ぶ人が自分で「やめます」と言うか、10分に達するまで待ちます。10分に達した場合は「ここまでで大丈夫です」と伝え、上限到達と記録します。
- 終了後すぐに hidden を外し、数字を書き写します。
- 次の質問を一度だけします。「やめようと思ったとき、何を考えていましたか」。答えは言葉のまま書き取ります。
記録する項目
- 版、単位:A/B、取り方:割り当て順
- 遊んだ時間、単位:秒、取り方:画面の経過秒
- タップ数、単位:回、取り方:画面の表示
- 拾った数、単位:個、取り方:画面の表示
- 逃した数、単位:個、取り方:画面の表示
- 終わり方、単位:自発/強制/上限、取り方:観察者が判定
- やめた理由、単位:言葉のまま、取り方:質問への答え
- 続けて遊ぶか、単位:はい/いいえ、取り方:次の質問
A版は3回逃すと強制的に終わります。強制終了のあとで「もう一度遊びますか」と聞き、遊ぶなら再読み込みして再開してもらってください。再挑戦した回数も記録します。こうしておくと、A版でも「自分から続けたい気持ち」を測れます。
結果の読み方
数字が揃ったら、まず版ごとに一人ずつの差を見ます。人数が少ないので平均の差よりも、全員が同じ方向に動いたかどうかを重視します。以下は、出た結果の組み合わせごとの解釈の指針です。
- B版の時間が長く、やめた理由が「満足した」「きりがいい」:終わりの不在が、自分のペースでの区切りを許したと読めます。
- B版の時間が長く、やめた理由が「なんとなく」「いつまでも終わらないので」:続いたのではなく、やめどきを見失った可能性があります。目標や区切りの設計が必要かもしれません。
- B版の時間が短く、やめた理由が「張り合いがない」「何を目指すのか分からない」:強制終了が目標の輪郭を作っていたと読めます。
- 時間は近いが、1秒あたりのタップ数がB版で少ない:切迫感が下がり、操作が丁寧になった、または注意が離れた、のどちらかです。やめた理由の言葉で見分けます。
- A版で再挑戦が多い:失敗が「もう一回」を生んでいます。B版には、これに相当する動機が別に必要になります。
- 地面の灯りに言及する人がいる:続いた理由が失敗の有無ではなく、見た目の変化にあった可能性があります。
どの読みでも、一回の実験で結論を固めないでください。人数を増やすか、同じ人に日を改めて遊んでもらうと、読みの確からしさが上がります。
起こりやすい誤り
差が二重になっている。 B版は終了がないだけでなく、逃した粒が灯りとして残ります。時間が伸びても、終了がないからか灯りが楽しいからかは分かりません。切り分けるには、灯りを描かないC版を追加します。lamps.push(d.x) を lamps.length++ のような記録だけの処理に変えれば、見た目は変わらないまま終わりだけを外せます。
A版が強制終了で短くなる。 3回逃せば必ず終わるので、A版の時間は構造的に短くなります。時間の長さだけで比べると、B版が有利に見えて当然です。比べるのは、自発的な継続の意思です。再挑戦の回数と、やめた理由の言葉を見ます。
ログが見えている。 逃した数が画面に出ていると、B版でも失敗を意識して遊びます。hidden を外すのは終了後だけにしてください。
質問が誘導になる。 「楽しかったですか」と聞くと、肯定の答えが返りやすくなります。「やめようと思ったとき、何を考えていましたか」のように、行動を思い出してもらう形にします。
作者が説明しすぎる。 「この版は終わりがありません」と先に伝えると、終わりを意識して遊びます。遊び方の説明は、版を問わず同じ一言にします。
上限で打ち切って、自発の記録を失う。 10分で切ると、それ以上遊びたかった人の意思が見えなくなります。上限に達した人が多いなら、上限を延ばして日を改めるか、「上限到達」の件数そのものを結果として読みます。
次の行動
まず上のコードを保存し、自分で一度だけ両方の版を遊んでみてください。ただし、自分の体感は参考にとどめます。次に、まだこのゲームを見たことのない人を4人探し、順序を入れ替えながら、記録用紙のとおりに1セッションずつ進めます。結果が出たら、数字よりも「やめた理由」の言葉を先に読み、自分のゲームで続けたい気持ちを支えているものが何かを書き出してみてください。

