Skip to content

付费扩容档位

unlock_costs.yml 定义 GUI 内付费扩容的价格档位。这是独立的业务数据文件:release_default_data 只在文件缺失时释放一次,版本升级不会覆盖管理员已有内容。

文件名由 config.ymlunlock.cost_file 指定,默认 unlock_costs.yml;是否开放购买由 unlock.purchase_enabledemakistorage.unlock.purchase 权限共同决定,见配置详解

unlock_costs.yml 结构

yaml
tiers:
  - count_range: "1-9"
    currency:
      type: vault
      amount: 1000
  - count_range: "10-19"
    item:
      source: "diamond"
      amount: 16
  - count_range: "20-49"
    currency:
      type: vault
      amount: 50000
    item:
      source: "netherite_ingot"
      amount: 4

fallback:
  currency:
    type: vault
    amount: "100000 * 1.05 ^ (%count% - 50)"
  max_amount: 1000000000

batch:
  enabled: true
  options: [1, 5, 10, 64]
字段类型说明
tiers[].count_rangestring该档覆盖的「第几格」区间,如 1-9。越靠前的档优先。
tiers[].currency.typeenum货币后端:vault / excellent
tiers[].currency.amountnumber 或 string金额。字符串走 CoreLib ExpressionEngine,可用 %count%
tiers[].item.sourcestringCoreLib ItemSource token。
tiers[].item.amountint所需物品数量。
fallback.currencysection超出所有 tiers 后每一格的价格。
fallback.max_amountnumber单格价格上限。必需项
batch.enabledboolean是否开放批量购买。false 时只提供 1 格选项。
batch.optionslist批量购买的档位选项。

逐格计价

批量购买按逐格计价再求和结算,不是「单价 × 数量」。玩家购买第 N 格时,用 N 落在哪个 count_range 决定该格价格;N 从 purchasedSlots + 1 开始递增。若按当前单价乘以数量,玩家可以在最便宜的档一次买下大批槽位,把本该属于昂贵档的格子锁定成低价。

%count% 在表达式中表示「即将购买的第几格」。

max_amount 护栏

fallback.max_amount 是必需项:缺失或非正数时兜底档整体失效,超出 tiers 的格子将不可购买(回报 no_price_defined)。它的作用是防止指数表达式溢出成 Infinity

当某一格的计算价格超过 max_amount 时,实现明确拒绝本次报价(price_over_cap),而不是静默钳到上限:管理员的公式产出了越过自己声明的护栏的价格,这次购买就不该继续。

支付顺序与逆序补偿

购买流程:报价 → 触发可取消的 StorageUnlockEvent → 扣货币 → 扣物品 → 增加 purchasedSlots

任何一步在扣款之后失败,都会按逆序补偿:先按倒序回滚已应用的物品扣除计划,再退还货币,然后才返回失败。purchasedSlots 在补偿路径上从未被修改过。

失败采用 fail-closed:没有匹配档位且没有可用兜底档时拒绝购买,而不是当成免费。

相关页面