前言
「指令ゲーム(Instruction Game)」は、私が所属する北大附中の書院で、毎年恒例となっている新入生オリエンテーションの伝統的なプロジェクトです。ルールは非常にシンプルです。ゲーム開始時、司会者が参加者全員に指令が書かれたカードをランダムに配布します。全員が自分の指令を順番通りに実行し、誰か一人でも間違えたら、ゲームは最初からやり直しになります。例えば:
カード1
大きな声で「皆さん注目してください、ゲームが始まりました」と叫ぶ
カード2
「ゲームが始まりました」という言葉を聞いた後、照明のスイッチを見つけて2回オンオフし、席に戻る
カード3
照明が2回オンオフされたら、左から3番目の同級生を誘って、円の中で一緒に3回ジャンプし、その同級生と一緒に席に戻る
とても簡単そうに聞こえませんか?最初、誰もがそう思いました。しかし、「間違い」の判定には、動作の間違い、順番の間違い、スムーズに繋がらなかった場合(明らかな詰まり)、そして誰かが喋ってしまうことが含まれます。
「指令ゲーム」の進行中、会場内は非常に静まり返り、全員が指令を実行している生徒を注視しています。このような重苦しいプレッシャーの中では、緊張のあまり動作をミスしたり、順番を忘れたりと、様々な事故(特に「右側にいる5人の同級生の名前を言う」という指令などは難関です)が起こりやすくなります。——そして、現実はその通りでした。私が「指令ゲーム」に参加した時は、たった1回のゲームを完遂するのに、午後いっぱい(4〜5時間)を費やしました。そして、新入生の代になっても、状況は改善されていませんでした。
否定できないのは、「指令ゲーム」はその活動内容を通じて、新入生同士がより親密になり、お互いを知るための興味深い手段であるということです。新入生間のチームワークを養い、いち早く集団に馴染ませることができます。また、精神を集中させ、自己をコントロールする能力を鍛えることもでき、これは附中での生活において非常に重要です。
附中での学習生活は非常に自律的であり、受け取る通知のすべてが極めて重要です。そのため、このゲームを通じて、指令の実行能力と厳格さを徐々に重視してほしいと考えています。今後の学園生活で受け取る指令は、課題であったり、通知であったり、あるいはチームでの協力作業であったりします。不注意や油断によって、チャンスを逃したり、成績を落としたり、さらには周囲からの信頼を失うことさえあるかもしれません。そのため、入学教育の期間中、先輩である私たちは、このゲームを通じて皆さんの仲を深めるだけでなく、活動から何かを学び、反省し、より良い附中生活を迎えてほしいと願っています。——『活動企画書』より

実際のゲーム過程で私が気づいたのは、時間の大部分が「間違えた後の指令カードの回収と再配布」に浪費されているということでした。誰かが指令を間違えた後、先輩たちがカードを回収し、シャッフルして、配り直す。このプロセスに毎回およそ2〜3分かかります。この繰り返される2〜3分の待ち時間の間に、参加者の忍耐と情熱は次第に削られ、後半になるにつれてプレッシャーは増大し、全体の規律も緩み始めます。この焦燥感を伴う待ち時間が、「諦め」の感情を引き起こしてしまうのです。
ゲームが終わった時、多くの参加者が感じたのは、おそらく「達成感」や「集団としての名誉」よりも、むしろ「解放感」だったのではないでしょうか。
そこで、ユーザーエクスペリエンス(UX)のデザイン思考によって、このゲームを改善できないかと考えました。
ニールセンのユーザーインターフェース設計の法則(Nielsen’s Law of User Interface Design)によれば、ユーザーの忍耐力は1秒以上の待ち時間で低下し始め、10秒を超えると完全に失われる可能性があります。 したがって、ミスした後のリセットと指令の配布は、参加者の注意力とゲームの連続性を維持するために、可能な限り迅速に行われるべきです。電子化されたゲームは、その有効な解決策となるでしょう。
電子デバイスを通じて指令を配布することで、物理的なカードの回収や再配布にかかる待ち時間を削減し、参加者が指令の実行にエネルギーを集中できるようにします。さらに、電子システムならミスが発生した瞬間にリセットが可能で、待ち時間が発生しないため、参加者の不安感を和らげることもできます。
同時に、使いやすいユーザーインターフェースとインタラクションモードを設計することで、ゲームのルールや現在のステータスを一目で把握できるようにし、ゲームの流暢性とプレイアビリティを向上させます。このような設計は、ゲームの核心的な理念を維持しつつ、ゲーム体験を最適化し、参加者の情熱をより引き出し、チームワークや指令実行能力を育むのに役立ちます。
明確需求
上述のゲーム内容の紹介に基づき、以下の要件を構築できます:
サーバーとクライアント間のリアルタイムな双方向通信が必要

管理者ユーザーとプレイヤーユーザーを区別する必要がある
オンラインユーザーの表示
ゲーム開始ごとに、すべてのプレイヤーに1枚のカードをランダムに割り当てる
管理者はゲーム開始、ゲームリセットの指示を出せる
プレイヤーの実名制
エラー処理:予期せぬネットワーク切断に対する対策
……
系统构建
要件を明確にした後、システムの構築に着手できます。
サーバーの双方向通信には、WebSocketベースのSocket.IOライブラリを採用しました。Socket.IOはイベント駆動型のアーキテクチャを持ち、イベントのトリガーとリスニングを通じて、サーバーとクライアント間のメッセージ伝達とデータ同期を容易に実現できます。ゲームの特定のニーズに合わせて、独自のイベントとハンドラを定義できます。また、Socket.IOには自動再接続メカニズムがあり、クライアントとサーバーの接続が切断された場合、自動的に再接続を試みます。さらに、エラー処理の仕組みも提供されており、接続エラーやタイムアウト、その他の例外状況をキャッチして処理できます。

サーバー側のバックエンドには、拡張性を考慮してNode.jsベースのExpressフレームワークを選択しました。これにより、一つのシステムをWebアプリケーション、アプリ、さらにはWeChatミニプログラムにも応用できます。
プログラムの核心部分——コマンドの割り当てとシャッフルの実装:
function assignCommands(users, commands) {
const shuffledCommands = shuffle([...commands]);
return users.reduce((acc, user, idx) => {
acc[user] = shuffledCommands[idx];
return acc;
}, {});
}
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
ユーザーリストとコマンドの配信:
// Server Side
socket.on('start_game', (username) => {
if (socket.isAdmin) {
userCommands = assignCommands(users, commands);
io.emit('game_started', userCommands);
io.emit('command_list_update', userCommands);
}
});
socket.on('refresh', (username) => {
if (socket.isAdmin) {
userCommands = assignCommands(users, commands);
io.emit('commands_refreshed', userCommands);
io.emit('command_list_update', userCommands);
}
});
socket.on('disconnect', () => {
//接続が切断されたユーザーをリストから削除
const index = onlineUsers.indexOf(socket.username);
if (index !== -1) {
onlineUsers.splice(index, 1);
io.emit('user_list_update', onlineUsers);
}
});
});
// Client Side
socket.on("game_started", userCommands => {
const command = userCommands[username];
document.querySelector("#command").textContent = `${command}`;
});
socket.on("commands_refreshed", userCommands => {
const command = userCommands[username];
document.querySelector("#command").textContent = `${command}`;
});
socket.on("user_list_update", userList => {
const list = document.querySelector("#user-list");
list.innerHTML = "";
userList.forEach(user => {
const div = document.createElement("div");
div.textContent = user;
list.appendChild(div);
});
});
成果展示
現在実装されている機能
ホワイトリストに含まれるプレイヤーのみがログイン可能

管理者がゲーム開始、指令の更新をコントロール

オンラインプレイヤーリストのリアルタイム更新

全プレイヤーの指令を表示

ユーザー権限の検証:管理者のみがゲーム開始、指令更新の操作を実行可能
ネットワーク切断時のプロンプトと自動再接続

完全なデモ動画:

TODO: 電子化された「指令ゲーム」の大きな課題の一つは、参加者が電子デバイスを手にすると、ついついWeChatや他のアプリに切り替えてしまう可能性があることです。この問題を解決するために、問券星などの試験用ページを参考に、Event Listenerを使用して画面の切り替えを検出し、警告を表示する機能を検討しています。
TODO:オンラインユーザーの追跡。現在、オンラインユーザーの配列はサーバーのメモリに保存されています。この方法では、サーバーの再起動や水平スケーリング(複数インスタンス化)の際にすべてのデータが失われてしまいます。より複雑なアプリケーションでは、データベースや中央集中型のストレージ(Redisなど)を使用してこれらのデータを保存する必要があるでしょう。
TODO:オフラインユーザーのレポート、およびより高度な再接続戦略。
TODO:より美しく、ゲーム性の高いインターフェースデザインとインタラクション。
总结
「指令ゲーム」は書院の入学教育から受け継がれてきた伝統ですが、その過度なプレッシャーや冗長なゲームプロセスは批判の対象でもありました。「指令ゲーム」を電子化することで、ゲームの核心的な理念や新入生研修における役割を維持しつつ、ゲームのフローとプレイヤー体験を向上させたいと考えています。
评论
No comments yet