Проблема точности
С самого начала команда инженеров знала, что непрерывный мир существенно повлияет на дизайн движка и контента, и основной проблемой была численная стабильность. Представьте себе двух персонажей, идущих в строю в двух метрах друг от друга и направляющихся на восток от источника. В какой-то момент расстояние друг от друга перекрыто расстоянием от начала координат, и символы окажутся «в одном месте».
С плавающей точкой, чем дальше вы находитесь от начала координат, тем больше точности вы теряете, что может вызвать самые неприятные проблемы. Вещи не сортируются правильно, между соседними сетками появляются трещины, пространство начинает квантоваться, и кошки и собаки начинают жить вместе. Dungeon Siege использует FPU в режиме одинарной точности для очевидного выигрыша в производительности и соответствия исходной точности видеооборудования. Однако, даже если бы мы повысили точность, это в конечном итоге никогда не решило бы проблему, потому что мир был запланирован и стал невероятно большим.
Проблема точности означала, что невозможно создать единое мировое координатное пространство, как в большинстве других игр. Вместо этого решением было сегментировать непрерывный мир в набор независимых координатных пространств и периодически переключаться между ними для сброса точности. В рамках этих ограничений было опробовано множество идей, и в итоге мы остановились на варианте стандартной портальной системы.
Наше решение состоит из реляционной системы координат на основе узлов, в которой каждый кусок геометрии (осадный узел) имеет свое собственное координатное пространство и пространственно связан с соседней геометрией через двери, которые он разделяет с этими соседями. Расположение узлов, соединенных дверями, образует непрерывный график, представляющий всю карту мира. Эта система узлов с течением времени развивалась от своей первоначальной цели поддержания точности FPU, чтобы стать основным методом эффективного разделения пространства и корнем бесчисленных оптимизаций.
Чтобы инкапсулировать концепцию трехмерного положения относительно определенного узла, традиционный вектор (x, y, z) должен был быть дополнен идентификатором узла (x, y, z, node) и представлять смещение от начала координат конкретного узла вместо. Этот 4-кортеж инкапсулирован как позиция осады или SiegePos. Позже мы добавили SiegeRot (кватернион, узел), чтобы обрабатывать сравнения ориентаций между узлами.
Фраза «нет мирового пространства» стала мантрой для команды, хотя буквально потребовались годы, чтобы все поняли, что это значит.