個人で開発したゲームのリリースまでのフローをまとめてみた

### はじめに

この記事ではアプリをリリースするまでにしたことを残して

- 過去の挫折経験を4回している私でも頑張ればアプリをリリースできる
- 開発で便利なサービスやツールの紹介をしたい！

ということを伝えたい記事になっております
なにか少しでもだれかの参考になれば嬉しいです

### 作ったゲームの紹介
小学生の時とかに良くやっていた「いっせーの、せ！」ってする指遊びゲームです

https://comomell.com/issenose

現在ストアで配信中なのでもしよろしければあそんでみてください！

### 使ったツールやサービス
- クライアント開発
    - UnityEngine (2022.3.17f1)
    - Rider
    - websocket-sharp
    - Xcode
- サーバー開発
    - deno Deploy
    - supabase
- その他開発に使ったもの
    - GitHub
    - GitHub Actions
    - Jira
    - Confluence
    - Miro
    - Figma
    - TestFlight

## 開発までのざっくりとしたフロー

1. どんなゲームを作るかをざっくりと決める
1. まずはインゲームからざっくり動くモックアップを作る
1. さらにイメージを固めていく
1. 実装を進める
1. デバッグする
1. 審査に提出する

大まかに上記のような形で制作の進行をしていきました。
各セクションで更に掘り下げて行きたいと思います。

## 1. どんなゲームを作るかをざっくりと決める
まずはどんなゲームを作るのかをざっくりと決めちゃいます

私の場合は仕事をしている時に、突然
「いっせーの、せ！」懐かしいい！
あれアプリでオンラインプレイできたら面白いのでは！？

と思いたったのがきっかけでした。（突然過ぎる）
この時点では過去にオフラインでするミニゲームを作ったことはあったので
サーバーサイドの勉強もしたいと思っていたため、丁度いい題材にもなるかなと思ってました。

次に、動くところまで作るのに目指すゴールを決めました

:::note info
- オンラインで指の上げ下げが同期できる
- 上げ下げが3Dモデルに反映される
:::

ところまでを目標にモックアップを作成することにしました。
### オンラインで指の上げ下げが同期できる
まずはここをどのように実現するかを考えました。
- Photonを使ってモデルの動きをリンクさせる
- WebSocketを使用してメッセージをやり取りしてそれをトリガーにする
- HTTP3のQUICを使用してメッセージをやり取りしてそれをトリガーにする
- P2P通信でなんとかする
- MagicOnionを使う

などが思いつきましたが、今回はWebSocketをやってみたいなと思ったので
2番目のWebSocketを使用する形で制作を進めることにしました。

### 上げ下げが3Dモデルに反映される
ここはメッセージのやり取りさえできてしまえはそのメッセージをトリガーにして
指の上げ下げメソッドを叩くようにすれば実装できそうだなと思っていました。
上げ下げはAnimatorを使用して実装するイメージで進めることにしました。


## 2. まずはインゲームからざっくり動くモックアップを作る
上記使用するものが決まれば早速実装です！


### サーバー側の実装
サーバーサイドでは今回denoを使用することにしました！
理由は使ったことがなくて勉強になりそうだなと思った点と
β版でkvとcronが使えるということで便利そうなのと
新しいものはぜひあたってみたいと思ったからです！

https://deno.com/

Socket通信を受信してconsoleに出力する、程度の実装は
比較的簡単に実装できました！WebSocketすごいですね！

https://developer.mozilla.org/ja/docs/Web/API/WebSockets_API/Writing_a_WebSocket_server_in_JavaScript_Deno

ここで指の上げ下げメッセージを受信したときは、送信相手に送ってあげる
という実装ができれば一旦サーバー側は完成しそうです！
とっても簡単な図ですが、このようなイメージでとりあえず橋渡しするだけです！

![スクリーンショット 2024-03-20 16.45.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708786/53e3f7a9-21d0-db2d-2931-28412a915d36.png)


### クライアント側の実装

こちらがハードル少しありました！
まずはWebSocket通信を確立するところから！と思いましたが、
調べてみるとUnityの標準機能ではSocket通信は対応していないとのことでした、、
そこでさらに調べるとwebsocket-sharpというのがあることを確認、
早速使ってみることに！

https://github.com/sta/websocket-sharp

いろんな記事を参考にVisualStudioでコンパイルしたものをUnityにインポート！
`_webSocket.Send("message");`でメッセージを簡単に送ることができて
これもすごく画期的に感じました！

メッセージの受信も
```c#
private void Start()
{
    _webSocket.OnMessage += (sender, me) =>
    {
        // ここに書いた処理がメッセージ受信したタイミングで走る
        Debug.Log("メッセージを受信した");
    };
}
```
ここに書くだけで、シンプル！
早速作った指を上げるメソッドをここに書いて実行！
とするとエラーが、どうやらwebsocket通信はUnityのメインスレッドとは別のスレッドで動いているらしく、

```c#
private SynchronizationContext _context;
private WebSocket _webSocket;

private void Start()
{
    // メインスレッドのコンテキストを取得
    _context = SynchronizationContext.Current;
    _webSocket.OnMessage += (sender, me) =>
    {
        _context.Post(state =>
        {
            // ここに書いた処理がメッセージ受信したタイミングで走る
            Debug.Log("メッセージを受信した");
        }, null);
    };
}
```
上記のような形でメインスレッドに移して処理をさせてあげる必要があります。
無事この対応でメソッドを叩くことができ、指の動きを他の端末と
Socket通信経由で動かすことができました！
※画像はリリース後のものになっています！

![名称未設定.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708786/c3e8abeb-b412-0e4d-e3fc-8d0a1eac6ead.gif)

## 3. さらにイメージを固めていく

ここまでくればあとはゲームロジックの実装やUI周りの制作になっていきます。

細かい部分の決めや、残っているタスクを明確にしていく中で
いろんなサービスを使うことで勉強になるかなと思いましたので
ここから様々なサービスなどを活用しながらの制作を進めていきます。
使ってみて良かったと思った点を共有させていただきます

### Figmaを使ってデザインのイメージを固める

今回デザインのプロトタイプを作る時にFigmaを使用しました

https://www.figma.com/ja/

○使用例
![スクリーンショット 2024-03-20 23.50.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708786/d5d0e175-736f-72a6-9f5f-d85edca5e263.png)

:::note info
ここが便利！
- UIを作った後にキャンバスをそのままPNGに出力できるのですぐにUnityに取り込める
- URLを共有することによって他の人に見せて意見を伺うなどが素早く行えた
- 一つの画像から出力サイズを複数指定できるのでアプリアイコンなど1ソース複数出力ができ便利だった
:::

### Miroでゲームロジックの実装イメージを固める

今回ゲームロジックを考える際にMiroを使用しました

https://miro.com/ja/

○使用例
![スクリーンショット 2024-03-21 0.15.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708786/d138b18b-c6bf-633f-fd1c-95a675a9ecdd.png)

:::note info
ここが便利！
- スマホアプリがあるので通勤中などでも作業ができた
- ちょっとしたメモや参考の画像など一時的なメモなどにも気軽に使用できた
:::


### Jiraを使ってタスクを管理する

今回はJiraを使用して

- タスクの見える化
- 進捗の把握
- 完成までのスケジュール管理

を行いました。

https://www.atlassian.com/ja/software/jira

形式はカンバンで一人での作業が主になりますのでタイムライン機能を使用し
チケットごとの期日を決めて少しずつ進行を進めました。
![スクリーンショット 2024-03-20 23.24.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708786/d9314ffc-b7e5-7aff-5921-05781759c2bb.png)

GitHubとの連携がすごく簡単でコミットやPRにチケットのキーを含めることで
Jiraから現在の情報やその実装に対するコミットなどを確認することができます。
また、GitHubで設定したdenoへのdeploy状況も確認することができ、
アルファ版でデバッグをする際に環境へ実装が反映されているかをここから確認することができるためとても便利でした
![スクリーンショット 2024-03-20 23.28.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708786/a3cd4790-3aed-659d-3c05-5e301cdec6a8.png)

:::note info
ここが便利！
- スケジュールを視覚的に管理しやすく、期日や優先度が明確になることにより開発の進行がしやすかった
- とりあえずタスクをチケット化することにより、実装漏れや残タスクがわかりやすくなった
- denoDeployの状況が見えるため、デバッグをしてもらう時に環境反映が完了しているかをデバッガーの方が認識しやすかった
:::


### Confluenceで決めた仕様をまとめる

仕様書の作成やリソースの権利情報などをまとめるのにConfluenceを使用しました

https://www.atlassian.com/ja/software/confluence

○使用例
![スクリーンショット 2024-03-21 0.38.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708786/4b738e60-0a1a-d876-60de-b0010fb87dfe.png)

:::note info
ここが便利！
- デバッグに協力してくれる方にJiraを共有すると同時に仕様書も共有することができる
- アバウトに書いてもいい感じにレスポンスデザインで表示してくれる
- Jiraのタイムラインやチケットの情報を貼り付けたり表示したりできる
:::


### GitHub Actionsで簡易的な自動テストを実装する

今回使用したdenoではブランチにPushしたりMergeした時に
自動的にDeployが走るものになっていますので、
特にmainにMergeするときには細心の注意が必要です
mainへマージする前に自動テストでDBの向き先が本番環境を見ているかの
テストを行うことにより、envの設定ミスが本番流出しないようにしました。

https://github.co.jp/features/actions

```yml:denoのtestを実行するactionsのyml
name: リリース前テスト

on:
  pull_request:
    types:
      - opened
      - synchronize
  workflow_dispatch:

jobs:
  releaseTest:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2

      - name: Checkout deno repository
        uses: denoland/setup-deno@v1

      - name: Run Deno Test
        id: deno_test
        run: deno test -A
```
:::note info
ここが便利！
- テストが通ったことを確認して本番環境にMergeでき安心感がすごい
:::


## 4. 実装を進める

上記で決まったことをもとに実装を進めていきます。
各実装を進めていくうえでハマってしまったことも各所でありました。
ここで上げていくときりがないので割愛させていただきますが
後日記事にして作成させていただいたいと思います。

とても簡単な図になってしまいますが、今回の運用イメージです

![スクリーンショット 2024-03-21 3.02.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708786/a7135685-9f2a-67b9-1aad-434275442871.png)

## 5. デバッグする

実装が完了して固まってきたら次にデバッグです
今回はスプレッドシートを使用してテストケースの作成を行いました。

https://docs.google.com/spreadsheets/d/1qB6IrbdwTSERoy2RskbxTml8HHQR04qnMcc7G60QNdo/edit?usp=sharing

実施者に名前が入ってしまっていますため、コピーしたものを公開させていただきますが、
リリース前にはすべてのテスト観点を実施し、バグが発見された箇所はチケットを作成して
別途優先度を決め、リリースまでに対応必須であるかなどを配慮しつつ
バグ修正や要望の追加実装を審査提出日前まで行いました。
デバッグは私も含めて5人の友人に協力を依頼し、
リリース前までに31件のバグチケットが作成されました。

クリティカルなバグなどもありましたが
しっかりと項目書でのデバッグを行ったことによりリリース後にクラッシュ報告やバグ報告などはまだ1件も来ておりません。

また、サーバーへの負荷テストも行っており、同時に20端末がアクセスしても
問題なく動作することを確認しております。

## 6. 審査に提出する

ここまでデバッグを行ってついに審査に提出します。
AppStoreとPlayStoreにリリースするため、どちらのストアにも審査に提出する必要があります。
まずはじめの課題は「プライバイシーポリシー」です。

審査に提出するためにはプライバイシーポリシーのURLを記載する必要があるらしく、
サイトの作成とドメインの取得を行いました。

https://comomell.com/privacypolicy.html

これで事前の準備は完了です。
ビルドのアップロードは
Androidではaab、
iOSではXcode経由でアップロードする必要があります。
（ここの手順も後日時間がある時に記事を上げれればなと思っております）