Cheb's Game Engine

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

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

Re: Cheb's Game Engine

Сообщение скалогрыз » 27.07.2015 22:47:59

runewalsh писал(а):Хотя так никто и не делает, лол. DLL всё же слишком низкий уровень.

id-tech (ака Quake движки)? хотя там по-моему, история обратная. Движок в dll-ке, а игра в .ехе.
скалогрыз
долгожитель
 
Сообщения: 1630
Зарегистрирован: 03.09.2008 02:36:48

Re: Cheb's Game Engine

Сообщение Mirage » 29.07.2015 00:44:11

Ну ID-то можно понять. Движок на С доолго компилируется. А dll один раз скомпилировал и используй.
А зачем это раздельнокомпилируемому Паскалю - открытый вопрос.
Кстати, если подумать, то на базе ppu/dcu можно неплохую такую динамическую нативную модульность запилить. С горячей заменой.
Хотя грузить все равно через механизм .dll/.so. Bpl наверное так и сделаны.
Mirage
энтузиаст
 
Сообщения: 745
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Cheb's Game Engine

Сообщение Cheb » 30.07.2015 19:01:07

Цитирую свой второй пост:
Мой движок построен вокруг уникальной архитектуры (было бы великой глупостью клепать просто ещё один клон огра, нэ?).
Фишка: исполняемый код можно менять на лету, не теряя данных.
Технически это организовано как вынесение практически всего кода движка в DLL, которая сохраняет состояние в файл, выгружается, другая загружается, восстанавливает состояние из файла. В чём же уникальность, спросите? Часть данных - а именно, текстуры, прочие объекты OpenGL и даже открытые файлы - сохраняются не в файле, а в памяти EXE-матки. Потом DLL берёт их обратно. Имеем: передёрнули исполняемый код, а все текстуры сохранились.
Конечно, это только на словах просто, а на деле там дофига и больше кода для сериализации, обеспечения совместимости вперёд/назад (состав полей класса после перекомпиляции может быть уже другим, нэ?) и прояая, и прочая.
Но итог таков: полная перезагрузка DLL занимает не дольше пары сотен милисекунд. Это часто даже на глаз незаметно. В итоговой игре данных будет поболе, но и тогда - не дольше 0.3..0.5 секунды.


TL;DR: мгновенность внесения изменений в работающий код.

Что-то отдалённо подобное есть только в Виндовс, которая умеет при накате обновления передёргивать код загруженных и выполняющихся DLL на лету. За счёт специальных NOP-заглушек в каждой ф-ии API, которые лёкким движением руки превращаются в JMP.
Но там структура полей записей и классов фиксирована, а у меня может меняться.

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

P.S. В настоящий момент проект в состоянии применения кувалды и такой-то матери к базовым классам выгружаемой DLL. Радикально перекорёживаю парадигму и менеджер потоков.

им может быть в том числе какая-то механика, специфичная для небольшой игровой локации,

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

Пример: объект корован движется вдоль объекта дорога, и каждые сто метров проверяет псевдослучайное число на предмет заметил ли его объект разбойники, сидящий на соседней ячейке глобальной карты. Если да - создаётся объект набигание, и начинают выполняться расчёты сколько тушек с какой стороны полегло.
Если игрок подходит ближе 500м., объект набигание генерирует разбойников, караванщиков и телеги, схематично расставляя их и включается ИИ. Пока игрок подойдёт достаточно близко, чтобы всё это безобразие попало в зону видимости, боевые действия неписей перемешают тусовку, скрыв следы того, что начала схватки не было, и она нарисовалась из воздуха с середины.

(Кстати, в Mount & Blade даже этим не заморачивались, когда с карты мира входишь в уже идущую битву - все уцелевшие войска расставляются по разные концы рандомно сгенерированной локации словно ещё не сражались.)
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 564
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение runewalsh » 30.07.2015 21:48:20

Cheb
>За счёт специальных NOP-заглушек в каждой ф-ии API, которые лёкким движением руки превращаются в JMP.
Пруфы? Не очень-то верится, проще остановить вообще всех, кто использует DLL, и передёрнуть без заморочек, или вовсе для не озаботившихся ресетом и/или не желающих вылезать из кода DLL оставить на время работы старую версию.

>текстуры, прочие объекты OpenGL и даже открытые файлы - сохраняются не в файле, а в памяти EXE-матки
И как это защищено от утечек? Как ты вообще представляешь другой код, который использует ресурсы выгруженного? Что, если какие-то из них больше не нужны?
Аватара пользователя
runewalsh
постоялец
 
Сообщения: 314
Зарегистрирован: 27.04.2010 00:15:25

Re: Cheb's Game Engine

Сообщение скалогрыз » 30.07.2015 22:08:18

runewalsh писал(а):Cheb
>За счёт специальных NOP-заглушек в каждой ф-ии API, которые лёкким движением руки превращаются в JMP.
Пруфы? Не очень-то верится, проще остановить вообще всех, кто использует DLL, и передёрнуть без заморочек, или вовсе для не озаботившихся ресетом и/или не желающих вылезать из кода DLL оставить на время работы старую версию.

Например вот так можно перехватить WinAPI функции для одного конкретного процесса. Но, игровому движку такими вещами заниматся слишком жирно.

В общем и целом, использовать всякие ассемблеры в игровых движках, в дни когда всё решают драйвера видео карты - не то что не актуально, а даже вредно. Да и мыли о кросс платформенности, что игра должна идти и на i386, x86_64 (в случае спец загрузки), всяких наборах ARM-ов и в итоге на какой-нибудь Dalvick машине (через явакод), упорно намекают на неиспользование ассемблера вообще. OpenGL (DirectX), OpenAL (DirectSound) становяться наинизжим уровнем для разработчика игр.
скалогрыз
долгожитель
 
Сообщения: 1630
Зарегистрирован: 03.09.2008 02:36:48

Re: Cheb's Game Engine

Сообщение runewalsh » 30.07.2015 22:26:13

скалогрыз писал(а):Например вот так можно перехватить WinAPI функции для одного конкретного процесса.

Здесь, по-видимому, начало сохраняется (для Unhook) и затирается прыжком, что намекает как раз на отсутствие и вообще ненужность >специальных заглушек штоб апдейтить на горячую.
Аватара пользователя
runewalsh
постоялец
 
Сообщения: 314
Зарегистрирован: 27.04.2010 00:15:25

Re: Cheb's Game Engine

Сообщение Cheb » 30.07.2015 22:44:46

Как ты вообще представляешь другой код, который использует ресурсы выгруженного? Что, если какие-то из них больше не нужны?

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

P.S. Даже открытые на чтение PK3 файлы не закрываются при перезагрузке DLL, так по прежнему открытыми и передаются ей. Только не спрашивайте, скольких слоёв врапперов мне стоило, чтобы DLL считала этот ктулхуфтагн обычным потомком TStream.

использовать всякие ассемблеры в игровых движках,

Ассемблер мне в посленднем случае понадобился чтобы творчески переработать кусок кода из модуля System, которому нужна внутренняя переменная модуля system, на старте инициализируемая ss. Где в паскале искать ss я не помню, искать было лень, взял значение из регистра в собственную переменную, инициализируемую на старте.
Это заморочки с обработкой исключений при сидении на двух стульях - см. http://bugs.freepascal.org/view.php?id=12974

Также я использую rdtsc для профайлинга двух с половиной мест, где нужна высокая оптимизация, и вообще для всех таймеров, ибо собственный ассемблерный таймер - очень легковесный, и мерит с точностью до наносекунд.
Для неверующих - гуглите invariant tsc (во всех современных процах этот счётчик работает с фиксированной частотой, не зависящей от текущей частоты ядра, и одинаков для всех ядер)

Пруфы? Не очень-то верится, проще остановить вообще всех, кто использует DLL,

Давно было (XP тогда была молодой), искать лень, но запомнил я это хорошо. В винде *точно* предусмотрен накат обновления БЕЗ остановки программ и перезапуска ОС, и это сделано резервированием места в коде всех точек входа API под команду перехода.

x86_64 (в случае спец загрузки)

Linux-x86_64 будет единственной поддерживаемой платформой выделенного сервера. Обычная игра - Win32 и Win64 (я *уже* раздвоил *все* ассемблерные вставки на {$ifdef cpu64}{$else}{$endif} . Что показывает, как у меня их много. :roll: )
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 564
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение dedm0zaj » 31.07.2015 03:28:17

hinst писал(а):я так и не понял, нафига было в динамическую библиотеку что либо вообще выносить?


менять логику программы на ходу (компилить при выполнении программы dll и подключать динамически)
dedm0zaj
новенький
 
Сообщения: 82
Зарегистрирован: 05.10.2012 19:55:20

Re: Cheb's Game Engine

Сообщение Cheb » 14.08.2015 23:37:53

Чуть не надорвал мосХ, просрал заметную часть отпуска... НО! Перелопатил таки механизм, попутно выкинув кучу говнокода и пофиксив несколько ужосныя багов.
Взял бритву Оккама, и резал, и резал, и резал. Очень многое оказалось не готово к многопоточности, включая (сюрприз!) chelinfo, мой загрузчик и парсер dwarf2. :x

Надеюсь завтра получить нечто б/м рабочее. Осталось вернуть на место загрузку сессии и вправить мозги классу TViewport, который забывает пересоздать FBO, гордо рисуя в изначальном стартовом 256x256 пока не переключишь в полноэкранный и обратно.

в 64-битной версии что-то пока не срастается, программа мгновенно умирает когда мой обработчик исключений пытается вернуть EXCEPTION_CONTINUE_SEARCH . Вроде ж правильно из исходников RTL передрал? :(

Добавлено спустя 2 часа 37 минут 18 секунд:
runewalsh писал(а):Cheb
>За счёт специальных NOP-заглушек в каждой ф-ии API, которые лёкким движением руки превращаются в JMP.
Пруфы? Не очень-то верится, проще остановить вообще всех, кто использует DLL, и передёрнуть без заморочек, или вовсе для не озаботившихся ресетом и/или не желающих вылезать из кода DLL оставить на время работы старую версию.

P.S. Наткнулся таки случайно
пример использования (2009), содержит ссылку на объяснение (2004)
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 564
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Cheb » 19.08.2015 12:01:44

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

1. Просто Гуй.
Для тулзетов, менюшек и прочая. Логика тикает синхронно с кадрами, то есть когда очередной кадр готов начаться, он будит логический поток, ждёт, пока тот закончит, потом сразу синхронизируется и приступает к рендеру. Потом логический поток засыпает до следующего кадра, а матка отправляет спать основной поток, в соответствиис лимитом FPS (30 в покое, 60 если юзер шевелит мышью). При ближайшем рассмотрении это то же самое, что раньше. Потоков два, но сначала основной ждёт логику, потом логика ждёт рендер. Всё равно, что один.

2. Игра.
Логика тикает с фиксированной частотой, учащаясь когда отстаёт. Ориентировочно, 100 раз в секунду. Рендер в основном потоке ждёт пока логика заснёт, затем вызывает синхронизацию для составления задания видеокарте: создание FBO и VBO, заполнение оных, задание команд шейдерами и т.д. Затем рендер разлочивает логику и выполняет всякие фоновые операции типа рендера импосторов и обновления скинов, которые понядобятся на следующий кадр. После этого выполняется *дополнительный* опрос ввода (очередь сообщений окна и т.п.) чтобы фактически удвоить частоту опроса и уменьшить лаг мыши. Затем основной поток выполняет SwapBuffers, во время которой OpenGL собственно выполняет весь рендер, т.к. драйвер любит кешировать команды где только можно. Как следствие, вызов SwapBuffers вполне может занять до 50% всего времени основного цикла основного потока (реальный пример: 4000..8000 мкс когда весь кадр при 60 FPS занимает 16667 мкс )

3. На всю железку.
Создание игрового мира или ускоренная промотка мира вперёд когда игрок спит, занимается крафтом или клиент догоняет сервер во время присоединения к сетевой игре.
Логический поток вообще не спит, тикает с максимально возможной частотой. Рендер замедлен до 30 FPS, когда выходит из спячки - дожидается очередного цикла логики и вклинивается, синхронизируя потоки для процедуры рендера. Потом SwapBuffers и баиньки.

Вот. Когда налажу скелет ентого безобразия - выложу тест на посмотреть.

З.Ы. Это всё возможно благодяря тому, что TimeBeginPeriod(1) действительно эффективна. Таймаут в TEventObject.WaitFor() соблюдается с точностью до милисекунды.
З.З.Ы. Переименовал TQualityAssurer в TLoadBalancer и научил его трюку "Аааа, FPS просели до 59!!! Срочно сбросить балласт!!!"
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 564
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Cheb » 26.08.2015 10:39:33

Застрял аки баран пред новыми воротами, не решаясь выбрать частоту тиков мира, а от неё зависит и архитектура подсистемы синхронизации потоков. С одной стороны, идеалом выглядит 100 или 120 Гц. С другой стороны, парадигма физики где каждый подвижный объект обладает своей частотой тиков, двигаясь рывками и засыпая, казалось бы, подталкивает к низкой частоте (33Гц) и интерполирующему рендеру (поскольку он по любому будет интерполирующим, изображая плавное движение там, где на деле всё движется рывками). Но тогда 1). синхронизация потоков превращается в Адъ 2) физика может оказаться достаточно толстой, чтобы синхронизируемый с ней рендер начал идти неравномерными рывками, а 3 кадра по 10 мс потом один по 30 мс визуально воспримется ничуть не лучше, чем честно тормозные 30 Гц.

Решил пока сделать 100 Гц, с бюджетом физики 5мс на тик, а там будем посмотреть.

З.Ы. Немного больше о парадигме: баундинг боксс спящего объекта охватывает весь путь его прямолинейного движения, и если кто-то ещё ткнётся туда, то разбудит спящего и заставит просчитать текущее положение прежде, чем взаимодействовать с ним. Таким образом, бредущий непись просчитывается один раз в две секунды, но если в него попадёт пуля - всё будет правильно.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 564
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение runewalsh » 26.08.2015 20:38:13

>TimeBeginPeriod(1)
Я тоже так делал, пока не почитал MSDN:
>However, it can also reduce overall system performance, because the thread scheduler switches tasks more often. High resolutions can also prevent the CPU power management system from entering power-saving modes.
Аватара пользователя
runewalsh
постоялец
 
Сообщения: 314
Зарегистрирован: 27.04.2010 00:15:25

Re: Cheb's Game Engine

Сообщение скалогрыз » 26.08.2015 21:05:59

почему у людей такая любовь к Multimedia API? которые уже хз сколько времени считаются deprecated и MS настойчиво рекомендует использовать DX аналоги?

да - проще, да - обратно совместимее :) ... но в какой-то момент нужно же адаптироваться.
скалогрыз
долгожитель
 
Сообщения: 1630
Зарегистрирован: 03.09.2008 02:36:48

Re: Cheb's Game Engine

Сообщение Cheb » 27.08.2015 10:59:55

скалогрыз писал(а):почему

Потому что один из моих главных понтов - полная поддержка Windows 98.

>However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.

Это приемлемый компромисс, поскольку
1. Игра - это по определению всересурсызажирающее приложение. Не нужно делиться.
2. Синхронизация потоков действительно требует 1мс точности. А также чтобы ограничить нагрузку в моменты простоя и не допустить самовозгорания видеокарты. А то некоторые игры на экранах загрузки или менюшках за 500 FPS зашкаливает. У меня же жёсткий потолок в 30 (60 когда пользователь шевелит мышью резвее 5 пикселов за кадр).
3. Я выключаю эту хрень когда ноутбук переключается на батарею. Не забыть ещё добавить отключение когда окно теряет фокус.

P.S. Чем дальше, дем больше хочется сделать частоту тиков 1000 Гц, и выполнять физику строго синхронно с рендером, столько этих килогерцовых тиков за раз, сколько милисекунд прошло с прошлого кадра. Раз уж частоты конкретных объектов всё равно виртуальные.

P.P.S Пробовал собрать в fpc 3.0.0rc1. Основной экзешник собрался с минимальным допилом. Продолжу когда компилятор перестанет падать с внутренней ошибкой на DLL игрового модуля.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 564
Зарегистрирован: 06.06.2005 15:54:34

Re: Cheb's Game Engine

Сообщение Mirage » 27.08.2015 23:12:21

Cheb писал(а):1. Игра - это по определению всересурсызажирающее приложение. Не нужно делиться.


Да, но не на переключения же контекстов эти ресурсы переводить.

Cheb писал(а):Синхронизация потоков действительно требует 1мс точности.


Спорно. Что именно требуется синхронизировать и зачем тут такая точность?

Cheb писал(а):А также чтобы ограничить нагрузку в моменты простоя и не допустить самовозгорания видеокарты. А то некоторые игры на экранах загрузки или менюшках за 500 FPS зашкаливает. У меня же жёсткий потолок в 30 (60 когда пользователь шевелит мышью резвее 5 пикселов за кадр).


Для этого хорош vsync. А если делать мимо него, то как раз подергивания и артефакты можно получить.
Mirage
энтузиаст
 
Сообщения: 745
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Пред.След.

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

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

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

Рейтинг@Mail.ru
cron