Вобщем, как обещал в начале дня:
Про маговскую механику мне никто так и не объяснил, так что претензии по выбранному классу не принимаются, вот.
Почему симкрафт не полная фигня, или введение в реверс-инжинеринг для самых маленьких
Бесспорно, как правильно указал в
своих постах Калант, мы не имеем доступа к коду сервера World of Warcraft, и не имеем возможности подсмотреть как на самом деле реализованы те или иные механики. Тем не менее, все мы располагаем мозгами, здравым смыслом, а так же клиентом игры, в котором содержится несколько больше информации, чем кажется на первый взгляд. Используя все это, мы можем построить математическую модель урона (и поделив на значение хейста, показатель дпс) того или иного спелла и самое главное - убедится что сама по себе она достаточно тривиальна, и не является чем-то за гранью фантастики, укрепив доверие к подобным инструментам.
Изначальный кейс стоял в расчете дамага одного единственного заклинания, и он нам вполне подходит. Это
смайт, дефолтный филлер дпс-ротации дисциплин приста, мало чем отличающийся от других филлеров. Что мы знаем о смайте?
1) Его урон зависит от спд.
2) Он способен критовать на 2х урона.
3) Он кастуется полторы секунды и это время можно уменьшить хейстом.
По первому пункту может возникнуть вопрос: каким образом он зависит от спд? Если мы снимем весь гир, то увидим что игра показывает его средний урон в 2538 единиц при 207 спд, т.е. у спелла явно есть базовая часть, и, когда мы одели весь гир кроме вепона, тринкетов, и плаща дабы исключить влияние проков на тестовый результат при 25685 спд его дамаг увеличился до 24347 по тултипу, следовательно мы получаем меньше единицы урона за каждое очко спеллдамага.
Несмотря на то, что этих данных уже хватает чтобы простой экстраполяцией найти и базовое значение, и впоследствии расчитать скейлинг - делать нам этого уже с давних пор не надо. Дело в том, что близзард с какой-то версии решили отображать не базовые значения урона от заклинаний в тултипах, а те что с учетом текущих ап/спд. Для этого в один из архивов клиента игры им пришлось сложить специальный файлик-табличку, который содержит информацию о всех возможных заклинаниях и их значениях базового урона и скейлинга. Этот файлик еще в давние времена раскопали команды, занимающиеся разработками эмуляторов сервера WoW, и впоследствии фанатские сайты, вроде
wowhead, научились ее отображать.
Таким образом, без каких-либо расчетов и прямо из рук Blizzard Entertainment мы знаем что смайт кастуется 1.5 секунды, имеет базовые значения в 2226 - 2496 урона и его показатель скейлинга от спд равен 85.6% (т.е. 0.856 ед. урона за каждый поинт спд).
Из этого следует, что средний урон одного смайта при 0% крита равен (2226+2496)/2+25685*0.856 = 24347.36 ед. урона, что с учетом правил математического округления полностью соответствует тултипу.

Что такое крит в рамках математической модели? На отрезке спама смайтов длиной в бесконечность, каждый процент крита просто поднимает наш дпс на 1% относительно базового. В моем гире у меня 31.03% крита, т.е. дамажную компоненту смайта с учетом крита можно записать как f(x) = (0.3103*x*2)+(1-0.3103*x), и сократить до f(x) = 1.3103*x.
24347 * 1.3103 = 31902 урона в среднем нанесет один смайт.
Важно! Таково лишь представление критического урона в рамках математической модели, где мы считаем средний показатель ДПС, либо общий дамаг на отрезке длиной в бесконечность. В реальности, урон от спелла нельзя описать как (1+Crit)*damage, несмотря на арифметическую правильность. Это полная группа из двух событий, где с шансом в Crit произойдет damage*2 урона, и с шансом 1-Crit - damage урона.Haste уменьшает базовый касттайм заклинания, который расчитывается по всем известной формуле CastTime = BaseCastTime / 1 + Haste. Поскольку на данный момент у нас 0% хейста, для чистой, без баффов и дебаффов, цели 90 уровня наш общий дпс на бесконечном промежутке времени должен, записывая одной формулой, составить:
(((2226+2496)/2+25685*0.856)*1.3103)/(1.5 / 1 + 0) = 21268.23054 дпс.
Достаточно догадок. Давайте просто поспамим ровно 30 смайтов в маникен, это займет всего 45 секунд (дисциплин имеет стакающиеся +4% дамага за каждый каст кары, а потому мы пока просто впишем /cancelaura в макрос для чистоты эксперимента). Также, к сожалению оба текущих аддона для замера dps (skada и recount) не очень хорошо определяют продолжительность боя, и как следствие - выдают кривоватые значения DPS. Так что единственная цифра на которую реально ориентироваться - Damage Done.
От 30 смайтов средним уроном в 31902 мы ожидаем увидеть 957060 дамаги:

Как мы видим, числа хоть и похожие (кто реально заботится о 58к дамаги?), но не совсем. Это произошло из-за того что нам не очень повезло с критом. Ничего страшного, бывает. Попробуем еще раз на большем отрезке в 200 смайтов, это 6380400 урона :

Погрешность всего в 0.4%! Кроме того, обратите внимание на минимальные и максимальные значения дамага. Следуя вышеприведенной формуле, мы должны получить разброс в 24212 - 24482 для обычного удара, и 48425 - 48965 для критического. Несмотря на то, что в двух точках полученые на лайве значения уперлись в границы - они их не пересекли.
Также, количество критовых ударов приблизилось ближе к своему ожидаемому значению.
Кроме того, учитывая наш касттайм смайта, мы получили дпс равный 6405784/(200*1.5) = 21352. Всего на 84 дпс разницы! Все факторы слишком точны, чтобы полагать что нам просто 200 раз повезло. Кто не верит - проверьте 300 раз, 500, или 10000.
С увеличением числа экспериментов точность выборки бесконечно будет приближаться к ожидаемому результату.Вандер, догадался откуда идеально ровные прямые?
Здесь начинается самое интересное. Таким методом, мы нашли возможность сравнить, например, 3200 крита и 1600 инты:
(((2226+2496)/2+27285*0.856)*1.2570)/(1.5 / 1 + 0) = 21550.81248 // Даже без учета селф- и рейд-баффов 1600 инты в плане дпс лучше, чем 3200 крита.
Но что если нам надо учесть бафф от
Евангелизма, который появляется у нас при касте смайта? При каждом нажатии спелла мы получим 4% к дамагу с капом в 20% и давайте сравним сколько мы можем получить за БЛ длиной в 45 секунд. Стоп. Несмотря на то что технически задача выполнима, не слишком ли сложной становится формула? Тем не менее, мы не можем каждый раз заходить в игру и долбить маникен по 120 минут когда нам надо найти разницу между гемом на 160 инты и 320 хейста. Эта разница слишком мала, чтобы рандом не "съел" ее за 200, 500 или даже 100000 кастов. Но если мы знаем (и даже доказали что знаем) как работает игра, почему бы не написать эмулятор нашего комбата?
Простой вариант, можете выполнить в консоли браузера:
// Количество итераций
var timelimit = 45;
var iterationsCount = 15000;
function getRandomArbitary(min, max)
{
return Math.random() * (max - min) + min;
}
var smite = {
min_damage: 2226,
max_damage: 2496,
mod: 0.856,
casttime: 1.5
};
var total = 0;
function doTry() {
var player = {
spw: 25685,
crit: 0.3103,
haste: 1.0 * 1.3, // Player + BL
evangelism: 0
};
var damage = 0;
var t = 0;
while (t < timelimit) {
t = t + smite.casttime / player.haste;
var dmg = getRandomArbitary(smite.min_damage, smite.max_damage) + smite.mod * player.spw;
if (Math.random() <= player.crit) {
dmg *= 2;
}
if (player.evangelism) {
dmg *= 1 + (4 * player.evangelism) / 100;
}
damage += dmg;
if (player.evangelism < 5) {
player.evangelism += 1;
}
}
var dps = damage / timelimit;
total += dps;
}
for (var i = 0; i < iterationsCount; i++) {
doTry();
}
console.log(iterationsCount+' iterations done, '+total / iterationsCount + ' dps');

Путем большого количества итераций с разными параметрами несложно не только найти среднее количество в ~33598 dps, но и вывести ценность 1 стата:
1% крита = 264 dps = 0.44% дпс за поинт
1% хейста = 255.8 dps = 0.60 дпс за поинт
500 спд = 598 dps = 1.19 дпс за поинт
Типичной ошибкой трактовки таких данных является то, что графики отображают лишь увеличение статов относительно текущего снапшота. Иногда это может вводить в заблуждение:
Механика хилинга дисциплин пристов такова, что крит и мастери взаимно усиливают друг друга (график ниже, К = сумма статов крита и искуности, ось Х - искусность, ось Y - коэффициент увеличения хпса). Крит увеличивает количество проков
Divine Aegis, в то время как мастери - толщину такого щита. При разных значениях одного и другого стата (а также интеллекта, который тоже баффает крит), как один, так и другой стат могут вырываться вперед. Если мы сняли снапшот динамики роста для персонажа с 10% крита и 20% мастери, и впоследствии говорим о том что симкрафт неочень, ведь каждому очевидно что нашем в овергире с 60% крита и 30% мастери баффать надо именно последний стат - это не проблема симкрафта. Это проблема трактовки результатов.

К самому симкрафту вообще очень мало может быть претензий, кроме недоверия. Но как я уже показал выше, модель боя в игре совсем не сложна. Отличие моего кейса от реальности лишь в том, что последняя объемней. Для достоверного результата мне надо добавить применение по КД
пенанса и
хф, взаимодействие с
глифом, а так же учесть возможные временные баффы от проков оружия и двух тринкетов. Это не сложно, но долго. Как минимум потребует построения кода на нормальной объектной модели. В этой статье было уже достаточно изобретенных велосипедов. Зачем из недоверия к чужому инструменту развивать свой? Разумеется, количество требуемых для нормального просчета таких тонких вещей как разница в 160 стата итераций тоже возрастет до десятка миллионов. Но. Есть ли у нас шанс когда-нибудь побить десять миллионов маникенов с разными камнями?
Важная деталь в заключение: это бета, и я не утверждаю что симкрафт на 100% рабочий инструмент. Так же, я не могу утверждать что он будет на 100% работоспособным на лайве. К результатам его использования вообще стоит относится критически, и перепроверять сразу как заподозрено что-то неладное. Но брать какой-то случайный график, и обсуждать его без приоритетов на спеллы, статов, математики, подтверждающей реальное положение дел и с вольным трактованием результата, а потом удивляться что реальности не соответствует примерно ничего довольно... странно, нет?