こんにちは、小島です!!
サラリーマンとしてプロダクトマネージャーをやりながら、趣味でWEBサービスの個人開発をしている岐阜県出身の25歳です。
今日は、個人開発のプロダクトで初月MAU20,000を達成したときのお話をします。
MAU20,000ごときで偉そうにするな😡 とお叱りの声が届きそうですが...
何を考えて企画したのか。またそれをどう実装したのか。そしてそれをどう広報したのか。
記事に残しておくことで、ほんの少しでも誰かの役に立てば嬉しいなということで筆を取ることにしました。
結構長々と語っています。ノウハウ(学んだこと)だけ教えろ!という方は、以下の章まで飛んでいただければ幸いです!
→ 学びと悩み
またこの記事は、私が所属している企業FLINTERSアドベントカレンダー22日目の記事でもあります。
幅広い内容の記事がギッシリ詰まってますので、この記事を読んだら他記事もぜひどうぞ!!
作ったモノ
ゲームキャラの格付けサービス「GGrating」 を作りました。
(現在はメンテナンス/アップデートを行なっていません)
ゲーマー界隈に存在する「キャラクターを格付けする文化」に着目し、それを最も簡単かつ高クオリティに実現できるプロダクトを目指して企画開発を行いました。
機能は2つ
- キャラクターランキングを閲覧できる
- キャラクターランキングを投稿できる
リリースから1ヶ月でMAU 20,000
と、投稿数 100
を達成しました。
企画・開発は僕1人で、構想からリリースまでの期間はちょうど1ヶ月でした。
企画
きっかけ
新しいゲームがリリースされたり、新キャラが登場したり、バランス調整が行われたりするタイミングで、Twitterのゲーマー界隈で最もホットになるのは「どのキャラが強いのか」というトピックです。
当時は、Pokemon UNITEというMOBA系のゲームの体験版が登場し、さらには製品版のリリースも間近という状況で、例に漏れずTwitterは「どのキャラが強いのか」という話で持ちきりでした。
その時から個人開発を行なっており、常にネタを探していた僕のアンテナには、この出来事がひっかりました。
チャンスだ、と。
競合調査
最初に行ったことは、既存の代替手段(競合)の調査です。
調査の結果、主に2つの代替手段があることがわかりました
- tiermaker.com というWEBサービス
- 画像編集ツール(photoshopなど)
競合は、想像していたよりも弱そうでした。
tiermaker.com には生成物のクオリティ高さで、
各種の画像編集ツールには手間の少なさで、
それぞれ圧倒的に勝てるイメージが湧いたので、この領域でプロダクトを作ることに決めました。
↓ 競合の tiermaker.com で作ったキャラクターランキング
ターゲット
このプロダクトのターゲットは、キャラクターランキングを作ろうとしてるゲーマーです。
彼らは、なぜキャラクターランキングを作ろうとしているのでしょうか?
ユーザー観察をするなかで、2パターンの動機がありそうだということがわかりました。
- コミュニティ内でのプレゼンス(影響力)を増やしたいから(認められたい!)
- 他者のキャラクターランキングに疑問を持ったから(自分ならもっと的確なものが作れる!)
この2パターンです。
これらの動機、ニーズを踏まえてユーザー体験を設計していきます。
ユーザー体験
まず、コアな体験として「キャラクターランキングを作成できる」ことは必須でしょう。
次に、「作成したキャラクターランキングをシェアできる」体験も必須かと思われます。
コミュニティ内でのプレゼンスを向上するためには、作成したランキングをコミュニティメンバーにみてもらう必要があるからです。
ここで1つの大きな分岐があります。画像としてシェアできるようにするか、URLとしてシェアできるようにするか、です。
先述の tiermaker.com は前者、画像として保存・シェアできるようにするアプローチをとっていました。
僕は、後者のアプローチを取ることにしました。理由は2つあります。
1つ目の理由は、ユーザーの手間を減らすためです。
画像としてシェアしてもらうためには、保存してもらう、Twitter認証してもらう、などの労力をユーザーに強いることになります。
2つめの理由は、プレゼンスがストックするようにするためです。
ユーザーが作成したキャラクターランキングがプラットフォーム上に記事としてストックするようなつくりにしておけば、プラットフォーム上のユーザーの目に触れる機会も生まれるようになります。これにより、「コミュニティ内でのプレゼンス(影響力)を増やしたい」というユーザーの欲求を、より高いレベルで満たすことができると考えました。
作成したキャラクターランキングをURLでシェアできるようにする場合、1つの問題が発生します。
それは、見た目の貧弱さです。
画像/動画などのメディア付き投稿は目を引きますが、URL付き投稿というのはあまりにも目を引きません...
この問題を解決しユーザーのニーズを満たすためには、OGPが最適だと考えました。
ユーザーが作成したキャラクターランキングがSNSでシェアされた時は、魅力的なOGPが併せて表示されるようにするのです。
↓ OGPとは、画像と説明文を使ってSNS等にシェアされたURLを強調する技術です
ユーザー体験の設計に戻ります。
ここまでをまとめると...
ユーザーのニーズ
- コミュニティ内でのプレゼンス(影響力)を増やしたい(認められたい!)
- 他者のキャラクターランキングに疑問がある(自分ならもっと的確なものが作れる!)
設計したユーザー体験
- キャラクターランキングを作成できる
- 作成したキャラクターランキングを魅力的なOGP付きURLでシェアできる
この時点で、他者のキャラクターランキングに疑問がある(自分ならもっと的確なものが作れる!)
このニーズを加味した体験が設計できていないことがわかります。
そこで、「(疑問を感じた瞬間に)他者のキャラクターランキングを編集できる」という体験を設計しようと考えました。
ただし、直接編集できるようにしてしまうと、ここでいう「他者」のプレゼンスを毀損してしまうことになります。
ですので、他者の投稿をコピーして編集し、新しい記事として投稿できるようにしました。
ここまでで、ユーザーのニーズを満たせる体験を設計できた気がします
- キャラクターランキングを作成できる
- 作成したキャラクターランキングを魅力的なOGP付きURLでシェアできる
- 他者のキャラクターランキングをもとに新しいランキングを作成できる
いよいよ実装に移りましょう!
↓ユーザー体験を考えながらiPadでワイヤーフレームを手書きするのが僕のスタイルです
開発(+詳細な仕様の検討)
技術選定
開発には以下の技術を使用しました。
- フロントエンド
- Next.js
- Tailwind CSS
- Draft.js
- バックエンド
- firebase(authentication/firestore)
- インフラ
- Vercel
- 動的OGP画像生成
- Cloudinary
技術の採用理由は「使い慣れているから」
個人開発においてはリソースがとにかく足りません。
ですから僕は、使い慣れた技術で個人開発することをお勧めしています。
作成したいプロダクトに対して最適な技術選定をおこなうことはもちろん重要ですし、新しい技術を検証することももちろん重要です。
が、これらは個人開発においてはアンチパターンだと考えています(というか僕自身が何回も失敗してきました)
”使い慣れた技術でとにかく早く、それなりのクオリティのプロダクトを作ってリリースし市場に問う”
このスピード感がないと、数打ってあたりを引くこともできないですし、なによりモチベーションが続きません。
動的にOGP画像を生成・設定する
- 作成したキャラクターランキングを魅力的なOGP付きURLでシェアできる
このユーザー体験を実現するために、ユーザーが作成した各ランキング記事にOGPを設定していきます。
まずは、どんなOGP画像にすればクリックが増えるかを考えます。
結論、以下のようなOGP画像にすることにしました。
こだわったところは、「目を引く配色」と「続きを読む」 の2つです。
配色については、さまざまなパターンを試して最もしっくりくるものを採用しました。
Twitterからデザイナーの方に声をかけて、壁打ち付き合っていただいたりもしました(その節はありがとうございました)
「続きを読む」については、ブログ等でみられるアレを参考にしました。
これにより、小さい画面に全キャラを詰め込んで見づらくなることを防ぐことと、サイト流入を促進することの2つを同時に満たすことができました。
次は、これをシステムで実装していきます。
実装上のポイントは3つ
- Next.jsの動的ルーティング機能で記事ページを作成する
- Next.jsのHeadコンポーネントで記事ページにOGPを設定する
- Cloudinaryで動的にOGP画像を生成・設定する
上2つに関しては、Next.jsの基本的な機能であるため、詳しい説明は公式ドキュメントに譲ります。
簡単に説明すると、これらを使用することで、/article
配下に複数のページを動的に作成することができるようになり(/article/[article-id]
)、動的に生成された各ページに、それぞれ独自のOGPを設定することができるようになります。
今回、動的なOGP画像生成に使用したのは、Cloudinaryです。
Cloudinaryは、画像のホスティングと、URLによる画像編集の2つの機能を持つSaaSです。
これを使ってOGP画像を動的に生成しました。手順は以下の通りです。
- ベースとなる画像をあらかじめCloudinaryにアップロードしておく
- ランキング情報(どのキャラが何位か)をURL作成関数に渡す
- URL作成関数が、ランキング情報を参照しながら画像を組み合わせてURLを作成する
- URLを記事ページにあるHeadコンポーネントのメタデータ(og:image)に渡す
とても長いのでスクロールしなくて良いんですが、例えばこんな感じのURLが生成されます↓
どの画像を背景にするか、どの画像をどの位置にどのくらいのサイズで合成するか、を順番にURLで指定するだけで画像を生成することができるので、OGP画像を動的に生成するという用途にはピッタリのサービスでした。
https://res.cloudinary.com/dpgh283yp/image/upload/c_fill,w_100,h_100,x_-126,y_-252,l_charas:d509ee278b7101e10a1d180d78682f59:ゲッコウガ_gqwdjw_jj45dd.png/c_fill,w_100,h_100,x_0,y_-252,l_charas:d509ee278b7101e10a1d180d78682f59:ルカリオ_nhaiqf_wjz1ep.png/c_fill,w_100,h_100,x_-126,y_-126,l_charas:d509ee278b7101e10a1d180d78682f59:カビゴン_o0meh2_swlgku.png/c_fill,w_100,h_100,x_0,y_-126,l_charas:d509ee278b7101e10a1d180d78682f59:ワタシラガ_ohbffg_dhdoqf.png/c_fill,w_100,h_100,x_126,y_-126,l_charas:d509ee278b7101e10a1d180d78682f59:プクリン_wwdcvv_risvou.png/c_fill,w_100,h_100,x_-126,y_0,l_charas:d509ee278b7101e10a1d180d78682f59:アローラキュウコン_zvpb1y_alescy.png/c_fill,w_100,h_100,x_0,y_0,l_charas:d509ee278b7101e10a1d180d78682f59:ウッウ_n2bkdm_swa5sp.png/c_fill,w_100,h_100,x_126,y_0,l_charas:d509ee278b7101e10a1d180d78682f59:エースバーン_zppala_mclggm.png/c_fill,w_100,h_100,x_252,y_0,l_charas:d509ee278b7101e10a1d180d78682f59:フシギバナ_uf2otn_lczjxi.png/c_fill,w_100,h_100,x_-126,y_126,l_charas:d509ee278b7101e10a1d180d78682f59:バリヤード_nvnrg3_wwkd5f.png/c_fill,w_100,h_100,x_0,y_126,l_charas:d509ee278b7101e10a1d180d78682f59:ファイアロー_vthbp3_jgq13n.png/c_fill,w_100,h_100,x_126,y_126,l_charas:d509ee278b7101e10a1d180d78682f59:カイリキー_c5jtov_ytsslv.png/c_fill,w_100,h_100,x_252,y_126,l_charas:d509ee278b7101e10a1d180d78682f59:リザードン_jfbi5l_w8tmmz.png/c_fill,w_100,h_100,x_378,y_126,l_charas:d509ee278b7101e10a1d180d78682f59:ピカチュウ_qpfqhm_wloesa.png/c_fill,w_100,h_100,x_504,y_126,l_charas:d509ee278b7101e10a1d180d78682f59:ヤドラン_stddmr_rlz9ze.png/c_fill,w_100,h_100,x_-126,y_252,l_charas:d509ee278b7101e10a1d180d78682f59:ゼラオラ_mtucus.png/c_fill,w_100,h_100,x_0,y_252,l_charas:d509ee278b7101e10a1d180d78682f59:サーナイト_i03pks.png/c_fill,w_100,h_100,x_126,y_252,l_charas:d509ee278b7101e10a1d180d78682f59:イワパレス_pv2bn7_ylcomr.png/c_fill,w_100,h_100,x_252,y_252,l_charas:d509ee278b7101e10a1d180d78682f59:ゲンガー_k07egj_jhqfvz.png/c_fill,w_100,h_100,x_378,y_252,l_charas:d509ee278b7101e10a1d180d78682f59:アブソル_htw6kr_f67ath.png/c_fill,w_100,h_100,x_504,y_252,l_charas:d509ee278b7101e10a1d180d78682f59:ガブリアス_e4gaev_jcjpx6.png/c_fill,x_0,y_0,l_ggrating_fr_ogp.png/q_auto:low,dpr_auto,w_840/ggrating_bg_ogp.jpg
あとは、サービス内にシェア動線を配置するだけです。
- コンテンツを作成した直後
- コンテンツを閲覧した直後
の2箇所にシェア動線を配置しました。
タップで完結するランキング編集
- キャラクターランキングを作成できる
このユーザー体験を実現するために、ランキング作成画面を検討・実装していきます。
ランキング作成画面のUI/UXは、ドラッグ型とタップ型の2パターンを検討しました。
ドラッグ型は、キャラクターをドラッグで動かして、ランキング表に配置していくというUI/UXです。
タップ型は、ドラッグではなくタップで移動させるUI/UXです。
初めは、直感的に操作できるぶん、ドラッグ型の方が優れていると考えていました。
しかし、試しにドラッグ型を作ってスマホで操作してみたところ、OSのジェスチャー機能が暴発して非常にUXが悪くなってしまいました。
スマホでの利用を想定していたため、泣く泣くタップ型でランキング作成画面を実装しました。
実装の概要は以下の通りです。
- ランキングの状態(二重配列)と、移動中かどうか(ブール値)をStateで管理
- キャラクターの画像をタップすると、移動中=trueに設定
- 移動中=trueの場合のみ挿入アイコンを表示
- 挿入アイコンをタップすると、そのアイコンの位置に応じてランキングの状態を更新
ログインなしで編集・投稿
- 他者のキャラクターランキングをもとに新しいランキングを作成できる
このユーザー体験を実現するためには、2つのことが重要だと考えました。
- いま閲覧しているランキングが編集できることをユーザーに伝える
- 編集できるようになるまでのハードルを可能な限り下げる
これらを念頭に実装をすすめます。
まず、「いま閲覧しているランキングが編集できることをユーザーに伝える」です
閲覧中のランキングを編集できるというのは、一般的ではない体験です。
ですから、可能な限りわかりやすく丁寧にコミュニケーションを取る必要があるでしょう。
結果として、ヘッダーと、ランキングの下部に「このランキングを編集する」ボタンを表示することにしました。
つぎに、「編集できるようになるまでのハードルを可能な限り下げる」です
これは、ログインしなくても投稿できるようにすることで実現しました。
世の投稿型サービスの多くはユーザーアカウントを作成してプロフィールを設定して...と投稿までのハードルが高すぎると感じていたので、今回は思い切ってログインしていない状態でも投稿できる仕様にしました。
実装にはFirebase Authentication の匿名認証の機能を活用しました。
これを使うと、アクセスしたユーザーに対しユーザーIDを自動発行することができます。
実装後もとくに弊害が発生しなかったのと、最初の1ヶ月で投稿数100件を達成することができたので、この方針は成功だったと考えています。
広報
個人開発で最も難しいのは広報のフェーズ、つまり「知ってもらう」ことだと思います。
知名度も権威性もない一個人が作ったアプリをどうすうれば知ってもらえるのでしょうか。
僕は、以下のような施策を試しましたが、どれもうまくいきませんでした。
- 開発の様子をツイートしてリリース前からファンを作る
- RT&投稿したらアマギフ5000円ぶんがあたるキャンペーン
- 見込みユーザーに直接DMやリプライを送って使ってみてください、と紹介する
唯一、大きく成功した施策を以下に紹介します。
コバンザメ作戦
今回試した施策の中で最もうまくいった施策は「コバンザメ作戦」でした。
コバンザメ作戦とは、伸びそうなツイートを探して、宣伝ツイートをリプライでぶらさげるという作戦です。
...はい。多分あなたは、卑怯・汚い・見苦しい と感じたのではないでしょうか💦
正直、否定できない部分もあります。
ですので、実際にそのツイートを見た方が不快な思いをしないように最新の注意を払いました。
この施策は、スケールしないし、泥臭いし、正直かなりダサいので、万人にお勧めできる手法ではありません。
が、効果はかなり良かったです。
この施策の肝は「伸びそうなツイートを見つけること」です。
ツイートが伸び切ったあとでコバンザメしても効果は良くなかったので、いかに伸びる前に伸びそうなツイートをみつけるか、という勝負になります。
最初は人力で定期的にTwitter検索するという方法でやっていましたが、後半は自動化していました。
具体的には、「IFTTTというサービスを使って、条件に一致する(ユナイトを含みRTが10以上)ツイートが見つかったらLINEに通知を送る」という処理を設定しておき、LINEに通知が来たらそのツイートにリプライする、という流れです。
学びと悩み
ここまで、個人開発のプロダクトで初月MAU20,000を達成したときのお話を、企画・実装・広報の3パートに分けて長々と語ってきました。
僕が学んだことを今一度、まとめます。
プラスの結果から学んだこと
- 「見た目が良く手間のかからない、ゲームキャラの格付けサービス」には需要がある →#
- 適切なシェア動線の配置と、目を引くOGPの設定によって、Twitterユーザーを呼び入れることができる →#
- Cloudinaryを使うことで、動的OGP画像を簡単に生成することができる →#
- ログインなしで投稿できるようにすることで、投稿数を増やせる →#
- コバンザメ作戦は初期ユーザーを確保するのに大いに役立つ →#
マイナスの結果から学んだこと
- ランキングをテキストで解説する機能は求められていない(利用者は1割にも満たなかった。Twitterで解説する人が多かった)
- タップ型のランキング編集は使いづらい。ドラッグ型をスマホでうまく実装する方法を調査すべきだった →#
- 開発の様子を発信してリリース前からファンを作るようなマーケティング手法は、王者のための戦略だと感じた。少なくともこのプロダクトには合わなかった
- プレゼントキャンペーンの応募条件に「サイト上での投稿」などぱっと見難しい条件を盛り込むべきではない。誰も参加してくれない。
こうして並べてみると、結構学びが多かったですね。
個人開発は多方面に学びを深め、ビジネスマンとしての総合力を高めることができる最高の趣味だと感じます。
一方で、悩みもあります。
このプロダクトをメンテナンス/アップデートするモチベーションが無くなりました
僕は極端にモチベーション・ドリブンな人間なのですが、その特性が悪い方向に働きました汗
先述のとおり、Pokemon UNITE というゲームにハマったことがこのプロダクトを作るきっかけでした。
しかし、Pokemon UNITEに飽きて以降、キャラランキングを作りたくなるようなゲームを遊ばなくなってしまったんですね。
自分自身がターゲットユーザーから外れてしまったことで、モチベーションが失われたのかと思います...。
ということでどなたかこのプロダクトの所有権を買ってください!5000兆円くらいで!
キャラクターを追加すればいまでも普通に使えるので、マーケティング次第でかなり頑張れるはずです(なんせ諸々検証済み!)
「個人開発のプロダクトで初月MAU20,000を達成したときのお話」は以上です!
ここまで読んでくださった方に、ほんのすこしでも役立つ知見があったら幸いです。
このあとは、FLINTERSアドベントカレンダーの他記事もぜひご覧ください。
おすすめの記事は「AIを騙してChatGPTの限界を覗く」です。今話題のAI:ChatGPTに円周率の5000兆桁目を計算させたりとやりたい放題してる最高の記事です笑