魔兽世界是一个充斥着数值的游戏。玩家和NPC之间的互动,由一系列的伤害数值、治疗数值、光环及其加成数值来表达。对于大多数扮演伤害型职业和专精的玩家来说,将每秒伤害(Damage Per Second, DPS)最大化,是他们共同的期望与追求。 作为一个复杂的互动过程,玩家在伤害输出过程中的角色属性、天赋选择、法术选择、施放时机、施法结果、触发特效等因素都会影响全局的DPS。这些因素与其最终产生的DPS结果之间,存在一定的关系。为了找出这个关系,就需要对伤害输出的场景进行建模,并从中寻找规律,进而找到使DPS最大化的方法。

在游戏机制不甚明朗的今天,作为仿真模拟的一种,SIMC对于DPS的模拟具有很大参考价值。
然而——也许仅仅因为看似过高的门槛——很少有人将关注点放在SIMC对于盗贼技能的判定优先级。

这直接导致盗贼们失去了一个用更科学严谨的方法讨论输出循环收益的机会——通过修改SIMC语句去实现对手法优化的测试。

因此本文不会讲述如何设置导入模拟结果三部曲,而是进一步讲目光放在如何理解以及修改SIMC语句。


一、过程比结果更接近真相

相信也有不少盗贼已经能熟练的运用SIMC分析自己的DPS或者计算自己绿字属性的收益。但大多数对运算的过程知之甚少。
以战斗天赋循环为例(我们可以在使用SIMC导入(Import)人物英雄榜数据后在Simulate选项卡中找到它。)
以下是当前版本[http://simulationcraft.googlecode.com/files/simc-542-1-win32.zip]SIMC对于战斗贼技能优先级的解释。
主体循环部分 ...

actions=virmens_bite_potion,if=buff.bloodlust.react|target.time_to_die<40
当存在嗜血buff 或 剩余战斗时间小于40S时,使用兔妖之啮。
actions+=/auto_attack
自动攻击
actions+=/kick

施放脚踢
actions+=/preparation,if=!buff.vanish.up&cooldown.vanish.remains>60
当不存在消失BUFF 且 消失冷却时间剩余大于60秒时,施放消失。
actions+=/lifeblood,if=time=0|buff.shadow_blades.up
actions+=/blood_fury,if=time=0|buff.shadow_blades.up
当进入战斗 或 存在暗影之刃BUFF时,施放血性狂怒。(兽人种族天赋)
actions+=/berserking,if=time=0|buff.shadow_blades.up
当进入战斗 或 存在暗影之刃BUFF时,施放狂暴。(巨魔种族天赋)
actions+=/arcane_torrent,if=energy<60
当能量值小于60时,施放奥术洪流。(血精灵种族天赋)
actions+=/blade_flurry,if=(active_enemies>=2&!buff.blade_flurry.up)|(active_enemies<2&buff.blade_flurry.up)
(当目标数量大于等于二 且 不存在剑刃乱舞BUFF时) 或(目标数量小于二 且 存在剑刃乱舞BUFF时),施放(即开关)剑刃乱舞。
actions+=/ambush
施放伏击
actions+=/vanish,if=time>10&(combo_points<3|(talent.anticipation.enabled&anticipation_charges<3)|(buff.shadow_blades.down&(combo_points<4|(talent.anticipation.enabled&anticipation_charges<4))))&((talent.shadow_focus.enabled&buff.adrenaline_rush.down&energy<20)|(talent.subterfuge.enabled&energy>=90)|(!talent.shadow_focus.enabled&!talent.subterfuge.enabled&energy>=60))
当(战斗时间大于10秒 且 连击点数小于3 或 (预感层数小于3)或(当不存在暗影之刃BUFF 且 (连击点数小于4 或 预感小于4))) 或((暗影集中天赋下 且 当存在冲动BUFF 且 能量小于20) 或 (夜行者天赋下 且 能量大于等于90) 或 (非暗影集中天赋下 且 非夜行者天赋下 且 能量大于等于60))时,施放消失。

actions+=/shadow_blades,if=time>5
战斗时间大于5秒时,施放暗影之刃。
actions+=/killing_spree,if=energy<45
能量小于45时,施放杀戮盛宴。
actions+=/adrenaline_rush,if=energy<35|buff.shadow_blades.up
能量小于35 或 存在暗影之刃BUFF时,施放冲动。
actions+=/slice_and_dice,if=buff.slice_and_dice.remains<2|(buff.slice_and_dice.remains<15&buff.bandits_guile.stack=11&combo_points>=4)
当切割剩余时间小于2 或 (切割剩余时间小于15 且 盗匪之诈计数等于11 且 连击点大于等于4)时,施放切割。 (即进入红灯前刷新15秒以下的切割)
actions+=/marked_for_death,if=talent.marked_for_death.enabled&(combo_points=0&dot.revealing_strike.ticking)
当死亡标记天赋下 且 连击点数等于0 且 存在要害打击DEBUFF时,施放死亡标记。
actions+=/run_action_list,name=generator,if=combo_points<5|(talent.anticipation.enabled&anticipation_charges<=4&!dot.revealing_strike.ticking)
当连击点数小于5 或 (预感层数小于等于4 且 不存在要害打击DEBUFF时),施放攒星技。 注[1.1] (可以看做SIMC无视控灯的10%剔骨加成)
actions+=/run_action_list,name=finisher,if=!talent.anticipation.enabled|buff.deep_insight.up|cooldown.shadow_blades.remains<=11|anticipation_charges>=4|(buff.shadow_blades.up&anticipation_charges>=3)
当非预感天赋下 或 红灯阶段 或 暗影之刃冷却小于等于11秒 或预感层数大于等于4 或(存在暗影之刃BUFF 且 预感天赋大于等于3)时,施放终结技。注[1.2]
actions+=/run_action_list,name=generator,if=energy>60|buff.deep_insight.down|buff.deep_insight.remains>5-combo_points
当能量大于60 或 非红灯阶段 或 红灯阶段的持续时间大于(5-连击点数)时,施放攒星技。


注1.1 攒星技 ...

# Combo point generators
actions.generator=fan_of_knives,line_cd=5,if=active_enemies>=4
当敌人数量大于等于4时,施放刀扇。
actions.generator+=/revealing_strike,if=ticks_remain<2
当要害打击BUFF持续时间小于2时,施放要害打击。
actions.generator+=/sinister_strike
施放影袭


注1.2 终结技 ...

actions.finisher=rupture,if=ticks_remain<2&target.time_to_die>=26&(active_enemies<2|!buff.blade_flurry.up)
当割裂剩余时间小于2秒 且 剩余战斗时间大于等于26秒 且(目标数量小于2 或 不存在剑刃乱舞BUFF)时,施放割裂。
actions.finisher+=/crimson_tempest,if=active_enemies>=7&dot.crimson_tempest_dot.ticks_remain<=2
当目标数量大于等于7 且 猩红风暴剩余时间小于等于2秒,施放猩红风暴。
actions.finisher+=/eviscerate
施放剔骨。



补充说明 ...

1.
SIMC以0.03125秒的间隔从上至下判定语句,并且依此执行。(当然如果之前有任何一个会触发GCD的操作被执行,之后任何会触发GCD的操作都可以看做被短路。)
2.逻辑运算中的判定优先级 非>与>或 翻译成程序语言! ---> & ---> |

3.SIMC会判断当前人物专精适当添加
actions+=/use_item,slot=hands,if=time=0|buff.shadow_blades.up
当进入战斗 或 存在暗影之刃BUFF时,使用工程手套。
actions+=/lifeblood,if=time=0|buff.shadow_blades.up
当进入战斗 或 BUFF暗影之刃存在时,使用生命之血。
并不影响循环理解 故没有加入基础循环
4.不会执行当前状况下无法执行的操作。


名词翻译 ...

Adrenaline Rush 冲动
Ambidexterity 双巧手
Ambush 伏击
Anticipation 预感
Assassin's Resolve 刺客决心
Backstab 背刺
Bandit's Guile 盗匪之诈
Blade Flurry 剑刃乱舞
Blind 致盲
Blindside 盲点
Burst of Speed 速度爆发
Cheap Shot 偷袭
Cheat Death 装死
Cloak and Dagger 暗里藏刀
Cloak of Shadows 暗影斗篷
Combat Potency 作战潜能
Combat Readiness 备战就绪
Crimson Tempest 猩红风暴
Crippling Poison 减速药膏
Cut to the Chase 穷追猛砍
Deadly Throw 致命投掷
Dirty Tricks 邪恶计谋
Disarm Trap 拆除陷阱
Dismantle 拆卸
Dispatch 斩击
Distract 扰乱
Elusiveness 飘忽不定
Energetic Recovery 能量恢复
Envenom 毒伤
Eviscerate 剔骨
Expose Armor 破甲
Fan of Knives 刀扇
Feint 佯攻
Find Weakness 洞悉弱点
Fleet Footed健步如飞
Garrote锁喉
Gouge凿击
Hemorrhage出血
Honor Among Thieves盗贼的尊严
Improved Poisons强化药膏
Kick脚踢
Kidney Shot肾击
Killing Spree杀戮盛宴
Leeching Poison吸血药膏
Marked for Death死亡标记
Master of Subtlety敏锐大师
Master Poisoner毒药大师
Mastery: Executioner精通:侩子手
Mastery: Main Gauche精通:左右开弓
Mastery: Potent Poisons精通:强效药膏
Mind-numbing Poison麻痹药膏
Mutilate毁伤
Nerve Strike神经打击
Nightstalker夜行者
Paralytic Poison瘫痪药膏
Premeditation伺机待发
Premeditation预谋
Prey on the Weak欺凌
Recuperate恢复
Redirect转嫁
Relentless Strikes无情打击
Restless Blades无息锋刃
Revealing Strike要害打击
Rupture割裂
Ruthlessness无情
Sanguinary Vein动脉破裂
Seal Fate封印命运
Shadow Blades暗影之刃
Shadow Dance暗影之舞
Shadow Focus暗影集中
Shadow Walk暗遁
Shadowstep暗影步
Shiv毒刃
Shroud of Concealment潜伏帷幕
Shuriken Toss飞镖投掷
Sinister Calling邪恶召唤
Sinister Strike影袭
Slice and Dice切割
Smoke Bomb烟雾弹
Sprint疾跑
Stealth潜行
Subterfuge狡诈
Swiftblade's Cunning迅捷之黠
Tricks of the Trade嫁祸诀窍
Vanish消失
Vendetta仇杀
Venomous Wounds剧毒创伤
Vitality活力
Wound Poison致伤药膏

Attack Power Multiplier攻击强度
Attack Speed攻击速度
Spell Power Multiplier法术强度
Spell Haste施法速度
Critical Strike暴击
Mastery精通
Stamina耐力
Strength,Agility,Intellect力敏智(王者爪子)
Bloodlust流血
Skull Banner颅骨战旗
Stormlash 风暴之鞭


部分语句解释 ...

名词空格处用_替换
!
&
|
if=判断语句
actions+=/XXXX 施放XXXX
buff. XXXX 增益BUFF
talent.XXXX 天赋
XXXX.remains 计时器剩余时间
buff.XXXX.up 当某buff存在
buff.XXXX.down 当某buff不存在


即使翻译过后的程序语言相对机械,我们依然可以理解其表达的字面意思。

例1.1 不存在任何判定的语句



actions+=/ambush
为例。
这条语句没有任何判定。即

actions+=/auto_attack
actions+=/kick
actions+=/preparation,if=!buff.vanish.up&cooldown.vanish.remains>60
actions+=/use_item,slot=hands,if=time=0|buff.shadow_blades.up
actions+=/blood_fury,if=time=0|buff.shadow_blades.up
actions+=/berserking,if=time=0|buff.shadow_blades.up
actions+=/arcane_torrent,if=energy<60
actions+=/blade_flurry,if=(active_enemies>=2&!buff.blade_flurry.up)|(active_enemies<2&buff.blade_flurry.up)

actions+=/ambush
由于红字部分没有触发GCD的操作,当玩家能施放伏击时(即处于)潜行或消失状态下。当语句判定执行到这一步之后,必定会施放伏击。


例1.2 存在单个判定的语句


actions+=/shadow_blades,if=time>5
为例。
由于暗影之刃不触发GCD,因此这条语句可以看做战斗时间5秒以后,暗影之刃卡CD开。


例1.3 存在多个判定的语句


actions+=/preparation,if=!buff.vanish.up&cooldown.vanish.remains>60
为例。
SIMC会根据逻辑顺序优先判定!buff.vanish.upcooldown.vanish.remains>60分别成立后,再判定两者是否同时成立&


例1.4 存在关联性的语句
actions+=/run_action_list,name=finisher,if=!talent.anticipation.enabled|buff.deep_insight.up|cooldown.shadow_blades.remains<=11|anticipation_charges>=4|(buff.shadow_blades.up&anticipation_charges>=3)
为例。
抛开上语句,从逻辑运算的角度来讲。当红字部分的判定结束之后,判定会在任何没有预感天赋的情况下施放终结技。
然而这并不意味着SIMC会将所有终结技都低度施放。
结合
actions+=/run_action_list,name=generator,if=combo_points<5|(talent.anticipation.enabled&anticipation_charges<=4&!dot.revealing_strike.ticking)
actions+=/run_action_list,name=finisher,if=!talent.anticipation.enabled|buff.deep_insight.up|cooldown.shadow_blades.remains<=11|anticipation_charges>=4|(buff.shadow_blades.up&anticipation_charges>=3)
对红字部分解读,我们发现红字部分过滤了所有连击点数小于5的情况。由于GCD的存在,先施放的攒星技的GCD会导致之后施放终结技的判定无效。


综合以上内容,我们可以理解SIMC关于战斗贼循环的几乎所有判定。

练习题

以下是SIMC541-2中战斗贼循环语句的内容

actions+=/auto_attack
actions+=/kick
actions+=/preparation,if=!buff.vanish.up&cooldown.vanish.remains>60
actions+=/use_item,slot=hands,if=time=0|buff.shadow_blades.up
actions+=/blood_fury,if=time=0|buff.shadow_blades.up
actions+=/berserking,if=time=0|buff.shadow_blades.up
actions+=/arcane_torrent,if=energy<60
actions+=/blade_flurry,if=(active_enemies>=2&!buff.blade_flurry.up)|(active_enemies<2&buff.blade_flurry.up)
actions+=/ambush
actions+=/vanish,if=time>10&(combo_points<3|(talent.anticipation.enabled&anticipation_charges<3)|(buff.shadow_blades.down&(combo_points<4|(talent.anticipation.enabled&anticipation_charges<4))))&((talent.shadow_focus.enabled&buff.adrenaline_rush.down&energy<20)|(talent.subterfuge.enabled&energy>=90)|(!talent.shadow_focus.enabled&!talent.subterfuge.enabled&energy>=60))
actions+=/shadow_blades,if=!set_bonus.tier14_4pc_melee&time>5
actions+=/killing_spree,if=!set_bonus.tier14_4pc_melee&energy<35&buff.adrenaline_rush.down
actions+=/adrenaline_rush,if=!set_bonus.tier14_4pc_melee&(energy<35|buff.shadow_blades.up)

actions+=/shadow_blades,if=set_bonus.tier14_4pc_melee&((cooldown.killing_spree.remains>30.5&cooldown.adrenaline_rush.remains<=9)|(energy<35&(cooldown.killing_spree.remains=0|cooldown.adrenaline_rush.remains=0)))
actions+=/killing_spree,if=set_bonus.tier14_4pc_melee&((buff.shadow_blades.up&buff.adrenaline_rush.down&(energy<35|buff.shadow_blades.remains<=3.5))|(buff.shadow_blades.down&cooldown.shadow_blades.remains>30))
actions+=/adrenaline_rush,if=set_bonus.tier14_4pc_melee&buff.shadow_blades.up&(energy<35|buff.shadow_blades.remains<=15)
actions+=/slice_and_dice,if=buff.slice_and_dice.remains<2|(buff.slice_and_dice.remains<15&buff.bandits_guile.stack=11&combo_points>=4)
actions+=/marked_for_death,if=talent.marked_for_death.enabled&(combo_points=0&dot.revealing_strike.ticking)
actions+=/run_action_list,name=generator,if=combo_points<5|(talent.anticipation.enabled&anticipation_charges<=4&!dot.revealing_strike.ticking)
actions+=/run_action_list,name=finisher,if=!talent.anticipation.enabled|buff.deep_insight.up|cooldown.shadow_blades.remains<=11|anticipation_charges>=4|(buff.shadow_blades.up&anticipation_charges>=3)
actions+=/run_action_list,name=generator,if=energy>60|buff.deep_insight.down|buff.deep_insight.remains>5-combo_points
以下是SIMC542-1中战斗贼循环语句的内容
actions=virmens_bite_potion,if=buff.bloodlust.react|target.time_to_die<40
actions+=/auto_attack
actions+=/kick
actions+=/preparation,if=!buff.vanish.up&cooldown.vanish.remains>60
actions+=/use_item,slot=hands,if=time=0|buff.shadow_blades.up
actions+=/blood_fury,if=time=0|buff.shadow_blades.up
actions+=/berserking,if=time=0|buff.shadow_blades.up
actions+=/arcane_torrent,if=energy<60
actions+=/blade_flurry,if=(active_enemies>=2&!buff.blade_flurry.up)|(active_enemies<2&buff.blade_flurry.up)
actions+=/ambush
actions+=/vanish,if=time>10&(combo_points<3|(talent.anticipation.enabled&anticipation_charges<3)|(buff.shadow_blades.down&(combo_points<4|(talent.anticipation.enabled&anticipation_charges<4))))&((talent.shadow_focus.enabled&buff.adrenaline_rush.down&energy<20)|(talent.subterfuge.enabled&energy>=90)|(!talent.shadow_focus.enabled&!talent.subterfuge.enabled&energy>=60))
actions+=/shadow_blades,if=time>5
actions+=/killing_spree,if=energy<45
actions+=/adrenaline_rush,if=energy<35|buff.shadow_blades.up

actions+=/slice_and_dice,if=buff.slice_and_dice.remains<2|(buff.slice_and_dice.remains<15&buff.bandits_guile.stack=11&combo_points>=4)
actions+=/marked_for_death,if=talent.marked_for_death.enabled&(combo_points=0&dot.revealing_strike.ticking)
actions+=/run_action_list,name=generator,if=combo_points<5|(talent.anticipation.enabled&anticipation_charges<=4&!dot.revealing_strike.ticking)
actions+=/run_action_list,name=finisher,if=!talent.anticipation.enabled|buff.deep_insight.up|cooldown.shadow_blades.remains<=11|anticipation_charges>=4|(buff.shadow_blades.up&anticipation_charges>=3)
actions+=/run_action_list,name=generator,if=energy>60|buff.deep_insight.down|buff.deep_insight.remains>5-combo_points

分析两者的区别,随后我们将进入下一部分的内容。