18
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ソーシャルゲームにおけるマスタ設計~ガチャ編~

Last updated at Posted at 2019-12-25

本記事はサムザップ #1 Advent Calendar 2019 の12/25の記事となります。

はじめに

Sumzapでサーバエンジニアをしています@chrno001です。

ソーシャルゲームにはゲームを動かす為に様々なマスターデータが存在します(キャラクターや敵の基本となるステータスの値だったり、武器の名前や攻撃力、防御力だったり)これらのマスターデータはゲームの内容によって色々と変化しますが、中には大きく変わることなく流用できる(できそうな)マスターデータも多くあるのが実情かと思います。

今回はそのようなマスターデータの1つであると思われるガチャのマスタ設計について考えてみたいと思います。

ガチャ関連のマスタ設計

gachagacha.png
サムザップではマスターデータをcsvで扱うプロジェクトが多いので、一般的なキャラクターを排出するようなガチャを実装するにあたって普段自分がどのようなcsvを定義しているかを紹介したいと思います。(あくまでも自分が設計する際の1例であって、プロジェクト毎で差異はあるかと思います)

今回想定するガチャの内容としては

  • 排出されるキャラクターのレアリティは★1~★4とする
  • 有償ガチャ、無償ガチャ、チケットガチャが存在する
  • 1日にそのガチャを購入できる上限回数が設定できる
  • レアリティ保障(たとえば10連中1回★3以上確定など)が設定できる
  • ノーメンテでガチャを更新できる
  • 将来的にローカライズも想定しておく

上記のようなガチャを構成するマスタデータとして下記のような4種類を定義してみます。

  • ガチャマスタ(gacha.csv)
  • ガチャ詳細マスタ(gacha_detail.csv)
  • ガチャ抽選マスタ(gacha_draw_(type)_(0-9).csv)
  • ガチャテキストマスタ(gacha_text.csv)

ガチャマスタ(gacha.csv)
ガチャの種類を管理するマスタ

フィールド PK 必須か 説明
id 数値 ガチャID
name 文字列 表示名(gacha_text.csvのtext_id)
description 文字列 説明テキスト(gacha_text.csvのtext_id)
gacha_type 数値 ガチャタイプ(1:有償ガチャ 2:無償ガチャ 3:チケットガチャなどタイプ分け)
draw_master_number 数値 このガチャで使用するガチャ抽選マスタのマスタ名を確定させるための識別子(例)gacha_type = 1, draw_master_number = 0 の場合 → 抽選に使うマスタ名 = gacha_draw_gem_0(例)gacha_type = 3, draw_master_number = 1 の場合 → 抽選に使うマスタ名 = gacha_draw_ticket_1
rarity_weight_1 数値 レアリティ★1の排出割合
rarity_weight_2 数値 レアリティ★2の排出割合
rarity_weight_3 数値 レアリティ★3の排出割合
rarity_weight_4 数値 レアリティ★4の排出割合
sp_rarity_weight_1 数値 特別枠のレアリティ★1出現割合
sp_rarity_weight_2 数値 特別枠のレアリティ★2出現割合
sp_rarity_weight_3 数値 特別枠のレアリティ★3出現割合
sp_rarity_weight_4 数値 特別枠のレアリティ★4出現割合
start_at 文字列 ガチャ公開開始日時(例:2019/12/25 14:30:00) 期限なしの場合はNULLを設定
end_at 文字列 ガチャ公開終了日時(例:2019/12/25 15:00:00) 期限なしの場合はNULLを設定

このマスタではガチャの種類(有償ガチャ、無償ガチャなど)と公開日時、それとレアリティ毎の排出割合を定義します。
ガチャの表示名や説明などは将来的にローカライズすることを意識し、このマスタに直接定義せずにガチャテキストマスタ側と関連づけておきます。
draw_master_numberというフィールドの値を使う事により使用するガチャ抽選マスタを切り替えます。こうすることによって1度作った抽選マスタを別のガチャでも再利用したりガチャの中身をごそっと入れ替えたりする事が可能です。
ノーメンテでガチャを更新したい場合は、現在公開されているガチャデータを上書きするような方法だとユーザーがアクセスしてきたタイミング次第で不整合が起こる可能性が否定できません。そこで同じ内容のガチャIDを2つ定義しておいてガチャ公開・終了日時の設定により現在公開中のガチャを切り替えるような方法で対応する事が可能です。

※csvなので型という概念はそもそもないですが、バリデーションチェックなどを想定した上でテーブル設計のように型も定義してあります。
※PKはPRIMARY KEY。こちらも概念としてはありませんがこのフィールドにてユニークとなる事を意味しています。
※必須か、が〇の場合は必ず値を設定すること、〇がついてない場合は値を設定しなくてもいい事を意味しています。なお、設定しない場合はNULLという文字列を定義します。

ガチャ詳細マスタ(gacha_detail.csv)
ガチャの排出回数など詳細情報を設定するマスタ

フィールド PK 必須か 説明
id 数値 ガチャ詳細ID
gacha_id 数値 ガチャID(gacha.csvのid)
consume_type 数値 ガチャを実行するために必要な通貨の種類(1:有償通貨 2:無償通貨 3:チケット)
consume_num 数値 ガチャを回す為の購入費用
limit_num 数値 購入可能回数(/day)1日の購入制限を設けたい場合に設定する
emit_num 数値 抽選回数(1連だったら1,10連だったら10を設定)
sp_emit_num 数値 0の場合は特別枠の抽選は行わない。1以上の場合は設定された回数分、特別枠の排出確率(gachaマスタのsp_rarity_weight_n)で抽選が行われる事になる。(どのタイミングで特別枠の排出確率が適用されるかはランダム)なお、emit_numより大きな数値を設定しないこと。

このマスタでは、gacha_idで紐づくガチャの詳細情報、ガチャの費用や排出回数(1連や10連など)や1日の購入可能回数を設定します。
consume_typeとconsume_numの2つのフィールドにてガチャの費用を決定します。例えば、consume_typeが3,consume_numが1ならそのガチャを1回回すのにチケットが1枚必要という形です。
sp_emit_numに1以上の値を設定することにより、レアリティ保障が設定できます。例としてはemit_numが10でsp_emit_numが2という場合は、10連ガチャ中2回gachaマスタのsp_rarity_weight_nの方の排出確率にて抽選が可能という想定です。

ガチャ抽選マスタ(gacha_draw_(type)_(0-9).csv)
ガチャのキャラクター毎の排出確率(重み)を定義するマスタ

フィールド PK 必須か 説明
id 数値 ガチャ抽選マスタ
character_id 数値 キャラクターID(キャラクターマスタに定義されているid、レアリティはキャラクターマスタから取得可能)
weight 数値 重み
start_at 文字列 抽選開始日時(例:2019/12/25 14:30:00)期限なしの場合はNULL
end_at 文字列 抽選終了日時(例:2019/12/25 15:00:00)期限なしの場合はNULL

このマスタではweightによってキャラクターの排出の確率を制御します。
排出するキャラクターを決定するまでの流れとしては、まずガチャマスタの値にてレアリティ抽選を行い、排出するレアリティが決定したらその後にガチャ抽選マスタの重みを見て排出キャラクターを決定します。重みの数値を調整することによりピックアップガチャなど特定のキャラクターが排出しやすいガチャを作ることも可能です。
また、抽選開始、終了日時を設定する事により指定の時間から特定のキャラクターをガチャから排出されるようにしたり排出を終了する事ができます。(コラボ系のキャラクターなどに使う事が可能かと思います)

ガチャテキストマスタ(gacha_text.csv)
ガチャにひもづく文言をまとめるマスタ

フィールド PK 必須か 説明
text_id 文字列 テキストID
ja_lang 文字列 文言(日本語)

ガチャに関わる文言はすべてこのマスタにて管理します。
将来的にローカライズする場合はXX_langのフィールドを増やす事により他のマスタのデータを特に変更することなく対応する事が可能となります。

さいごに

今回のマスタ設計については自分が考えるガチャの1例ですのでこれが正解という訳ではなく要件によって色々変化するものだとは思います。
ただ、車輪の再発明をするのではなく使える知見は有効に活用する事が重要かと思いますので、同じように設計される際の参考になれば幸いです(また、もっと良い設計ももちろんあると思いますので是非意見を頂ければと思います)

18
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?