4Hえんぴつ|React+TypeScriptでWeb RPGを作る
第1章「小さなWeb RPGを作り始める」
第1回:なぜWebから始めたのか
1. 今回のテーマ
異世界ファンタジーRPG「冒険に行こう!」を個人開発しています。
もともとは、Unity+C#を使ってゲームを作ることを考えていました。
しかし、実際に計画を具体化していく途中で、開発する順番を見直しました。
現在の順番は、
Webアプリ
↓
PCアプリ
↓
将来の別プラットフォーム
です。
今回は、
なぜ最初からUnityで作らず、React+TypeScriptによるWebアプリから始めることにしたのか
を整理します。
なお、ゲームの世界観や、この連載を始めた背景については、第0回で紹介しています。
2. 最初はUnity+C#を考えていた
ゲームを作るのであれば、Unityのようなゲームエンジンを使う方法があります。
私も当初は、
Unity
+
C#
を中心に考えていました。
スマートフォン向けに作り、その後PCなどへ展開する構想です。
Unityを使えば、
- 画面表示
- 入力
- アニメーション
- 音
- ゲーム用の各種機能
などを、一つの開発環境で扱えます。
将来、より本格的なゲームへ広げることを考えると、今でも有力な選択肢だと考えています。
それでも、最初の開発対象はWebアプリへ変更しました。
3. 問題は「技術」より「まだ分からないことが多い」ことだった
Unityを使うこと自体が問題だったわけではありません。
問題だったのは、
ゲームの基本部分が成立するか、まだ確認できていない
ことでした。
例えば、このゲームでは、
町で「依頼」を受けます。
依頼は、一般的なRPGでいうクエストに近いものです。
その後、「街道」と呼んでいる移動ルートへ出て、途中でゲーム内の出来事であるイベントに遭遇します。
基本の流れは、次のようになります。
町
↓
依頼を受ける
↓
街道へ出る
↓
イベントが起きる
↓
解決方法を選ぶ
↓
結果を受け取る
↓
町へ戻る
イベントでは、
戦闘
交渉
調査
から解決方法を選べるようにしています。
しかし、開発を始める前の段階では、
- この流れはゲームとして成立するのか
- 戦闘以外の選択肢に意味を持たせられるのか
- スマートフォンで操作しやすいのか
- 町や依頼を増やしたとき拡張できるのか
- 途中で保存して続きを遊べるのか
といったことが、まだ分かりませんでした。
そこで、
まず遊びの核だけを、小さく動かして確かめる
ことを優先しました。
4. 最初に必要だったのは「完成版」ではなく「一周できる試作品」
最初のWebプロトタイプでは、思い切って範囲を小さくしました。
町 1つ
街道 1本
依頼 1つ
イベント 1つ
「プロトタイプ」とは、本格的に作り込む前に、基本的な仕組みが成立するか確認するための試作品です。
最初から、
- 多くの町
- 大量の依頼
- 複雑な戦闘
- 大きなマップ
- 完成した世界
を作ることはしませんでした。
確認したかったのは、
町を出て、出来事に遭遇し、何かを選び、結果を受け取り、町へ戻れるか
という一周だけです。
この範囲であれば、Webアプリでも十分に検証できます。
5. Webアプリなら、確認したい部分に集中できた
今回のWeb版は、3D空間を自由に歩き回るゲームではありません。
画面に情報を表示し、プレイヤーが選択し、その結果によってゲーム状態が変わります。
例えば、画面としては、
- 町
- 依頼
- 街道
- イベント
- 結果
などがあります。
その裏では、
- HP
- ゴールド
- 評判
- 現在地
- 依頼の進行状況
- イベントの進行状況
などが変化します。
つまり、最初に確認したかった中心部分は、
画面と状態の変化
でした。
この構造なら、普段のWebアプリ開発に近い形で小さく試せます。
そこでReact+TypeScriptを採用しました。
6. Reactを選んだ理由
Reactを使った理由は、今回のゲームが、
ユーザーの操作によって画面と状態が変わるアプリ
だからです。
例えば、依頼を受けると、
未受注
↓
受注中
へ状態が変わります。
イベントを解決すると、
未解決
↓
成功
あるいは、
未解決
↓
部分成功
などへ変わります。
こうした状態に応じて、
- 表示する文章
- 押せるボタン
- 行ける場所
- 次に進める画面
も変わります。
そのため、まずWeb版ではReactを使って、UIと状態の関係を組み立てることにしました。
7. TypeScriptを選んだ理由
RPGは、作り始めるとデータの種類が急に増えます。
例えば、
Town 町
Road 街道
Quest 依頼
Event 出来事
Player プレイヤー
GameState 現在のゲーム状態
SaveData セーブするデータ
などです。
町を説明用にかなり単純化すると、例えば次のような型で考えられます。
// 考え方を説明するため、実際の実装を簡略化しています。
type Town = {
id: string;
name: string;
questIds: string[];
roadIds: string[];
};
TypeScriptを使うことで、
そのデータには何が必要なのか
をコード上でも明確にできます。
実際にMVPへ広げたときも、
「町そのもののデータ」と、
「その町へ現在行けるかという状態」
を分けて考える必要が出てきました。
このあたりは、第2章で詳しく扱う予定です。
8. 現在のWeb版で使っているもの
現在のWeb版では、主に次の技術を使っています。
| 技術 | 主な役割 |
|---|---|
| React | 画面とUI |
| TypeScript | 型とゲームデータ |
| Vite | 開発・ビルド環境 |
| React Router | 画面遷移 |
| Vitest | 自動テスト |
| Playwright | E2Eテスト |
| Oxlint | コードの静的チェック |
| IndexedDB | セーブデータの保存 |
| Dexie.js | IndexedDBの操作 |
セーブ機能は当初localStorageから始めましたが、その後、公開準備の品質強化でIndexedDB+Dexie.jsへ移行しています。
9. Webから始めたことで、問題を早く見つけられた
小さなWebプロトタイプを完成させたあと、町や依頼、街道、イベントを増やしてMVPへ広げました。
すると、最初には見えていなかった問題が出てきました。
例えば、
- イベントが増えると管理方法を変える必要がある
- 街道途中で保存するなら進行位置も保存する必要がある
- 失敗した依頼を成功と同じ状態にできない
- 失敗時には報酬を渡してはいけない
- 再挑戦時には前回の一時状態を初期化する必要がある
- HPが0なら次の冒険行動を止める必要がある
といった問題です。
こうした問題は、
設計書だけを考えている段階では気づきにくく、実際に触ることで初めて見える
ものもありました。
Webから始めたことで、小さい範囲でこうした問題を見つけ、修正を繰り返すことができました。
10. Unityをやめたわけではない
ここは誤解されないようにしておきたいところです。
今回行ったのは、
Unity+C#を不採用にしたことではありません。
開発する順番を変えただけです。
現在は、
Webアプリ
↓
PCアプリ
↓
将来の別プラットフォーム
という順番で考えています。
Web版で、
- ゲームの基本ルール
- データ構造
- 状態管理
- セーブ
- テスト
を整理したあと、それを次の環境へどう持っていくかを考えます。
つまりWeb版は、単なる仮画面ではなく、
ゲームの仕組みそのものを検証する最初の実装
として位置づけています。
11. 今回のポイント
今回のポイントは3つです。
- Unity+C#を否定したのではなく、使う順番を後ろへ移した
- 最初に確認したかったのは、完成した世界ではなく「一周遊べるか」だった
- UIと状態変化を小さく検証するため、React+TypeScriptによるWebアプリから始めた
個人開発では、
どの技術が一番高機能か
だけでなく、
今、一番確かめたいことは何か
から開発環境を考える方法もあると思います。
今回は、それがWebアプリでした。
この記事を最後まで読んでいただき、ありがとうございます。
「いいね」を押していただけるとうれしいです。これからの記事づくりの励みになります。
もし気に入っていただけましたら、フォローもよろしくお願いします。
12. 次回
次回は、
個人開発のRPGで「最初から全部作らない」ために決めたこと【第2回】
です。
Webから始めることを決めたあと、次に考えたのは、
「では、最初に何を作り、何を作らないのか」
でした。
プロトタイプの範囲をどう小さくしたかを整理します。
この連載の現在位置
第0章 この連載について
第1章 小さなWeb RPGを作り始める
- 第1回 なぜWebから始めたのか ← 今回
- 第2回 「最初から全部作らない」ために決めたこと
- 第3回 町1つ、街道1本、依頼1つの最小プロトタイプ
- 第4回 画面とゲーム状態をどう分けるか
前の記事
第0回 React+TypeScriptで異世界RPGを作る――連載の目的と開発ロードマップ
次の記事
第2回 個人開発のRPGで「最初から全部作らない」ために決めたこと
連載トップ
連載全体のロードマップ
- 第0章 この連載について
- 第1章 小さなWeb RPGを作り始める ← 現在
- 第2章 RPGをデータとして設計する
- 第3章 街道とイベントを設計する
- 第4章 戦闘・交渉・調査と状態管理
- 第5章 セーブと再開
- 第6章 実際に起きた不具合と改善
- 第7章 テストと品質管理
- 第8章 Web公開・互換性・永続化