Простое убывающее возвращение с крышкой

19

проблема

Игрок получает 5 очков за уровень до уровня 80 с максимумом 400. Есть 5 характеристик, которые будут распределены, и нет максимального ограничения на количество, которое вы можете добавить к стату.

  • Сила
  • выносливость
  • интеллект
  • проворство
  • Удача - дарует критический шанс и критический урон

Я хотел бы реализовать уравнение убывающей доходности, скажем, на удачу. Для критического шанса я не хочу, чтобы игрок имел возможность нанести 100% критического шанса.

Будет потолок, к которому он достигнет, так как все более и более замедляющийся рост достигает 0 к добавленной точке.

Например, если максимальный критический шанс, который я хочу получить от игрока, составляет 40%, каждое очко удачи будет увеличивать критический шанс все меньше и меньше, пока критический шанс не достигнет примерно 40%. По которой 1 удача даст очень очень маленькую сумму.

Какие-либо решения? Спасибо и ваша помощь очень ценится!

Ник
источник
Возможный дубликат Как разработать формулы повреждений RPG? - tl; dr ключевое слово, которое вы ищете, это сигмовидная кривая
BlueRaja - Дэнни Пфлугхофт
@BlueRaja Я думаю, что это не дубликат. Этот вопрос о функциях убывающей отдачи в целом - о вычислении ущерба. Так получилось, что ответы на этот вопрос в основном обсуждали функции убывающей отдачи, но я думаю, что вопросы по-прежнему явно разные.
Анко

Ответы:

30

Вы хотите начать с асимптотической функции. То есть тот, который начинается с числа aи приближается к другому числу b, но на самом деле никогда не достигает его. Это, вероятно, будет проще, если a = 0и b = 1. Вы возьмете это уравнение, введете количество очков статов (очков удачи), которое имеет персонаж, и получите фактическое значение статов (шанс крита) в качестве выходных данных.

Очень простой пример - y = x / (x + n)где nнекоторая положительная константа. Вот xваш ввод, в котором вы вводите количество баллов статистики, и yваш вывод, где вы получаете окончательное значение статистики.

Чтобы n = 5проверить, как это выглядит:

y = x / (x + 5) график для x в [0,100]

Когда вы кормите, x = 0вы получаете y = 0, но независимо от того, насколько большой xвы положили, yникогда не достигает 1. Идеально.

Теперь вы можете настроить это по своему желанию сердца. Вы можете умножить на коэффициент масштабирования, чтобы установить «ограничение» на то, что вы хотите. y = a * x / (x + 5), Если вы хотите, чтобы кепка составляла 40%, умножьте на .4. y = .4 * x / (x + n), Теперь, когда вы кормите в x'ы, yувеличится, но он никогда не достигнет .4.

Отрегулируйте, nчтобы установить, насколько быстро или медленно увеличивается уравнение. n = 100будет расти намного медленнее, чем n = 5:

y = x / (x + 100) график для x в [0,400]

Вы можете решить это уравнение, nесли знаете, что хотите получить значение статистики, которое вы хотите достичь в определенном количестве. Допустим, у персонажа должно быть 35% Шанса Крита при 100 очках Удачи. Решая .35 = .4 * 100 / (100 + n)для nурожайности n = 14.29.

Эти числа не обязательно должны быть необработанными константами. Может быть, другие показатели идут в расчете значений n. Может быть, некоторые персонажи имеют разные значения n, поэтому они лучше масштабируются в своей «предпочтительной» статистике.

Если вам нужна кривая, которая имеет другую форму или является более сложной, есть много других примеров асимптотических функций, которые вы также можете использовать. Я оставлю вас, чтобы изучить это, как вы хотите.

Адам
источник
3
Моя любимая кривая - экспоненциальная. Просто возьмите фиксированное соотношение оставшегося пула с каждым уровнем.
Джон Дворак
@JanDvorak для полноты, можете ли вы привести пример? Существует множество экспоненциальных кривых, и читатель может не знать, как применить ваше предложение только из предыдущего комментария.
Адам
Это хорошая отправная точка, и математика хорошо объяснена, но имейте в виду, что вы не можете просто выбрать функцию, которая выглядит хорошо; эта проблема требует тщательного рассмотрения и много доработок. Например, одним из недостатков этого метода является препятствие специализации. Если все пять характеристик одинаково жизнеспособны, очки, потраченные на наименее развитую, будут наиболее ценными (а самая развитая - наименее). Идеальной сборкой было бы равное распределение очков, что делает выбор игрока о том, как их потратить, менее интересным.
Томас Томас
@MarcksThomas Это не предполагает синергии между атрибутами или способности тактически изолировать атрибут и «выиграть» с ним. В качестве примера представим удивительного лучника, который доводит свою ловкость до такой степени, что противники умирают до того, как достигают их: даже если ловкость имела снижающуюся эффективность, выбранная тактика делает другие атрибуты неважными. Другая тактика, включающая силу, может быть одинаково эффективной, поэтому атрибуты имеют «равную ценность», но тактика часто означает, что специализация является доминирующей. Если ваша система атрибутов также поощряет специализацию, игра расходится.
Якк
Я называю это системой «извлекать камни из сумки». Значение P = x/(x+n)- это вероятность того, что с учетом сумки с n черными камнями и x белыми камнями вы вытянете белый камень из слепой сумки. Один из подходов, который вы можете сделать, - это установить криты X = ваша удача, а N = их удача. Тогда ваш шанс критического удара составляет 50%, если вам повезло с противником. Если вы хотите, чтобы базовый шанс составлял 10%, тогда мы X = ваша удача, N = 9x их удача.
Якк
10

Хорошая база будет похожа на функцию arctan, поскольку она проходит через начало координат и имеет горизонтальную асимптоту.

агс

Масштаб его 40 / (pi/2), или 80/piдля требуемого предела. Затем трансформируйтесь, luckчтобы получить искривленную кривую.

critical = 80/pi * arctan(f(luck))
jmegaffin
источник
8

Мне очень нравится, как игры Souls решают эту проблему. Вместо того, чтобы каждая статистика давала бонусы на основе непрерывной функции, как было предложено, она дает бонусы в кусочно-линейной функции.

Я не могу вспомнить точные цифры на макушке, но функции соответствуют следующим (каждая статистика имеет свои константы)

{0 <= x <20: y = 4x, 20 <= x <30: y = 3x + 20, 30 <= x <40: y = 2x + 50, 40 <= x <60: y = 1x + 90 , 60 <= x: y = 0.5x + 120}

участок

Этот метод дает много преимуществ для дизайнера и игрока. Преимущество дизайнера заключается в том, что вы можете настроить точную выгоду за очко в навыке довольно тривиально, а игрок выигрывает, поскольку точно знает, какую выгоду он получит от уровня к уровню.

В случае непрерывной функции некоторые уровни могут дать преимущество, которое не отражается в числах из-за наложения измерений. Конечно, последний уровень дал вам 0,9 увеличения бонуса XYZ, но поскольку фактическое значение изменилось с 23,52 до 24,42, и вы округлили число до его отображения, игрок не осознает, что что-то изменилось.

С точки зрения UX, я бы определенно предложил использовать кусочно-линейную функцию. Тем не менее, использование непрерывной функции может быть легче настроить позже, так как игроки не будут привязаны к круглым константам.

Kaslai
источник
1
Аппроксимация кривой, которая не требует много математики и проста для изменения. Мне это нравится. :)
Кейси Кубалл
> Вы округлить число до отображения его => один из способов компенсировать это ceilза суммы увеличения , прежде чем добавить, и разрешить только целым числом стат уровней. или floorзатем , x <= 0: x = 1чтобы избежать случайного перехода на мягкую крышку.
Боб
1
Хотя вы все еще можете выполнять кусочную функцию, она не дает того эффекта, который вы ищете здесь. Значение удачи в процентах, с максимальным рейтингом 400. Это означает, что каждая рейтинговая точка должна приводить к увеличению стоимости на 1%, даже в линейной функции со 100% удачей. Трюк просто показывает достаточно десятичных точек, что у (399) отличается от у (400). Ваша функция делает то же самое, заставляя y расти очень большими, поэтому увеличение всегда может быть целым. При х = 40 у более чем в 4 раза превышает значение х.
MichaelS
@MichaelS Я просто привел пример типа функции, используемой в Dark Souls. Он должен быть сбалансирован по-разному в зависимости от ситуации, к которой он применяется, но моя точка зрения по-прежнему заключается в том, что игроки поймут эффект кусочно-линейной функции гораздо легче, чем арктангенсная кривая или коническое сечение.
Каслай
3

Ян Дворжак указывает на экспоненциальную функцию в комментарии. Я объясню это здесь.

Обратите внимание, что экспоненциальные (и триггерные) операции значительно дороже в вычислительном отношении, чем даже операции с квадратным корнем, которые сами по себе намного хуже, чем базовая математика, поэтому, вероятно, вам лучше использовать подход Адама, если вы будете выполнять эти вычисления много раз в секунду , Если вы просто рассчитываете значения, когда уровень игрока, смена снаряжения и т. Д., Скорость не важна, так что используйте то, что дает лучшую кривую.

Экспоненциальная функция некоторое основание, Б , в некоторой степени, х , y=B^x. Математики обычно используют основание e (~ = 2.718), но нет причин, по которым вы не можете использовать 2 или 10, если хотите.

y=e^x выглядит так: у = е ^ х

Обратите внимание, что левая сторона асимптотически движется к 0. Таким образом, мы можем перевернуть ось х, выполнив y=e^(-x) , но она все еще уменьшается от 1 до 0, и мы хотим, чтобы она поднималась. Таким образом, мы можем перевернуть его по оси Y с помощью y=-e^(-x) . Теперь это возрастание от -1 до 0. Мы можем добавить 1, чтобы получить y=1,- e^(-x) и это возрастание от 0 до 1.

у = 1-е ^ (- х)

Отсюда, это просто вопрос масштабирования по вертикали и горизонтали. Мы можем умножить всю вещь на некоторое значение, назовем это A , которое устанавливает асимптотический предел. Затем мы можем умножить x на значение скорости изменения k , чтобы скорректировать, насколько быстро оно приближается к пределу.

Это дает нам окончательное уравнение y=A*(1 - e^(-k*x)). Используя значения k=0.012and A=0.5, мы можем установить ограничение в 50% и позволить ему приблизиться к этому пределу x=400.

у = 0,5 * (1-е ^ (- 0,012 * к))

Теперь вы можете сделать несколько изменений в этом. Один твик, который я сделал, менялся A=0.5041, поэтому, если мы округлим до процента с двумя десятичными знаками (например, 32,23%), y (399) = 49,99% и y (400) = 50,00%. Начиная с y (347), есть несколько мест, где требуется 2 очка, чтобы получить изменение в 0,01%. Но этот последний возможный момент все еще дает (едва) ощутимое преимущество и доводит его до 50%.

С другой стороны, мы можем настроить kзначение, чтобы получить аналогичный эффект. При k=0.02305значении округляется до 49,99% при y=399и 50,00% при y=400. Однако проблема заключается в том, что в конце график очень неглубокий - для получения последней сотой процента (от y(352)=49.99%до y(399)=49.99%до y(400)=50.00%) требуется 48 баллов, а последний шанс крита в 1% получает колоссальные 230 баллов (от y(170)=49.01%до y(400)=50.00%) что, вероятно, слишком уменьшается при возврате.

Если вы хотите, вы можете отрегулировать как A, так и k, чтобы оно уменьшалось до несколько более высокого предела с более медленной скоростью, чтобы получить что-то среднее между линейным и экспоненциальным затуханием. Делая y=0.6*(1-e^(-0.00447*x)), вы в конечном итоге с этим: у = 0,6 * (1-е ^ (- 0,00447 * х))

Обратите внимание, что кривая продолжается более 50%, но, поскольку существует жесткий предел в 400 баллов, игрок не может пройти этот балл (и, если ему все-таки удастся его пройти, остаётся жесткий предел в 60% крит). С помощью этого уравнения вы можете использовать 1 знак после запятой и по-прежнему видеть увеличение каждые 2–3 балла с последним тиковым значением от y(399)=49.9%до y(400)=50.0%.

Математически, более ранние уравнения могут показаться лучше, поскольку на самом деле они приближаются к 50%, но я лично считаю, что прирост на 0,1% в каждой паре очков кажется лучше, чем прирост на 0,01%. Даже с A=0.05041и k=0.012, требуется 102 балла, чтобы перейти от y(298)=49.00%к y(400)=50.00%. 25% ваших очков, потраченных на 2% вашего крита, вероятно, слишком уменьшены. Уравнение 60% берет только 20 баллов за последний процент (что все еще в 5 раз выше, чем 4 балла, необходимых для первого процента).

С этими последними несколькими уравнениями я просто включил уравнения в электронную таблицу и вручную настраивал значения, пока они не выглядели хорошо. Вам бы пришлось сделать что-то похожее, если бы вы хотели другую шапку.

Michaels
источник
2
Примечание об относительной скорости математических операций является правильным, но, вероятно, не имеет отношения к статистике игрока. Узкими местами в современных играх обычно являются вещи, которые обрабатывают многие тысячи элементов за кадр (например, физика и рендеринг). Сценарии геймплея, которые, вероятно, запускаются несколько десятков раз за кадр, вряд ли будут ошибкой по сравнению с этим, и, как правило, полны пропусков кеша, которые в любом случае оставят центральному процессору достаточно времени, чтобы выполнить любую математику, какую пожелаете. tl; dr: Не испытывайте давления, чтобы избежать дорогостоящих операций, если вы не пишете шейдеры или другие вещи, которые должны запускаться
большими
-1

Для очень простого решения, как насчет квадратного корня х 2

Квадратный корень из 400 (максимально возможный) равен 20, 20 * 2 = 40.

Catwood
источник
Почему голосование против? Это решает заданный вопрос и является простым, который также просили.
Катвуд
1
Я не отрицатель, но это было, вероятно, потому что ваш ответ слишком конкретен и не предоставляет никакой информации, которая еще не была предоставлена ​​(квадратный корень - просто возведение в степень 1/2), и вы не объясняете причины, почему это может быть полезно.
Каслай
Я не понизил голос, но я не думаю, что это хороший ответ, потому что он не очень гибкий - квадратный корень не асимптотический, поэтому, если максимальный уровень когда-либо изменяется, вам нужно изменить формулу, чтобы сохранить максимальный стат такой же.
BlueRaja - Дэнни Пфлюгофт