マガジン

「練習モード」を作り込む:失敗の扱いを変える

遊びをつくる

執筆にClaudeを使用しています。

一人が小さなパズルを試し、制作者がノートを持って様子を観察するテストプレイ風景
記事のテーマをもとに制作したAI生成の写真風イメージ。

新しいゲームの序盤で、同じ場所で3回続けて失敗する場面を考えてみます。そのたびに最初からやり直しになり、点も減り、残り回数が削られていくとしたら、遊び手は操作を覚える前に気持ちが切れてしまいます。かといって、練習用に敵を弱くし、制限時間を延ばし、お題まで易しくすると、今度は本番とは別のゲームになります。練習では上手にできたのに、本番では何も持ち越せません。 この記事の問いは、練習モードと本番の違いを「失敗の扱い」だけで作れるか、です。操作、ルール、画面、お題は本番と同じにしておきます。変えるのは、失敗したときに何を失い、どこから再開し、何を教えてもらえるかだけです。この方針なら、練習で身につけた手の感覚がそのまま本番に使えます。 以下は、番号付きの手順で小さなサンプルを作りながら進める構成です。結果の数字は載せません。記録の取り方と読み方を示すので、自分のゲームで確かめてください。

この記事の目次
  1. 失敗の扱いを5つの部品に分けます
  2. 手順で作る:失敗の入口を一つにして、値を差し替えます
  3. 公式作品の設計から読み取れること
  4. 自分で確かめる:記録の取り方と起こりやすい誤り
  5. 次の行動

失敗の扱いを5つの部品に分けます

「失敗の扱い」を一語で考えると、つい難易度の話に流れます。そこで先に部品へ分解します。

  • 罰、本番の例:点が減る、練習の例:減らない、決めるときの問い:何を失うと本番らしい緊張が生まれるか
  • 終了条件、本番の例:ミスが一定回数で終わる、練習の例:終わらない、決めるときの問い:練習をいつ止めてよいか
  • 再開位置、本番の例:最初からやり直す、練習の例:失敗した地点から続ける、決めるときの問い:失敗後に同じ地点を何度も試せるか
  • 失敗の情報、本番の例:何も教えない、練習の例:正しい答えを示す、決めるときの問い:失敗から何を学んでほしいか
  • 記録、本番の例:記録に残る、練習の例:残さない、決めるときの問い:練習の結果が本番の成績に混ざらないか

この5つは互いに独立して動かせます。たとえば「罰はなし、再開位置は最初から」という組み合わせも作れます。練習モードの作り込みとは、この5つの値を一つずつ決めていく作業です。

手順で作る:失敗の入口を一つにして、値を差し替えます

最初に、練習で身につけさせたいことを一文で書きます。たとえば「5つの数字の順番を覚えて押す感覚」のように、本番でも使う動作を言葉にします。その動作を止めてしまう失敗だけが、練習で消す対象になります。

次に、本番で失敗したときに起きることを、上の5部品に沿って書き出します。すべて書けたら、各部品について練習用の値を決めます。

ここからが実装です。守る点は一つで、失敗の処理を onMiss という一つの関数に集めることです。失敗の判定があちこちに散らばっていると、モードごとの違いを足すたびに修正漏れが出ます。次のコードは、1枚のHTMLとして単独で動きます。お題の5つの数字は最初だけ表示され、最初のボタンを押すと隠れます。

html
<!doctype html>
<meta charset="utf-8">
<p id="info"></p>
<div id="pad"></div>
<button id="mode">モード切替</button>
<script>
const MODES = {
  practice: { label: "練習", missLimit: Infinity, penalty: 0, reveal: true, resetOnMiss: false },
  real:     { label: "本番", missLimit: 3, penalty: 30, reveal: false, resetOnMiss: true }
};
let mode = MODES.practice, seq, pos, miss, score, over, shown;

function start() {
  seq = Array.from({ length: 5 }, () => Math.floor(Math.random() * 4));
  pos = 0; miss = 0; score = 100; over = false; shown = true;
  draw("お題を覚えて押してください");
}
function onMiss() {
  const answer = seq[pos] + 1;
  miss++; score -= mode.penalty;
  if (mode.resetOnMiss) pos = 0;
  if (miss >= mode.missLimit) { over = true; draw("終了です"); return; }
  draw(mode.reveal ? `違います。正しくは ${answer}` : "違います");
}
function press(i) {
  if (over) return;
  shown = false;
  if (i !== seq[pos]) return onMiss();
  pos++;
  if (pos === seq.length) { over = true; draw("成功です"); return; }
  draw("正解です");
}
function draw(msg) {
  const q = shown || over ? seq.map(n => n + 1).join(" ") : "?????";
  info.textContent = `${mode.label}|${msg}|お題 ${q}|進み ${pos}/${seq.length}|ミス ${miss}|点 ${score}`;
  pad.innerHTML = "";
  for (let i = 0; i < 4; i++) {
    const b = document.createElement("button");
    b.textContent = i + 1;
    b.onclick = () => press(i);
    pad.append(b);
  }
}
document.getElementById("mode").onclick = () => {
  mode = mode === MODES.practice ? MODES.real : MODES.practice;
  start();
};
start();
</script>

実装の手順は次のとおりです。

  1. MODES に2つのモードを並べ、5部品のうち罰(penalty)、終了条件(missLimit)、再開位置(resetOnMiss)、失敗の情報(reveal)を値として持たせます。
  2. 失敗したときは必ず onMiss を通します。罰も終了判定も再開位置も、この関数の中だけで決まります。
  3. 練習の値では、ミスしても点は減らず、終了せず、押す位置は据え置かれ、正しい数字が表示されます。本番の値では、点が減り、3回で終わり、最初に戻り、何も教えません。
  4. 画面の先頭に、今のモード名を必ず表示します。モードが見えないと、遊び手は今の失敗が成績に響くのかどうかを判断できません。
  5. 「モード切替」ボタンで両方を交互に遊び、MODES の2行以外に差がないことを確かめます。

記録の部品は、このサンプルでは保存処理そのものを持たないので省略しています。自分のゲームに組み込むときは、練習モードの結果を保存先へ書き込まない分岐を、保存する関数の入口に置きます。

公式作品の設計から読み取れること

アソバースの公式作品にも、失敗の扱いに触れられる例があります。ここで挙げるのは確認済みの仕様から読み取れる範囲だけです。細かな挙動は、作品を開いて確かめてください。

「時計じかけの台所」には、時間制限なしの見習いと、1皿28秒・配膳6秒・ミス3回までの本番があります。設計から読み取れるのは、練習側では時間とミス回数の圧力を外し、本番側ではその両方を数値で与えているという点です。2つのモードで材料の順序や火の扱いがどこまで共通かは、作品を開いて確かめる部分です。

「こだまの森」は、聴き直しが15点減、間違いが30点減で、間違いが3回に達すると終了します。助けを借りる行為と失敗に、別々の値段が付いています。練習モードを作るときも、「ヒントを見る」と「間違える」を別の部品として扱えます。

「かたちのあいだ」には、一手戻す機能があり、手数は減りません。ヒントは最短手とは限らないとも案内されています。「プリズムの道」にも、戻す操作と一歩だけのヒントがあります。失敗そのものを消すより、戻る手段とヒントの強さを調整するやり方もあります。この2作品を比べると、練習の助けが「やり直し」「情報」「記録の扱い」のどこに置かれているかを観察できます。

自分で確かめる:記録の取り方と起こりやすい誤り

作ったモードが狙いどおりに働いているかは、プレイを記録して判断します。次のように設計します。

  • 問い:練習で失敗した直後の行動は、本番で同じ失敗をした直後の行動と変わるか。
  • 準備:練習用と本番用に同じ版のゲームを用意し、どちらのモードか分かる表示を付けます。数人に頼むなら、順番を入れ替えます。練習から始める人と本番から始める人を半々にします。
  • 記録する項目:1プレイごとに、ミスの回数、終了した理由(成功・ミス上限・自分でやめた)、ミス直後に次の操作までかかった時間、を残します。単位は1プレイです。各モードで最低でも10プレイ分は集めます。
  • 読み方:練習で本番より再開が早く、自分でやめた回数も少なければ、失敗の重さが下がっていると読めます。練習でも全プレイが成功して終わる場合は、緩すぎる可能性があります。本番のミス上限に到達するプレイがほとんどの場合は、練習で得たものが活きていないか、段差が大きすぎる可能性があります。

起こりやすい誤りは次の4つです。

  1. 練習だけ別のゲームにしてしまう:敵やお題まで変えると、何が効いたのか分かりません。まず失敗の扱いだけを変えます。
  2. 練習の情報が本番で消えて崖になる:練習で正解を示し続けた結果、本番で急に何も教えないと、落差が大きくなります。正解の表示を「2回目のミスから」などに段階化するのも一案です。
  3. モードの表示が弱い:今が練習か本番かを遊び手が取り違えると、苦情や不信感の原因になります。
  4. 練習の点が成績に混ざる:練習中も点を表示するなら、保存や共有の対象から外します。

次の行動

まず自分のゲームで、本番の失敗を「罰・終了条件・再開位置・失敗の情報・記録」に分けて書き出してください。次に、そのうち一つだけを練習用に変えて遊び、残りを変えるかどうかを記録から決めます。一つずつ足していくと、どの部品が効いているかが分かります。

単一のHTMLにまとまったゲームは、アソバースにHTMLとして直接アップロードして公開できます。公開の前に、練習モードの表示と、記録が残らない挙動を自分の目で確かめておいてください。