«Ведь там в монастыре иноки, наверно, полагают, что в аде, например, есть потолок. А я вот готов поверить в ад только чтобы без потолка; выходит оно как будто деликатнее, просвещеннее, по-лютерански то есть. А в сущности ведь не всё ли равно: с потолком или без потолка? »

Ф. М. Достоевский, «Братья Карамазовы»

Тема полой Земли существует сотни лет: есть мифология, есть научные и псевдонаучные теории, есть фантастическая литература.

И компьютерные игры с ходьбой по внутренней поверхности конечно же существуют. Тем не менее такие игры пока не относятся к категории обычных, значит, есть интересная возможность поупражняться в проектировании новых игровых механик. Ходьба, бег и прыжки внутри полой сферы по сути близки к разработкам физики для игр на ленте Мебиуса. Но на этот раз реализация будет на Godot Engine 4.5.

First person контроллер любого нестандартного игрового мира с ходьбой по непонятной поверхности вместо привычной плоской земли под ногами – это в первую очередь модель гравитации. Ориентация оси «голова-ноги» игрока в пространстве - это вертикаль (как направление вектора силы тяжести в точке), то есть гравитация. Динамика полета в прыжке – тоже сплошная гравитация (и лишь в очень тонких физических моделях еще и немного аэродинамика).

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

\vec{g} = \vec{g}(\vec{r}), \tag{1}

где \vec{g} – напряженность гравитационного поля, измеряемая в Н/кг (она же ускорение свободного падения, в м/с2), \vec{r} – радиус-вектор позиции в пространстве, в метрах (конкретные единицы величин здесь даны для определенности; конечно, к примеру, метры могли бы быть заменены саженями, дюймами или мерными попугаями без какой-либо потери смысла).

Рассмотрим задачу с позиции двух свойств вектора: направления и величины.

Приемлемых вариантов направления \vec{g} для ходьбы по внутренней поверхности сферы не так много, точнее, он один: местная сила тяжести прижимает игрока к поверхности сферы по нормали к этой поверхности, то есть вертикаль всегда направлена в центр сферы. Аналогичный принцип был использован в контроллере для ленты Мебиуса: местная горизонтальная плоскость всегда касается поверхности. Фантастика, обыгрывающая теорию полой земли, обычно использует аналогичную гравитацию. Например, герои научно-фантастического романа В. А. Обручева «Плутония» (1915 г.) ходят внутри планеты головой к ее центру.

С учетом выбранной модели направления \vec{g} уточним уравнение (1), совместив начало координат с центром сферы:

\vec{g} = {g}(\vec{r}) \frac{\vec{r}}{|{\vec{r}}|}, \tag{2}

где g– скалярное ускорение свободного падения, м/с2 (заметим, что функция не определена в центре сферы, то есть нам может понадобиться особая обработка соответствующего случая).

Далее будем использовать следующие обозначения величин: R– радиус сферы; h– высота внутри сферы, отсчитываемая от ее поверхности к центру, то есть h=R-|\vec{r}|.

С модулем ускорения свободного падения (то есть функцией {g}(\vec{r})) все менее однозначно. Вполне жизнеспособный вариант – классическое упрощение плоскоземельных игровых миров: введем какую-то константу g_0для уровня h= 0, а все прыжки будем считать движениями «примерно на этом уровне»

h ≈ 0 ⇒g≈g_0

Для сфер с R > 10 м такая физика точно подойдет, если высота прыжка не превышает пары метров.

Но если мы создаем сферический мир с возможностью видеть все далекие объекты «с высоты», то почему бы не реализовать высокий и дальний прыжок, сопоставимый по максимальной высоте с R (0,3R или 1,01R - это уже отдельный вопрос). Как минимум полет внутри сферы будет ощущаться необычно. При такой механике прыжка упрощение g = const может дать негативные впечатления, ощущение «неправильной» физики.

Но какая физика является правильной? Позволим себе обозначить принципы субъективной физичности сферического мира:

  1. Разумно и «интуитивно» ожидать отсутствия гравитации в центре сферы, то есть g = 0 при h = R. На это намекает идеальная симметрия притягивающего объекта относительно точки, обещающая взаимную компенсация гравитации со всех сторон.

  2. В точках, одинаково удаленных от центра, напряженность поля равна по модулю h_1 = h_2 \Leftrightarrow|\vec{g}_1| = |\vec{g_2}|, то есть уравнение (2) можно переписать в следующем виде:

    \vec{g} = {g}({h}) \frac{\vec{r}}{|{\vec{r}}|}, \tag{3}

    Источник также симметрия сферы.

  3. Кажется разумным не ожидать резких изменений гравитации с высотой, то есть функция  g(h) не просто непрерывна и дифференцируема: значение производной g_h'мало в субъективном смысле, то есть небольшому (в масштабах движения человека) изменению h может соответствовать только небольшое (по ощущению) изменение g. На это намекает опыт общения человека с гравитационным полем в реальном мире.

  4. Не существует причин для наличия экстремумов g(h) при h ∈ [0,R] . Просто эти причины трудно придумать.

Пункты 1-3 в совокупности делают логичным g \approx 0 для всех h \approx R(вот и решена проблема области определения функции, представленной уравнением (2)). На уровне ощущений это означает следующую возможность: оказавшись каким-то образом поблизости от центра сферы в полете с небольшой скоростью (как обычно бывает около верхней точки прыжка в высоту), игрок будет ощутимое время медленно парить, прежде чем начнет заметно ускоряться вниз.

Пункты 1-4 все вместе дают какую-то плавную гравитацию, одинаково по всей сфере убывающую по модулю с высотой. Простейшая подходящая модель, конечно, линейная:

g(h) = g_0\frac{R-h}{R},\tag{4}

что с учетом (3) дает следующую модель:

\vec{g} = g_0\frac{R-h}{R}\frac{\vec{r}}{|\vec{r}|}\tag{5}

или

\vec{g} = g_0\frac{\vec{r}}{R}\tag{6}

Вертикальное движение в прыжке с учетом линейной модели гравитации по формуле (4) описывается следующим дифференциальным уравнением:

\ddot{h} = - g_0(1 - \frac{h}{R})\tag{7}

Для просчета движения в прыжке требует найти решение, удовлетворяющее заданным начальным условиям (решить задачу Коши): есть начальная высота h(0) = 0 и начальная скорость  \dot{h} (0) = v_0 , то есть начальные условия прыжка. Необходимо определить h(t) для нескольких последовательных значений t. Численное интегрирование методом Эйлера решает задачу неплохо:

  • код интегрирования, сводящийся к описанию итерации, компактный и простой для понимания;

  • вычислительная сложность итерации (фрейма в компьютерной игре) более чем скромная;

  • погрешность решения, хотя и считается относительно высокой (например, в сравнении с методом Рунге-Кутты), для применения в игре не так уж плоха, что показано на графике ниже.

Точность численного решения в условиях воспроизведения игры может проигрывать продемонстрированной здесь, «в тепличных условиях». Ошибка может накапливаться быстрее за счет снижения частоты обновлений ниже 60 FPS и использования более экономных по занимаемой памяти типов чисел (часто в игровой физике используют 32-битные float, а не 64-битные).

Аналитическое решение дает довольно громоздкую формулу для h(t). Но она позволяет всесторонне изучить модель, оценив влияние каждого параметра на все возможные процессы. Рассмотрим некоторые стороны математической модели, опираясь по возможности на графическое представление вместо формул.

Поверхность на следующем графике описывает комбинации условий, соответствующих прыжку с остановкой в центре сферы. Каждой паре значений (радиус сферы, гравитация у поверхности сферы) поставлена в соответствие потребная начальная скорость прыжка.

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

Покажем «крупным планом» двумерный частный случай, взяв для него эту границу (на предыдущей диаграмме это линия, разделяющая две низшие области, зеленую и желтую).

Для гравитации на уровне поверхности, соответствующей 9,8 Н/кг, радиус сферы выходит очень скромным (настолько, что в пределах такого компактного мира едва ли допустимо считать человека материальной точкой). Вывод: нельзя совместить реальное земное значение гравитации у поверхности g_0 = 9,8 Н/кг, реалистичную стартовую скорость прыжка до 5 м/с, сферу радиусом более 5 метров и прыжок в область ее центра. Что-то из перечисленного обязательно не будет достигнуто.

Рассмотрим саму динамику движения. Для снижения количества факторов примем g_0 = 9,8 Н/кг. Тогда процесс прыжка, функция h(t), будет определяться значениями начальной скорости и радиуса сферы. На графиках ниже показано влияние обоих факторов на характер движения.

Синяя кривая с круглым маркером на обоих графиках соответствует условиям достижения центра с остановкой в нем.

Визуализация законов движения при разных сочетаниях условий прыжка показывает: для стартовых скоростей, меньших скорости выхода в центр, в большинстве случаев характер движения мало отличается от квадратичной параболы из реального мира. Настолько мало, что едва ли эти различия можно ощутить в игре. Особая динамика возникает только в случае приближения к условиям достижения центра.

Граница между «особой» и «обычной» динамикой, конечно, размыта, но уверенно можно сказать:

  1. Стартовая скорость менее 80% скорости достижения центра точно не дает заметных особенностей динамики.

  2. Увеличение радиуса сферы вдвое и более, если для исходного радиуса обеспечивалось достижение центра с остановкой, делает динамику «стандартной» по ощущениям.

Второй пункт наглядно подтверждается следующими двумя зависимостями. Стартовая скорость прыжка для них подобрана из условия достижения центра сферы с полной остановкой в нем при значении ее радиуса 10 метров (меньшие значения рассматривать не будем).

Область определения обеих функций (говорим о значениях R от 10 метров до бесконечности), можно разделить на две части с условной (то есть зависящей от конкретно заданных критериев) границей между ними:

  1. Ограниченный интервал существенного влияния изменений радиуса на динамику прыжка (вблизи R = 10 метров).

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

Выбрав другое значение стартовой скорости прыжка, мы получили бы другое значение первоначального радиуса из условия достижения центра сферы с остановкой в нем. Но качественного изменения роли фактора радиуса происходить не будет: при любом значении стартовой скорости для всех значений R, превышающих некоторое достаточно большое значение, динамика прыжка примерно одинакова.

Неограниченный рост R при фиксированной начальной скорости приводит к «стандартной» физике постоянного ускорения свободного падения, когда высота прыжка становится пренебрежимо малой по сравнению с радиусом сферы, соответственно, пренебрежимо малыми становятся изменения гравитационного поля в процессе прыжка.

Аналогичного эффекта можно достичь устремлением к нулю стартовой скорости при фиксированном значении R. На рисунке ниже для малых значений стартовой скорости высота прыжка пропорциональна ее квадрату (как при постоянном ускорении свободного падения). При приближении стартовой скорости к минимальной скорости достижения центра характер зависимости меняется.

Практические выводы:

  1. Для ощутимого проявления особенностей принятой модели гравитации необходимо выбирать сочетание параметров, дающее высоту прыжка близко к R (стартовая скорость порядка 95-99% скорости достижения центра).

  2. Реализация механики высокого (как в п. 1) прыжка – компромиссное решение с точки зрения «реализма», нужна нереалистично слабая начальная гравитация или нереалистично высокая начальная скорость (или сочетание обеих в какой-то пропорции, подобранной по субъективным ощущениям).

  3. Преодолеть ограничения первых двух пунктов можно только отказом от линейного закона убывания напряженности гравитационного поля с высотой в пользу какой-то нелинейной модели (у поверхности гравитация должна слабеть с высотой интенсивнее, чем у центра).

Модель реалистичной (или псевдореалистичной) игровой гравитации в общем виде определена.

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

Формула закона всемирного тяготения, известная из школьных учебников:

F = G\frac{m_1 m_2}{r^2},\tag{8}

где F – сила притяжения, Н, m_{1,2}– массы первой и второй материальных точек, кг, r – расстояние между ними, м, G – гравитационная постоянная, м3/(кг*с2).

Близкая по смыслу формула дана в «Математических началах натуральной философии» Ньютона (1687 г.). Все величины скалярные. Автор использовал геометрический подход без векторной нотации, которой в его время просто не существовало.

Векторная форма закона всемирного тяготения, известная с XIX века, дополняет модель направлением:

\vec{F} = Gm_1 m_2\frac{(\vec{r}_2 - \vec{r}_1)}{|\vec{r}_2 - \vec{r}_1|^3},\tag{9}

где \vec{r}_{1,2}– радиусы-векторы, задающие положения соответственно первой и второй материальных точек. Конечно, вектор  \vec{F} в формуле (9) определяет, с какой силой первая материальная точка притягивается второй.

Геометрическая компонента формулы (9) усложнилась по сравнению с (8). Скалярный множитель  r^{-2} первоначальной формулы заменила дробь с векторными выражениями. Для сопоставления формул выразим r^{-2} через радиусы-векторы точек:

\frac{1}{r^2} = \frac{1}{|\vec{r}_2 - \vec{r}_1|^2}\tag{10}

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

\vec{F} = F\hat{r}=G\frac{m_1m_2}{r^2}\hat{r}=G\frac{m_1m_2}{r^2}\frac{\vec{r}_2-\vec{r}_1}{|\vec{r}_2-\vec{r}_1|}=G\frac{m_1m_2}{|\vec{r}_2-\vec{r}_1|^2}\frac{\vec{r}_2 - \vec{r}_1}{|\vec{r}_2-\vec{r}_1|} ==Gm_1m_2\frac{(\vec{r}_2 - \vec{r}_1)}{|\vec{r}_2 - \vec{r}_1|^3},\tag{11}

где \hat{r} – вектор направления, |\hat{r}| = 1.

С материальными точками все ясно, вернемся к сферической оболочке.

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

Сила притяжения, действующая на материальную точку массой m_0, расположенную в позиции r_0, со стороны сферической оболочки:

\vec{F}(\vec{r}_0) = \int\int\int_VG\rho(\vec{r}) m_0\frac{\vec{r} - \vec{r}_0}{|\vec{r} - \vec{r}_0|^3}dV\tag{12}

где \rho – местная плотность вещества, кг/м3, V – объем вещества оболочки между внешней и внутренней сферами, м3, \vec{r}– радиус-вектор точки между внутренней и внешней границами сферической оболочки, то есть позиция материальной точки, составляющей сферу, м, \vec{r}_0- радиус-вектор материальной точки, для которой рассматривается притяжение сферой, м. Учитывая равномерную плотность оболочки, выносим константы из-под интеграла:

\vec{F}(\vec{r}_0) = G\rho m_0\int\int\int_V\frac{\vec{r} - \vec{r}_0}{|\vec{r} - \vec{r}_0|^3}dV\tag{13}

или

\vec{g}(\vec{r}_0) = G\rho \int\int\int_V\frac{\vec{r} - \vec{r}_0}{|\vec{r} - \vec{r}_0|^3}dV\tag{14}

Стоит отметить, что решение рассматриваемой задачи известно довольно давно.

Теорема Ньютона о сферической оболочке в числе прочего утверждает, что \vec{g}(\vec{r}_0) = 0для всех точек внутри тонкой оболочки с равномерно распределенной массой. Следствие теоремы: гравитация отсутствует и внутри оболочек, имеющих толщину.

Приведем формулировку теоремы из русского перевода «Математических начал натуральной философии» академика А. Н. Крылова 1936 года:

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

В примечании А. Н. Крылова поясняется, что под выражением «точки сферической поверхности» следует понимать бесконечно малые элементы этой поверхности, причем притяжение каждым элементом предполагается пропорциональным его площади, так что притяжения элементами, равными по площади, равны. Доказательство теоремы опирается на идею бесконечно малых, хотя имевшийся в распоряжении Ньютона аппарат математического анализа находился по сути в зачаточном состоянии (до строгой формализации пределов Коши остается полтора столетия, производные и интегралы приходится изобретать в процессе, когда и самого термина «функция» еще нет).

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

Возьмем за основу уравнение (14). Нас пока не интересуют абсолютные числа, важен характер зависимости  \vec{g}(\vec{r}), поэтому смело объявив G\rho=1, займемся интегралом для «приведенного» g:

\vec{g}_{пр}(\vec{r}_0) = \int\int\int_V\frac{\vec{r} - \vec{r}_0}{|\vec{r} - \vec{r}_0|^3}dV\tag{15}

Такой интеграл для заданных внешнего и внутреннего радиусов несложно получить методом Монте-Карло, заменив его векторной суммой «притяжений» тысяч случайных точек, распределенных равномерно (с приемлемой для практики равномерностью) по объему оболочки.

Ниже представлена реализация численного решения в коде на C# (содержит обращения к API Godot, работает в C# версии Godot Engine 4.5).

using Godot;
using System;

public partial class GravitySimulation : Node
{
	private const float R_OUTER = 100.0f;
	private const float R_INNER = 50.0f;
	private const int H_STEPS = 20;
	private const float EPSILON = 0.000001f;
	private const int POINTS_NUM = 100000;

	private Vector3[] gravityPoints;

	public override void _Ready()
	{
		float sqRadiusOuter = R_OUTER * R_OUTER;
		float sqRadiusInner = R_INNER * R_INNER;
		int pointsCount = 0;

		RandomNumberGenerator randomGenerator = new RandomNumberGenerator();
		randomGenerator.Randomize();

		// Предварительное выделение памяти по количеству генерируемых случайных точек:
		gravityPoints = new Vector3[POINTS_NUM];
		
		for (int i = 0; i < POINTS_NUM; i++)
		{
			// Генерирация точек в пределах куба с центром в начале координат и с ребром, равным внешнему диаметру сферы
			Vector3 pos = new Vector3(
				randomGenerator.RandfRange(-R_OUTER, R_OUTER),
				randomGenerator.RandfRange(-R_OUTER, R_OUTER),
				randomGenerator.RandfRange(-R_OUTER, R_OUTER)
			);
			// Оптимизированная (без вычисления квадратного корня) проверка на попадание точки между сферами
			float sqMag = pos.LengthSquared();
			if (sqMag < sqRadiusOuter && sqMag > sqRadiusInner)
			{
				gravityPoints[pointsCount++] = pos;
			}
		}
		// Создание нового массива нужного размера
		Vector3[] finalPoints = new Vector3[pointsCount];
		Array.Copy(gravityPoints, finalPoints, pointsCount);
		gravityPoints = finalPoints;
		// Вывод фактического количества точек в оболочке и теоретического (по отношению объемов оболочки и куба)
		GD.Print($"Точек в грунте {pointsCount} из {POINTS_NUM}");
		float theoreticalPointsNum = POINTS_NUM * ((4.0f / 3.0f) * Mathf.Pi * (R_OUTER * R_OUTER * R_OUTER - R_INNER * R_INNER * R_INNER)) / (8.0f * (R_OUTER * R_OUTER * R_OUTER));
		GD.Print($"Теоретическое количество точек {theoreticalPointsNum}");
		CalcGravity();
	}

	private void CalcGravity()
	{
		float hStep = R_INNER / H_STEPS;
		// Генерация точек внутри сферы, для каждой из которых будет определяться суммарная гравитация от сгенерированных точек оболочки
		// Точки располагаются с постоянным шагом на оси Х, от внутренней поверхности до центра,
		// достаточно одной оси, поскольку в силу симметрии вдоль любого радиального направления результат, g(h), одинаков
		for (int i = 0; i <= H_STEPS; i++)
		{
			float h = i * hStep;
			Vector3 pos = new Vector3(R_INNER - h, 0.0f, 0.0f);
			Vector3 sum = Vector3.Zero;
			foreach (Vector3 gPoint in gravityPoints)
			{
				sum += GetGravity(pos, gPoint);
			}
			float xVal = sum.X;
			GD.Print(xVal.ToString("F3").Replace('.', ','));
		}
	}

	private Vector3 GetGravity(Vector3 p1, Vector3 p2)
	{
		Vector3 displacement = p2 - p1;
		float distSq = displacement.LengthSquared();
		if (distSq < EPSILON)
			return Vector3.Zero;
		Vector3 dir = displacement.Normalized();
		return dir / Mathf.Pow(displacement.Length(), 3.0f);
	}
}

Код генерирует POINTS_NUM псевдослучайных точек, равномерно заполняющих куб, описывающий фигуру оболочки. Далее для эксперимента отбираются точки, лежащие в толще оболочки, определенной внешним (R_OUTER) и внутренним (R_INNER) радиусами. Таким образом имеется возможность моделировать оболочки различной толщины. Визуализированные точки фрагментов толстой и тонкой оболочек представлены на рисунках.

Проведем численный эксперимент со следующими значениями констант:

внешний радиус R_OUTER = 100;

внутренний радиус R_INNER = 10;

общее число случайных точек POINTS_NUM = 100000.

Из сгенерированных точек в фигуру попали 52285 точек (теоретически должно быть около 52308).

Зависимость гравитации от высоты показана на графике. Высота выражена в радиусах сферы (h = 1 соответствует центру), размерность g не указывается.

Во втором эксперименте увеличим значение POINTS_NUM до 500000.

Из сгенерированных точек в фигуру попали 261431 точек (теоретически должно быть около 261538). Результаты представлены на графике.

Изменим толщину оболочки, увеличив значение R_INNER до 90. Результаты представлены на графике.

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

Можно утверждать, что гравитация нелинейно убывает с высотой до нуля в центре сферы. Модуль производной g по h убывает с высотой. Нелинейность в большей мере проявляется для тонких оболочек, то есть при достаточной толщине оболочки g(h) может считаться линейной функцией.

Учитывая приведенные в первой половине статьи «субъективно-физические» соображения, полученный результат нельзя назвать неожиданным. Да и много ли было шансов пусть даже у самого Ньютона правильно решать такие задачи без полноценного математического анализа, линейной алгебры и хоть какого-нибудь ПК?

Но шутки в сторону, теперь речь зашла о действительно опасных вещах. Внимательный читатель, конечно, заметил критическое несоответствие кода C#, ответственного за гравитацию точки, и подынтегрального выражения в формуле (15). Для всех остальных:

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

Ссылка на исходный код проекта.

Может показаться, что представленные материалы исследования математической модели сферического мира дают почти исчерпывающее понимание его устройства для проектирования fp-контроллера. В действительности сферический мир гораздо сложнее. Не рассмотрены даже поверхностно довольно существенные вопросы:

  1. Горизонтальная компонента движения (влияние горизонтальной скорости в момент прыжка на стартовую вертикальную скорость, модель ходьбы и бега с плавным изменением скорости для продвинутых прицельных дальних прыжков, учет горизонтальной скорости в полете при изменении местной вертикали, изменение местной вертикали и ориентация оси «голова-ноги» игрока).

  2. Параметры прыжков с ненулевой высоты (например, с камня или крыши здания).

  3. Нелинейные модели снижения ускорения свободного падения с высотой.

  4. Механика падения в шахту, ведущую за пределы внешнего контура сферической оболочки.

  5. Механика «спуска под землю» по лестнице с выходом на внешнюю поверхность сферической оболочки.

  6. Игровые механики для сферической оболочки, плавно меняющей R в процессе игры.