概要
コンテンツ内で販売する商材として、ソーシャルゲームにおける所謂ガチャは有力な選択肢になり得ます。
しかし、ユーザーの所持データを更新すれば理論上無限に排出できるゲームアイテム等と異なり、NFTトークンは1度排出されると2度と排出することができません。
よって、NFTトークンを排出物に含むガチャをコンテンツ内で販売する場合、ガチャに必要な機能(開催情報などの定性データや排出される景品などを登録する管理機能、ユーザー操作を受けて実行される景品の抽選機能、ガチャの実行履歴の確認機能など)は、ソーシャルゲームにおけるそれよりも複雑なものとなります。
ここでは、一般的なソーシャルゲームのガチャとの違いを中心として、PMP提供のAPIを組み合わせたガチャ機能の設計について述べます。
注意
Web3で所謂ガチャ機能を提供する際の法的な留意点につきましては、各社法務でご確認の上、設計実施を行ってください。弊社として一切の責任を負うものではございません。
システム設計
フローチャートの一例
---
title: NFTトークンが排出されるガチャ
---
graph TB
SYSTEM01(["ガチャ画面"])
API01{{"決済開始API"}}
SYSTEM01-."ガチャ実行".->API01
DB01[("必要情報をレコード")]
API01--"発行成功"-->DB01
WINDOW01("エラー通知")
DB01--"レコード失敗"-->WINDOW01
API01--"発行失敗"-->WINDOW01
API02{{"決済確認API"}}
DB01--"PMP決済ページを表示"-->API02
API03{{"決済キャンセルAPI"}}
API02-."中止".->API03
BRANCH01{"失効成功"}
BRANCH01--"NO"-->API02
API03-->BRANCH01
DB02[("ステータス更新")]
BRANCH01--"YES or 有効期限切れエラー"-->DB02
BRANCH02{"更新成功"}
DB02--"キャンセル"-->BRANCH02
WINDOW03("キャンセル通知")
BRANCH02--"NO"-->DB02
BRANCH02--"YES"-->WINDOW03
BRANCH03{"決済完了"}
API02-->BRANCH03
subgraph SUB01 ["トランザクション"]
direction TB
SUB01SYSTEM01(["抽選処理"])
SUB01DB01[("抽選結果等のレコード")]
SUB01SYSTEM01--"抽選完了"-->SUB01DB01
SUB01DB02[("ステータス更新")]
SUB01DB01-->SUB01DB02
SUB01BRANCH01{"正常終了"}
SUB01DB02--"決済完了"-->SUB01BRANCH01
SUB01BRANCH01--"NO"-->SUB01SYSTEM01
end
BRANCH03--"CREATED, PAYMENT_WAITING"-->API02
BRANCH03--"CANCELED, PAYMENT_FAILDE, EXPIRED"-->DB02
BRANCH03--"COMPLETED"-->SUB01SYSTEM01
WINDOW04("ガチャ演出など")
SUB01BRANCH01--"YES"-->WINDOW04
subgraph SUB02 ["トランザクション"]
direction TB
SUB02SYSTEM01(["ゲームアイテムの付与など"])
SUB02DB01[("ステータス更新")]
SUB02SYSTEM01--"付与完了"-->SUB02DB01
SUB02BRANCH01{"正常終了"}
SUB02DB01--"購入完了"-->SUB02BRANCH01
SUB02BRANCH01--"NO"-->SUB02SYSTEM01
end
WINDOW04-->SUB02SYSTEM01
WINDOW05("ガチャ結果画面")
SUB02BRANCH01--"YES"-->WINDOW05
利用するAPI
ガチャの実行に際して利用されるPMP提供APIは以下のとおりです。
決済関連
NFT移転関連
ガチャのデータ管理のポイント
開催情報などの定性データは、コンテンツ内で表示する情報などを考慮して、必要なだけ準備をお願いします。
ここではシステムの根幹、ガチャから排出される景品情報の管理について述べます。
NFTトークンの最大の特徴は、理論上無限に排出できるゲームアイテム等と異なり、1度排出されると2度と排出することができないことです。このため、必ずNFTトークン単位で景品情報を登録する必要があります。
また、NFTトークンはトークン単位で厳密な所有者のデータを有するため、登録されるNFTトークンが間違いなくコンテンツ口座に保持されている必要があります。
以上を踏まえると、PMPではコンテンツからユーザーへのNFT移転にNFT移転APIを利用いただいておりますので、NFTトークンを排出景品として登録する際には、次のような手順が必要になります。
- CONTENTS_DEFAULT口座が保有しているNFTトークンを確認する。
- それらの中で開催期間に重複のある他のガチャに景品として登録されたNFTトークンを取り除く。
- 残ったNFTトークンから必要なものを選別して実際の排出景品に登録する。
管理機能を設計する際には、この流れから外れないようにしてください。
ガチャの抽選処理のポイント
前述の排出される景品情報とも関連しますが、NFTトークンを含めたガチャの抽選処理について述べます。
繰り返しになりますが、ユーザーの所持データを更新すれば理論上無限に排出できるゲームアイテム等と異なり、NFTトークンは1度排出されると2度と排出することができません。
このため、NFTトークンを含めたガチャの処理には、排出されたNFTトークンが再び排出されないような機能を折り込む必要があります。
たとえば、次の表のような景品が排出される小さなガチャを例にあげます。
景品 | 最大排出数の設定 | 未排出の景品個数 |
NFTトークン(トークンID: 1) | 1 | 1 |
NFTトークン(トークンID: 2) | 1 | 1 |
NFTトークン(トークンID: 3) | 1 | 1 |
ゲームアイテムA | 10 | 10 |
ゲームアイテムB | 100 | 100 |
ゲームアイテムC | 1000 | 1000 |
それぞれの景品の排出確率(%)は、100 ×(対象の景品の未排出の個数)÷(すべての景品の未排出の景品個数の和)になります。
よって初回抽選時のNFTトークン(トークンID: 1)の排出確率は、未排出の景品個数の和が 1 + 1 + 1 + 10 + 100 + 1000 = 1113 であることから、100 × 1 / 1113 ≒ 9% です。
仮に初回抽選でNFTトークン(トークンID: 1)が排出されたとすると、以降の抽選でのNFTトークン(トークンID: 1)の排出確率は常に 0% となります。
また、300回抽選してNFTトークン(トークンID: 1)が排出されなかったとすると、次の抽選のでNFTトークン(トークンID: 1)の排出確率は、 未排出の景品個数の和が 1 + 1 + 1 + 10 + 100 + 1000 - 300 = 813 であることから、100 × 1 / 813 ≒ 12% です。
なお、実際のNFTトークンの移転処理を開始する前に、必ず抽選結果の記録を行い、ガチャの抽選処理を完了させてください。
何度も繰り返して恐縮ですが、NFTトークンは1度排出されると2度と排出することができません。
たとえば1度に複数回の抽選を行って、いくつかのNFTトークンに当選したユーザーがいたとして、そのユーザーの最終的な抽選結果が確定する前にNFTトークンの移転を開始してしまうと、NFTトークンの移転処理でエラーが発生した際に取り返しがつかなくなります。
NFTトークンの移転開始を抽選結果が確定した後にしさえすれば、別のユーザーの抽選で移転すべきNFTトークンが排出されることは絶対にないため、仮に移転でエラーが発生しても、同じトークンを同じユーザーに移転させるよう再度APIをリクエストしていただくだけで解決します。
- ガチャの抽選結果を確定させる。
- 当選したNFTの移転を行う。
この流れを必ず守って実装してください。
非同期でのNFTトークン付与について
ゲーム上の性質として、同じNFTアセットに属するNFTトークンが、ガチャからの排出時に全く同じ機能を持つ場合は、NFTトークンではなくNFTアセットが排出されるようなガチャにすることも検討に値します。
次のような景品が排出されるガチャを作成するイメージです。
景品 | 最大排出数の設定 | 未排出の景品個数 |
NFTアセットA | 10 | 10 |
NFTアセットB | 10 | 10 |
NFTアセットC | 10 | 10 |
ゲームアイテムA | 50 | 50 |
ゲームアイテムB | 100 | 100 |
ゲームアイテムC | 1000 | 1000 |
このような形にするメリットは、排出物であるNFTアセットA, B, Cを、たとえば交換チケットといったゲームアイテムにし、そのゲームアイテムと交換する形で、実際のNFTトークンをユーザーへ付与するようなシステムが採用できる点です。
コンテンツからユーザーへのNFT移転にはNFT移転APIを利用いただく関係上、どうしてもリクエストオーバーヘッドが避けられず、ガチャの処理には時間が掛かってしまいます。
しかし、前述のシステムを採用すれば、ガチャの抽選とNFTトークンの付与を非同期に処理できるため、ガチャのパフォーマンスを引き上げることができ、その分だけユーザー体験も大きく向上させられます。
ガチャはコンテンツの収益の柱になり得る重要な商材であることが多いため、そのUXを追求する意味で、このような方針も是非ご検討ください。
ガチャの実行履歴のポイント
前述のガチャの抽選処理とも関連しますが、ガチャの実行履歴はユーザーからのリクエスト単位で、そのリクエスト中に実行される抽選回数を1つのグループにしたトランザクションを実行履歴に残す必要があります。
たとえば、ユーザーAから10回ガチャを引くリクエストが来た場合、ほぼ時間差なくユーザーBからも1回ガチャを引くリクエストが来たとしても、必ず先着したユーザーAの10回分の抽選を実行して履歴を残したあと、ユーザーBの1回分の抽選を実行して履歴を残さなければなりません。
トランザクションロックに失敗した場合は、既に排出済みのNFTトークンを再度排出しようとするような、超低頻度で発生する厄介なバグを呼び込むことになるため、十分に注意して実装してください。
具体的に言うと、抽選処理の開始から抽選後の履歴記録まで、ガチャの一連の処理を実行するに当たっては、少なくとも未排出の景品個数の読み出しから排他制御を掛け、他のリクエストの影響を遮断することが必須となります。
また、NFTトークン単位で景品情報を登録することと同じく、ガチャの実行履歴もまたNFTトークン単位で排出物を記録してください。
なお、コンテンツ内で分析などに用いる情報などは、上記のような単純な排出データに加えて、独自に必要な分だけ記録をお願いします。