Cheb's Game Engine

Планы, идеология, архитектура и т.п.

Модератор: Модераторы

Re: Cheb's Game Engine

Сообщение Cheb » 14.12.2015 00:42:40

Прогресса пока нет. Медитирую над структурой многослойного мира, пишу корявые реализации разрежённых массивов, проектирую для игровых объектов кэш-фриндли умный указатель.

Чтобы совсем не стояло, начал откапывать обратно линуксовую версию и прочие порты за пределы Вынь-32. Попутно и поддержку SDL2 прикручу.

64-битная виндовая версия по прежнему не может даже оторваться от земли. В зависимости от версии компилятора, либо умирает сразу (3.0.1), да так, что антивирус отправляет её на анализ, либо работает две секунды нормально, потом крашится в непредсказуемом месте (2.6.4). Даже не понимаю в какую сторону копать: то ли в компиляторе генератор кода кривой (в пользу чего свидетельствует откровенно сломанный екзешник от 3.0.1, крашащийся на ассемблерной вставке) то ли моя прога так былинно стреляет себе в ногу. Но как? Там отличий от 32битной версии с гулькин нос. :(

Перепилил на юникод, с сохранением обратной совместимости с FPC 2.6.4. Очень помогло своевременное введение типа TFileNameString, который для него - Ansi а для третьего - Unicode. Юникодная версия (на 3.0.1) всё ещё не может быть протестирована: экзешник-матка собирается и вроде работает, но исходники игрового модуля гарантированно роняют Паскаль.

Ищо, в связи с трагической кончиной (точнее, запоздалым закапыванием дурнопахнущего трупа) Виндовс 98, задался поисками другой платформы, поддержка которой вызовет закономерные "Лолшто?" и "не, он точно тронулся". После недолгих поисков была найдена Raspberry Pi 2.
Ха!
Да это идеальная low-end платформа для задания лимитов и стресс-тестирования концепций!


P.S. Лазарус ставился отколо четырёх часов, причём загрузка процессора была 6% (системный диск - это микро SD карточка, да). Потом долго боролся с чёрной рамкой вокруг экрана, ругая китайский конвертор HDMI->VGA, пока не вспомнил, что у этой штуки есть аналоговый выход для ЭЛТ телевизора, и рамочка эта специально вштырена. Полез в файл, исполняющий обязанности BIOS, убрал рамочку нахрен, умилился набором опций видеорежима (HDMI / NTSC /PAL). Долго трахался, пытаясь запустить OpenArena, получил только софтверное слайд-шоу. Вспомнил, что на этой платформе ускорен только OpenGL ES, плюнул, запустил идущий в комплекте с операционкой урезанный майнкрафт. Умилился как он резво летает в 1920х1080. Потрогал микросхему процессора. Было очень больно. Сося палец, подумал, что это как то не тянет на два с половиной ватта заявленной мощности. Выдернул провод питания. Машинка продолжила работать. Откуда она берёт электричество? Из USB хаба в обратную сторону сосёт? Или по HDMI кабелю?.. Загадка.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 761
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение debi12345 » 15.12.2015 12:11:20

Чтобы не страдать от тормозов Paspberry Pi, а запускать на нем только скомпилированные проекты - можно эмулировать эту Pi в QEMU-эмуляторе ARM9-проца на обычном мощном компе. В широком доступе есть полная и актуальная версия DEBIANа, специально заточенная под него, с дистрибутивом FPC и т.д, ставящая и раздающая пакеты программ по сети...
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5321
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Cheb's Game Engine

Сообщение Sergei I. Gorelkin » 15.12.2015 16:19:24

Отличия 64-битного кода от 32-битного таки необходимы. Там фиксированный стек и байт-код с описанием структуры стека. Вот просто так написать "push rax" там, где захотела левая пятка, нельзя. И обработка исключений тоже очень сильно отличается.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1384
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Cheb's Game Engine

Сообщение Cheb » 15.12.2015 21:38:54

Чтобы не страдать от тормозов Paspberry Pi, а запускать на нем только скомпилированные проекты

Да вроде ж не тормозит особо?. Это ж Pi 2, это четыре почти гигагерцовых ядра, это мощь (такая, что трогать больно).
Иначе бы я с нею и не связывался.

Вот просто так написать "push rax" там, где захотела левая пятка, нельзя.

О. То есть, это таки я стреляю себе в ногу.
Спасибо, это многое объясняет :oops:
Если бы не RDTSC - и не подумал бы связываться с этим ассемблером.
Вроде, в новых версиях была такая фича, чтобы в заголовке ASM блока указать компилятору "засираю такие-то регистры" ? Но синтаксис я забыл :oops:

И обработка исключений тоже очень сильно отличается.

Это то я как раз уже (кажется) сделал. Как и с 32 битной версией, скопипастил кусок RTL и допилил.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 761
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Sergei I. Gorelkin » 15.12.2015 22:07:09

Синтаксис для изменяемых регистров: asm .... end ['rbx','r12',...]; Это не новая фича, она была с самого начала.
Но и без списка компилятор считает, что каждый ассемблерный блок портит volatile регистры, т.е. равносилен вызову функции. Поэтому вокруг RDTSC (изменяющей только rax и rdx) вообще ничего не нужно сохранять/восстанавливать, в том числе и на win32.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1384
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Cheb's Game Engine

Сообщение скалогрыз » 15.12.2015 22:46:44

Cheb писал(а):Если бы не RDTSC - и не подумал бы связываться с этим ассемблером.

перестань им пользоваться. Используй системные вызовы.
Minecraft же RDTSC не использует и ничё!
скалогрыз
долгожитель
 
Сообщения: 1694
Зарегистрирован: 03.09.2008 02:36:48

Re: Cheb's Game Engine

Сообщение Cheb » 16.12.2015 01:27:25

перестань им пользоваться

Но он самый быстрый! 40нс или меньше! Как же профайлинг :(

З.Ы. Обратил, наконец, внимание на ворнинги от используемой библиотеки работы с картинками, Vampyre Imaging.
Мама. :shock:
Такой развесистой, кустистой, всезаполняющей арифметики указателей с многоэтажными кастами в целые и обратно... нет, наверно, больше нигде.
Причём! Там для этого честно объявлен отдельный тип, ptr2int = cardinal, и рядом подробный комментарий, почему он должен совпадать по размеру с указателем.
И тишинааа...
Хоть бы assert на sizeof вставили, ейбогу :x

Добавлено спустя 18 минут 52 секунды:
"Ошибка приложения 0xc000007b" проявляется или нет в зависимости от того, в каком порядке я указываю модули в списке uses.
Моск уже отваливается :(

Добавлено спустя 15 минут 2 секунды:
Я эпический дятел. :oops:
Уже начал прикручивать SDL2, и в конфиге прописал её для 64 бит как дефолтную.
Но в папке-то с экзешником лежала 32-битная SDL2.dll !
Вот винда и давилась при попытке подцепить ея.

Добавлено спустя 8 минут 27 секунд:
Синтаксис для изменяемых регистров: asm .... end ['rbx','r12',...]; Это не новая фича, она была с самого начала.
Но и без списка компилятор считает, что каждый ассемблерный блок портит volatile регистры,

ПОЧЕМУ Ж ЭТО НИГДЕ НЕ НАПИСАНО В ДОКУМЕНТАЦИИ Изображение
Я уже 12 лет использую Фри Паскаль, но об этом почему-то узнаю только сегодня!
Доки сливают хотя бы той же php.net чуть менее, чем полностью :x

...но это всё фигня.
Вырезал все push к.. далеко и надолго - и 64-битный екзешник сразу по-ле-тееел! Изображение
Больше не падает! :D
Последний раз редактировалось Cheb 31.07.2018 22:48:17, всего редактировалось 1 раз.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 761
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Cheb » 17.12.2015 21:45:03

Настроил типы и дефайны так, чтобы движок, собранный на фпц >=3.0.0 был юникодным, а собранный на 2.6.4 - легаси версия с Ansi путями и именами файлов.

64-битный 2.6.4 делает всё как надо, а 64-битный 3.0.1 генерирует екзешник, всегда дающий AV на строчке
Код: Выделить всё
Mother^.ExceptionState.AbbrTitleForIndicator:= 'mai';
, где
AbbrTitleForIndicator: ShortString3;
, где
ShortString3 = String[3];


Такштаааа... Юникодной пока может быть только 32-битная версия. :evil:

В линуксе пока доступен только 2.6.4 (новейшая версия Дебиан 8 ), но там эта проблема, кагбе, не лежала: утф8 и т.п.

Финальный вердикт: нуегона, этот третий, этот юникод, и эту поддержку SDL2.
Лучше сначала с многослойным миром разберуся.

Главное - знаю, что могу. Не заржавеет.

Добавлено спустя 17 часов 44 секунды:
Сегодня мой моСХ, наконец, прорвало, и я понял, что знаю, как надо!

Теперь испытываю душевные муки Буриданова осла, застыв между двумя парадигмами. Каждая имеет свои вкусные плюшки и жирные минусы.

И Я НЕ ЗНАЮ, КОТОРУЮ ВЫБРАТЬ!!!

Сначала общие положения.
-- трёхслойная игровая физика с глобальными лагокомпенсацией и предсказанием. То есть, не общепринятая клиент-серверная, с передачей и лагокомпенсацией объектов поштучно, а хитровывернутый вариант древней lockstep технологии, где передаются только инпуты и контрольные суммы.
1. ТруЪ - слой. Лагает и отстаёт, дожидаясь инпутов всех игроков (с отсечкой в 500..1500мс)
2. Догоняющий слой: периодически, первичный слой копируется ВЕСЬ, и этот новый слой догоняет реальное время так быстро, как потянет процессор.
3. Рилтаймовый слой: тот, который видит игрок. Периодически сносится КЕМ, заменяясь на догнавший его догоняющий слой.
-- число игроков фактически ограничено только сетевой архитектурой: при грамотно построенной системе ретрансляторов от сервера клиентам, тысяча игроков - как два пальца об асфальт.

Парадигма новая, с реальной многослойностью.
*Принципы:
-- объекты ссылаются друг на друга посредством умных индексов со счётчиками ссылок.
-- слои частичные - т.е. реально физически существуют лишь отличия дочерних слоёв от родительского
-- обращаться по индексу можно только через методы «получить на чтение экземпляр текущего слоя» и «получить для записи экземпляр текущего слоя или скопировать из родительского»
*Достоинства и недостатки:
- нужно запиливать новый велосипед класса Чеперси для реализации всех этих слоёв.
- использовать подобную схему удобно, как плавать в валенках
+ позволяет получить гораздо больше контроля за связями и их использованием
+ позволяет организовать взаимодействие объектов через кошерную систему событий
- все слои должны укладываться в одно ядро, т.е. системные требования одного ядра для мультиплеера = 4х от сингла.
+ гораздо более кеш-фриндли: клонируются только *изменения* в слоях, статические объекты лежат в памяти нетронутыми, в *одном* экземпляре
- огромный объём работы по отладке и подводные камни на стыке между родительским слоем и его частичной копией-потомком



Парадигма старая, на основе Чеперси.
Эту я планировал изначально, но потом оказалось, что у Чеперси тупо не хватает скорости завершить клонирование мира за один кадр. Пришлось изобретать лисапед №2. Но! То была лишь косность мЫшления. Уже добавив многопоточность, я понял, что стоимость клонирования ВСЕГО мира можно свалить на отдельный поток, в котором выполнять ТруЪ слой. Раз уж он всё равно по определению лагает.
*Принципы
-- для каждого слоя - свой поток (минимум три, можно 4 или 5, на 6- или 8-ядернике, если у Чеперси пуп не развяжется их плодить. Чтобы параллельно иметь несколько догоняющих слоёв на разной стадии).
-- тяжесть создания ПОЛНОЙ копии мира принимает на себя поток ТруЪ-слоя. Остальные вообще не использут Чеперси.
*Достоинства и недостатки
+ достаточно старой доброй Чеперси, всё уже есть, только пару оптимизаций ей вставить. Былинная экономия затрат труда.
+ гораздо проще связывать объекты и обращаться к ним (обычный Паскаль еси)
- периодическое, несколько раз в секунду, копирование всех объектов, включая все статические чанки мира
- кеш (и память в целом) стонет и плачет, гоняя одновременно три ПОЛНЫХ копии мира
- потенциальный упсник, если игроки в ММО разбредутся по миру. Активно существует зона 500метров округ каждого, это около 4 тысяч чанков. Помножаем на тысячу... Упс? Упс. :( А вот в новой парадигме было бы абсолютно по... до лампочки, сколько там миллионов чанков реализовано, если они статические.
+ требования к одному ядру для мультиплеера всего х2 (потянет и х1.5)
- мультиплеер возможен *только* на четырёхъядерном проце. Или оченно быстрый двухъядерник - но это почти оксюморон.



Парадигма гибридная, всё как у старой но со следующими отличиями:
-- пул неизменённых, статических чанков мира - это вообще отдельная сущность за гранью добра и зла. Сидит в отдельном потоке и тикает раз в минуту, согласно глобальному состоянию мира, которое получает из ТруЪ-слоя. Все слои обращаются к нему по индексу,, для изменений клонируют себе копию чанка.
*Достоинства и недостатки
- геморрой с реализацией. Меньше, конечно, чем у новой парадигмы, но всё же
+ можно развести себе гигантский кеш чанков, да хоть толщиной в гигабайт. Коий кеш, при умном сливании на диск, может служить для полного сохранения изменений мира в сингле.
+ может служить отличным сэндбоксом для глобальной модели мира
+ все статические чанки выводятся из механизма многослойной лагокомпенсации нахрен.

Добавлено спустя 5 часов 16 минут 49 секунд:
Ежели никто не ответит - буду думать думу тяжкую до января :mrgreen:
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 761
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Mirage » 18.12.2015 22:06:30

Можно подробнее зачем три слоя? Особенно в сингле.
Вообще что за догоняющий слой не понял.
По вопросу - я бы сделал как быстрее, т.е. по старому варианту. Если будут проблемы со слишком большим кол-вом игроков, то это приятные проблемы. А проверить концепт стоит, похоже, побыстрее.
Mirage
энтузиаст
 
Сообщения: 858
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Cheb's Game Engine

Сообщение Cheb » 18.12.2015 23:50:51

В сингле-то, как раз, один слой.

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

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

Ситуация:
Игрок А начинает: "Кааамеее... Хааамееее..."
- но это ситуация на 100мс назад. Клиент игрока Б должен экстраполировать это в будущее:
"...Хаааа!!!" - и распидорашивает все чанки на километр вправо от игрока Б. В ландшафте эпическая дырка!
Потом - опа - прилетает запоздалый пакет, игрок А успел подправить прицел. Дырка немного в другом месте, игрок Б фрагнут!
Проходит ещё время - опаньки, а игрок Б то, оказывается, успел игрока А ножиком чик, чик. Дырка отменяется, никакого "Ха" не было.

Причём, вся эта котовасия должна туда-сюда переключать шустро.

Ломал мозг, дошёл до идеи частичных ублюдочных недо-слоёв, чтобы экстраполяция только ближних 100 метров шустрила, а для более дальних ландшафтообразующее воздействие корректировалось более лениво дискретно.
Проблема то в том, что эпичного хочется, море там с волнами, по которому броненосцы плавают, реально вытесняя её :roll:
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 761
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Mirage » 19.12.2015 00:30:00

Т.е. слой 1 это то, что приходит с сервера, т.е. заведомо верное состояние.
Слой 3, который видит игрок, это локальный результат действий игрока, возможно, не учитывая последних апдейтов на сервере, которые могут повлиять, т.к. они приходят с задержкой.
А слой 2 это что? Который догоняющий? Опять не понял.
Mirage
энтузиаст
 
Сообщения: 858
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Cheb's Game Engine

Сообщение Cheb » 19.12.2015 01:32:37

это то, что приходит с сервера, т.е. заведомо верное состояние.

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

Слой 2 это механизм передачи изменений из слоя 1 в слой 3. Тупо копировать нельзя, надо учитывать все изменения по ходу - получается, ускоренная промотка вперёд. Все инпуты на интервале от 1 до 3 запоминаются, и слой 2 использует их при промотке. То есть, слой 1 - это "гарантированно все неотсечённые инпуты дошли, новых не будет", слой 3 получает *только* инпуты локального игрока напрямую, а слой 2 по дороге от 1 к 3 собирает всё, что сервер успел передать с задержкой от 0 до 500 мс, поскольку сервер рассылает инпуты как только получит.

Естественно, желательно, чтобы слой 2 пробегал от 1 до 3 как можно чаще. Лучше бы 10 раз в секунду, но это вряд ли возможно.
Предположим, игра тикает 100 раз в секунду. Тогда 1 отстоит от 3 на 1 с. (100) тиков. Если одно ядро процессора/поток может гнать физику на х2 скорости - это 200 тиков в секунду. Пренебрегая временем клонирования, слой 2 будет обновлять состояние других игроков 2 раза в секунду, с добавленной к инпутам его собственной задержкой от 0 до 500. Это никуда не годится. Вывод? Время отставания уменьшаем до 500 (что плохо скажется на надёжности дохождения инпутов - могут теряться) плюс постулируем, что нужен ещё более быстрый проц (х4 скорость на ядро). Тогда слой 2 будет всплывать 8 раз в секунду, привнося лаг 0..125 мс. Для ураганного шутера - не айс, но лучшего от данной технологии не получить.
Возможны варианты с разрезанием осетра на ломтики:
Слой 1 - ТруЪ, на -1000мс.
Слой 2 - догоняющий, от -1000 до -200мс один раз в секунду, собирая все сильнолагнувшие инпуты.
Слой 3 - промежуточный, бежит параллельно рилтайму с отставанием на -200 мс
Слой 4 - второй догоняющий, от -200 до 0мс 40 раз в секунду, собирая все своевременно дошедшие инпуты и внося смешной доп. лаг в 25мс .
Слой 5 - рилтайм.
где, условно говоря, 1,2,3 - на одном ядре, 4 - на втором, а 5 - на третьем.

Хотелось бы, чтобы это было так, но надо сурово оптимизировать Чеперси на скорость клонирования. Потому что даже просто клонировать 40 раз в секунду - это из области фантастики.
Надо ещё расчёты проводить, но, похоже, простой путь накрывается :(
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 761
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Mirage » 19.12.2015 02:08:29

Все равно неясно зачем доп. слои.
Во-первых, откуда 1000мс задержки? Современные сети даже между континентами дают пинг 60-80мс. Возьмем 200мс для туда-сюда.
Во-вторых, зачем 1-му слою обновляться раз в секунду?
По мне так пусть идет с обычной скоростью и обновляется инпутами (хотя думаю лучше все же состояние передавать) по мере поступления.
Тогда будет актуальная версия мира, отстающая на ~100ms от реальности.
Для отсутствия видимого лага, есть другой слой, где действия пользователя не гоняются на сервер, точнее не ожидаются их результаты.
Если между первой и второй версией обнаруживается значимое отличие, второй слой откатывается к первому.
Что считать значимым зависит от игры. В случае передачи по сети состояния, а не инпутов, различать значимое и незначимое по-моему проще.
Например, координаты боеприпаса врага - значимая инфа. А состояние его (врага) анимации - не значимая.
Mirage
энтузиаст
 
Сообщения: 858
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Cheb's Game Engine

Сообщение Cheb » 19.12.2015 03:19:40

Все равно неясно зачем доп. слои.

Лучше объяснить не могу :(

Во-первых, откуда 1000мс задержки?

Дерьмо случается. :evil:
50,50,50,гоп-стоп-600-не-ждали?,50,50,50
А терять пользовательский ввод - это Смертный Грех.
При игре в Ace Of Spades такое периодически случается. Копаешь, копаешь, копаешь - раз! инпут маха лопатой потерялся, сбваешься с ритма, следующий мах приходится на кубик мимо, тоннель выходит криво: бежать по такому труднее, задеваешь за потолок или стены и замедляешься. Или вообще вражий снайпер за этим изгибом нычку устроит.
БЕСИТ :evil:

Во-вторых, зачем 1-му слою обновляться раз в секунду?

Он не раз в секунду обновляется, а идёт с нормальной скоростью, только с отставанием на одну секунду.

Но!!!
Я эпический дятел! Былинный!
Прорабатывал же вариант, где на слои разбивается *только* актуальная зона вокруг игрока. И все эти догоняющие и прочая слои - это кусочек игрового мира диаметром в километр.
То есть, сколько бы там ни было всего активного в заднем слое, клонироваться будет лишь кусок строго ограниченного размера. Чуть больше, чем радиус тумана.
А маленький кусочек и копировать не накладно, и гонять можно с многократной скоростью - и всё задёшево!
Не зря я принял решение оптимизировать, пока сингл не будет летать на Raspberry Pi 2.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 761
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Mirage » 19.12.2015 17:19:28

Cheb писал(а):только с отставанием на одну секунду.

Зачем такое отставание-то? Девиации в пинге могут быть и более секунды.
И терять ввод не нужно (тут TCP рулит). Но если он пришел на сервер с задержкой, тот в любом случае так его и должен учесть - как будто пользователь произвел действие с задержкой.
Mirage
энтузиаст
 
Сообщения: 858
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Пред.След.

Вернуться в Разработки на нашем сайте

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru