新ゲームタイトル Meisyo+(仮)の開発決定・ゲームコンセプトについて

東京オリンピックが終わりましたね。
野球が稲葉監督の元、優勝し、強かったなーと思っているこの頃です。

今回、名将と呼ばれた者達(Meisyo)の新タイトル、Meisyo+(仮)を開発することにしました。
ゲームコンセプトを変え、よりシミュレーション要素を入れた、プレイ時間がより必要になるシステムを採用する予定です。

テストプレイメンバーは近日中に募集を開始する予定です。

開発理由

大きくは3つあります。

  1. プレイ人口を増やせる可能性が高い
  2. コンセプトを達成するためには、プログラム言語の能力が足りていない
  3. 収益が見込める

1. プレイ人口を増やせる可能性が高い

まずは、多くの人に継続的にプレイをしてもらいたいと以前から思っています。
現在は月150名程度ですが・・・月1万名など、中堅ソーシャルゲーム以上の人口を獲得したいと思っています。

このゲームは、人が増えれば増えるほど戦略が必要になって楽しくなるゲーム性ですし、
考えて、試して、誰も知らないあなたなりの答えを見つけることは、人が多いと色々考慮できますしね!
人が多いほど人が増えるというネット上の特性もありますし、拡大は進めていきたいと思っています。

かつ、「3. 収益が見込める」に関連しています。
現状、ゲーム収入が広告費をはじめとする運営費を上回っています。
ROIで言えば3倍くらい(人件費抜き)ですね。
つまり、広告費をもっとかければプレイ人口を増やせるのでは?と思っています。

2. コンセプトを達成するためには、プログラム言語の能力が足りていない

Meisyoでは、バックエンドをPHP5(CakePHP2)で書いています。
ただ、処理が遅くて実装できていないことが多いです。
たとえば、投球1球ごとのデータ保存・分析等ですね。
敵投手の配球を分析し、読み勝ちすることも今のところ出来ません。

本来Meisyoで使用したいスポーツアナリティクスには、データ分析やさらに高度な分析能力(機械学習他)が必要ですが、、PHPではフルスクラッチ(全部自作)で実装しないといけません。つらい。

そのため、Meisyo+をPython(Flask2)で実装します。
機械学習やその他分析モジュールも使えるようになるので、可視化等も簡単にできるようになります。

Meisyo+では、追加練習(特訓)を現実に近い下記のようなものを想定しています。

  1. 投球実践
  2. 投球実践をしたい投手を選びます。打者はオーダー通りです。
    27アウトを取られるまで、チェンジありで試合を続けます。

  3. フリー打撃
  4. 打撃実践をしたい打者、対戦するフリー打撃投手NPCを選びます。
    27アウトを取られるまで、チェンジありで試合を続けます。
    打者本来の打撃能力や長打・HR率を確認するために利用する想定です。
    *フリー打撃投手NPC: ストレートしか投げないNPC投手。Meisyoの「そこのお前」のようなモノ。

  5. 打撃実践
  6. 打撃実践をしたい打者、対戦する投手を自校から選びます。
    27アウトを取られるまで、チェンジありで試合を続けます。

  7. 守備練(全体)
  8. 1000本?ノックを全選手に分散して行います。
    練習後、守備範囲を表示します。
    *守備範囲: どこに球が飛んで、ヒットorアウトだったのか可視化

  9. 守備練(個別)
  10. 1000本?ノックを特定の選手に行います。
    練習後、守備範囲を表示します。
    *守備範囲: どこに球が飛んで、ヒットorアウトだったのか可視化

  11. 紅白戦
  12. スタメン(紅軍)とそれ以外の自動選定チーム(白軍)で試合を行います。

Meisyoでは、他校の選手(のコピーを作り出して)と対戦することが可能でしたが、Meisyo+では自チーム内のみの対戦を想定しています。
Meisyo+では他校との対戦は、練習試合または模擬戦で行ってくださいというスタンスになります。その分、模擬戦の実行がチケット入手等を含め楽になる予定です。

データ分析をより細かくできるようになる&試合処理を改善したので、上記のようにシミュレーション系を多くしたいなと思っています。
その分、プレイ時間がよりかかるかなと思っています。

3. 収益が見込める

これまでは趣味の範疇でしたが、黒字になったのでちょっと希望を見出しています。

実績は下記の通りです。
表示数は1.5万とまだまだですが、いけるんでね?と思ってます。

CTR等も表示場所、方法によって大きく変わるので追加検討していきたいですね。

ただ、ゲームコンセプトが失われないようにしていきたいです。

少額のお金のためにコンセプトがぶっ壊れて、誰も遊ばなくなるのはヤですから。

コンセプトシート

PJ_Meisyo+

※追記(08/27)
データ教育のための機能を作成します。
ゲームとしてできること、教育資材としてできることは違うと思いますので、そちらにも対応していきたいと思います。

最後に

コンセプトは以前発表していた[Meisyo] ゲーム内容刷新予定についてを参考にしてはいますが、大きく異なることもございます。ご了承ください。

ヒストグラムの階級数を決める方法論

データ分析業務ははっきり言って泥臭い。
分析の設計を行い、可視化を行ってから使えるデータかどうか判断できる。
そもそもそれはデータ分析前の話なのだが。

今回は、可視化の中でもデータの傾向を把握するのに役立つヒストグラム、その階級数を決める方法論を確認したい。
そこには思わぬ落とし穴があった。

1. きっかけ

筆者はコンサル(自社)やデータ分析受託会社、事業会社への研修を行うことが度々ある。
統計学をはじめ、科学は一つ一つの積み重ねで結果を出す。
そのうち、1ステップでも間違いがあれば結論が覆ることがある。

初学者はよく間違いを犯す。私もそうだった。

~その昔~
上長「決定木で要因分析した後、分かれたノードごとに数値を確認しておいて。」

ワイ「平均値と標準偏差が一致することを確認しました!問題ないです!」
上長「おっ早いね。分布はどうだった?」
ワイ(あ、分布は見てなかったわ・・)
ワイ「データはあるので今可視化しますね~」

ワイ「なんやこれ・・・全然違うやんけ」
上長「せやな」(やり直して来いよー)

ここまではっきり出ることは珍しいが、よくありがちなミスである。
要因分析をしたところで、ユーザー層が全く違う人たちを取ってくることはままある。
ユーザー層が似通っている根拠づけとして、分布を確認することは必要だろう。

データ分析の前段階で良く行うのは、平均値や中央値、標準偏差など代表値を確認することである。
ただし、今回のように当たり前に使われている代表値が意味をなさないことがある。

ちなみに、上記の平均値と分散は、どちらも10、4.5あたりである。
(実験コード(1)は後に記載している。)
可視化しない場合はほぼ変わらないと判断されてもおかしくはないだろう。
今回可視化したことによって、判断が変わることだろう。

2. ビン数決定どうしよう…

そういった背景もあり、基本的に私は必ず分布を確認することにしている。
ただ、分布を確認する場合、どうしても越えなければならない壁がある。

階級数設定(ビン付け)が経験則になることである。

それに対して、最近統計学入門(基礎統計学Ⅰ;赤本)を読み返していたところ、可視化のうち、ヒストグラムに関する記載があった。

P.22

このように、ヒストグラムを描くことによって、現象の基礎にある本質が発見されることがあり、単に理解の手助けとなるだけではないことが分かる。

同

度数分布表やヒストグラムを作成するときに注意すべき点は、階級数の問題と階級幅の問題である。
(略)
このように、階級をどのように取るかを決める統一的ルールはない。

うーん確かになあ。
例題として挙げるなら、以下のような分布があったらどうするかという話が一般的だろうか。

まずはそのままビン数は10。

正規分布かな・・・?170という数字に意味があるのかな。

次にもう少し細かくしてみる。k(ビン数)=100だ!

なんだろう・・・細かすぎてよくわからない。

ここで正解を出しておこう。
これは、30代の日本人男女の身長(cm)の分布を合わせたものである。

データは国民健康・栄養調査 身長・体重の平均値及び標準偏差 – 年齢階級、身長・体重別、人数、平均値、標準偏差 – 男性・女性、1歳以上〔体重は妊婦除外〕 を利用した。

簡単な多峰性を持つ正規分布だということは答えを見たらわかるが、ヒストグラムを描写しているときはイマイチわからなかったのではないか。
この正解の図を簡単に出せるとありがたいのだが。

赤本によると、スタージェスの公式というものがあるらしい。

k ≒ 1+log2(n)
*k=階級数の目安
*n=サンプルサイズ

ふむ、使ってみよう。今回は10になるのか。これって最初に確認したような・・・

やっぱりわからねえええええええ。。。。。。

答えが分かっているから何となくそれっぽく見えるが、前情報がないと判断できないだろう。
前情報が分からないから判断は難しいのである。

よし!それなら総当たりや!

for i in np.arange(10, 100):
    print("i=%s" % i)
    plt.hist(y, bins=i)
    plt.show()

1つずつ見たけど、なんもわからん・・・という人が多いのではないか。
それっぽく見えるけど、決定的な証拠として採用できるものがない。

作成したy1, y2のデータは、コード(2)の通りである。

y1 = np.random.normal(loc=171.2, scale=5.5, size=257)
y2 = np.random.normal(loc=158.6, scale=6.0, size=282)

「これならわかりそうなもんだけどなあ・・・」
私も思った。でもわからないのだ。

このように、分布を確認したほうが良いが、したところで何かが分かるとは限らないことに注意が必要だ。
ヒストグラムの階級数を決める方法論は・・・今のところなさそうだ。

今回のように多峰性があり、かつ分布が2つのみであることが事前に分かっているのであれば何らかの方法は取れるかもしれない。

しかし、ビン付けの総当たりをしてみたが、有効そうな数値は存在しなかった。
そのため、どのような数値を計算式で求めたところで意味がないと判断した。
*この判断も経験則であるが、ヒトのイメージでの判断能力は意外と高い。画像認識も然りだ。

実験コード

(1)

import numpy as np
import matplotlib.pyplot as plt
n = 10000

# 一様分布用関数
def randint(a, b, n):
    return (b - a) * np.random.rand(n) + a

# 正規分布
y1 = np.random.normal(loc=10.0, scale=4.5, size=n)
y1 = np.where(y1 < 0, np.nan, y1)
y1 = y1[~np.isnan(y1)]

# 一様分布
y2 = randint(2, 18, n) 
y2 = np.where(y2 < 0, 0, y2)
y2 = y2[~np.isnan(y2)]

# 可視化
plt.hist(y1, bins=100, alpha=0.5, label='A')
plt.hist(y2, bins=100, alpha=0.5, label='B')
plt.title('User Segments')
plt.legend()
plt.show()

# 代表値計算
print("A:", np.mean(y1), np.std(y1))
print("B:", np.mean(y2), np.std(y2))

(2)

y1 = np.random.normal(loc=171.2, scale=5.5, size=257)
y2 = np.random.normal(loc=158.6, scale=6.0, size=282)

y = np.append(y1, y2)

# 問題提起
plt.hist(y)
plt.show()

# ビン100
plt.hist(y, bins=100)
plt.show()

# 正解
plt.hist(y1, alpha=0.5)
plt.hist(y2, alpha=0.5)
plt.show()

# スタージェスの公式
def calc_sta(n):
    return int(1 + np.log2(n))

plt.hist(y, bins=calc_sta(len(y)))
plt.show()
print(calc_sta(len(y)))

# 総当たり
for i in np.arange(10, 100):
    print("i=%s" % i)
    plt.hist(y, bins=i)
    plt.show()

参考文献

[Meisyo] ゲーム内アイテムの課金での価格設定について

Meisyoではアイテム課金制を採用しています。
ただ、その価格設定理由があいまいだったので記載しておきます。

記載内容

アイテムリストとそれぞれの価格設定理由
(2021年7月現在)

基礎方針

アイテムはゲーム内通貨ですべて購入可能。1P=1円。
※課金ポイントでのみ購入できるアイテムは存在するが、利用可能期間がさらに長いもののみ。

有償ガチャはなし。
※通常ガチャ用Pはゲーム内通貨1P=2Pで交換可能。

課金するなら一人月1000円程度を想定している。
※売上を確保するなら、ガチャなどで強さを追い求めさせる方がいいことは分かっている。ただ、ゲームコンセプトにある通り少ないゲームプレイ時間(1日5分程度)に制限しながら、月に1万以上かけさせるのはあるべき姿を逸脱しているのでは?と思っているためこの金額設定。

戦略が大事なゲームなので、課金者が強くなり過ぎないよう制限を設けている。

アイテムリスト

選手強化

気合の塊

+3までの強化用に不足しているなら買っていい。+4~5は成功確率的にこのPでは購入すべきではないだろう。
この価格に設定している理由は、販売の最低額(10分の1で売れる=1P/個)を保証するため。
探索等で集めて売って、その他の欲しいアイテムを購入してもらうために最低でも10Pにしている。

体力の塊・調子の塊

あまりにも安すぎると、「大会(公式戦)で使うのは当たり前」になってしまうので20Pにしている。
体力の塊は1つでHP30回復なので、スタメンに代わりが居ないチームで試合間隔が短いと20P×10~15人が必要。それよりも代わりを育成してほしい。
調子の塊は1つで調子+5(使用上限70)なので、意図的に上げることは強さに直結すると言えばする。使用上限を70に設定しているのは、100まで上げることが可能だと能力上昇値が高く、強すぎるため。

経験の巻物

お手軽LvUPアイテムだが、Lvでの減衰が利く等簡単になりすぎないようにしている。価格も高めの40Pにしている。

選手能力リセットチケット

育成にはランダム要素が強いので、試行錯誤を繰り返せるほうが強い。
ただ、あまりにも簡単にできるとゲームバランスが壊れる(Meisyoの前ゲームで実証済み)ので150Pにしている。

監督強化

育成のコア。切り替えが容易になると、育成したい選手ごとに最適化できるようなありえない姿になるため、500Pにしている。

アイテムボックス

課金で売り出したらすぐ強くなれてしまい、積み重ねをする意味がないので非売品にしている。

その他

試合チケット

経験の巻物等の課金アイテムの価格と、得られる経験値やアイテムを換算したら40Pになった。
20Pにすると、買って使う → 試合での入手期待値が20P なので永久機関が出来上がる。

プレミアムアカウントチケット

30日500P(課金するなら一人月1000円程度を想定)のベースになっている。
放置可能時間を長くできるのと、取得経験値アップがあるので、基本的にプレイしている間は常に欲しい。

スロット増加チケット

5個で50人増える。
プレミアムアカウントチケットよりは効果は見劣りするが、選択肢の一つとして採用してもらうために500Pにしている。
育成できる選手の幅を増やしたい場合はこちら。

選手EXP増加チケット

プレミアムアカウントチケットよりは効果は見劣りするが、選択肢の一つとして採用してもらうために500Pにしている。
強くしたい選手を早めに育成したい場合はこちら。

さいごに

今回はアイテム価格設定理由を明確にしました。
「こんなアイテムが欲しい!」等ありましたら、コメントいただければ幸いです。

Work It! 更新予定 2021.07

知り合いと話してきて、案をもらったので更新しておきます。

課題点

Must to Haveではない

具体的な使い道が分からない

チュートリアルがない

いくら課金させるのかわからない

タスクをコピーできないので汎用性がない

解決策

Must to Haveではない

「具体的な使い道がない」と同じ。

具体的な使い道が分からない

「何度も繰り返し行う、ミスをしたくない定型業務(行政書類や入社書類など)の手順を明確にし、具体的な進捗状況を共有できる&報告が可能となる」ような言語化が必要か

チュートリアルがない

そもそも「具体的な使い道がない」と説明ができない気がする。。

いくら課金させるのかわからない

まだ作ってません。
ビジネスユースが基本ですね。

タスクをコピーできないので汎用性がない

「何度も繰り返し行う、ミスをしたくない定型業務」のタスクは使いまわしするはずなのに、そのユースケースを考えて作っていない。
方針を決めないとダメですね。

良い所

ユーザーの感情を考慮に入れている

何かを完了した時にコメントが少しでもあると嬉しい
タスク管理サービスは無味乾燥になりがち

タスクリストさっくりと作れるのは楽

WindowsやMacだと、系統的にリストを作るのすらだるい。
タスクを階層的に表示してくれるのはかなり良いポイントだと思う。

その他

色々と話していて思ったのですが、方針設定があいまいだったかなと思います。

Pythonでアプリは作れるようになったものの、まだビジネスユースには使えないと思います。
利用目的が明確でないので。
自分の業務管理に使えるようなレベルにしたいですね。

[Meisyo] ゲーム内容刷新予定について

Work It!がある程度形ができてきたので、
Meisyoで今考えているゲーム内容の刷新を公開しておきます。

刷新内容

プログラム再構築

 UI改修、高速化とセキュリティ向上のため、プログラムを再構築しようと考えています。
 現在使っているフレームワーク(CakePHP)のバージョンが低くなっているので、Python(Flask or Django)で書き直します。
 もちろんですが、データは引き継ぐ予定です。

 UIが現代風になり使いやすく、データ分析機能が強化されるかもしれません。
 ※もしかしたら、機械学習でのデータ分析や待ち球設定などができるかも(技術的には可能です)

ストーリー刷新

 ストーリーが個人的に作ったものでイマイチなので、刷新しようと思います。
 ストーリーに合わせて機能も作り直します。ストーリーありきで進めたいところです。

 小説家になろう等で調べて、作者の方に声をかけてみようとは思っています。
 良さそうなストーリーを知っている、または作者の方がいらっしゃれば連絡をお願いしたいところです。
 ※レベニューシェアのような契約を考えています。ある程度ストーリーが長くあると嬉しい。
 ※画像イメージ等の共有もあるので、作者の方の意向がMeisyoに大分入りそうです。

ソーシャル機能の強化

 Meisyoは完全にソロゲーだったので、フレンド等が意味があるように作り変えます。
 加えて、(3回までの)リアルタイム対戦機能などを実装する予定です。

終わりに

 これはあくまで案ですが、もっと多くの人に遊んでもらいたい欲があるので、具体的に進めていきたいですね。

 スケジュール:
 1・ストーリーの選定(利用条件等の選定)
 2・実装内容検討
  ストーリーに合った機能内容を検討。
 3・画像等の用意
 4・方針公表
 5・プログラム作成
  現在のPHP版をベースに作成。
  テーブル構造等はほぼ同じになるはずなので、データ移行は可能。
 6・テスト公開
  現在のMeisyoのデータを移行して、テストプレイを行ってバグを減らしていく。
 7・正式公開
  現在のMeisyoのデータを移行後、PHP版をクローズ。
  Python版(URLも新しく取得)のみプレイ可能に。
  ※PHP版はプログラムをフリー公開する。

結構長丁場になりそうですが、お楽しみいただけるように進めていきます。

[Meisyo] Viewは不要!SQL処理高速化方法

今回の問題は、対戦成績をデータ分析用に選手対選手で個別に保存していたことから始まります。

選手個人の総合成績をView処理で出力しまいした。
ただ・・・インデックス等がないのでめっちゃ計算時間が掛かるー!

ユーザーを少なく見積もって100ユーザーでも、1ユーザー最低10選手=1000選手持っています。
最大組み合わせ数は、1000選手×999選手=ほぼ100万・・・多すぎる(^^;

そういったものをSQLでSUMすればどうなるか。
そして、試合ごとに全選手を更新する。

もちろん重かった。
悲しかったです。

というわけで、対応策は下記の通りにしました。
・Viewではなく、総合成績の中間テーブルを作るようにしました。
・更新対象を狭め、自分と対戦相手の選手のみとしました。

改良前

個別成績テーブルスキーマ:
選手ID, 対戦選手ID, 試合数…

↓ 試合ごとにSQLでSUM(アクティブなユーザーの全選手)

総合成績Viewスキーマ:
選手ID, 試合数…

↓

各種データ呼び出し

改良後

個別成績テーブルスキーマ:
選手ID, 対戦選手ID, 試合数…

↓ 試合ごとに自分と対戦相手の選手の成績だけ、SQLでSUM

総合成績テーブルスキーマ:
選手ID, 試合数…

↓

各種データ呼び出し

結果

試合の待ち時間5~10秒(またはエラー)が、2秒以内に収まるようになりました。
SQLをテキトーに設定していたのですが、やっぱりちゃんと考えて書かないとダメですね。
いい教訓になりました。

WorkIt! Lv機能の追加

Work It!に新機能を追加しました。

Lvは良い行動が継続しているかどうかを量的に確認できる指標となります。

ある研究では、良い行動を継続するためには、
・きっかけ
・少しの楽しさ(報酬)

が必要とされています。

そのため、Lvが上がることにより楽しさを達成できるのではないか?と考えています。
目安は、Lv10で10分に1程度、最長で8時間に1タスク終了ごとに上がります。

今後は、チュートリアル作成と多言語対応を行いたいと思います。

Work It! 共有機能等のアップデート

Work It!のアップデート情報をお知らせします。

下記アップデートを行いました。
・他人へのタスク共有機能の追加
・タイムライン機能の強化
 他人の行動が見れる、Goodを送れるようにした。
・その他表示等の改修

Work It!は「誰かと一緒にタスクを進めるために」が中心の思想ですので、共有機能は必須でした。
今後はレベルデザインをしてみて、課金システム導入、広告施策実行を行う予定です。

Work It! ランディングページの作成

トップページをランディングページ(サイトの情報をユーザーに適切に伝えるページ)に変更しました。

内容はWebマーケティングの知識と合わせて、GithubやAtlassian、Trelloなどの類似機能を持つアプリを参考に作成。

これまでは説明少なすぎたなと反省しています。
特に重要なことは、どんなユースケースが存在するのかを明確にすること。

ちょっと作りが甘いので更新する予定ではあります。

Work It! タスクタイムライン機能のリリース

Work It!のアップデート情報をお知らせします。

タスクタイムライン機能をリリースしました。
こちらの機能は、自分を含め他ユーザーが何をしているか見ることができます。
タイムラインに表示させたくない場合はプライベート設定を行うことで対応が可能です。

想定利用用途

・他の人が進めているのを見てやる気を出す

使い方

Timelineから閲覧できます。
プライベート設定をしたタスクは鍵マークがつくようになっています。

表示は下記のようになっています。
今後、ユーザー設定の追加があるので、こちらの表示がもう少しわかりやすくなる予定です。

さいごに

不具合等ございましたらコメントくださいませ。