リアルタイムに通信する「今風しりとりゲーム」の技術とリリースまでの流れ

先日の週末、時間が空いたので「100万人が一緒に遊べるしりとりゲーム」を作りました。

https://shiritori.me/

![ogp2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226439/aa6ca5ba-52b8-4b8d-f93c-128206cbcb7f.png)

## ゲームを作った理由

以前から「同時体験型のサービス」を作りたいと思ってまして、しりとりであれば文字情報だけのやりとりなので作るのが簡単だなと。

(もう一つ理由がありますが長くなったので記事最後にまとめました)

タイトルの「100万人」というには、Firebaseの有料プランの同時接続数が100万だったのでそう名付けました。本当に100万人いけるかは未確認です。そして100万行く前に僕の財布が空になると思います。

## 使用技術と選定理由

#### フロントエンド

- nuxt.js (spa)
- pug
- scss

jQuery では心許ないのである程度のフレームワークを使う必要があります。Nuxt.js が好きで使用歴もあるのでこちらを使うことにしました。

今までは便利なツール(pug など)を使おうとすると gulp 等のランナーを別途使う必要がありましたが、Nuxt.js はそれ単体でアプリケーションが作れるので最高ですね。

#### バックエンド

- Firebase Authentication
- Firebase Functions
- Firebase Firestore

今回の要件は以下 3 つです。

1. Twitter 認証
2. サーバ側で処理を実行
3. データの保管

「サーバ側で処理を実行」についてですが、今回のゲームはしりとりの発言をすると 1 ポイント手に入ります。そのための計算をサーバ側で行う必要があります。(ポイントは特に何に使うわけではない)

Firebaseは、単体で全て出来るわけではありませんが、今回のように拡張の構想があるわけでもなく、さくっと作るにはすごく便利ですね。

#### ホスティング

- Gitlab Pages

ホスティング(HTML をどこに置くか)については、以下の 3 点から Gitlab Pages にしました。

1. CircleCI 等の CI 環境を別に作らなくてもよい
2. お金がかからない
3. 過去に Gitlab Pages を使った実績があった

余談ですが、Github ではなく Gitlab を使っているのは、Github のプライベートリポジトリ無料化の波に乗り遅れたからです。

## Firestore の構成

Firestore の構成(データ構造)はこんな感じです。

#### ユーザー情報

主キー：ユーザー ID

```
User {
  point: number; // ポイント保持
}
```

#### しりとり投稿情報

主キー：投稿した時間

```
Contents {
  uid: string; // ユーザーID
  user: {
    name: string; // 名前
    picture: string; // サムネイル画像
  };
  state: 'post' | 'success' | 'fail'; // 投稿の状態
  word: string; // 投稿したワード
  createdAt: number; // 投稿時間
}
```

「しりとり」なので、一つ前の発言を基に今回の発言が問題ないかチェックしなければいけません。
FirestoreはAuto Incrementがないので正確な投稿の時系列が取れません。そのため「投稿した時間」を主キーにして投稿の時系列テーブルを作っています。全く同じ時間に投稿された場合には後に発言された方(Firestore側の制御による)はエラーになります。


## リリースまでの流れ

制作時間は 16 時間くらいです。

(1 年前に簡単にデザインを作ったのでもうちょっとかかってますが)

#### 1. デプロイ環境構築

まず始めに本番リリースを行います。正確には「本番リリースのためのデプロイ環境を整える」ですね。
ドメインの接続には時間がかかるのと、実際本番にデプロイしようと思うと何気につまづく(エラーが起きて原因特定に時間がかかる)ことが多いので、まず始めにこちらを行います。

1. お名前.com でドメインを取得
2. Nuxt.js でテンプレートプロジェクトを作成
3. Gitlab ビルド用に.gitlab-ci.yml を作成
4. Gitlab プロジェクトを作成し、テンプレートプロジェクトを Push
5. GitlabPages にドメインを接続

ドメイン接続に時間がかかるのでこちらで一旦放置します。

#### 2. デザインとコーディング作業

私は実装の「最初」と「最後」にデザインを決めることにしています。(出来るだけコーディング中にデザインをやることがないように)
まず始めに 70%くらいの完成度でデザインを作り、コーディングをします。サーバも含めて実装完了後に修正しがてらマージン修正やスマホ対応をしていきます。

1. sketch でワイヤーを作る (可能なら一晩寝かして再度チェック)
2. デザインを基に PC のコーディングを行う

#### 3. サーバ及びインフラ側作業

1. Firebase プロジェクトを作成し、必要な設定を行う
2. リポジトリに firebase ディレクトリを作成し、`firebase init` を行う
3. functions の実装を行う

#### 4. フロントとサーバの繋ぎ込み

1. firebase emulator を起動する
2. フロントとサーバの繋ぎ込みを行う
3. デザインの修正を行う
4. スマホ対応のコーディングを行う

firebase emulatorを初めて使いましたがすごく便利ですね。Firebase Authenticationの認証はこちらで出来ないようですが、Functionsの本番リリース時によくありがちなエラーである「cors」も再現されていました。

![slack-imgs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226439/e242698a-b1a6-91f5-eed6-359fea63b58f.png)



#### 5. 残り作業

1. ogp 画像や icon 画像を作成して組み込む
2. html の meta 情報を入れる
3. 本番にデプロイして動作チェックする

## 終わりに

#### 作って何か意味があるのか？

今回のゲームですが、1 年くらい前から構想はしていましたが、何より「作って何か意味があるのか」という点がネックで着手していませんでした。若手でもないのでこれが実績作りになるわけでもなく、またお金になるわけでもなく、学んだ技術が直近で役に立つわけでもなく。

今回作ろうと思ったのが「作りたい」以外の作るべき理由が増えたからです。
先日個人開発で[サービスを作ってリリース](https://qiita.com/koma2hiroki/items/487c4e48909558a0623c)しましたが、何かと広報が苦手なので「サービス作ったよ！」と何度も宣伝するのが忍びないと思ってしまいます。つまり「シェアして欲しい」がなかなか出来ません。

なので今回はこの「シェアして欲しい」という「発言をすることを慣れる」ためにゲームを作ることにしました。

私は「理由」があれば何かと発言ができると思ってます。なので、このしりとりゲームを作る際にその点を考慮し、連続して発言が出来ない仕様にしました(一人遊びができない)。そうすることで誰かが発言しないとゲームが続かなくなるわけですね。

どこまで気持ちが持つか分かりませんが、リリース後は「シェアして欲しい」と言い続けようと思います。

#### そして、シェアして欲しい

100万人でしりとりしましょう！！！
いや、むしろ1000人でも！！！！！
むしろ僕にみんなとしりとりさせてください！！！！
爆速でフィードが流れるしりとりを見せてくださいお願いします！！！！

シェアお願いしますシェアお願いしますシェアお願いします！！！！！
シェアああああああ！！！！！！！！！１

https://shiritori.me/