シャニマスのカードを検索できるサイトを作ってちょっとバズったけど公式に検索機能がついて終わった話



アイドルマスターシャイニーカラーズ(シャニマス)遊んでますか？

5月末に公開した「シャニマスsSSR検索」について、数ヶ月経過しましたがせっかく作ったので顛末(?)の記事を書こうと思います。
コードらしいコードはでてきません。
(ゲームに直接関与するツールではありませんが、権利的にグレー?な部分があると思います。連絡を取りたい権利者の方はTwitter@nok0714にDMをください)

サイトはこちらです↓
https://shiny-support-search.netlify.app/

## 背景

シャニマスは、2018年の4月24日にサービスを開始したアイドルマスター(アイマス)シリーズの末っ子です。

ソシャゲ・音ゲーのスタイルを取る他のスマホ向けアイマスとは異なり、アイドル育成&ライブ対戦(公式のジャンル説明)ゲームとなっています。
ジャンルの通りゲームは大まかに2パートに別れています。

1. アイドル育成: プロデュースでシナリオを見つつ好きなキャラを育てる
2. ライブ対戦: ↑で育てたキャラを5人選んで編成したユニットで、他のプレイヤーのユニットと対戦する

2.では3人の審査員(Vo/Da/Vi)に効果的なアピールをたくさん行ったほうが勝ち(ざっくり)というスタイルになっています。
効果的なアピールをするには、自分の立てた戦略をうまく回せるような編成が必要になります。

そのためには1.の育成でいかに強いアイドルを育てられるか、が重要になります。
1.の育成パートでは、育成対象のキャラ(プロデュースアイドル)に対して、5人の**補助キャラ(サポートアイドル・ゲストアイドル)**を参加させられます。

![編成画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/5c507faa-bf47-ef2f-bb41-1072f00baf54.png)


サポートアイドルにはそれぞれスキルが設定されています。例↓

* 一緒にダンスレッスンをするとダンスのステータスがたくさん伸びる「ダンスマスタリーDa」
* おやすみ(体力回復)のときにたくさん回復する「おやすみブースト」
* 同じユニットのキャラが同じレッスンやお仕事にいるとメンタル(対戦時の体力)が伸びる「ユニットマスタリーMe」

シナリオを勝ち抜いたり、強い対戦用アイドルを作ったりするには、このスキルをうまく編成することが重要な要素のひとつになります。
スキルはカードごとに違うものが設定されています。
シャニマスでは現在6ユニット・23人のキャラがいます。
ユニットの登場時期によって異なりますが、各キャラに10枚程度はカードがあります(レアリティSSRとSRを合わせるとこれくらいかと)。

2020年5月当時でサポートSSRカードは90枚ほどありました。
また、当時は新シナリオであるG.R.A.D.が実装され、初期シナリオの W.I.N.G.編、1周年時に実装されたファン感謝祭編の3本立てとなったところでした。
それぞれのシナリオでどのようなスキルが重要になるかが異なり、ファン感謝祭とG.R.A.D.ではスキル以外にアイディア、ひらめきと呼ばれる要素が追加されました。
(例: オーディションを行わないファン感謝祭では、オーディションに勝つと特定のステータスが追加で伸びるオーディションマスタリーは無駄)

**当時はシャニマス側にキャラの検索機能がなく**、いい加減覚えられないなーと思った & 2周年で入ってきた初心者さんが「あのスキルは誰が持ってるんだー！」と困っているだろうと考えたので、Reactの勉強も兼ねて、**指定したスキルを持つカードを検索できるWebアプリを書いてみる**ことにしました。
(Twitterで「こんなんあったら便利かなー」って言ったらフォロワーに後押しされたので、それも原動力になりました)

## 実装

### React使おう

今どきっぽいWebの書き方は全然知らなかったのですが、自分が管理に関わるサイトで使っているGatsbyを見て「おお～こうやるのか～」と思ったので、Reactをベースにしてみることにしました。
で、どうもReactで何かを作るなら[Create-react-app](https://github.com/facebook/create-react-app)がいいらしいと聞き、これを使ってみることにしました。
Create-react-appでは、最低限の環境をお膳立てして、Reactを使ったWebアプリを製作できるようにしてくれます。

で、なるべくなら画面をかっこよくしたいということで、UIフレームワーク的なものも入れてみることにしました。
コンポーネントの充実具合(特に"カード"が良かった！)で[Material UI](https://github.com/mui-org/material-ui)を選びました。

まずはなにか表示できないかなと思って、適当に作ってみたのがこれ。
最初は、上の方の画像で示したプロデュースユニットを再現しようとしていました。

![プロトofプロト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/2f006b82-369e-8e9f-27b4-de7be52eb190.png)

同じものが15枚並んでいますが、個々のものは[カードのコンポーネント](https://material-ui.com/components/cards/)と[チップのコンポーネント](https://material-ui.com/components/chips/)を組み合わせて作りました。

このあたりで、「自前で好き勝手にコンポーネントを組み合わせて部品として名前をつけて自由に使えるってスゲー！」ってなってました。
ついでに、`npm install`で欲しい物を持ってこられるのもすごいし、ソースを変えればホットリロードされるのもすごい！！って喜んでました。
あとなにかしくじったときに意外と丁寧にエラーを教えてくれて「意外とやるやん」となっていました。

### 画面構成を考える

↑と前後して「どういう画面構成にするか」について考え始め、しばらくお絵かきをしました。
変遷はこんな感じでした↓

| その1 | その2 | その3 |
| :-: | :-: | :-: |
| ![1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/2506c53c-414e-c768-6e98-eba34786bfc3.jpeg) | ![2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/e78087d9-bda8-b27f-4017-7f19e5342917.jpeg) | ![3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/23c28b61-9f16-88a4-6dad-a67e62fcae5f.jpeg) |

「その1」はシャニマスのプロデュースユニット編成画面とサポートアイドル一覧画面をガッチャンコしたようなものですね。
「その2」の上側では2枚のカードを比較する構成でした。下側でかなり画面が固まってきて、左ペインで持っているスキルを選択し、右ペインで検索結果を表示する形となっています。
実際、上のプロトタイプはその1とその2の途中くらいで作ったものだと思います。
で、結局「その3」(落書きは無視で…)で画面構成が固まりました。

### 本格的に作る

半年近く前なのでもうどういう順序で作ったか覚えていませんが、左ペイン・右ペインをページ全体で包む構造にしました。
実際にはMaterial UIのサイトを眺めて[Drawer](https://material-ui.com/components/drawers/)が使えそう！ということでこれを使いました。

で、順にお絵かき通りのものを作っていきました。

* 右ペイン
    * カード: プロトタイプのものを引っ張ってきて、`props`で渡したデータを表示できるように。
    * カードを並べる部分: [Grid](https://material-ui.com/components/grid/)コンポーネントに`props`でカード一覧を入れられるように。
* 左ペイン
    * 感謝祭アイディア・G.R.A.D.ひらめき: [Radio](https://material-ui.com/components/radio-buttons/)を使用。
    * マスタリー・その他スキル: カードに使ったChipsをクリックできるようにして表示。

ガワはできたのですが、`props`と`state`とイベントについてよくわかっていなかったので、左側で絞り込んだスキルをどうやって右側に渡すんだろうとしばらく悩んでいました。
「スキルの絞り込みパネルで`onClick`はつけられるけどどうやって親にこれを渡すんだ？」「親から渡ってきたとして右側ってもう描画されてるはずじゃんどうやって変更するの？？？」みたいな状態でした。

結局色々やっているうちに「親が`props`で送りつけた関数を子の`onClick`内で叩くのか」「`React.useState`で作った変数を`props`として渡して、それに合わせて個々のカードの描画するしないを決めれば勝手に描画し直すんだ」とわかりました。
完全に雰囲気で書いているので合っているのか本当にわかりませんが、とりあえず動きました。

そうしてできた初期のスクショがこちら。

![初期スクショ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/7bd68fed-b7ab-e695-4706-7c8606fb7dae.png)

この時点でデータがかけらも入っていなかったので、画像を集めつつ(持っていなかったカードの画像を提供してくれた友達に感謝)、シャニマス攻略Wiki(wikiwikiのやつ)のデータにお世話になりつつ、表示用データを整えてついに完成しました。

![202005241950_resized.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/2e142bd0-8788-4c75-4bee-3cb1b93a4829.png)

ファイルの作成日を見た結果、どうやら5月20日にプロトタイプをゴニョゴニョしはじめて、5月22日に本実装を始め、**5月23日に公開用バージョン**ができいたようなので、かなり一気に書いたんだなあ。

## 公開

公開するからにはWebサーバが必要だぞ、となったのですが↑の実装で気力が尽きていて、自分で建てるのも嫌だったのでいまどきらしくNetlifyにおまかせしました。
作ったもの自体はすべてビルドバンドルで完結しており、動的に何かをする必要もなかったので(静的サイトって言うんですかね)Netlifyで十分でした。

GitHubのプライベートリポジトリにコードをpushして、Netlifyでそのリポジトリと連携し、どのブランチをビルド対象にするか、ビルドコマンドはなにか等々を設定すればそれで完了だったので非常に楽でした。
(URLもサブドメイン部分なら好きに変えられるし！)

そんなこんなで公開し、Twitterで作ったよ！ツイートを出しました。
それがこれ。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">結構カードも増えて「こんな性能の子いなかったっけ？」と探すのが大変なので、シャニマスのサポートカード検索機をつくってみました！SSRサポートを感謝祭アイデア・GRADひらめき・保有マスタリーで検索できます(が，スマホだと表示崩れします) <a href="https://t.co/dOSs7ivxsw">https://t.co/dOSs7ivxsw</a> <a href="https://t.co/g0WaGsk0On">pic.twitter.com/g0WaGsk0On</a></p>&mdash; モアイ|再生産 (@nok0714) <a href="https://twitter.com/nok0714/status/1264186850232504322?ref_src=twsrc%5Etfw">May 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

当時はシャニマス本家で一切キャラの絞り込みができなかったので、それなり(?)にウケました。
通知止まらんｗを初めて体験しました。
ただ、イマドキのサイトなのにスマホ対応が全然できていなくて、そのあたりは失敗だったなあと思っています。
今は更新しているのでこうなりませんが、当時はデスクトップの表示がそのままスマホでも出ていて、`width`の指定がテキトーだったので、検索にマッチするカードが3枚?を切ると表示がイカれていました↓

| 読み込み直後 | マッチなし |
| :-: | :-: |
| ![初期1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/77f84010-469e-8714-8343-ec0dbaaa6b71.png) | ![初期2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/43941777-8d7d-9601-44ed-fc257ad05166.png) |


## ゴミ化

RTやlikeをしてくれた人をちょくちょく覗いてみて「便利」「公式にくれ」って発言を見て鼻高々になったり、リプライで「便利ですね！」とお言葉をもらい天狗になっていたのですが、終焉はすぐに訪れました。
**7月1日**に「公式側に検索機能が実装される」という告知が行われたのです。ひと月少々の命でした。
実際に7月10日の更新で絞り込みができるようになり、サポートスキル(この記事でスキルと呼んでいるもの)・ライブスキル(サポートアイドルがオーディションに参加した際に利用できるスキル)・未読コミュの有無・登場種類(期間限定、イベント配布など)といった条件でキャラを探せるようになりました。
公開してるサイトより遥かに便利です。負け惜しみがこれ↓

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">㊗シャニマス本体に絞り込みがついた㊗ので，サポートカード検索はお役御免です(短い一生だったな)<br><br>サイト自体は開けたままにしておきますが，今後はシャニマス本体の絞り込みを使っていきましょう！ <a href="https://twitter.com/hashtag/%E3%82%B7%E3%83%A3%E3%83%8B%E3%83%9E%E3%82%B9?src=hash&amp;ref_src=twsrc%5Etfw">#シャニマス</a> <a href="https://t.co/0GBPjqiCOS">https://t.co/0GBPjqiCOS</a> <a href="https://t.co/xGczyUE2Hk">pic.twitter.com/xGczyUE2Hk</a></p>&mdash; モアイ|再生産 (@nok0714) <a href="https://twitter.com/nok0714/status/1281482502616477696?ref_src=twsrc%5Etfw">July 10, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

とはいえせっかく作ったのに放置するのももったいない。
ということで、自分が「ほしいな～」と思った機能を付け足すことにしました。

## 機能追加

いまどんな感じかは https://shiny-support-search.netlify.app/ を見てください。

最初に公開したときにマスタリー以外での絞り込みの機能はないの？と訊かれていたので、その機能の更新から始めました。
機能を追加する、つまりgitのブランチを勉強できる！ということで、見様見真似でブランチを切ってみました。

* `master`: 公開用
* `develop`: 開発用よろづ
* `feature/x`: xの機能開発用
* `hotfix/x`: なんか急務の更新用
* `package-update`: `npm`で入れているパッケージの更新
* `data-update`: シャニマス側で新しいカードが追加された際のデータ追加

で、細々したコード変更は`develop`で行い、それなりに量のありそうな作業は`feature`で行ってから`develop`にマージしました。
我流でやったので合っているのかもよくわかりません。
結果、以下の更新を行いました。

* マスタリー以外のスキルで絞り込み(5/24): リプライで指摘されて。公開した最初のバージョンではマスタリーでしか絞り込めませんでした。実は準備はしていたので一瞬でした。
* スマートフォン対応(9/10): 小さい画面では検索条件ペインを開閉できるようにしました。3ヶ月以上開いていますが、この間は細かい表示調整をしていました。
* キャラ別の絞り込み(9/28): スキルの絞り込みと同じ形で、キャラ単位の絞り込みを実装しました。
* アコーディオンメニュー(9/28): 検索条件が増えてきたので、折り畳めるようにしました。キャラ別の絞り込みと同時です。
* OGPプレビュー機能(9/30): Twitterやfacebookでリンクをツイートするとリッチな感じになります。なかなかの曲者で、こいつのためにステージング環境を用意することになりました(それまではローカルで挙動を見て問題なさそうなら公開)。
* 画像だけモード(10/3): 右ペインのカード一覧からあえてスキルを非表示にできる。シャニマスの**美しいイラストを眺めたい**欲望で生まれました。

そんな感じで更新を続けて、途中でサイト名を変えたりしましたが、(これも適当ですが)初期公開でv0.1.0だったバージョンが10月22日現在ではv0.4.2になりました。

ちなみにスマホ対応直後はこんな感じで、メニューが開閉できます(カードの一覧性が下がった感じはしますが)

| 読み込み直後 | メニューオープン時 |
| :-: | :-: |
| ![スマホ対応1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/326d3bbf-b2fc-58da-d58e-b90c82685d4f.png) | ![スマホ対応2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/240f91d9-9575-659d-4b06-b3f8418083dc.png) |


## このサイトの実装や更新を通して勉強できたこと

意外とまともに開発をしたことがなかったので、色々と勉強になりました。

* Reactを使ったフロントエンド?開発(ベタにHTMLを書くなんてもうできないなー)
* Material-UIを使ったUIづくり(スタイリングはあまりいじっていませんが、かなりコンポーネントが充実していて、組み合わせればいけそう感がよかったです)
* Netlifyを使ったCD/CI(git pushだけでいいんだから楽ちん)
* ちゃんとブランチを切ったGit開発(複数の機能を同時に、ということがなかったので結局一本道ですが)

今後も自分の思うままに更新していきたいなーという感じです。例えば

* 画像非表示モードで一覧性を上げる
* サービスワーカーを使ったオフライン動作
* サーバープッシュ(できるのだろうか?)
* スキル以外の性能でも検索
* シャニマス攻略Wikiへのリンク
* レアリティSRの追加(枚数が増えすぎるのであまりやりたくない)
* 内部のリファクタリング
* URLパラメタから検索条件を取得して、Twitterでのリンク共有から絞り込み済みの状態にアクセス(「どうしよー」「こん中から選べ ほらリンクだぞ」ってできたら便利そう)

などですかね。

## 最後に

かわいい(けどそれだけじゃない)キャラクター・美麗なイラスト・よく練られたストーリー~~・引きやすいガシャ~~にぶん殴られるアイドルマスターシャイニーカラーズをぜひ遊んでみてください。
PCブラウザでも遊べます。こちらから→ https://shinycolors.enza.fun/
スマートフォンアプリ版もあります。PCと同じセーブデータを使えるので、外ではスマホ・家でPCという感じでプレイ環境を変えられます！

-----------------

P.S. ゲーム大好き・自分に自信が持てないけど変わりたい・双子のお姉ちゃん・顔が良い眠り姫こと**大崎甜花**ちゃんをよろしくおねがいします。

![甜花.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99470/b833e332-d0a2-7acd-1253-e0095c503db3.jpeg)

2020年10月22日現在、左下の【トゥインクル・トゥインクル】を入手できるイベント「ミルキィウェイ61-世界と世界がまじわる夜に-」が復刻開催されています。
これから始めるという方でも、プロデュースを2回終えると(早いシーズンで負けてしまってもOK)イベントポイントで1枚は入手できます！！！
(追記: この復刻イベントは終了しました)