はじめまして。
インターンの李芳信(フロントエンド)と土居健太郎(バックエンド)です。
今回は、すごろくトークのアプリ化を行いました。
背景
すごろくトークとは、チームの団結力を目的とした、Nulab社内で初対面の社員同士の交流時に行われているゲームで、特に新入社員との交流に使われています。
1人がサイコロを振り、出た数分だけマスを進み、そのマスに書かれたテーマについて本人が話し、これを繰り返すというシンプルなゲームです。
アンケート調査を行ったところ、平均して1人6〜7回ほどこのゲームの経験があり、このことから、Nulabではチームの団結の手段として、すごろくトークをそれなりに採用していると見受けられます。
従来では、自社製品のCacooというホワイトボーディングツールにマスを書き、それを画面共有していただけのシンプルな設計で、これを改善して欲しいとの要望がありました。
Cacoo版
課題
従来のすごろくトークには、以下のような課題(不満点)がありました。
- トークテーマが変わらない
- サイコロが振れないなど、ゲーム性がない
- 参加者を募っても、なかなか人が集まらない
- 企画側に多少の準備が必要だった
これに対して、私たちは以下の解決手段を取ろうと思いました。
解決手段
- ユーザがまたやりたくなるようなゲーム要素
- 事前準備なしでできるお手軽さ
以上を実現できるWebアプリケーションを作ろうと考えました。
まずは以下のゲーム要素を追加することにします。
- AIによるお題のランダム生成
- サイコロのリアルなアニメーション
- マスを進んでコインを稼ぐ仕組み
技術選定
バックエンドとフロントエンドで使う技術は予め決められていました。しかし、初めて使うものであるため、それぞれの特徴を簡潔に説明します。
フロントエンド
フロントエンドはTypeScript(Next.js)を採用しました。
Next.jsはReactをベースに構築されており、サーバーサイドレンダリング(SSR)や静的サイト生成(SSG)、クライアントサイドレンダリング(CSR)を柔軟に選択できるため、パフォーマンスとSEOの両立が可能です。また、TypeScriptとの相性が非常によく、型安全性を確保することで大規模開発においても保守性の高いコードを実現できます。
さらに、ルーティングやAPI Routesがフレームワークに統合されているため、開発者は煩雑な設定を意識せずに効率的な開発を進めることができます。UI/UXの向上に加え、SSRによる初期描画の高速化やISR(Incremental Static Regeneration)による最新データの配信もサポートしており、ユーザー体験を損なうことなく最新情報を届けることが可能です。
Next.jsは特に、ユーザー数の増加を前提としたWebサービスや、検索エンジン最適化が重要なメディアサイト、またリアルタイム性が求められるインタラクティブなアプリケーションにおいて真価を発揮します。ECサイトのように表示速度と信頼性が売上に直結するケースや、ゲームやSNSのようにユーザー体験を重視するサービスにおいても最適です。
バックエンド
バックエンドはRust(axum)を採用しました。
Axumがバックエンド構築で選ばれる主な理由は、生産性と安全性の両立にあります。Rust言語の強力な型システムと所有権モデルにより、コンパイル時に多くのバグ(データ競合など)を防ぐことができ、堅牢かつ安全なアプリケーションを構築できます。
また、AxumはTowerというエコシステムの上に構築されており、ミドルウェアの追加やサービスの状態管理を柔軟に行えます。これにより、開発者は複雑なロジックを効率的に実装できます。さらに、非同期処理を扱うためのtokioとの統合がスムーズで、高い並行性とパフォーマンスを要求されるアプリケーションにも適しています。
Axumは特に、マイクロサービスや高トラフィックなWeb APIの構築において真価を発揮します。金融取引システムのようにデータの整合性と安全性が最優先される場面や、リアルタイム通信を必要とするゲームサーバー、大量のリクエストをさばくIoTプラットフォームのバックエンドなど、パフォーマンスと信頼性が不可欠なユースケースに最適です。
認証
認証には、Backlog認証とJWT認証を採用しました。
Backlog認証を採用した理由はゲームの事前準備を減らすためです。
Nulab社員は全員が仕事用Backlogアカウントを持っています。そのアカウントの情報を取得することで、ユーザーの登録の手間を省けると考えました。
JWT認証を採用した理由は、そのステートレス性とスケーラビリティにあります。
従来のセッション認証では、サーバー側でユーザーごとのセッション情報を管理する必要があります。 ユーザーの増加に伴い負荷が大きくなり、水平スケーリングが困難になるという課題がありました。
JWT認証は、サーバーが状態を保持する必要がありません。この特性により、以下のメリットが生まれます。
-
どのサーバーもトークンの検証だけで済むため、サーバーの台数を増やしても複雑にならず、大規模なシステムにも対応しやすいです。
-
複数のサービスやドメインにまたがるRESTful API、マイクロサービス、モバイルアプリなどで、認証を効率的に実現できます。
セキュリティへの配慮
今回は、セキュリティを考慮し、リフレッシュトークンを利用する仕組みを導入します。これにより、アクセストークンが漏洩した場合でも、有効期限を短く設定することで被害を最小限に抑えることができます。
また、リフレッシュトークンを使用することで、ユーザーは再認証の手間なくサービスを利用できる、シームレスな体験を実現しました。
Websocket通信
マッチング・ゲーム中はリアルタイム通信を実現するため、WebSocket通信を採用しました。
接続前はJWTトークンを含めたハンドシェイクリクエストを送ります。そして、JWTトークンが有効な間だけコネクションを確立できるようにしています。
ゲームには複数人が参加することを想定し、クライアント間で直接通信は採用せず、すべての通信をクライアントとサーバー間の接続に限定しています。
例えば、クライアント同士が互いにブロードキャストを行う場合、参加者が n人 だと各クライアントは n−1本の接続を持ち、全体では n(n−1) = O(n²) 本の通信経路が発生します。
これだと接続管理・送信・受信すべてがクライアントに重くのしかかり、プレイヤー数が増えるほど、クライアントの負荷が急激に増大します。
一方で、すべての通信をサーバー経由にすると、各クライアントは サーバーと1本だけ接続すればよく、全体の接続数も n本(O(n)) に抑えられます。
このゲームは3人以上のプレイヤーが参加することを想定しています。
このような状況では後者の方がクライアントの負担は圧倒的に小さく、通信の安定性・スケーラビリティの両面で優れていると判断しました。
インフラ構成
通信面でも共通する点はありますが、クライアントへの負担とスケーラビリティを重視しました。
そのため、バックエンドはフロントエンドに依存しない構成とし, フロントエンドはクライアントサイドのみで完結する設計としています。
インフラは、新入社員の方が担当してくださいました。
- フロントエンド: Next.jsを静的エクスポートし、CloudFront + S3によりホスティング
- バックエンド: ECS上で稼働し、ALBを介してリクエストを受け付け
- DB: RDS(MySQL)
ユーザーテスト
ユーザーテストを行い、以下のような感想をいただきました。
- 自分でサイコロを振ることができ、プレイしている感が出た
- AI生成でお題が変わるので飽きがこなさそう
- コインが蓄積される仕組みが、繰り返しの参加を促せそう
- 自動でアイコンと連携したりなど、気の利いた機能が多くて手間の削減になりそう
- 英語対応が良かった
当初の課題は多少なりとも改善できたように思われます。
アドバイス
また、テストユーザーからは以下のようなアドバイスもいただきました。
- サイコロの数を任意に選べるとより良さそう
- コインを1つのゲームの中で活かす仕掛けがあると良いかも
- お題が抽象的だったり答えづらかったりするものが多い気がした
- 固めの質問だったかも。もう少しゆるくても良い
- 出発点付近は簡単に答えられるようにするとかだと、時間経過ごとに深い話ができるようになっていい感じかも
- 答えづらい質問はスキップできるようにしてほしい
- トーク中のカウントダウン機能が欲しい
- 他の人が移動している感が薄い
- 目的地が無いので迷う
- 上下左右自由に移動ができると狭く感じた
- いつも最初に自己紹介からはじめるので、システムで何か組み込んでも良いかも
- 1人で話して終わりにならないような要素
- 強制的にコメントさせる機能など欲しい
- 質疑した人は追加でポイントゲットとか良いかも
- 相互に会話が生まれる仕掛けがあるといいかも
- ランダムイベントが欲しい
- 最初にお題を設定したい
- ランキング(4半期・トータル)などが欲しい
全体的にもっとゲーム要素の改善や追加の要望が多く見受けられました。やりがいがありそうです。
今後の展望
今回の研修はとても有意義なものとなったので、今後の活動にも活かしていきたいです。
すごろくトークは、フィードバックをもとに改良していきます。そして、社内でこのアプリを定着させたいと思います。
また、フロントエンド(9月10日)とバックエンド(8月27日)のブログを投稿するので、よければそちらもご覧ください。
*この記事はヌーラボブログリレー2025夏の2日目として投稿しています