跳到正文
烈焰甘蔗Wiki

Diminishing Returns(递减收益)

基本信息

属性 值
类型 食物修正机制
触发方式 AppleCore FoodEvent.GetPlayerFoodValues 事件
引擎 EvalEx 表达式解析器

功能

SpiceOfLife 的核心机制。当玩家重复食用相同或相似的食物时,食物的饱食度和饱和度会被动态降低,从而鼓励玩家多样化饮食。

修正系数通过表达式公式计算,应用于 AppleCore 的 FoodValues(饱食度和饱和度修正值)。

默认公式

MAX(0, (1 - count/12))^MIN(8, food_hunger_value)

含义:最近食用相同食物的次数越多,修正系数越低。基础历史长度为 12,超出后最旧的食物被移除(FixedSizeQueue 继承 LinkedList,super.remove() 弹出队首即最旧项,FixedSizeQueue.java:16-22)。

[!NOTE] 生效前置条件 递减收益需要同时满足:food.modifier.enabled(默认 true)、食物不是黑名单食物组成员、玩家累计吃过 ≥ new.player.food.eaten.threshold(默认 6)次(FoodModifier.java:45, 84-89)。不满足时系数恒为 1f,即食物完全不被削弱。

可用变量

变量 说明
count 该食物(或所属食物组)在历史中被食用的次数
hunger_count 该食物(或所属食物组)在历史中恢复的饥饿值总和(1 饥饿 = 半格)
saturation_count 该食物(或所属食物组)在历史中提供的饱和度总和
max_history_length 食物历史最大长度
cur_history_length 当前食物历史长度
food_hunger_value 食物的基础饥饿恢复值(1 = 半格)
food_saturation_mod 食物的基础饱和度修正值
cur_hunger 玩家当前饥饿值(20 = 满)
cur_saturation 玩家当前饱和度
total_food_eaten 玩家历史中所有食物的食用总次数
food_group_count 该食物所属的食物组数量
distinct_food_groups_eaten 当前食物历史中不同食物组的数量
total_food_groups 已启用的食物组总数
exact_count 不考虑食物组,该食物在历史中的精确食用次数

配置项

配置项 默认值 说明
food.modifier.enabled true 总开关(ModConfig.java:39)
food.history.length 12 食物历史最大长度(ModConfig.java:86)
food.modifier.formula 见上方 修正公式(ModConfig.java:156)
new.player.food.eaten.threshold 12 / 2 = 6 新玩家累计吃过这么多次食物之前,递减收益完全不生效(ModConfig.java:204,FoodModifier.java:88-89)。默认值由历史长度推导,不是独立数字
affect.food.hunger.values true 是否影响饥饿值(ModConfig.java:101)
affect.food.saturation.modifiers false 是否影响饱和度修正(ModConfig.java:113)
affect.negative.food.hunger.values false 是否让负饥饿值食物变得更负(ModConfig.java:103)
affect.negative.food.saturation.modifiers false 是否让负饱和度修正变得更负(ModConfig.java:125)
food.hunger.rounding.mode round 饥饿值取整方式,可选 round / floor / ceiling(ModConfig.java:96-99, 518-540)
food.eating.speed.modifier 1.0 大于 0 时按营养值拉长进食时间(ModConfig.java:131)
food.eating.duration.max 0 进食时长上限 tick,0 = 不限(ModConfig.java:136)
use.hunger.restored.for.food.history.length false 按饥饿值而非食物数量计算历史长度(ModConfig.java:145)
food.history.persists.through.death false 食物历史是否跨死亡保留(ModConfig.java:89)
use.food.groups.as.whitelists false 设为 true 时不属于任何食物组的食物被排除在递减收益之外(ModConfig.java:94)

[!WARNING] 已订正(本轮源码审计)

  • 原文列的 7 个配置项与默认值逐条核对无误,但漏了 6 个上表中的配置项,其中 new.player.food.eaten.threshold(默认 6)和 food.hunger.rounding.mode(默认 round)会直接改变玩家看到的数值,不可省略。
  • 补记一条语义容易写反的规则:负值食物不是乘以 modifier,而是乘以 2 - modifier(即营养值越低、负得越狠),见下节(FoodModifier.java:69-77)。

数值如何落到饱食度/饱和度

修正系数 modifier 不是直接当饱食度用,而是作为乘数(FoodModifier.getModifiedFoodValues,FoodModifier.java:64-81):

情形 计算式 配置门槛
饥饿值 > 0 hunger = round(hunger × modifier) 需 affect.food.hunger.values
饥饿值 < 0 hunger = round(hunger × (2 − modifier)) 需上述 且 affect.negative.food.hunger.values
饱和度修正 > 0 saturationModifier ×= modifier 需 affect.food.saturation.modifiers
饱和度修正 < 0 saturationModifier ×= 2 − modifier 需上述 且 affect.negative.food.saturation.modifiers

取整用 food.hunger.rounding.mode(Math.round / Math.floor / Math.ceil,ModConfig.java:518-540)。默认 round 意味着结果会被取整到整数:例如饥饿 4、modifier 0.0625 → round(0.25) = 0,而不是 0.25。

饥饿值改为 0 时,客户端工具提示会额外用红色标出原始负值(TooltipHandler.java:88-92)。

进食速度联动

food.eating.speed.modifier > 0 时,进食时长按 duration / modifier^速度系数 拉长(营养值越低吃得越久),并受 food.eating.duration.max 截断;modifier 为 0 时时长被设为 Short.MAX_VALUE(近乎无限)除非设了上限(FoodModifier.java:152-172)。

食物组自定义公式

每个食物组可以在 JSON 配置中定义独立的公式,覆盖全局公式。实现是每个食物组各自持有一个 FoodModifier:formula != null ? new FoodModifier(formula) : FoodModifier.GLOBAL(FoodGroup.java:153)。一个食物属于 N 个组时,N 个系数分别计算后取算术平均(FoodModifier.java:91-104)。

相关条目

浏览全部模组