FMCRAFT 玩家活跃指数(Activity Index)解析

这是什么

活跃指数是一个 0 到 5 分的数字,用来回答一个问题:

这个玩家最近还活跃吗?

它只做一件事:把玩家最近 3 周的有效游戏时长,压缩成一个可以直接比较的分数,并贴上一个人类可读的标签("非常活跃"、"不活跃"等)。

分数越高 = 玩得越勤、越稳定;分数越低 = 玩得越少、越不规律。


核心思路:三条规则

理解这个指数,只需要记住三条规则。

规则一:只看最近 3 周

指数只统计最近 21 天的数据,超过 3 周的记录一律不看。

所以它是一个"滑动窗口"指标——3 周前爆肝 100 小时,今天玩 1 分钟,指数依然会很低。

规则二:AFK 时间不算

玩家的有效游戏时长 = 在线总时长 − 挂机(AFK)时长。

Plan 默认挂机超过 3 分钟不移动就判定为 AFK。挂机时间会被扣掉,所以"开着电脑睡觉"不会虚增指数。

可以在 config.yml 里调整 Time.Thresholds.AFK_threshold。

规则三:连续性 > 爆发力

这是这个指数最重要的设计。同样的总时长,分摊到 3 周比集中在 1 周得分高得多。

后面有详细例子。


核心计算公式

完整公式

$$ \mathrm{Index} \;=\; 5 \;-\; \frac{5}{3}\left( \frac{1}{1 + \frac{\pi}{2}\cdot\frac{t_1}{T}} \;+\; \frac{1}{1 + \frac{\pi}{2}\cdot\frac{t_2}{T}} \;+\; \frac{1}{1 + \frac{\pi}{2}\cdot\frac{t_3}{T}} \right) $$

等价写法(把平均摊进系数里,更直观):

$$ \mathrm{Index} \;=\; 5 \;-\; 5 \times \frac{1}{3}\left[ S(t_1) + S(t_2) + S(t_3) \right] $$

其中 $\dfrac{\pi}{2} \approx 1.5708$。

符号说明

符号含义默认值 / 取值
$\mathrm{Index}$最终活跃指数结果落在 $[0,\ 5)$ 区间
$t_1$最近 7 天的有效游戏时长$=\sum(\text{在线时长} - \text{AFK 时长})$
$t_2$往前第 2 个 7 天的有效游戏时长同上
$t_3$往前第 3 个 7 天的有效游戏时长同上
$T$一周活跃基准线 (Playtime_threshold)默认 $30$ 分钟 $= 1{,}800{,}000\ \text{ms}$
$\dfrac{\pi}{2}$曲线调节系数固定 $\approx 1.5708$

三层结构

公式可以拆成三层来看:

第一层 —— 单周曲线(调和函数衰减)

$$ S(t) \;=\; \frac{1}{1 + \frac{\pi}{2}\cdot\frac{t}{T}} $$

性质:

$$ S(0) = 1, \qquad S(T) = \frac{1}{1+1.5708} \approx 0.389, \qquad S(2T) \approx 0.242, \qquad \lim_{t \to \infty} S(t) = 0 $$

  • $S(0)=1$:一点没玩 → 满分惩罚
  • $S(T)\approx 0.389$:玩满基准线 → 惩罚降到 39%
  • $S(\infty)\to 0$:玩无限久 → 惩罚趋近于 0
  • 单调递减、且凸(越往后越平)

第二层 —— 三周算术平均

$$ \bar{S} \;=\; \frac{S(t_1) + S(t_2) + S(t_3)}{3} $$

等权。没有"最近一周更重要"的加权。

第三层 —— 反向映射到 $0 \sim 5$

$$ \mathrm{Index} \;=\; 5 - 5\bar{S} \;=\; 5\left(1 - \bar{S}\right) $$

因为 $\bar{S} \in (0,\ 1]$,所以 $\mathrm{Index} \in [0,\ 5)$。

$$ \text{门槛} \iff \mathrm{Index} \geq x \iff \bar{S} \leq 1 - \frac{x}{5} $$

$\bar{S}$$\mathrm{Index}$含义
$1.000$$0.00$三周完全没玩
$0.800$$1.00$不规律门槛
$0.600$$2.00$常规门槛
$0.400$$3.00$活跃门槛
$0.250$$3.75$非常活跃门槛
$0.000$$5.00$理论极限,永不达到

关键边界结论(由公式直接推出)

只活跃 1 周时的理论上限:

设 $t_2 = t_3 = 0$,则 $S(t_2) = S(t_3) = 1$,于是:

$$ \mathrm{Index} \;=\; 5 - \frac{5}{3}\left( S(t_1) + 2 \right) $$

当 $t_1 \to \infty$ 时 $S(t_1) \to 0$,取极限得:

$$ \mathrm{Index}_{\max} \;=\; 5 - \frac{5}{3}\cdot 2 \;=\; \frac{5}{3} \;\approx\; 1.67 $$

无论第一周玩 1 小时还是 100 小时,只要另外两周零活跃,指数最高只能到 $1.67$(不规律)。
想突破 $2.00$(常规)这条线,至少需要两周有实际游戏。

达到"非常活跃"($\ge 3.75$)的条件:

$$ 3.75 \leq 5\left(1 - \bar{S}\right) \iff \bar{S} \leq 0.25 $$

三周均等时 $S(t) = 0.25$,反解得:

$$ \frac{1}{1 + \frac{\pi}{2}\cdot\frac{t}{T}} = \frac{1}{4} \iff \frac{\pi}{2}\cdot\frac{t}{T} = 3 \iff \frac{t}{T} = \frac{6}{\pi} \approx 1.910 $$

即每周需要 $t \geq 1.91\,T \approx 57.3$ 分钟(默认配置下约每天 8 分钟)。


怎么算的(逐步展开)

第 1 步:算出每周的有效时长

把最近 21 天切成 3 个 7 天的窗口,分别累加有效游戏时长:

$$ \begin{aligned} t_1 &= \text{最近 7 天的有效时长} \\ t_2 &= \text{往前第 2 个 7 天的有效时长} \\ t_3 &= \text{往前第 3 个 7 天的有效时长} \end{aligned} $$

第 2 步:每一周单独打一个"周分"

每一周用同一条曲线打分:

$$ S(t) \;=\; \frac{1}{1 + 1.5708 \cdot \frac{t}{T}} $$

其中 $T$ 是"一周活跃基准线",默认 $30$ 分钟(可在 config.yml 的 Time.Thresholds.Activity_index.Playtime_threshold 调整)。

这条曲线的形状是这样的:

这周玩了周分 $S(t)$含义
$0$ 分钟$1.000$这周完全没玩
$10$ 分钟$0.656$碰了一下
$20$ 分钟$0.489$玩了一会儿
$30$ 分钟 $(=T)$$0.389$达到基准线
$60$ 分钟 $(=2T)$$0.242$玩得比较多
$120$ 分钟$0.137$玩得很多
$\infty$$\to 0$趋近于 0

注意周分的走向是反的:玩得越少,周分越高。玩得越多,周分越低,并且越降越慢(曲线是平的)。

这就是"递减边际":从 0 分钟玩到 30 分钟,指数涨得飞快;从 60 分钟玩到 90 分钟,指数只挪动一点点。这样可以避免"在线时间一长就无限刷分"。

第 3 步:三周合并,反向放大

$$ \bar{S} = \frac{S(t_1) + S(t_2) + S(t_3)}{3} \qquad\qquad \mathrm{Index} = 5\left(1 - \bar{S}\right) $$

最后这一步把结果反过来,并拉伸到 $0 \sim 5$:

  • 三周都没玩 $\Rightarrow S_i = 1 \Rightarrow \bar{S}=1 \Rightarrow \mathrm{Index} = 5-5 = \mathbf{0}$
  • 三周都玩爆 $\Rightarrow S_i \to 0 \Rightarrow \bar{S}\to 0 \Rightarrow \mathrm{Index} \to \mathbf{5}$

分数对应什么标签

指数区间标签
$\mathrm{Index} \ge 3.75$非常活跃 (Very Active)
$\mathrm{Index} \ge 3.00$活跃 (Active)
$\mathrm{Index} \ge 2.00$常规 (Regular)
$\mathrm{Index} \ge 1.00$不规律 (Irregular)
$\mathrm{Index} < 1.00$不活跃 (Inactive)
理论上 5 分是"无限游戏时长"的极限,实际玩家几乎不可能达到 5 分。即使三周每周玩 2 小时(合计 42 小时),指数也只有 4.31 左右。

实际算例

假设基准线 T = 30 分钟(默认)。

例 1:稳定肝帝

最近 1 周第 2 周第 3 周
有效时长60 分60 分60 分
周分0.2420.2420.242

$$ \bar{S} = \frac{0.242 + 0.242 + 0.242}{3} = 0.242 $$

$$ \mathrm{Index} = 5\left(1 - 0.242\right) = 3.79 $$

→ 非常活跃 (Very Active)

三周均匀发力,稳稳站上 Very Active 线。


例 2:刚好够到"活跃"

最近 1 周第 2 周第 3 周
有效时长30 分30 分30 分
周分 $S(t)$0.3890.3890.389

$$ \bar{S} = \frac{0.389 \times 3}{3} = 0.389 $$

$$ \mathrm{Index} = 5\left(1 - 0.389\right) = 3.06 $$

→ 活跃 (Active)

这就是基准线的设计意图:一周有效玩 30 分钟,三周都玩,就该算"活跃"。


例 3:只玩了一周

同样只玩 60 分钟,但只集中在最近一周:

最近 1 周第 2 周第 3 周
有效时长60 分0 分0 分
周分 $S(t)$0.2421.0001.000

$$ \bar{S} = \frac{0.242 + 1 + 1}{3} = 0.747 $$

$$ \mathrm{Index} = 5\left(1 - 0.747\right) = 1.26 $$

→ 不规律 (Irregular)

对比例 1:同样是 60 分钟/周 × 3 周(3.79,非常活跃)

差距 $3.79 - 1.26 = 2.53$ 分。这就是"连续性"的威力。


例 4:回归的老玩家

最近 1 周第 2 周第 3 周
有效时长180 分0 分0 分

$$ S(180) = \frac{1}{1 + 1.5708 \times \frac{180}{30}} = 0.096 $$

$$ \bar{S} = \frac{0.096 + 1 + 1}{3} = 0.699 $$

$$ \mathrm{Index} = 5\left(1 - 0.699\right) = 1.51 $$

→ 不规律 (Irregular)

玩了整整 3 小时仍然只有 1.51 分。

关键结论:只活跃 1 周,数学上的天花板就是 $\dfrac{5}{3} \approx 1.67$ 分(不规律)。
因为另外两周各贡献 $S=1$,$\bar{S}$ 被锁死在 $\frac{2}{3}$ 附近,无论你第一周玩多久都拉不上去。想让指数爬过 2 分(常规),至少要两周有实际游戏。


例 5:逐渐流失

同一个人,一步步掉活跃度:

场景三周时长(分)指数标签
三周前开始玩10 / 10 / 101.72不规律
第二周20 / 20 / 202.56常规
第三周30 / 30 / 303.06活跃
第四周(停一周)30 / 30 / 02.04常规
第五周(再停一周)30 / 0 / 01.02不规律
第六周(停三周)0 / 0 / 00.00不活跃

指数滑落得非常平滑,不会出现断崖式跳变——这正是 1/(1+x) 这种"平滑递减"曲线带来的好处。每停一周大约掉 1 分左右(当周时长接近基准线时)。


例 6:低时长玩家的自洽性

一周只玩 5 分钟,零门槛玩家:

最近 1 周第 2 周第 3 周
有效时长5 分5 分5 分
周分 $S(t)$0.7930.7930.793

$$ \bar{S} = \frac{0.793 \times 3}{3} = 0.793 $$

$$ \mathrm{Index} = 5\left(1 - 0.793\right) = 1.04 $$

→ 不规律 (Irregular)

即使一周只玩 5 分钟,只要坚持了三周,也能拿到 1.04 分,够到"不规律"的门槛($1.00$)。不活跃($<1.00$)基本只留给"三周内确实没怎么玩"的人。


常见误解

❌ "我挂机了一晚上,指数应该很高吧?"

不会。AFK 时间(默认超 3 分钟不动)被完全扣除。挂机只会被算成"没有活跃时长"。

❌ "我时间被偷走了 / 指数突然变低?"

如果你开启了 Remove_inactive_player_data_after(默认 3650 天,实际不触发),或者服务器更换导致历史 session 缺失,指数会回落。另外刚建档的新玩家因为历史数据不足,前几天指数天然偏低。

❌ "为什么我的分数看起来总是卡在 3.x 上不去?"

因为边际递减。三周从 30 分钟/周提到 57 分钟/周(+90% 的时间),指数才从 3.06 涨到 3.75。想要"非常活跃",稳定每天上线比偶尔肝一天有效得多。

❌ "分数是按天刷新的吗?"

不是。指数是实时计算的,没有缓存表,读取即重算最近 3 周的 session。所以任何时刻查看,结果都反映当下。

⚠️ 跨周的长挂机会重复计入

如果你有一次连续在线很多天的会话(且没有被判定为 AFK),它的完整时长会被同时算进它覆盖到的每一个周窗口。极端情况下会让指数偏高,这是已知的小瑕疵。


调整参数

两个阈值都在 config.yml 的 Time 段下:

配置项默认值说明
AFK_threshold3 分钟挂机多久后不计入有效时长
Activity_index.Playtime_threshold30 分钟一周活跃基准线 T

关于 T 的调整建议:

  • 调高 T(如 60 分钟)→ 曲线整体右移,同样的游戏时长会得到更高的指数,分组更容易达成。对休闲型服务器合适。
  • 调低 T(如 15 分钟)→ 同样的时长得到更低的指数,只有真正肝度爆表才能到 Very Active。对硬核服合适。
⚠️ 调整 T 会让新旧数据不可比——今天调了配置,历史统计图上的曲线会整体平移,看起来像所有玩家同时变活跃/变不活跃。建议在固定的时间点调整,或调完配置后清空活跃相关的展示缓存再观察。

一句话总结

$$ \boxed{\;\mathrm{Index} \;=\; 5 \;-\; \frac{5}{3}\left( \frac{1}{1 + 1.5708\cdot\frac{t_1}{T}} + \frac{1}{1 + 1.5708\cdot\frac{t_2}{T}} + \frac{1}{1 + 1.5708\cdot\frac{t_3}{T}} \right)\;} $$

$t$ = 每周有效游戏时长(已扣 AFK) · $T$ = 一周基准线(默认 30 分钟) · 结果 $\in [0, 5)$

它奖励稳定出勤,惩罚一周爆发 + 两周消失,并把挂机时间当作零。

连续三周、每周 30 分钟有效游戏 $\approx 3.06$ 分(活跃)。
只玩一周,无论玩多久,上限 $\frac{5}{3} \approx 1.67$ 分(不规律)。

最后修改:2026 年 10 月 01 日
如果觉得我的文章对你有用,请随意赞赏