gcsim 队伍 DPS 模拟器
gcsim 是一个功能强大的原神组队模拟工具,由 Keqing Mains 社区的 srl 大佬开发,可以自定义队伍角色等级、技能、武器以及圣遗物属性以及最重要的角色动作 (攻击、技能释放) 序列等队伍配置,模拟器会给出队伍平均 DPS 以及输出时间轴、角色 DPS 占比、角色站场时间占比、元素反应次数、元素微粒统计等信息总结。
PaiGram 通过集成 gcsim 实现更快速的 PVP (确信)
PYPI 安装
pip install gcsim-pypi
pip install gcsim-pypi
主框架
plugins/genshin/gcsim/plugin.py
存放了命令入口,你可以通过 /gcsim
命令呼出可以模拟的队伍伤害
plugins/genshin/gcsim/gcsim/runner.py
控制了 gcsim 程序的运行,返回程序的运行结果
plugins/genshin/gcsim/renderer.py
通过 gcsim 程序返回的结果进行渲染输出
plugins/genshin/model
中将 enka 数据源的数据类型转换为 gcsim 的数据类型
技术细节
runner
在 runner 中,我们采用了 “PriorityQueue” 以及 “BoundedSemaphore” 分别实现任务排队和并发限制
队列限制的最大数量为 21,在程序中普通用户最大将只能推入 21 - 1 = 20 个任务,剩余 1 个任务是为了方便高权限用户的任务进行插队,加快调试速度
并发数量限制为 cpu 核心数,防止程序过高占用被 kill 掉
测试
所有云端脚本都通过编写 CI 进行了自动化测试,确保了脚本的可用性
问题和解决方案
gcsim 内存溢出
在不正确的脚本运行时,可能会使 gcsim 程序发生死循环,快速消耗剩余内存
在 linux 下,我们使用了 ulimit
以及 timeout
限制程序可以使用的内存和程序的最长运行时间,防止程序出现异常
模拟默认环境模板
为了方便用户将模拟结果进行横向纵向对比,有必要统一模拟模板。基于尽量模拟深渊半间高血量打桩环境的思路,目前暂定模板如下。
环境选项
options swap_delay=12 iteration=1000;
options swap_delay=12 iteration=1000;
模拟次数采用常见的 1000。
swap_delay=12
模拟的是实际约 100ms 的常见高延迟环境,例如移动设备,或操作较慢的玩家。如果确信该队在高延迟环境下不成立,可以使用 swap_delay=4
,等于 33ms 延迟环境。
敌人选项
target lvl=100 resist=0.1 radius=2 pos=0,2.4 hp=3050301 particle_threshold=1016767 particle_drop_count=1.5;
target lvl=100 resist=0.1 radius=2 pos=0,2.4 hp=3050301 particle_threshold=1016767 particle_drop_count=1.5;
模拟当前充能最差环境, 12-3 水形幻人,每 33% 血量掉 3 元素微粒,对于非水系角色等于 1.5 微粒。(对于水系角色有点不公平,但确实是当前除纯水队外充能压力最大的环境。)
如果后续游戏推出充能条件更差的敌人将会统一替换为该敌人。
角色配置
脚本里定义的队伍 4 个角色,如果玩家的 player card 没有某个角色,会使用脚本定义的角色取代,在渲染结果会在角色卡添加“试用”标记。使用如下配置。
角色本身
角色等级 90 级,天赋 999。
武器
武器等级 90 级。
常驻池五星武器精 1,限定四星武器精 1,常驻四星武器精 5,锻造武器精 5,三星武器精 5。
不允许使用限定五星武器。
圣遗物
写法
主词条和副词条应分开书写,例如:
xiangling add set="emblemofseveredfate" count=5;
xiangling add stats hp=4780 atk=311 er=0.518 pyro%=0.466 cr=0.311 ;
xiangling add stats def%=0.248 hp%=0.2 atk%=0.1 er=0.11 em=120 cr=0.231 cd=0.726;
xiangling add set="emblemofseveredfate" count=5;
xiangling add stats hp=4780 atk=311 er=0.518 pyro%=0.466 cr=0.311 ;
xiangling add stats def%=0.248 hp%=0.2 atk%=0.1 er=0.11 em=120 cr=0.231 cd=0.726;
而不是:
xiangling add set="emblemofseveredfate" count=5;
xiangling add stats def%=0.248 hp=4780 hp%=0.2 atk=311 atk%=0.1 er=0.918 em=80 cr=0.542 cd=0.726 pyro%=0.466;
xiangling add set="emblemofseveredfate" count=5;
xiangling add stats def%=0.248 hp=4780 hp%=0.2 atk=311 atk%=0.1 er=0.918 em=80 cr=0.542 cd=0.726 pyro%=0.466;
副词条数值
单条副词条采用常见的四种初始值的平均值,对于某些数值四舍五入处理便于记忆与书写:
属性 | 数值 |
---|---|
百分比攻击 | 5% |
百分比生命 | 5% |
百分比防御 | 6.2% |
元素精通 | 20 |
暴击率 | 3.3% |
暴击伤害 | 6.6% |
充能效率 | 5.5% |
副词条数量
生命防御攻击的非百分比词条,省略不写。
由于目前仅计算输出能力不考虑生存能力,若角色的某类词条没有参与输出贡献,可以省略不写,例如香菱的百分比防御,诺艾尔的百分比生命。
圣遗物给定的标准为刷取 30 天的期望词条数。
- 双暴直接参与输出角色:
- 双暴 18 条,为了配平双暴最多可使用 12:6 的倾斜比例。
- 角色基础伤害乘区的有效属性 6 条(如,香菱百分比攻击,诺艾尔百分比防御等);
- 有一种次要有效属性额外补 4 条(如,菲谢尔 80 精通);
- 有两种次要有效属性的可再补 2 条(如,香菱 6 攻击 4 精通 2 充能);
- 以上除双暴以外的有效词条,可以在其总数范围内自由调整,但某种词条不能低于 2。例如:
- 菲谢尔,有效为攻击精通,可以 8 攻击 2 精通,但不能 10 攻击 0 精通。
- 胡桃,有效为生命精通攻击,可以 6 生命 4 精通 2 攻击。但不能 10 生命 2 精通 0 攻击,或 12 生命 0 精通 0 攻击。
- 双暴不直接参与输出角色:
- 双暴 10 条,最多可使用 8:2 的倾斜比例。
- 三有效词条角色,20 条,可以自由倾斜但某种词条不能高于 10 条或低于 2 条。
- 例如心海,有效为生命充能攻击,可以 10 生命 6 充能 4 攻击,但不能 11 生命 6 充能 3 攻击,不能 10 生命 10 充能 0 攻击。
- 双有效词条角色,16 条,可以自由倾斜但某种词条不能高于 10 条。
- 例如久岐忍,有效为生命精通,可以 10 精通 6 生命,但不能 11 精通 5 生命。
- 单有效词条角色,14 条。
- 例如班尼特的充能。
- 特别地,主词条使用三个相同属性的角色: 继承以上“双暴不直接参与输出角色”规则,同时副词条的该属性不多于 8 条。
- 例如砂糖携带三精通风套,有效为充能精通,属于上述的双有效词条角色,可以 8 精通 8 充能,可以 6 精通 10 充能,但不能 9 精通 7 充能,不能 5 精通 11 充能。
- 例如妮露携带三生命 2 千岩 2 花海,有效为生命精通充能,属于上述的三有效词条角色,可以 8 生命 6 充能 6 精通,但不能 9 生命 6 充能 5 精通。
其他约定配置
在脚本最开头的注释会作为脚本作者留言显示到计算结果图片上,一般用于写上例如脚本采用的循环手法,推荐充能等信息。但建议不超过 200 字。
战斗循环统一使用 while 1 {}
循环,可以不考虑用户配置过低带来的程序 OOM 问题,上层调用的代码有对进程可使用内存进行限制。