面向后端 / 前端 / 数值工程师 · 只讲 JILI Super Ace(game_id 10100039)本身
这份文档解决什么问题。技术团队要实现、对接或评估老虎机,但整个产品机制没有一份成体系的技术侧说明。 结果是数值、运营、研发各说各的,而老虎机里恰好有一批「按字面实现就会埋雷」的地方。
范围。只讲一款游戏:JILI 的 Super Ace(game_id 10100039)。
不做跨厂商对照 —— 不同厂商的同名游戏是不同的数学模型,而线上表现差异里混着运营侧的开关,
拿它当算法证据会得出错误结论。
三个来源交叉。玩法规则与赔付表取自游戏内官方规则页;接口与结算取自 JILI 官方接入文档; RTP、命中率与派彩分布取自本平台注单(447,284 局)。冲突处以官方规则页为准。
核心问题在第 7、8 章:赔付表能不能从截图完整还原(能), 以及能不能进一步倒推出卷轴配置(不能,且给出了两个可验证的下界作为证明)。
文中有 10 个可交互实验。拖动参数就能看到因果 —— 比如每轮多放一个 Scatter,免费局触发率涨多少; 或者输入目标 RTP 与命中率,直接反解出对应的数学参数。
Super Ace 是 JILI 的老虎机,平台注单里的标识是 game_id = 10100039、game_plat_form = 1010。
本文所有玩法规则取自游戏内官方规则页,所有数字取自这个 game_id 的注单。
5 轮 × 4 行,1024 ways。1024 = 45:每轮 4 个可见格,一条中奖路径在每轮各取一格, 5 轮相乘就是 1024 种组合。这不是「1024 条固定线」——没有线的概念,只要从最左轮开始、连续相邻的若干轮都出现同一符号就算中。
判定规则只有三条:
成局的路数 = 各轮匹配格数连乘。比如 ♠ 在第 1 轮出现 2 格、第 2 轮 3 格、第 3 轮 1 格、第 4 轮 0 格, 那就是 3 连、2×3×1 = 6 条路,赔付 = 6 × ♠的三连赔付。
共 8 个赔付符号:A、K、Q、J 四张牌,加 ♠♥♦♣ 四个花色。每个符号都有金框和银框两种卡面, 赔付完全相同 —— 金框(Golden Card)的区别在消除之后,见第 3 章。
另有两个非赔付符号:SCATTER(触发免费局)和 WILD / Joker(万能替代,但它不会直接落在盘面上,只能由金卡转化而来)。
| 量 | 值 | 口径 |
|---|---|---|
| 局数 | 447,284 | 2026-04-27 ~ 05-04,3,760 名玩家 |
| RTP | 94.42% | 总派彩 ÷ 总投注 |
| 命中率 | 24.15% | 派彩 > 0 的局占比(一局算一次,哪怕级联连消五轮) |
| 观测最大倍数 | 643.2× | 官方封顶是 10,000×,44 万局远不足以撞到 |
这三个数在后面第 7、8 章会被反复用到 —— 它们是倒推卷轴配置时唯一的硬约束。
「RTP 94.42% 就是能拿回 94 块」是最常见的误解。下面模拟 1000 个玩家,看他们实际剩多少:
Super Ace 不是「转一次、看结果、结束」。一次 spin 内部是个循环。
下注
├─ 落盘(5×4)
├─ 判定 ways ──── 无中奖 ──→ 结算(本局 0)
│ │
│ 有中奖
│ ↓
│ 累计赢分 × 当前连击倍数
│ 中奖符号消除;其中的金卡翻成 Joker
│ 上方符号下落 + 顶部补新符号
│ 连击倍数升一档
│ ↓
└──── 回到「判定 ways」
(直到某一轮没有中奖)
结算:把整条链累计的赢分一次性给玩家
三个容易写错的点:
整条级联链跑完才结算。哪怕连消五轮,注单上也只有一行,
bet 是本次下注,result 是整条链的总和。
所以「命中率」的分母是 spin 数不是级联数 —— 第 1 章那个 24.15% 是这个口径。 如果按级联数算,同一批数据会得到完全不同的值。
未参与中奖的格子原地保留,不重新抽。这是级联和「重转一次」的本质区别: 下一轮判定的盘面里,大部分格子是旧的。
官方规则:单次 spin 的最大派彩比例是 10,000×。达到时立即停止继续匹配、直接结算。 不是「算完再截断」,是「够了就不再算了」。实现时这个判断要放在级联循环里,不是循环外。
官方另给了一个概率口径:最大派彩「guaranteed to be won in 100000000 rounds of play」—— 一亿局。我们这 44 万局观测到的最大是 643.2×,与之不矛盾。
这是 Super Ace 最容易被讲错的机制,因为「Joker」在三个不同层面上指不同的东西。
每个赔付符号都有金框和银框两种卡面。赔付完全一样 —— 金卡在成局判定里就是个普通符号。
官方规则给了三条硬约束:
| Little Joker | Big Joker | |
|---|---|---|
| 效果 | 该金卡自己变成 Joker | 该金卡变 Joker,另外在第 2~5 轮随机再挑 1~4 个符号一起变 Joker |
| 不可被选中 | — | Scatter 和已经是 Joker 的格子 |
Joker 替代除 Scatter 外的所有符号。
因为在 1024 ways 里,一个 Joker 会同时参与所有 8 个符号的判定。 它不是「补上一个缺口」,是「给每一条可能的连线都补上一个缺口」。
第 8 章有实测:金卡率从 0 提到 5%,RTP 从 136.3% 涨到 238.0%。 这是全套参数里最灵敏的一个,调它的步长要比调赔付表小一个数量级。
这里必须分清,否则读协议和读规则会得出矛盾的结论:
| 层面 | Joker 是什么 |
|---|---|
| 玩法规则(官方 Info 页) | 一个概念,分 Big / Little 两种模式 |
| 玩家看到的 | 一张画着小丑皇冠的卡面(红金框和蓝绿框两种) |
| 协议实现 | 不是一个符号 id,而是格子的一个状态位 |
写代码时按第三行来:Joker 不占符号枚举值,它是格子的状态。 按前两行去协议里找「Joker 符号」,会找不到而误判「这游戏没有 Joker」。
连击倍数(Combo Multiplier)是这款游戏的发动机。它把「级联」从一个视觉效果变成了数学结构。
| 档位 | 第 1 次消除 | 第 2 次 | 第 3 次 | 第 4 次及以后 |
|---|---|---|---|---|
| 普通局 | ×1 | ×2 | ×3 | ×5 |
| 免费局 | ×2 | ×4 | ×6 | ×10 |
规则要点:
单次消除的赢分通常很小 —— 第 7 章的谱形里,一半以上的中奖局总派彩不到 0.5 倍。 大额派彩几乎全部来自长级联链:链越长,后面每一段的倍数越高,而且盘面上残留的未消除符号越少、越容易再中。
所以这款游戏的波动率不是靠赔付表堆出来的(赔付表最高才 2.5 倍),是靠级联长度的分布堆出来的。 想改波动率,改级联的续接概率比改赔付表有效得多。
免费局的倍数表是普通局的整体两倍(1,2,3,5 → 2,4,6,10), 不是「加了一档」也不是「概率变好」。这一点第 5 章会展开。
下面这个实验可以让你亲手转一次,看连击链怎么走、倍数怎么爬:
| 来源 | 怎么触发 | 注单表现 | 钱从哪来 |
|---|---|---|---|
| 游戏内触发 | 盘面出现 3 个或以上 Scatter | 与基础局压成一行,bet 是原下注额 | 已经算在游戏 RTP 里 |
| Buy Bonus | 玩家花钱直接买 | 正常注单,bet 是购买价 | 玩家自己付,见第 6 章 |
| 运营发放 | 调 CreateFreeSpin 接口 | 每一转一笔注单,bet = 0,带 freeSpinData | 不在游戏 RTP 分母里,见第 10 章 |
这三种在注单上的粒度不同,是最容易出错的地方。 游戏内触发的免费局不会产生额外注单行;运营发放的每一转都产生一行。 算 RTP、算打码量、做财务口径时,必须先分清楚在数哪一种。
官方规则页对这一条有明确表述:
Rule of Free Game are same as the normal game, only difference in the "Combo Multiplier" level.
(免费局规则与普通局完全相同,唯一区别是连击倍数档位。)
命中结构完全一样,卷轴没有换,符号概率没有变。唯一的差别就是倍数表整体翻倍。
玩家体感上「免费局更容易中大奖」是真的,但机制是同样的中奖被乘以两倍的倍数, 不是中奖变多了。实现时不要给免费局单开一条判定分支,只换倍数表。
官方中断机制规定:已经下注、且玩家已无法影响结果的那一局,结果保持有效,系统自动完成并结算。 免费局的剩余次数保存,下次登录继续。
注意这与 Buy Bonus 相反 —— Buy Bonus 断线时未开始的剩余次数直接取消(第 6 章)。 两套规则方向相反,实现必须分开处理,不能共用一段恢复逻辑。
玩家可以直接花钱买免费局,价格是当前注额的 41 倍,一次最多买 99 次。
41 倍这个价格本身是个信息:它意味着厂商估算的「一次免费局触发的期望价值」约等于 41 倍注额除以某个大于 1 的系数 —— Buy Bonus 的 RTP 通常略低于基础局,差额就是这个功能的毛利。
| 项 | 值 |
|---|---|
| 单次 spin 最大派彩倍数 | 10,000× |
| 最大派彩金额 | ₱100,000,000 |
| 最小投注 | ₱0.25 |
| 最大投注 | ₱10,000 |
两个封顶同时生效,取先撞到的那个。注意 10,000 × ₱10,000 = ₱1 亿,两条线在最大注额上正好重合 —— 说明金额封顶是按最大注额×倍数封顶推出来的,不是独立设的。
封顶会中断级联(第 2 章):达到比例时立刻停止继续匹配、直接结算。
我们这 44 万局里观测到的最大是 643.2×,离封顶还差一个多数量级。 官方给的口径是最大派彩「一亿局」量级才保证出现一次 —— 44 万局观测不到是正常的, 不能据此判断「这个版本封顶更低」。
官方规则页给出的赔付表是这样的(标注「Payouts are shown as bet = 1」,即相对单注的倍数):
| 符号 | 5 连 | 4 连 | 3 连 | 基值 |
|---|---|---|---|---|
| A | 2.5 | 1.5 | 0.5 | 0.5 |
| K | 2 | 1.2 | 0.4 | 0.4 |
| Q | 1.5 | 0.9 | 0.3 | 0.3 |
| J | 1 | 0.6 | 0.2 | 0.2 |
| ♠ | 0.5 | 0.3 | 0.1 | 0.1 |
| ♥ | 0.5 | 0.3 | 0.1 | 0.1 |
| ♦ | 0.25 | 0.15 | 0.05 | 0.05 |
| ♣ | 0.25 | 0.15 | 0.05 | 0.05 |
把每行的三个数除以最后一列,八行全部得到同一组比例:
A 2.5 : 1.5 : 0.5 = 5 : 3 : 1
K 2 : 1.2 : 0.4 = 5 : 3 : 1
Q 1.5 : 0.9 : 0.3 = 5 : 3 : 1
J 1 : 0.6 : 0.2 = 5 : 3 : 1
♠♥ 0.5 : 0.3 : 0.1 = 5 : 3 : 1
♦♣ 0.25: 0.15: 0.05 = 5 : 3 : 1
所以整张表可以写成一个乘积:
赔付(符号, 连长) = 基值(符号) × 形状(连长)
基值 A=0.5 K=0.4 Q=0.3 J=0.2 ♠=0.1 ♥=0.1 ♦=0.05 ♣=0.05
形状 3连=1 4连=3 5连=5
24 个数字压缩成 8 + 3 = 11 个,而且这 11 个里形状那三个是固定的。 实际可调的只有 8 个基值,而且它们本身也成等比:10 : 8 : 6 : 4 : 2 : 2 : 1 : 1。
这对实现的意义很直接:不要把赔付表写成 8×3 的二维表,写成一个基值数组加一个长度系数数组。 改数值时只动基值,形状不要碰 —— 形状一变,所有符号的相对波动率结构都跟着变。
最小的一次赔付是 ♦ 或 ♣ 的三连、一条路:0.05。所有其他赔付都是它的整数倍 (基值全是 0.05 的倍数,形状是整数,路数是整数)。一局里多个符号同时中、多次级联累加, 结果仍然是 0.05 的整数倍。
这是个可以直接证伪的预测。拿 447,284 局里派彩小于 10 倍的部分去数:
| 检验 | 结果 |
|---|---|
| 落在 0.05 整数倍上的局 | 98.59% |
| 格点外的取值 | 379 种,每种只出现 6~8 次,合计占 1.41% |
格点外那 1.41% 是整数除法的舍入残渣(注单里 bet 与 result 都是整数,注额不是整数时相除会有尾差), 不是新的赔付档位。赔付表读对了。
把落在格点上的派彩按倍数排开,会看到一个非常规则的分裂:
| 倍数 | 0.05 | 0.10 | 0.15 | 0.20 | 0.25 | 0.30 | 0.35 | 0.40 | 0.45 | 0.50 |
|---|---|---|---|---|---|---|---|---|---|---|
| 占比 | 5.08% | 14.60% | 2.56% | 9.58% | 1.63% | 12.50% | 0.45% | 11.96% | 0.80% | 7.71% |
0.1 的整数倍(粗体)全部远高于两侧的奇数格点,相差 5 到 25 倍。原因是八个基值里只有 ♦ 和 ♣ 带 0.05 的奇数粒度, 其余六个都是 0.1 的倍数。要落在 0.15、0.35、0.55 这些点上,必须有奇数份 ♦/♣ 的贡献。
换句话说,这个分裂的深浅直接测量了 ♦♣ 参与成局的频率。 它是一个不需要任何模型假设就能从注单里读出来的量 —— 第 8 章会用它当约束。
数据说明:JILI Super Ace(game_id=10100039,gpf=1010),
2026-04-27 ~ 05-04,447,284 局。谱形统计限定在派彩 < 10 倍的中奖局内归一(60,438 局)。
把实测派彩谱画出来,第 7.3 节说的那个奇偶分裂一眼可见:
这是个可以给出确定答案的问题。先把它拆开。
一款老虎机的数学由两部分构成:
RTP = Σ P(某个中奖组合) × 赔付(该组合)
组合
└──── 概率侧 ────┘ └──── 赔付侧 ────┘
卷轴配置 赔付表
官方规则页给的是赔付侧,而且给全了。第 7 章已经把它压成 8 个基值加固定形状 —— 没有任何遗漏,没有隐藏档位, 「派彩落在 0.05 格点上」这条预测在 44 万局里以 98.59% 的精度成立,就是它读对了的证据。
概率侧,规则页一个字都没提。这就是 PAR 表的主体:每一轮卷轴带上各符号各放多少个、怎么排列。
8 个赔付符号 × 5 轮 = 40 个占比,加 SCATTER、金卡率,再加卷轴带的排列方式。
能拿来解的方程,全部来自注单:命中率 1 个、RTP 1 个、派彩谱 21 个格点。约 23 个。
23 个方程解 40+ 个未知数,方程组本身就是欠定的。这一步不需要做实验就能看出来。
但欠定不等于没用 —— 如果加上「五轮成分相同」这个常见简化,未知数掉到 9 个,就变成超定了。 所以真正的问题是:这个简化成立吗?
做法是:按官方规则页写一个前向模拟器(盘面、ways 判定、级联、金卡转 Joker、连击倍数、免费局全部照实现), 然后不去拟合,而是去求极值 —— 在「五轮成分相同、逐格独立」这个假设下,命中率和 RTP 各自能压到多低。 如果连最低值都高于实测,这个假设就被排除了,与优化器收不收敛无关。
在所有满足「免费局触发率 ≤ 2%」的配置里搜命中率的最小值:
| 值 | |
|---|---|
| 逐格独立模型的命中率下界 | 45.87% |
| 实测命中率 | 24.15% |
差 1.9 倍。而且这个下界还刻意关掉了 Wild 和级联 —— 两者只会让命中率更高,所以真实下界只会更严。
同样求 RTP 的最小值,取到最省的那套配置,再逐步把游戏实际有的机制加回去:
| 配置(都取在 RTP 最小化的占比上) | 命中率 | RTP |
|---|---|---|
| 裸盘:无金卡、无 Joker | 50.56% | 136.3% |
| + 金卡率 5% | 50.55% | 238.0% |
| + 金卡率 13.5% | 50.59% | 470.1% |
| + 金卡率 13.5% + 符号堆叠 | 26.52% | 491.4% |
| 实测 | 24.15% | 94.42% |
平坦卷轴连 Joker 机制都还没加,RTP 就已经是实测的 1.44 倍。
两个下界都被违反,而且是同方向:平坦卷轴对玩家太慷慨了。 所以「五轮成分相同」这个简化不成立,未知数回到 40+,倒推不出唯一的 PAR 表。
既然平坦不行,就给模型加上真实卷轴唯一没被建模的东西:各轮成分不同。 真实 PAR 表里第 1 轮和第 5 轮的符号分布差别极大 —— 前面的轮次放高赔付符号,后面的轮次放低赔付符号, 这样长连(4 连、5 连)就变罕见。
用一个参数来控制它:卷轴错位。八个符号按基值排成一列,每一轮从这列里取一个高斯窗口, 窗口中心随轮次移动。错位 = 0 时五轮完全相同(退化回平坦),错位越大各轮的符号集越不重叠。
把它从 0 拉到 1.6:
| 卷轴错位 | 0.0 | 0.4 | 0.8 | 1.2 | 1.4 | 1.6 |
|---|---|---|---|---|---|---|
| 命中率 | 55.6% | 51.1% | 37.8% | 23.3% | 17.2% | 12.0% |
| RTP | 7509% | 3224% | 665% | 167% | 95.8% | 58.3% |
两个量都被拉进了目标附近 —— 但不在同一个错位值上:命中率在 1.17 附近穿过 24.15%, RTP 在 1.41 附近穿过 94.42%。再联调金卡率(第 8.4 节会说明它是纯 RTP 旋钮),最接近的一组是:
| 模型 | 参数量 | 命中率 | RTP |
|---|---|---|---|
| 平坦卷轴 | 9 | ≥ 45.87% | ≥ 136.3% |
| + 卷轴错位 | 10 | 22.73% | 101.80% |
| 实测 | — | 24.15% | 94.42% |
差距从「差一个数量级」缩到「差 1.4pp 和 7.4pp」。方向确认了:缺的就是逐轮差异。 但一个参数补不齐 —— 而且上表那组解还需要把金卡率归零,可真游戏是有金卡的。 真实卷轴有 40 个自由度,它把这些自由度都用上了;我们的注单只给得出 23 个约束。
顺带,这组参数下的卷轴长这样(各轮符号占比 %)—— 它的形状就是真实 PAR 表的形状:
| A | K | Q | J | ♠ | ♥ | ♦ | ♣ | |
|---|---|---|---|---|---|---|---|---|
| 第 1 轮 | 25.6 | 40.7 | 25.7 | 6.4 | 0.6 | 0.0 | 0.0 | 0.0 |
| 第 2 轮 | 4.1 | 19.5 | 37.4 | 28.4 | 8.6 | 1.0 | 0.1 | 0.0 |
| 第 3 轮 | 0.2 | 2.6 | 15.3 | 35.2 | 32.2 | 11.7 | 1.7 | 0.1 |
| 第 4 轮 | 0.0 | 0.1 | 1.7 | 11.6 | 32.2 | 35.4 | 15.4 | 2.7 |
| 第 5 轮 | 0.0 | 0.0 | 0.1 | 1.1 | 8.9 | 29.5 | 39.0 | 20.5 |
高赔付符号(A、K)几乎只在前两轮出现,第 5 轮完全没有。所以 A 的 5 连在这套配置下是不可能事件 —— 这正是长连罕见、波动率被压住的机制。
金卡率是最贵的旋钮。上表第二行:金卡率从 0 提到 5%,RTP 从 136.3% 涨到 238.0% —— 几乎翻倍。 原因是金卡消除后变 Joker,Joker 替代除 Scatter 外的所有符号,一个 Joker 会同时参与多个符号的判定。 调这个参数时步长要非常小。
堆叠能在 RTP 几乎不动的前提下单独压命中率。上表第三、四行:加入堆叠后命中率从 50.59% 掉到 26.52%, RTP 只从 470.1% 动到 491.4%。这是因为真实卷轴带上的 4 个可见格是连续 4 个位置, 符号成组堆叠时同一轮内会重复 —— 这降低了「三轮共享同一符号」的概率,但一旦中了,路数反而更多,两个效应互相抵消。
逐格独立的模型给不出这个自由度。这也是为什么命中率必须靠卷轴带的排布来调, 而不能只靠符号的占比。第 9 章末尾的 PAR 实验台可以把这六个旋钮全部拖一遍。
上面全部是从注单反推。同一个结论从完全不同的方向也出现了一次:我方 QA 在验收环境里试图核算理论 RTP,八个用例全部阻塞。
| 用例 | 阻塞原因(原文) |
|---|---|
| 理论 RTP 复核 | 未提供 PAR、Reel Strip、Paytable 和 Feature 数学规则 |
| Hit Rate 验证 | 未提供 PAR 目标 Hit Rate 与批量样本 |
| Monte Carlo 收敛 | 无 Monte Carlo 模拟器、目标 RTP 和配置 Hash;UI 小样本不能用于 RTP 结论 |
| 模块 RTP 分解 | 无 Base / Free Spin / Bonus 分项模拟输出 |
| 固定 Seed 可复现 | 环境不支持指定 Seed 或结果回放 |
| 结果完整性审计 | 无批量逐局明细或 SQL 导出 |
第一行就是本章的前提:卷轴配置不在我们手上。所以「能不能倒推」不是一个学术问题 —— 它是验收流程当前实际卡住的地方。
最后一行则指向解法。「无批量逐局明细」正是 smResult 要填的空:
把它打开并落库,理论 RTP 复核、Hit Rate 验证、结果完整性审计这三条会同时解锁,
因为它们要的都是同一样东西 —— 逐局的盘面与结果明细。
数据说明:本节引自我方 SuperAce 验收测试报告(P0–P3,2026-09-02 首次执行 / 09-07 回测)。 引用的是用例执行结果,即环境实际提供了什么,不是对游戏机制的描述。
| 问题 | 答案 |
|---|---|
| 赔付表能从截图拿到吗 | 能,而且完整。8 个基值 + 固定形状,已被 0.05 格点检验证实 |
| 卷轴配置能从截图拿到吗 | 不能。规则页完全没有这方面信息 |
| 截图 + 注单汇总指标够吗 | 不够。23 个约束对 40+ 个未知数;平坦简化被两个下界排除,加一个错位参数仍差 1.4pp / 7.4pp |
| 那能做什么 | 能拟合出一套行为等价的卷轴 —— 复现命中率、RTP 与谱形。克隆够用,但不等于知道原表 |
| 什么数据能真正解开 | 逐局的盘面快照。协议里有这个字段,我们没要 —— 见下 |
最后一行是可执行的结论,而且路径是现成的。JILI 在 2025-08-13 给 /bet 与
/sessionBet 加了一个参数:
smResult string No 盘面字串(葡萄牙合规市场需求)
这就是逐局盘面快照 —— 葡萄牙监管强制要求,所以厂商已经实现了,只是我们的接入没有开启。 有了它,各轮各符号的占比是直接数出来的,根本不用解方程。
所以要拿到真实 PAR 表,动作不是做更复杂的统计,而是要求 JILI 在我们的接入上打开
smResult,并在注单表里落这一列。这是本文唯一一条需要对外协调的结论。
复现说明:模拟器 lib/superace_sim.py,实验 stages/60_par_inversion.py。
逐轮差异实验 stages/61_taper_reachability.py。
模拟器经解析式单元检验 —— 首轮期望赔付 模拟 0.5697 / 解析 0.5770,比值 0.987。
第 8 章的结论是倒推不出原表。但反过来,从零设计一张能用的表是完全可行的 —— 而且第 8 章的模拟器就是工具。
| 旋钮 | 主要影响 | 灵敏度 |
|---|---|---|
| 各符号在卷轴上的占比 | RTP、命中率(同向) | 中 |
| 符号在卷轴带上的堆叠程度 | 命中率(RTP 几乎不变) | 高 |
| 逐轮成分差异(越靠后越稀) | 连长分布 → 波动率 | 中 |
| 金卡率 | RTP | 极高 |
| Big / Little Joker 比例 | 波动率 | 高 |
| Scatter 密度 | 免费局触发率 → RTP | 高(且非线性) |
这些旋钮互相耦合,但耦合方向不同,可以排出一个不用反复回头的顺序:
盘面 20 格,Scatter 每格概率 p(若卷轴上 Scatter 不堆叠,各格近似独立), 触发条件是至少 3 个:
P(触发) = 1 − P(0 个) − P(1 个) − P(2 个)
= 1 − Σ C(20,k) · p^k · (1−p)^(20−k)
k=0..2
免费局对 RTP 的贡献 = P(触发) × E[一次免费局的总派彩]。 后者本身又依赖再触发概率,是个几何级数 —— 如果再触发概率乘以追加局数接近 1,这个级数会发散。 设计时必须先验算这一项,否则参数看起来正常,RTP 却会爆掉。
设计时有两件事在受监管市场是明确禁止的,与商业选择无关:
这两条决定了 PAR 表必须是静态的:一张表配一个 RTP 档位,切档位是换整张表,不是在运行时调概率。
下面这个反解器接受目标 RTP 与命中率,直接给出对应的数学参数:
把第 8 章那个模拟器接上六个旋钮。目标是复现实测的命中率 24.15% 与 RTP 94.42%。 先把「卷轴错位」拉到 0 —— 那就是第 8 章证明过不可行的平坦卷轴,你会看到两个指标同时失控。
Scatter 是最灵敏的旋钮之一。下面这个计算器可以拖动参数,看触发率怎么变:
免费局在业务上只是"送几把",在工程上却是两套完全不同的数据流。上一章讲的是谁发、发多少;这一章只回答一件事:注单落到我们库里之后,怎么认、怎么记、怎么对账。这块埋的雷最多,而且大多数是上线半年后才在月结时炸出来的。
游戏内触发的免费局(3 个以上 Scatter 打出的 Free Game)和运营通过 CreateFreeSpin 发放的免费局,注单形态完全不同。
| 游戏内触发(3+ Scatter) | 运营发放(CreateFreeSpin) | |
|---|---|---|
| 注单粒度 | 与触发它的基础局压成一行 | 每一次旋转发一笔独立注单 |
| betAmount | 玩家真实下注额 | 0 |
| freeSpinData | 无 | 有 |
| 成本归属 | 已包含在该局 RTP 里 | 后台单独记录,月底结算 |
一笔运营发放的注单长这样:
{
"game": 110,
"round": 17238050501001102002,
"betAmount": 0,
"winloseAmount": 55,
"freeSpinData": {
"referenceId": "freespintest0001",
"remain": 9,
"originalBet": 0.5,
"deduct": 1
}
}
originalBet 是名义押注,不产生任何扣款;remain 是这一组发放剩余的局数;deduct 是本笔扣掉几局。另有一个 skipRidValidation,双方合作活动时部分免费局由游戏商自己派发并生成局号,营运端要跳过序号连续性检查——如果你的对账脚本会因为局号断档报警,这个字段必须提前接进去。
这个 0 是好事,也是唯一的窗口期。一旦启用,bet = 0 的行会立刻出现在注单表里,而 RTP 分母、打码口径、财务口径三条线的定义必须在那之前就定好,否则第一天的数据就是脏的,回头再补要重跑历史。
规则一句话:有 freeSpinData 且 betAmount = 0 → 运营发放;否则一律按正常局或游戏内触发处理。
其余字段只用于交叉校验,不参与分类判断:
betAmount 应为 0 —— 不为 0 说明上游拼错了referenceId 应能在本地发放记录里查到remain 应随同组注单单调递减deduct 与 remain 的差值应自洽任何一项不一致,告警并挂起,不要自行推断。见过的坑是:有人写"betAmount 是 0 但没有 freeSpinData,那大概也是免费局吧"——于是把游戏商的一次异常空单认成了发放,月结时多算一笔成本。分类逻辑必须是单字段的、可判定的,推断留给人。
下面这个实验可以让你逐个开关字段,看分类结果和校验告警怎么变:
同一笔免费局注单,在四个系统里的处理方式互不相同,不能用一套逻辑糊过去。
| 线 | 运营发放的免费局怎么算 | 理由 |
|---|---|---|
| RTP 统计 | 分母不计(bet=0),分子的派彩要单独成列 | bet 进分母会把 RTP 撑到无穷;派彩进分子而分母不动,会让站点 RTP 虚高 |
| 打码流水 | 按官方口径记最小投注额,不记 0,也不记 originalBet | 官方明确:免费局投注额设为最小投注额,投注额记录也按最小投注计 |
| 财务口径 | 派彩是真实支出,计入彩金成本;下注侧为 0 | 玩家赢的钱是要提走的真金 |
| 玩家账变 | 只有派彩一笔入账,没有扣款那一笔 | originalBet 不扣款,账变表不该出现负向记录 |
再补一个查询侧的坑:GetFreeSpinRecordSummary 的响应里 BetAmount 这一项必定是 0,不要拿它去和打码流水核对——那两个数天生对不上。对账要用同一响应里的 TotalSend / TotalUsed / TotalUnused。
| 接口 | 形态 | 适用 |
|---|---|---|
/bet | 下注与派彩合并成一笔 | 默认路径 |
/sessionBet | 拆成两笔,共用同一 round 与 sessionId | 老虎机与鱼机可选 |
/cancelBet | 按 round 撤销已入账注单 | 老虎机与鱼机 |
sessionBet 拆开后的两笔:
下注 type=1 betAmount=0 winloseAmount=0 freeSpinData.deduct=2
派彩 type=2 betAmount=0 winloseAmount=1.5 freeSpinData.deduct=0
注意扣局数只发生在 type=1 那笔,type=2 的 deduct 是 0。如果你的消费端按 round 去重,会把这两笔当成重复投递而丢掉派彩——去重键必须带上 type。
取消的余额公式是确定的:
取消后余额 = 取消前余额 + betAmount − winloseAmount
对免费局而言 betAmount 是 0,所以取消等于把派彩原路扣回。硬约束两条:取消后余额不可为负;余额不足时返回错误码 6。玩家赢了免费局的钱立刻提走再触发取消,这个分支一定会命中,不能只在测试环境里假设它不会发生。另外游戏商会一直重发直到拿到回应,且可能在玩家掉线时发送,所以请求里除 token 外还带 userId ——鉴权逻辑不能只认 token,否则掉线场景下所有取消都会失败重试到爆。
下面这个实验可以调下注额、派彩额和当前余额,看合并发送、拆分发送、取消三条路径下的余额走向和错误码:
这是最容易写错的一条,因为两种免费局的规则方向正好相反:
共用一个"断线恢复"函数的实现,一定会在其中一边出错。这两条路径的状态恢复逻辑必须物理分开。
还有几条绑定规则会影响状态机设计:免费局数在玩家进入游戏那一刻绑定,绑定后必须用完才恢复正常玩法;账号绑定到进入的第一个游戏,绑定后同组的其他游戏不可用;有多组可用时按 referenceId 绑定最早到期的那组;有效期只在进入游戏那一刻判定,进去之后即使跨过到期时间也能用到耗尽;只要还有有效免费局数,系统会优先使用免费局,玩家不能选择先用真金。最后这条经常被客服当成 bug 上报,提前写进 FAQ。免费局进行中,游戏内的 Free Game 与 Bonus Game 仍可正常触发,也就是免费局里还能嵌套免费局——数据结构要能表达这层嵌套。
官方的重送策略是:发送失败会重送到成功或满 10 次为止。也就是说重复投递是常态而非异常,幂等必须做在我们这边。
| 场景 | 幂等键 | 说明 |
|---|---|---|
| 发放(CreateFreeSpin) | ReferenceId | 上限 50 字符;重复会返回错误码 102 ReferenceId Exist,这本身就是一层天然幂等,不要把它当失败重试 |
| 注单入账(/bet) | round | round 是注单唯一识别值 |
| 拆分入账(/sessionBet) | (round, type) | 下注与派彩共用 round,只用 round 会吞掉一笔 |
| 取消(/cancelBet) | round | 取消也以 round 识别;重复取消必须返回首次结果而非二次扣款 |
去重表的保留期要长于重试窗口。10 次重送若带退避可能横跨数小时甚至更久,而免费局有效期最长可到 31 天(FreeSpinValidity 用 GMT-4,且不得与开始时间相差超过 31 天),按天清理去重记录是不够的。
其余会打到实现的参数约束:GameIds 逗号分隔且含逗号上限 200 字符;BetValue 不填时一律用游戏最小投注额,填错返回 101;币种不存在返回 104;MaxWin 不填则无上限,这个默认值在配置界面必须显式提示;AllowStop 决定玩家能否中止旋转,会影响剩余局数的回收路径;SendReport 决定是否进月报表,直接影响对账口径。EnableCustomBet 允许 BetValue 精确到小数后两位,官方同时警告中奖倍率可能把赢分推到小数后三位——金额字段用整数分存储的系统开这个开关前必须先改精度。
bet > 0 过滤本章的字段结构、参数约束、错误码与规则条款均取自 JILI 官方接入文档的免费游戏章节(该章共 13 个接口,含另一种性质不同的 CreateSpinBonus,本章未展开);bet = 0 行数为 0 的结论来自本平台注单表当前的实际统计。
运营发放免费局走 POST /CreateFreeSpin。参数不多,但有几个的语义容易想当然:
| 参数 | 必填 | 说明 |
|---|---|---|
Account | 是 | 玩家账号。账号不存在时会自动创建 |
ReferenceId | 是 | 本批的唯一序号,长度上限 50。重复会报 102 ReferenceId Exist |
FreeSpinValidity | 是 | 有效期,时区是 GMT-4,且与开始时间相差不得超过 31 天 |
NumberOfRounds | 是 | 局数 |
GameIds | 是 | 可用游戏,逗号分隔,含逗号长度上限 200 |
BetValue | 否 | 不填一律用该游戏的最小投注额,不是「不限制」 |
StartTime | 否 | 不填则立即可用 |
AllowStop | 否 | 是否允许玩家中止免费旋转 |
MaxWin | 否 | 累计赢分上限。不填则无上限 |
EnableCustomBet | 否 | 允许 BetValue 精确到小数后 2 位 |
三个坑。
① FreeSpinValidity 用 GMT-4,不是 UTC 也不是马尼拉时间,直接传本地时间会差 12 小时。
② 不填 MaxWin 是无上限,不是「按游戏封顶」—— 发放前必须显式算尾部风险。
③ 官方对 EnableCustomBet 有明确警告:开启后中奖倍率可能让赢分出现小数后 3 位。
账务按 2 位小数存储会产生舍入差,开之前先确认下游能接。
下面这个配置器可以调 CreateFreeSpin 的参数,看发放成本与尾部风险怎么变:
先说我们平台的现状,因为它决定了这一章该怎么读。
| 检查 | 结果 |
|---|---|
Super Ace 44.7 万局的 jackpot_contribution / jackpot_win_amount | 全部为 0 |
| 全站单日 4,010 万局的同两列 | 全部为 0 |
feature_type 实际取值 | 只有 1 / 2 / 3 |
| 验收环境 Jackpot 用例(四条) | 全部阻塞:「Jackpot 暂不可启用」「奖池配置列表共 0 条」 |
最后一行来自我方验收测试报告,与上面三行的注单统计是两个独立方向 —— 一个查生产注单,一个在测试环境点后台。两边指向同一件事。
目前没有任何游戏在跑 jackpot。三个字段是 schema 预留、从未被写入。 所以第 1 章那个 RTP 94.42% 是纯基础局的值,不含任何 jackpot 成分 —— 这一点是验证过的,不是假设。
名字里带 “Jackpot” 的几款游戏(如 Super Ace Jackpot)抽水同样是 0。 那是游戏名或局内玩法,不是活跃的累积奖池。
厂商接入文档里唯一有完整接口定义的奖池机制是满额必开 —— 池子涨到阈值就必须开,
不是「配一个每转的中奖概率」。接口 POST /GetMustHitBy 按游戏 ID 查询,返回两个数:
MustHitByPool 满额必开水箱 ← 当前累积
MustHitByValue 满额必开数值 ← 触发阈值
官方响应示例(THB):
| 游戏 | GameId | 当前池 | 阈值 |
|---|---|---|---|
| SuperAce | 49 | 2,937.4401 | 3,000 |
| Dragon Treasure | 46 | 3,000 | 3,000 |
| CrazySeven | 35 | 2,459.8625 | 3,000 |
| Bao boon chin | 36 | 2,413.6871 | 3,000 |
三件事可以直接读出来:
JP: true/false 标记哪款内建奖池),
只是我们的接入没开。| 方式 | 触发条件 | 代价 |
|---|---|---|
| 概率触发 | 每转一个概率 | 概率必须随注额缩放,否则小注玩家的 jackpot EV 被放大 |
| 满额必开(JILI) | 池子达到阈值 | 可预测 ⇒ 会引来蹲池的套利者,见 11.3 |
| 符号 / 转盘触发 | 盘面命中特定符号 | 占用赔付表预算,与基础局数学耦合 |
设抽水率 r、阈值 V、当前池位 P。池子从 P 涨到 V 需要的总流水是 (V−P)/r, 而这段流水最终对应的奖金是 V。所以这一段期间的 jackpot 回报率是:
jackpot 回报率(P) = V / ((V − P) / r) = r · V / (V − P)
取 r = 1%、V = ₱3,000:
| 池位 | 0% | 50% | 80% | 90% | 95% | 99% |
|---|---|---|---|---|---|---|
| 剩余需流水 | ₱300,000 | ₱150,000 | ₱60,000 | ₱30,000 | ₱15,000 | ₱3,000 |
| jackpot 回报率 | 1.0% | 2.0% | 5.0% | 10.0% | 20.0% | 100.0% |
全周期平均回报率恰好等于抽水率 1%(池子最终必然全额派出,一分不多一分不少)。 但回报率沿池位是发散的:只在满池附近下注的人,拿到的是均值的几十到几百倍。
而 GetMustHitBy 正是一个把池位暴露出来的接口。
如果池位被透到玩家侧(前端展示、或接口未鉴权被抓),蹲池就是一个不需要任何技巧的稳定盈利策略。
上线前必须确认三件事:池位对玩家可见到什么精度、是否有最低投注门槛、
以及实际开奖点是恰好在 V 还是在 [种子, V] 内随机——
后者是行业标准的缓解手段,但示例里 Dragon Treasure 停在整数 3,000,看起来更像前者。这一条文档没写明,需要问厂商。
这两种设计经常被混为一谈,但经济学完全不同:
| 累积奖池 | 固定奖金 | |
|---|---|---|
| 派奖额 | 派出当前池余额,然后重置到种子 | 注额的固定倍数 |
| 池的作用 | 就是奖金本身 | 负债准备金,不是奖金 |
| 池 > 派奖额时 | 不会发生(派的就是池) | 超出部分是运营毛利 |
| RTP 贡献 | = 抽水率 | = 实际派出率,低于抽水率 |
如果做成「持续抽水累积,但只派固定额」,那个池子在会计上是未兑付负债,不是奖池。 两个后果要先想清楚:
认证口径里 jackpot 必须计入理论 RTP,标准写法是拆开列:
总 RTP = 基础局 RTP + jackpot 贡献
三个前提:
JILI 用 statementType 区分注单性质,jackpot 相关的是这几个:
| 码 | 含义 |
|---|---|
| 1 | 一般下注 |
| 12 | 购买 bonus(Buy Bonus,见第 6 章) |
| 19 | 免费游戏 |
| 28 | 旋转奖金(Spin Bonus) |
| 17 / 18 | 满额必开(下注 / 开奖)——投注侧与派奖侧是两条独立注单 |
| 33–36 | Jackpot Legend Mini / Minor / Major / Grand |
17 和 18 分开,意味着抽水与派奖在数据上天然可分离,基础局 RTP 与 jackpot RTP 不会混在一起。 这是好事,但前提是厂商真的按这个类型发送。
四档那组码的名字是 “Jackpot Legend”,与 17/18 这一对不是同一件事。 两者的证据边界见下一节。
这一章的每条结论对应的证据强度不同,混用会得出错误判断。分开列:
| 结论 | 证据 | 强度 |
|---|---|---|
| 满额必开机制存在,按 (游戏, 币别) 分池 | 接入文档 GetMustHitBy 接口定义与响应示例 | 厂商官方 |
| 四档 MINI/MINOR/MAJOR/GRAND 结构在 JILI 生态里存在 | 接入文档附录 C 注单类型码 33–36 | 厂商官方 |
| 抽水与派奖在数据上可分离 | 码 17 / 18 分列 | 厂商官方 |
| Super Ace 有内建奖池能力 | 游戏列表 JP 标记 + GetMustHitBy 示例含 SuperAce | 厂商官方 |
| 我方当前未启用任何奖池 | 注单统计 + 验收环境 | 实测 |
| Super Ace 实际走哪一套、四档参数是多少 | 无 | 未知 |
码 33–36 的名字是 “Jackpot Legend”,读起来像一条具体产品线的标识, 而不是所有游戏通用的架构;通用的是 17/18 这一对。 四档分池在行业里很常见,但「Super Ace 用的是四档」这句话目前没有任何厂商侧证据。 内部资料里有这个说法,那是团队的理解,不能当作厂商确认 —— 要定案只能问 JILI。
| 项 | 为什么必须先定 |
|---|---|
| 管道验证 | 三个字段至今从未被写入过。不能假设厂商会填 —— 先小流量跑,确认真的有值,否则财务口径静默漏账 |
| 抽水计入时点 | 下注时记成本,还是派奖时记?两者的日 P&L 波动差很大 |
| 池位可见性 | 见 11.3。透出去就等于公开套利入口 |
| 抽水率与种子 | 文档不披露,只能问厂商商务,或开通后自己从 jackpot_contribution 反推 |
| 池是否跨运营商共享 | 文档未说明。共享池的数字更好看,但我方抽水会补贴别家的玩家 |
文档覆盖度。JILI 接入文档提供的是读取接口与注单类型
(GetMustHitBy、JP 标记、码 17/18/33–36);
不提供抽水率、种子金额、重置规则、派奖额如何决定、四档如何分水、是否跨运营商共享。
经济学参数全部在厂商侧。
下面这个计算器可以拖抽水率、阈值、日流水,看开奖周期与套利敞口怎么变:
| 词 | 含义 | 常见误解 |
|---|---|---|
| ways | 从最左轮起连续相邻轮各取一格构成的路径。5×4 盘面共 45=1024 种 | 不是「1024 条线」,没有线的概念 |
| PAR 表 | 卷轴带配置 + 赔付表的总称,决定这台机器的全部数学 | 不只是赔付表;主体是卷轴配置 |
| 级联 / Cascade | 中奖符号消除、上方下落补入、再判定的循环 | 整条链只结算一次,注单只有一行 |
| 连击倍数 | 级联链内逐次递增的倍数,spin 之间不继承 | 不是「越玩越高」 |
| 金卡 / Golden Card | 金框卡面,赔付与银框相同,被消除后翻成 Joker | 金卡本身不是 Wild |
| Joker / Wild | 替代除 Scatter 外所有符号。协议里是格子的状态位,不是符号 id | 去符号表里找「Joker」会找不到 |
| 命中率 | 派彩 > 0 的 spin 占全部 spin 的比例 | 分母是 spin 不是级联次数 |
| RTP | 总派彩 ÷ 总投注 | 是长期期望,不是「每 100 块能拿回 94 块」 |
| 项 | 值 |
|---|---|
| 游戏 | Super Ace,game_id = 10100039,game_plat_form = 1010(JILI) |
| 窗口 | 2026-04-27 ~ 2026-05-04 |
| 样本 | 447,284 局 / 3,760 名玩家 / 投注 ₱927,641 |
| RTP | 94.42% |
| 命中率 | 24.15% |
| 观测最大倍数 | 643.2× |
| 谱形样本 | 派彩 < 10 倍的中奖局 60,438 局 |
同名不等于同款。平台注单里带 “Super Ace” 字样的 game_id 有十来个,
包含 Super Ace 2、Super Ace Deluxe、Super Ace Joker、3 Super Ace 等等 —— 它们是不同的游戏,
不是同一款的不同版本。特别是「3 Super Ace」(10100236)不是 Super Ace 的第三版,是另一款游戏。
引用任何数字都必须带上 game_id。
本文每个数字都可以追到下面某一层。层级不同,能承担的结论也不同:
| 来源 | 它能证明什么 | |
|---|---|---|
| 1 | 游戏内官方规则页 | 真实游戏的玩法规则、赔付表、封顶、投注上下限 |
| 2 | 厂商接入文档 | 真实的接口、参数、结算与断线语义、厂商侧机制 |
| 3 | 平台注单库 | 这一批实际发生了什么——可以证伪规则是否被这样执行,不能推翻规则表述 |
| 4 | 内部理解文档 | 只证明团队目前怎么理解。与 1–2 一致时不构成独立佐证(作者很可能读的是同一份材料) |
| 5 | 第三方网页 | 线索。已证实含事实错误,见下 |
冲突时取层级高的。第 4 层与前三层冲突,记为「理解偏差」待澄清,不能用它去修正前三层。 测试报告是例外 —— 它记录的是执行结果(环境实际提供了什么),属于观测,按第 3 层对待。
技术团队搜 “JILI Super Ace RTP” 会大量命中联盟站与 SEO 站。这类页面的游戏规格不可用。 拿其中一个流传较广的页面对照官方规则页:
| 该页面声称 | 官方规则页 / 实测 | |
|---|---|---|
| 盘面 | 50 adjustable paylines | 5×4,1024 ways,没有 payline 概念 |
| 最大派彩 | 8,000× | 10,000× |
| RTP | 96.60% | 规则页不写 RTP;本批实测 94.42% |
| 特性 | Ace collection、bonus wheel、expanding wilds、re-spin | 规则页无这些机制;实际是金卡→Joker + 级联 |
盘面结构、封顶、玩法特性三项全错。这类内容通常由不接触游戏数学的人批量生成, 数字看着具体但没有来源。引用前先回到第 1–2 层核对。