GS2-SkillTree SDK for Game Engine API リファレンス

ゲームエンジン向け GS2-SkillTree SDK の モデルの仕様 と API のリファレンス

モデル

EzStatus

スキルツリーの解放状況

特定のプレイヤーとプロパティに対するスキルツリーの解放状態を追跡するモデルです。
解放済み(アンロック済み)のノード名のリストを管理します。ノードは解放(リストに追加)、拘束(リストから削除)、リセット(全クリア)が可能です。
既に解放済みのノードを解放しようとしたり、未解放のノードを拘束しようとするとエラーになります。
ユーザーが初めてアクセスした際に自動作成されます。

有効化条件必須デフォルト値の制限説明
statusIdstring
~ 1024文字ステータス GRN
※ サーバーが自動で設定
userIdstring
~ 128文字ユーザーID
releasedNodeNamesList<string>[]0 ~ 1000 items解放済みノードモデル名リスト
このスキルツリーでプレイヤーがアンロックしたノードモデル名のリスト。
解放(追加)、拘束(削除)、リセット(全クリア)操作により更新されます。
最大1000エントリ。

EzNodeModel

ノードモデル

スキルツリー内のノードを定義するモデルで、解放コスト・前提条件・返却動作を含みます。
各ノードには検証アクション(解放前の条件チェック)、消費アクション(支払うコスト)、先に解放が必要な前提ノードを設定できます。
ノードを拘束(未解放状態に戻す)すると、消費したリソースが返却率に基づいて部分的に返却されます。
返却入手アクションは消費アクションに返却率を乗じて自動的に計算されます。

有効化条件必須デフォルト値の制限説明
namestring
~ 128文字ノードモデル名
ノードモデル固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。
metadatastring~ 2048文字メタデータ
メタデータには任意の値を設定できます。
これらの値は GS2 の動作には影響しないため、ゲーム内で利用する情報の保存先として使用できます。
releaseVerifyActionsList<EzVerifyAction>[]0 ~ 10 items解放検証アクションリスト
このノードを解放する前に実行され、条件が満たされているかを確認する検証アクションのリスト。
例えば、プレイヤーが特定のレベルに達しているか、特定のアイテムを所持しているかを検証できます。
いずれかの検証アクションが失敗すると、ノード解放は拒否されます。最大10アクション。
releaseConsumeActionsList<EzConsumeAction>[]1 ~ 10 items解放消費アクションリスト
このノードを解放する際に実行される消費アクションのリストで、解放コストを表します。
これらのアクションは返却入手アクションの計算にも使用されます。ノードを拘束する際、各消費アクションが返却率に基づいて逆転されます。
最低1つの消費アクションが必要です。最大10アクション。
returnAcquireActionsList<EzAcquireAction>0 ~ 10 items返却入手アクションリスト
このノードを拘束(取り消し)する際に実行される入手アクションのリストで、プレイヤーに返却されるリソースを表します。
このフィールドは解放消費アクションに返却率を乗じて自動生成されます。
例えば、解放コストが100ゴールドで返却率が0.8の場合、拘束時に80ゴールドが返却されます。
最大10アクション。
restrainReturnRatefloat1.00.0 ~ 1.0返却率
このノードを拘束(未解放状態に戻す)した際に消費リソースが返却される割合。
1.0 は全額返却、0.5 は半額返却、0.0 は返却なしを意味します。
デフォルトは 1.0(全額返却)。有効範囲: 0.0〜1.0。

EzConfig

コンフィグ設定

トランザクションの変数に適用する設定値

有効化条件必須デフォルト値の制限説明
keystring
~ 64文字名前
valuestring~ 51200文字

EzAcquireAction

入手アクション

有効化条件必須デフォルト値の制限説明
action文字列列挙型
enum {
"Gs2AdReward:AcquirePointByUserId",
"Gs2Dictionary:AddEntriesByUserId",
"Gs2Enchant:ReDrawBalanceParameterStatusByUserId",
"Gs2Enchant:SetBalanceParameterStatusByUserId",
"Gs2Enchant:ReDrawRarityParameterStatusByUserId",
"Gs2Enchant:AddRarityParameterStatusByUserId",
"Gs2Enchant:SetRarityParameterStatusByUserId",
"Gs2Enhance:DirectEnhanceByUserId",
"Gs2Enhance:UnleashByUserId",
"Gs2Enhance:CreateProgressByUserId",
"Gs2Exchange:ExchangeByUserId",
"Gs2Exchange:IncrementalExchangeByUserId",
"Gs2Exchange:CreateAwaitByUserId",
"Gs2Exchange:AcquireForceByUserId",
"Gs2Exchange:SkipByUserId",
"Gs2Experience:AddExperienceByUserId",
"Gs2Experience:SetExperienceByUserId",
"Gs2Experience:AddRankCapByUserId",
"Gs2Experience:SetRankCapByUserId",
"Gs2Experience:MultiplyAcquireActionsByUserId",
"Gs2Formation:AddMoldCapacityByUserId",
"Gs2Formation:SetMoldCapacityByUserId",
"Gs2Formation:AcquireActionsToFormProperties",
"Gs2Formation:SetFormByUserId",
"Gs2Formation:AcquireActionsToPropertyFormProperties",
"Gs2Friend:UpdateProfileByUserId",
"Gs2Grade:AddGradeByUserId",
"Gs2Grade:ApplyRankCapByUserId",
"Gs2Grade:MultiplyAcquireActionsByUserId",
"Gs2Guild:IncreaseMaximumCurrentMaximumMemberCountByGuildName",
"Gs2Guild:SetMaximumCurrentMaximumMemberCountByGuildName",
"Gs2Idle:IncreaseMaximumIdleMinutesByUserId",
"Gs2Idle:SetMaximumIdleMinutesByUserId",
"Gs2Idle:ReceiveByUserId",
"Gs2Inbox:SendMessageByUserId",
"Gs2Inventory:AddCapacityByUserId",
"Gs2Inventory:SetCapacityByUserId",
"Gs2Inventory:AcquireItemSetByUserId",
"Gs2Inventory:AcquireItemSetWithGradeByUserId",
"Gs2Inventory:AddReferenceOfByUserId",
"Gs2Inventory:DeleteReferenceOfByUserId",
"Gs2Inventory:AcquireSimpleItemsByUserId",
"Gs2Inventory:SetSimpleItemsByUserId",
"Gs2Inventory:AcquireBigItemByUserId",
"Gs2Inventory:SetBigItemByUserId",
"Gs2JobQueue:PushByUserId",
"Gs2Limit:CountDownByUserId",
"Gs2Limit:DeleteCounterByUserId",
"Gs2LoginReward:DeleteReceiveStatusByUserId",
"Gs2LoginReward:UnmarkReceivedByUserId",
"Gs2Lottery:DrawByUserId",
"Gs2Lottery:ResetBoxByUserId",
"Gs2Mission:RevertReceiveByUserId",
"Gs2Mission:IncreaseCounterByUserId",
"Gs2Mission:SetCounterByUserId",
"Gs2Money:DepositByUserId",
"Gs2Money:RevertRecordReceipt",
"Gs2Money2:DepositByUserId",
"Gs2Quest:CreateProgressByUserId",
"Gs2Schedule:TriggerByUserId",
"Gs2Schedule:ExtendTriggerByUserId",
"Gs2Script:InvokeScript",
"Gs2SerialKey:RevertUseByUserId",
"Gs2SerialKey:IssueOnce",
"Gs2Showcase:DecrementPurchaseCountByUserId",
"Gs2Showcase:ForceReDrawByUserId",
"Gs2SkillTree:MarkReleaseByUserId",
"Gs2Stamina:RecoverStaminaByUserId",
"Gs2Stamina:RaiseMaxValueByUserId",
"Gs2Stamina:SetMaxValueByUserId",
"Gs2Stamina:SetRecoverIntervalByUserId",
"Gs2Stamina:SetRecoverValueByUserId",
"Gs2StateMachine:StartStateMachineByUserId",
}
入手アクションで実行するアクションの種類
requeststring
~ 524288文字アクション実行時に使用されるリクエストのJSON文字列

EzConsumeAction

消費アクション

有効化条件必須デフォルト値の制限説明
action文字列列挙型
enum {
"Gs2AdReward:ConsumePointByUserId",
"Gs2Dictionary:DeleteEntriesByUserId",
"Gs2Enhance:DeleteProgressByUserId",
"Gs2Exchange:DeleteAwaitByUserId",
"Gs2Experience:SubExperienceByUserId",
"Gs2Experience:SubRankCapByUserId",
"Gs2Formation:SubMoldCapacityByUserId",
"Gs2Grade:SubGradeByUserId",
"Gs2Guild:DecreaseMaximumCurrentMaximumMemberCountByGuildName",
"Gs2Idle:DecreaseMaximumIdleMinutesByUserId",
"Gs2Inbox:OpenMessageByUserId",
"Gs2Inbox:DeleteMessageByUserId",
"Gs2Inventory:ConsumeItemSetByUserId",
"Gs2Inventory:ConsumeSimpleItemsByUserId",
"Gs2Inventory:ConsumeBigItemByUserId",
"Gs2JobQueue:DeleteJobByUserId",
"Gs2Limit:CountUpByUserId",
"Gs2LoginReward:MarkReceivedByUserId",
"Gs2Mission:ReceiveByUserId",
"Gs2Mission:BatchReceiveByUserId",
"Gs2Mission:DecreaseCounterByUserId",
"Gs2Mission:ResetCounterByUserId",
"Gs2Money:WithdrawByUserId",
"Gs2Money:RecordReceipt",
"Gs2Money2:WithdrawByUserId",
"Gs2Money2:VerifyReceiptByUserId",
"Gs2Quest:DeleteProgressByUserId",
"Gs2Ranking2:CreateGlobalRankingReceivedRewardByUserId",
"Gs2Ranking2:CreateClusterRankingReceivedRewardByUserId",
"Gs2Schedule:DeleteTriggerByUserId",
"Gs2SerialKey:UseByUserId",
"Gs2Showcase:IncrementPurchaseCountByUserId",
"Gs2SkillTree:MarkRestrainByUserId",
"Gs2Stamina:DecreaseMaxValueByUserId",
"Gs2Stamina:ConsumeStaminaByUserId",
}
消費アクションで実行するアクションの種類
requeststring
~ 524288文字アクション実行時に使用されるリクエストのJSON文字列

EzVerifyAction

検証アクション

有効化条件必須デフォルト値の制限説明
action文字列列挙型
enum {
"Gs2Dictionary:VerifyEntryByUserId",
"Gs2Distributor:IfExpressionByUserId",
"Gs2Distributor:AndExpressionByUserId",
"Gs2Distributor:OrExpressionByUserId",
"Gs2Enchant:VerifyRarityParameterStatusByUserId",
"Gs2Experience:VerifyRankByUserId",
"Gs2Experience:VerifyRankCapByUserId",
"Gs2Grade:VerifyGradeByUserId",
"Gs2Grade:VerifyGradeUpMaterialByUserId",
"Gs2Guild:VerifyCurrentMaximumMemberCountByGuildName",
"Gs2Guild:VerifyIncludeMemberByUserId",
"Gs2Inventory:VerifyInventoryCurrentMaxCapacityByUserId",
"Gs2Inventory:VerifyItemSetByUserId",
"Gs2Inventory:VerifyReferenceOfByUserId",
"Gs2Inventory:VerifySimpleItemByUserId",
"Gs2Inventory:VerifyBigItemByUserId",
"Gs2Limit:VerifyCounterByUserId",
"Gs2Matchmaking:VerifyIncludeParticipantByUserId",
"Gs2Mission:VerifyCompleteByUserId",
"Gs2Mission:VerifyCounterValueByUserId",
"Gs2Ranking2:VerifyGlobalRankingScoreByUserId",
"Gs2Ranking2:VerifyClusterRankingScoreByUserId",
"Gs2Ranking2:VerifySubscribeRankingScoreByUserId",
"Gs2Schedule:VerifyTriggerByUserId",
"Gs2Schedule:VerifyEventByUserId",
"Gs2SerialKey:VerifyCodeByUserId",
"Gs2Stamina:VerifyStaminaValueByUserId",
"Gs2Stamina:VerifyStaminaMaxValueByUserId",
"Gs2Stamina:VerifyStaminaRecoverIntervalMinutesByUserId",
"Gs2Stamina:VerifyStaminaRecoverValueByUserId",
"Gs2Stamina:VerifyStaminaOverflowValueByUserId",
}
検証アクションで実行するアクションの種類
requeststring
~ 524288文字アクション実行時に使用されるリクエストのJSON文字列

EzVerifyActionResult

検証アクションの実行結果

有効化条件必須デフォルト値の制限説明
action文字列列挙型
enum {
"Gs2Dictionary:VerifyEntryByUserId",
"Gs2Distributor:IfExpressionByUserId",
"Gs2Distributor:AndExpressionByUserId",
"Gs2Distributor:OrExpressionByUserId",
"Gs2Enchant:VerifyRarityParameterStatusByUserId",
"Gs2Experience:VerifyRankByUserId",
"Gs2Experience:VerifyRankCapByUserId",
"Gs2Grade:VerifyGradeByUserId",
"Gs2Grade:VerifyGradeUpMaterialByUserId",
"Gs2Guild:VerifyCurrentMaximumMemberCountByGuildName",
"Gs2Guild:VerifyIncludeMemberByUserId",
"Gs2Inventory:VerifyInventoryCurrentMaxCapacityByUserId",
"Gs2Inventory:VerifyItemSetByUserId",
"Gs2Inventory:VerifyReferenceOfByUserId",
"Gs2Inventory:VerifySimpleItemByUserId",
"Gs2Inventory:VerifyBigItemByUserId",
"Gs2Limit:VerifyCounterByUserId",
"Gs2Matchmaking:VerifyIncludeParticipantByUserId",
"Gs2Mission:VerifyCompleteByUserId",
"Gs2Mission:VerifyCounterValueByUserId",
"Gs2Ranking2:VerifyGlobalRankingScoreByUserId",
"Gs2Ranking2:VerifyClusterRankingScoreByUserId",
"Gs2Ranking2:VerifySubscribeRankingScoreByUserId",
"Gs2Schedule:VerifyTriggerByUserId",
"Gs2Schedule:VerifyEventByUserId",
"Gs2SerialKey:VerifyCodeByUserId",
"Gs2Stamina:VerifyStaminaValueByUserId",
"Gs2Stamina:VerifyStaminaMaxValueByUserId",
"Gs2Stamina:VerifyStaminaRecoverIntervalMinutesByUserId",
"Gs2Stamina:VerifyStaminaRecoverValueByUserId",
"Gs2Stamina:VerifyStaminaOverflowValueByUserId",
}
検証アクションで実行するアクションの種類
verifyRequeststring
~ 524288文字アクション実行時に使用されるリクエストのJSON文字列
statusCodeint0 ~ 999ステータスコード
verifyResultstring~ 1048576文字結果内容

EzConsumeActionResult

消費アクションの実行結果

有効化条件必須デフォルト値の制限説明
action文字列列挙型
enum {
"Gs2AdReward:ConsumePointByUserId",
"Gs2Dictionary:DeleteEntriesByUserId",
"Gs2Enhance:DeleteProgressByUserId",
"Gs2Exchange:DeleteAwaitByUserId",
"Gs2Experience:SubExperienceByUserId",
"Gs2Experience:SubRankCapByUserId",
"Gs2Formation:SubMoldCapacityByUserId",
"Gs2Grade:SubGradeByUserId",
"Gs2Guild:DecreaseMaximumCurrentMaximumMemberCountByGuildName",
"Gs2Idle:DecreaseMaximumIdleMinutesByUserId",
"Gs2Inbox:OpenMessageByUserId",
"Gs2Inbox:DeleteMessageByUserId",
"Gs2Inventory:ConsumeItemSetByUserId",
"Gs2Inventory:ConsumeSimpleItemsByUserId",
"Gs2Inventory:ConsumeBigItemByUserId",
"Gs2JobQueue:DeleteJobByUserId",
"Gs2Limit:CountUpByUserId",
"Gs2LoginReward:MarkReceivedByUserId",
"Gs2Mission:ReceiveByUserId",
"Gs2Mission:BatchReceiveByUserId",
"Gs2Mission:DecreaseCounterByUserId",
"Gs2Mission:ResetCounterByUserId",
"Gs2Money:WithdrawByUserId",
"Gs2Money:RecordReceipt",
"Gs2Money2:WithdrawByUserId",
"Gs2Money2:VerifyReceiptByUserId",
"Gs2Quest:DeleteProgressByUserId",
"Gs2Ranking2:CreateGlobalRankingReceivedRewardByUserId",
"Gs2Ranking2:CreateClusterRankingReceivedRewardByUserId",
"Gs2Schedule:DeleteTriggerByUserId",
"Gs2SerialKey:UseByUserId",
"Gs2Showcase:IncrementPurchaseCountByUserId",
"Gs2SkillTree:MarkRestrainByUserId",
"Gs2Stamina:DecreaseMaxValueByUserId",
"Gs2Stamina:ConsumeStaminaByUserId",
}
消費アクションで実行するアクションの種類
consumeRequeststring
~ 524288文字アクション実行時に使用されるリクエストのJSON文字列
statusCodeint0 ~ 999ステータスコード
consumeResultstring~ 1048576文字結果内容

EzAcquireActionResult

入手アクションの実行結果

有効化条件必須デフォルト値の制限説明
action文字列列挙型
enum {
"Gs2AdReward:AcquirePointByUserId",
"Gs2Dictionary:AddEntriesByUserId",
"Gs2Enchant:ReDrawBalanceParameterStatusByUserId",
"Gs2Enchant:SetBalanceParameterStatusByUserId",
"Gs2Enchant:ReDrawRarityParameterStatusByUserId",
"Gs2Enchant:AddRarityParameterStatusByUserId",
"Gs2Enchant:SetRarityParameterStatusByUserId",
"Gs2Enhance:DirectEnhanceByUserId",
"Gs2Enhance:UnleashByUserId",
"Gs2Enhance:CreateProgressByUserId",
"Gs2Exchange:ExchangeByUserId",
"Gs2Exchange:IncrementalExchangeByUserId",
"Gs2Exchange:CreateAwaitByUserId",
"Gs2Exchange:AcquireForceByUserId",
"Gs2Exchange:SkipByUserId",
"Gs2Experience:AddExperienceByUserId",
"Gs2Experience:SetExperienceByUserId",
"Gs2Experience:AddRankCapByUserId",
"Gs2Experience:SetRankCapByUserId",
"Gs2Experience:MultiplyAcquireActionsByUserId",
"Gs2Formation:AddMoldCapacityByUserId",
"Gs2Formation:SetMoldCapacityByUserId",
"Gs2Formation:AcquireActionsToFormProperties",
"Gs2Formation:SetFormByUserId",
"Gs2Formation:AcquireActionsToPropertyFormProperties",
"Gs2Friend:UpdateProfileByUserId",
"Gs2Grade:AddGradeByUserId",
"Gs2Grade:ApplyRankCapByUserId",
"Gs2Grade:MultiplyAcquireActionsByUserId",
"Gs2Guild:IncreaseMaximumCurrentMaximumMemberCountByGuildName",
"Gs2Guild:SetMaximumCurrentMaximumMemberCountByGuildName",
"Gs2Idle:IncreaseMaximumIdleMinutesByUserId",
"Gs2Idle:SetMaximumIdleMinutesByUserId",
"Gs2Idle:ReceiveByUserId",
"Gs2Inbox:SendMessageByUserId",
"Gs2Inventory:AddCapacityByUserId",
"Gs2Inventory:SetCapacityByUserId",
"Gs2Inventory:AcquireItemSetByUserId",
"Gs2Inventory:AcquireItemSetWithGradeByUserId",
"Gs2Inventory:AddReferenceOfByUserId",
"Gs2Inventory:DeleteReferenceOfByUserId",
"Gs2Inventory:AcquireSimpleItemsByUserId",
"Gs2Inventory:SetSimpleItemsByUserId",
"Gs2Inventory:AcquireBigItemByUserId",
"Gs2Inventory:SetBigItemByUserId",
"Gs2JobQueue:PushByUserId",
"Gs2Limit:CountDownByUserId",
"Gs2Limit:DeleteCounterByUserId",
"Gs2LoginReward:DeleteReceiveStatusByUserId",
"Gs2LoginReward:UnmarkReceivedByUserId",
"Gs2Lottery:DrawByUserId",
"Gs2Lottery:ResetBoxByUserId",
"Gs2Mission:RevertReceiveByUserId",
"Gs2Mission:IncreaseCounterByUserId",
"Gs2Mission:SetCounterByUserId",
"Gs2Money:DepositByUserId",
"Gs2Money:RevertRecordReceipt",
"Gs2Money2:DepositByUserId",
"Gs2Quest:CreateProgressByUserId",
"Gs2Schedule:TriggerByUserId",
"Gs2Schedule:ExtendTriggerByUserId",
"Gs2Script:InvokeScript",
"Gs2SerialKey:RevertUseByUserId",
"Gs2SerialKey:IssueOnce",
"Gs2Showcase:DecrementPurchaseCountByUserId",
"Gs2Showcase:ForceReDrawByUserId",
"Gs2SkillTree:MarkReleaseByUserId",
"Gs2Stamina:RecoverStaminaByUserId",
"Gs2Stamina:RaiseMaxValueByUserId",
"Gs2Stamina:SetMaxValueByUserId",
"Gs2Stamina:SetRecoverIntervalByUserId",
"Gs2Stamina:SetRecoverValueByUserId",
"Gs2StateMachine:StartStateMachineByUserId",
}
入手アクションで実行するアクションの種類
acquireRequeststring
~ 524288文字アクション実行時に使用されるリクエストのJSON文字列
statusCodeint0 ~ 999ステータスコード
acquireResultstring~ 1048576文字結果内容

EzTransactionResult

トランザクション実行結果

サーバーサイドでのトランザクションの自動実行機能を利用して実行されたトランザクションの実行結果

有効化条件必須デフォルト値の制限説明
transactionIdstring
36 ~ 36文字トランザクションID
verifyResultsList<EzVerifyActionResult>0 ~ 10 items検証アクションの実行結果リスト
consumeResultsList<EzConsumeActionResult>[]0 ~ 10 items消費アクションの実行結果リスト
acquireResultsList<EzAcquireActionResult>[]0 ~ 100 items入手アクションの実行結果リスト

メソッド

getNodeModel

特定のスキルツリーノードの詳細を取得する

ノード名を指定して、前提条件、解放コスト、返還設定を含む詳細を取得します。

プレイヤーがスキルツリーでノードをタップした際に詳細情報を表示する場合に使います。たとえば:

  • 「パワーストライク」— 必要: 通常攻撃(解放済み)。コスト: スキルポイント3。効果: 攻撃力+50%
  • ノードの拘束返還率が80%なら、このノードを戻す際にコストの80%が返還される

レスポンスには以下が含まれます:

  • 前提ノード名: 先に解放が必要なノードのリスト
  • 解放時の消費アクション: 解放に必要なコスト(例: スキルポイント3消費)
  • 解放時の検証アクション: 解放を許可する前にチェックされる条件(例: プレイヤーレベル >= 10)
  • 拘束返還率: ノードを戻す際に返還されるリソースの割合(0.0〜1.0)

Request

有効化条件必須デフォルト値の制限説明
namespaceNamestring
~ 128文字ネームスペース名
ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。
nodeModelNamestring
~ 128文字ノードモデル名
ノードモデル固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。

Result

説明
itemEzNodeModelノードモデル

実装例

    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    ).NodeModel(
        nodeModelName: "status-0001"
    );
    var item = await domain.ModelAsync();
    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    ).NodeModel(
        nodeModelName: "status-0001"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;
    const auto Domain = Gs2->SkillTree->Namespace(
        "namespace-0001" // namespaceName
    )->NodeModel(
        "status-0001" // nodeModelName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
値の変更イベントハンドリング
    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    ).NodeModel(
        nodeModelName: "status-0001"
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);
    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    ).NodeModel(
        nodeModelName: "status-0001"
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);
    const auto Domain = Gs2->SkillTree->Namespace(
        "namespace-0001" // namespaceName
    )->NodeModel(
        "status-0001" // nodeModelName
    );
    
    // イベントハンドリングを開始
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::SkillTree::Model::FNodeModel> value) {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    Domain->Unsubscribe(CallbackId);

listNodeModels

スキルツリーの全ノードの一覧を取得する

スキルツリーのすべてのノード定義を取得します。
各ノードはプレイヤーがリソースを消費して解放(アンロック)できるスキル、能力、または強化を表します。

スキルツリーは分岐構造で、ノードには前提条件があります。後のノードを解放するには先のノードを解放済みにしておく必要があります。
たとえば「通常攻撃」→「パワーストライク」→「クリティカルスラッシュ」のように、各ノードの解放には前のノードが必要です。

各ノード定義には以下が含まれます:

  • 前提ノード: このノードを解放する前に解放済みである必要がある他のノード
  • 解放コスト: ノードを解放するためにプレイヤーが消費するリソース(例: スキルポイント、ゴールド、素材)
  • 解放条件: 追加で満たす必要がある要件(例: 最低レベル)
  • 拘束返還率: プレイヤーが後でこのノードを戻す(ロックする)際に返還されるリソースの割合

スキルツリーUIを構築する際に使います。全ノードを描画し、前提条件に基づいて接続し、どのノードが解放可能かを表示できます。

Request

有効化条件必須デフォルト値の制限説明
namespaceNamestring
~ 128文字ネームスペース名
ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。

Result

説明
itemsList<EzNodeModel>ノードモデルのリスト

実装例

    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    );
    var items = await domain.NodeModelsAsync(
    ).ToListAsync();
    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    );
    var it = domain.NodeModels(
    );
    List<EzNodeModel> items = new List<EzNodeModel>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }
    const auto Domain = Gs2->SkillTree->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto It = Domain->NodeModels(
    );
    TArray<Gs2::UE5::SkillTree::Model::FEzNodeModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }
値の変更イベントハンドリング
    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.SubscribeNodeModels(
        () => {
            // リストの要素が変化した時に呼び出される
        }
    );

    // イベントハンドリングを停止
    domain.UnsubscribeNodeModels(callbackId);
    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.SubscribeNodeModels(
        () => {
            // リストの要素が変化した時に呼び出される
        }
    );

    // イベントハンドリングを停止
    domain.UnsubscribeNodeModels(callbackId);
    const auto Domain = Gs2->SkillTree->Namespace(
        "namespace-0001" // namespaceName
    );
    
    // イベントハンドリングを開始
    const auto CallbackId = Domain->SubscribeNodeModels(
        []() {
            // リストの要素が変化した時に呼び出される
        }
    );

    // イベントハンドリングを停止
    Domain->UnsubscribeNodeModels(CallbackId);

getStatus

プレイヤーのスキルツリーの進行状況を取得する

指定されたプロパティIDのスキルツリーで、プレイヤーがどのノードを解放(アンロック)済みかを取得します。

propertyId はどのスキルツリーのインスタンスを参照するかを特定します。ゲームがキャラクターごとに1つのスキルツリーを持つ場合、propertyId にはキャラクターIDを使えます。
たとえば戦士キャラクターと魔法使いキャラクターはそれぞれ異なる propertyId で別々のスキルツリー進行状況が管理されます。

スキルツリー画面を描画する際に使います。ListNodeModels でツリー全体の構造を取得し、プレイヤーの解放状態を重ねて表示します:

  • 解放済みノード(アンロック済み、ハイライト表示)
  • 解放可能ノード(前提条件を満たしている、次に解放できる)
  • ロック中ノード(前提条件を満たしていない、グレーアウト表示)

Request

有効化条件必須デフォルト値の制限説明
namespaceNamestring
~ 128文字ネームスペース名
ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。
gameSessionGameSession
GameSession
propertyIdstring
~ 1024文字プロパティID
ユーザーごとに複数の独立したスキルツリーインスタンスを持つための識別子。
同一ネームスペース内で、プレイヤーが異なるキャラクターやコンテキストに対して別々のスキルツリーを持つシナリオを実現します。
最大1024文字。

Result

説明
itemEzStatusステータス

実装例

    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        propertyId: "property-0001"
    );
    var item = await domain.ModelAsync();
    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        propertyId: "property-0001"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;
    const auto Domain = Gs2->SkillTree->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Status(
        "property-0001" // propertyId
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
値の変更イベントハンドリング
    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        propertyId: "property-0001"
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);
    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        propertyId: "property-0001"
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);
    const auto Domain = Gs2->SkillTree->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Status(
        "property-0001" // propertyId
    );
    
    // イベントハンドリングを開始
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::SkillTree::Model::FStatus> value) {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    Domain->Unsubscribe(CallbackId);

release

スキルツリーのノードを解放する

スキルツリーの1つまたは複数のノードを解放(アンロック)します。プレイヤーが必要なリソースを消費し、ノードが有効になります。

スキルツリーUIの「スキル習得」「アンロック」ボタンに対応します。プレイヤーが解放したいノードをタップすると:

  1. すべての前提ノードが既に解放済みかチェックされる
  2. 解放条件(検証アクション)がチェックされる(例: プレイヤーの最低レベル)
  3. 解放コスト(消費アクション)が差し引かれる(例: スキルポイント3消費)
  4. ノードが解放済みとしてマークされる

複数のノード名を渡すことで一度に複数のノードを解放できます。各ノードの前提条件とコストがそれぞれ検証されます。

前提条件が満たされていない場合や、プレイヤーのリソースが不足している場合は解放が失敗し、リソースは消費されません。

Request

有効化条件必須デフォルト値の制限説明
namespaceNamestring
~ 128文字ネームスペース名
ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。
gameSessionGameSession
GameSession
nodeModelNamesList<string>
1 ~ 1000 itemsノードモデル名のリスト
propertyIdstring
~ 1024文字プロパティID
ユーザーごとに複数の独立したスキルツリーインスタンスを持つための識別子。
同一ネームスペース内で、プレイヤーが異なるキャラクターやコンテキストに対して別々のスキルツリーを持つシナリオを実現します。
最大1024文字。

Result

説明
itemEzStatusステータス
transactionIdstring発行されたトランザクションID
stampSheetstring解放処理の実行に使用するスタンプシート
stampSheetEncryptionKeyIdstringスタンプシートの署名計算に使用した暗号鍵GRN
autoRunStampSheetboolトランザクションの自動実行が有効か
atomicCommitboolトランザクションをアトミックにコミットするか
transactionstring発行されたトランザクション
transactionResultEzTransactionResultトランザクション実行結果

実装例

    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        propertyId: "property-0001"
    );
    var result = await domain.ReleaseAsync(
        nodeModelNames: new List<string> {
            "node-0001",
        }
    );
    // New Experience ではスタンプシートはSDKレベルで自動的に実行されます。
    // エラーが発生すると TransactionException がスローされます。
    // TransactionException::Retry() でリトライが可能です。
    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        propertyId: "property-0001"
    );
    var future = domain.ReleaseFuture(
        nodeModelNames: new List<string> {
            "node-0001",
        }
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    // New Experience ではスタンプシートはSDKレベルで自動的に実行されます。
    // エラーが発生すると TransactionException がスローされます。
    // TransactionException::Retry() でリトライが可能です。
    const auto Domain = Gs2->SkillTree->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Status(
        "property-0001" // propertyId
    );
    const auto Future = Domain->Release(
        []
        {
            auto v = TOptional<TArray<FString>>();
            v->Add("node-0001");
            return v;
        }() // nodeModelNames
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

reset

スキルツリー全体をリセットする(フルリスペック)

スキルツリーのすべての解放済みノードを一括で未解放状態に戻します。各ノードの拘束返還率に基づいてリソースが返還されます。

「全スキルリセット」「フルリスペック」ボタンに対応します。プレイヤーはスキルツリーをゼロからやり直します。

たとえばプレイヤーが様々なコストで10個のノードを解放済みの場合、10個すべてが戻され、設定された返還率に基づいてそれぞれ部分的な返金が行われます。

主な使い方:

  • プレイヤーが異なる戦略でスキルツリーを組み直せる「リスペック」機能
  • 全プレイヤーがゼロからやり直すシーズンリセット
  • ゲームバランスの変更で現在のビルドが最適でなくなった際に、プレイヤーに再調整させたい場合

Restrain(特定のノードを選択的に戻す)とは異なり、Reset は依存関係に関係なくツリー全体に影響します。

Request

有効化条件必須デフォルト値の制限説明
namespaceNamestring
~ 128文字ネームスペース名
ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。
gameSessionGameSession
GameSession
propertyIdstring
~ 1024文字プロパティID
ユーザーごとに複数の独立したスキルツリーインスタンスを持つための識別子。
同一ネームスペース内で、プレイヤーが異なるキャラクターやコンテキストに対して別々のスキルツリーを持つシナリオを実現します。
最大1024文字。

Result

説明
itemEzStatusステータス
transactionIdstring発行されたトランザクションID
stampSheetstringリセット処理の実行に使用するスタンプシート
stampSheetEncryptionKeyIdstringスタンプシートの署名計算に使用した暗号鍵GRN
autoRunStampSheetboolトランザクションの自動実行が有効か
atomicCommitboolトランザクションをアトミックにコミットするか
transactionstring発行されたトランザクション
transactionResultEzTransactionResultトランザクション実行結果

実装例

    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        propertyId: "property-0001"
    );
    var result = await domain.ResetAsync(
    );
    // New Experience ではスタンプシートはSDKレベルで自動的に実行されます。
    // エラーが発生すると TransactionException がスローされます。
    // TransactionException::Retry() でリトライが可能です。
    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        propertyId: "property-0001"
    );
    var future = domain.ResetFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    // New Experience ではスタンプシートはSDKレベルで自動的に実行されます。
    // エラーが発生すると TransactionException がスローされます。
    // TransactionException::Retry() でリトライが可能です。
    const auto Domain = Gs2->SkillTree->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Status(
        "property-0001" // propertyId
    );
    const auto Future = Domain->Reset(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

restrain

特定のノードをロック状態に戻す

解放済みの1つまたは複数のノードを未解放状態に戻します。各ノードの拘束返還率に基づいて、解放時に消費したリソースの一部が返還されます。

「部分的なリスペック」機能です。スキルツリー全体をリセットする代わりに、特定のノードだけを選んで取り消せます。

たとえばノードの解放に100ゴールドかかり、拘束返還率が0.8(80%)の場合、拘束時に80ゴールドが返還されます。

重要なルール:

  • 他の解放済みノードが依存しているノード(前提条件として参照されているノード)は拘束できない
  • 他の解放済みノードの前提となっているノードを拘束するには、先に依存するノードを拘束する必要がある
  • これによりスキルツリーは常に有効な状態が保たれます(孤立したノードが発生しません)

スキルツリーUIの「スキル取り消し」「元に戻す」機能として使います。

Request

有効化条件必須デフォルト値の制限説明
namespaceNamestring
~ 128文字ネームスペース名
ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。
gameSessionGameSession
GameSession
nodeModelNamesList<string>
1 ~ 1000 itemsノードモデル名のリスト
propertyIdstring
~ 1024文字プロパティID
ユーザーごとに複数の独立したスキルツリーインスタンスを持つための識別子。
同一ネームスペース内で、プレイヤーが異なるキャラクターやコンテキストに対して別々のスキルツリーを持つシナリオを実現します。
最大1024文字。

Result

説明
itemEzStatusステータス
transactionIdstring発行されたトランザクションID
stampSheetstring未解放状態に戻す処理の実行に使用するスタンプシート
stampSheetEncryptionKeyIdstringスタンプシートの署名計算に使用した暗号鍵GRN
autoRunStampSheetboolトランザクションの自動実行が有効か
atomicCommitboolトランザクションをアトミックにコミットするか
transactionstring発行されたトランザクション
transactionResultEzTransactionResultトランザクション実行結果

実装例

    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        propertyId: "property-0001"
    );
    var result = await domain.RestrainAsync(
        nodeModelNames: new List<string> {
            "node-0001",
        }
    );
    // New Experience ではスタンプシートはSDKレベルで自動的に実行されます。
    // エラーが発生すると TransactionException がスローされます。
    // TransactionException::Retry() でリトライが可能です。
    var domain = gs2.SkillTree.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Status(
        propertyId: "property-0001"
    );
    var future = domain.RestrainFuture(
        nodeModelNames: new List<string> {
            "node-0001",
        }
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    // New Experience ではスタンプシートはSDKレベルで自動的に実行されます。
    // エラーが発生すると TransactionException がスローされます。
    // TransactionException::Retry() でリトライが可能です。
    const auto Domain = Gs2->SkillTree->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Status(
        "property-0001" // propertyId
    );
    const auto Future = Domain->Restrain(
        []
        {
            auto v = TOptional<TArray<FString>>();
            v->Add("node-0001");
            return v;
        }() // nodeModelNames
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }