Malandrinus 615 Опубликовано 21 Декабря 2015 Задачи, как таковой и не было поставлено изначально. Была некая схема и некий весьма общий вопрос. При этом не было оговорено никаких условий, а "что же считать правильным"? ок. Попробую обобщить. Получилось многословно, так что смотри под спойлером. В сущности, ничего нового я там не написал, всё давно было сказано в разных правильных книгах. Я здесь попробую последовательно обосновать мысль насчёт того, как должен себя вести программист. Общие задачи при написании программы Когда пишем программу, то надо: потратить на написание как можно меньше времени, сделать код как можно эффективнее (в смысле быстрее) и как можно надёжнее (т.е. чтобы работал без сбоев). Думаю, это не нуждается в обосновании. Скорость (Эффективность) Сразу выскажу простую мысль по скорости кода. Скорость работы кода почти не зависит от усилий по написанию программы. Под этим я разумею вот что. В целом скорость выполнения определяется: выбранным алгоритмом, компилятором и библиотеками, компьютером. От усилий программиста в такой постановке уже мало что зависит. По усилиями я имею в виду избыточные усилия программиста сверх того, что необходимо на реализацию выбранного алгоритма. Эти избыточные усилия - это то, что называют оптимизацией. Т.е. оптимизация даёт как правило жалкие крохи добавочной скорости. Поэтому вопрос повышения скорости я здесь вообще не рассматриваю. Затраты на написание и надёжность Остаются только два важных вопроса: время написания и надёжность программы. Хочу здесь уточнить кое-что. Время написания - это не просто время, нужное на то, чтобы надолбать на клавиатуре выбранный алгоритм (обозначим его Т0). Так не бывает на практике, поскольку нужно время на отладку, т.е. исправление ошибок. Причём в целом всё это время выходит гораздо больше, чем Т0, зачастую во много раз больше. Отсутствие сбоев - тоже вещь неоднозначная. Это не обязательно отсутствие ошибок, но также и наличие затычек на имеющиеся косяки. В целом можно сказать, что меньшее время написания и надёжность кода друг другу противоречат. Вполне очевидно, что на более надёжную программу нужно больше времени. Далее. Можно также утверждать, что всё развитие программирования направлено именно на решение двух этих задач - надёжности кода и сокращение времени его написания. Более того, это почти всегда делается в ущерб скорости выполнения. Из всего сказанного следует простой вывод. Как время написания, так и надёжность напрямую зависят только от одной вещи: допускаемых программистом ошибок. Думаю, это тоже очевидно. Соответственно, возникают две задачи - делать ошибок как можно меньше и исправлять их как можно быстрее. Причины ошибок Вообще ошибки вызываются сложностью программы. Это звучит крайне тривиально, но это ключевой момент. Весь прогресс в области ПО - это не что иное, как борьба со сложностью: прямой ввод кодов заменили мнемоническим ассемблером, который заменили языком высокого уровня, а затем ещё более высокого уровня. Перфокарты заменили текстовым редактором, а потом текстовый редактор получил подсветку синтаксиса и автоматическое форматирование. Прямое манипулирование памятью заменили автоматическим управлением. Парадигма процедурного языка сменилась парадигмой ООП. И т.д. Каждое нововведение упрощает какой-либо аспект работы программиста. Позволяет уменьшить сложность. Пути борьбы со сложностью Что же остаётся программисту? Ну во первых конечно выбор для работы всего, что способно сократить нам сложность. Язык обычно навязан соображениями эффективности, но и здесь вопрос не закрыт полностью. Ассемблер или С/С++? Ассемблер - это чудовищное увеличение сложности и далеко не пропорциональное ему повышение скорости. Какие-то некритичные по скорости задачи можно решить в языке ещё более высокого уровня, чем С/С++? Значит разбиваем программу на части и реализуем по отдельности на разных языках. Но это конечно не применимо к модостроению, где всё уже решено за нас. Так что же остаётся в итоге? Мы выбрали алгоритм для реализации, у нас есть среда разработки, у нас уже есть языки. Остаётся лишь способ написания кода, позволяющий бороться со сложностью и находить легче ошибки. Ну вот и всё в сущности. Из этого вытекают все действия действительно хорошего программиста, из стремления уменьшить сложность: комментарии и самодокументированность, структурирование кода, аккуратное оформление, комментарии, логичное группирование по модулям, стремление у визуальному упрощению кода (то самое линейное оформление вместо "матрёшки" кода). Что ещё забыл? Ах да, комментарии конечно. Способы борьбы с внесёнными ошибками В плане упрощения отлова ошибок тоже можно много чего сказать. Здесь опять же можно констатировать, что прогресс в области программирования также влиял и на лёгкость отлова сбоев: появились отладчики с пошаговым выполнением, точками останова, просмотром переменных в памяти и т.п. Но вот в модостроении это всё вдруг стало недоступно, и надо что-то делать. Здесь есть как минимум несколько путей: первое использование универсальных компонент с отладочным функционалом. Например, система событий (их уже имеется несколько разных) не только снижает сложность системы за счёт унификации вызовов, но и позволяет отлавливать определённые типы сбоев. Также крайне рекомендуется широкое использование отладочного вывода в дамп (что вообще говоря стимулирует к стилю записи одна операция - одна строка), по возможности создавать функции с кодами возврата. Отдельного упоминания заслуживают ассерты, т.е. искусственные вылеты по условию. Штука совершенно незаменимая и настолько же недооцененная в модостроительном сообществе. Что делают неправильно И наконец. Что является вредным и неправильным в свете сказанного? Первое - трюкачество любого рода. Тут всё просто. Трюкачество по определению повышает сложность кода и значит безусловно вредно. Крайне вредна ненужная бравада своей способностью написать и понять сложный и запутанный код. Опять же понятно, что это ведёт к трюкачествую и также к нежеланию комментировать. Вредна лень, приводящая к полному отсутствию комментариев, нежеланию переписать код, чтобы сделать его проще и вообще нежелание переписывать код. Поленились прокомментировать и упростить код сейчас - потратим гораздо больше времени потом. Вредно стремление затыкать ошибки, вместо того, чтобы найти их источник. Исправив ошибку в источнике мы снижаем общую сложность кода, а сделав затычку - напротив повышаем. Т.е. затычки в итоге делают систему сложнее и повышают общее время разработки. Упомянутые же выше ассерты - это как раз способ заставить себя самого не ставить затычки, а найти и исправить источник проблемы. Ну вот как-то так. Изменение стиля написания кода, с которого я начал выше, - это как раз пример в этом направлении "всё для борьбы со сложностью" 1 1 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 26 Апреля 2016 Вот только вертолёт не хочет слушать команды как надо, из -за большой задержки Вертолёт вообще-то и должен быть инерционным. Даже ствол пулемёта мгновенно не развернуть, а уж многотонную машину и подавно. Ты в авиасимуляторы играл? ассемблер рулит, он круче С++, просто потому что ПОНЯТНЕЙ!!!!!!!!! Был у меня в бытность мою преподом в Питере один студент, который ваял программы под винду на ассемблере. Именно что целиком, а не просто вставочки в СИ-код. Я видел, как это выглядело в его исполнении. Куча макросов для вызовов API, фактически СИ-образный код (из-за обилия макросов), отладка в средневековом стиле. Это было конечно интересно, но крайне непродуктивно. Неужели действительно настолько сложно освоить С/С++ ? Это повысит производительность разработки на порядок. Любые временные вложения в обучение окупятся многократно. 2 2 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 13 Июля 2016 Зачем в исходном коде столько классов для оружия? Хороший вопрос. Ответ на него: совершенно незачем иметь столько классов для оружия. Как минимум всё стреляющее обычными пулями можно было бы сделать на одном классе, слегка кастомизируемом конфигами (типа наличия затворной задержки или режима автоматического огня). Соответственно останется ещё пара-тройка классов для многоствольных агрегатов и всякой экзотики. А может и вовсе стоило бы сделать один универсальный класс с настройкой под конкретные параметры чисто конфигами. Проблема в том, что разрабы не делали платформу для разработки, а просто делали игру под свои нужды, поэтому вопросами оптимальности не затруднялись. Занимается ли кто-то созданием единой абстракции для оружия? Наверное стоило бы этим заняться, но для начала надо создать проект с собираемым движком и разобраться со многими другими сопутствующими проблемами. Я так понимаю, что если кто что и сделал, то застрял на втором этапе, так что до оружия руки не доходят =) Велика ли внешняя зависимость от "лишних" классов вооружения? Не совсем понимаю, что ты имеешь в виду, но вполне можно как минимум все автоматы перевести на один класс, скажем от АК, а на остальные забить. Пистолеты не получится, поскольку у автоматов нет затворной задержки. нож — стреляющий объект, что забавно. Нож внутри использует специальную пулю для нанесения хита. В этом есть свой смысл, поскольку не нужно отлаживать альтернативный механизм. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 13 Июля 2016 А по другому не реализовать Это вопрос? Если вопрос, то ответ на него простой: а зачем? Есть уже реализованный способ, зачем делать что-то ещё? мысль есть. Если сделать механический удар шейпом с материалом атаченного предмета, по подобию радиационной воды, то можно наносить урон. Только надо еще движок править и СДК на новый килл. Геометрия худа принципиально не может взаимодействовать с геометрией уровня или объектами уровня. Это просто картинка, рисуемая на фоне всего остального. И возвращаясь к началу, а зачем это всё надо, если уже есть готовый способ нанесения хита? В игре есть класс авто, ...но на этом классе нельзя делать танк с гесеницами. вот и было бы два класса: колёсная техника и гусеничная. Но ведь не надо при этом делать по отдельному классу на Запорожец, Ниву, БТР и т.д., не так ли? Вот с машинами разрабы сделали грамотно, создали общий класс, где есть в том числе и оружие, которое можно при необходимости заблокировать для конкретной секции. У оружия полно завязок Эти завязки есть потому, что разрабы их сделали. При небольшом усилии вполне можно было бы сделать гибкую настройку, когда анимации вписываются конфигами произвольно, ненужные отключаются, ненужные фичи отключаются и т.д. Как например сделано с аддонами. Есть класс CWeaponMagazined для оружия без подствольника, но он совершенно не нужен. Можно взять класс CWeaponMagazinedWGrenade и заблокировать установку подствольника конфигом. Снайперскую винтовку вполне можно сделать на ровно том же классе CWeaponMagazinedWGrenade, попросту отключив все аддоны и отключив стрельбу очередями. Даже пистолет можно сделать на этом же классе, если не нужна затворная задержка. А потрудились бы разрабы сделать её опциональной у CWeaponMagazinedWGrenade, и вся линейка класса пистолета была бы не нужна. Дробовик тоже по-сути несложно было бы объединить со всем остальным, включая и стрельбу из двух стволов. Конечно, тогда можно было бы конфигами делать мутантов типа двустволки с прицелом и гранатомётом и стрельбой очередями, но это было бы уже на совести настройщика конкретного ствола. У меня есть стойкое ощущение, что ряд частей движка поручали людям по остаточному принципу. Вот оружие и GUI явно относятся к этой категории. 2 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 19 Июля 2016 подключаю в xr_ioc_cmd.cpp файл actor.h и проект перестаёт собираться Это файлы из разных проектов. xr_ioc_cmd.cpp из проекта экзешника, а actor.h - из xrGame. У проектов совершенно разные настройки по поиску включаемых файлов, да и вообще такое включение выглядит бессмыслицей, поскольку в проекте экзешника ничего и никому не известно о классах игровых объектов. Там максимум известны объекты сервера, клиента, ГУИ и т.п. 1 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 23 Августа 2016 Предлагаю поговорить на общую тему, которую можно сформулировать примерно так: "каким должен быть движок X-Ray". Или возможно так: "Что бы я там изменил/возможное направление для развития". Для затравки предлагаю мысль. В текущем состоянии движок развитию не подлежит. Там что-то можно подкрутить, что-то поменять, но реально продвинуться невозможно. Тому есть несколько причин. Если попытаться их перечислить, то мне на ум приходят такие (уверен, что список далеко не полный): сетевая архитектура движка разные среды разработки (и в сущности разные языки) самого движка и SDK архитектура, основанная на dll, а не на статических библиотеках разные версии рендера абсолютная недокументированность кода Соответственно, любые перспективы хоть какого-то развития на мой взгляд подразумевают в первую очередь искоренение указанных причин. Ну вот начать хотя бы с сетевой архитектуры. Сколько из-за неё бед! Клиент-серверное взаимодействие создаёт только проблемы: по паре объектов на каждый реальный игровой, асинхронное взаимодействие со всеми последствиями, использование нетпакетов для загрузки/сохранения и для передачи сообщений, масса кода, который реально ничего не делает в сингле, но засоряет почти каждый модуль. В качестве наглядного примера последствий можно привести последовательность загрузки/создания игры. В сущности концептуально простая последовательность действий - загрузить уровень, загрузить алайф, загрузить в него спавн/сейв, вывести в онлайн объекты уровня - превращается в предельно мистическое действо из пересылки кучи сообщений с сервера на клиент и обратно, выполнением по шажку за раз с пересылкой подтверждения туда-сюда, ожиданием ответа на каждой стороне и т.п. При этом в сингле масса кода, который задействован в сетевой игре, не работает, но понять, что работает, а что нет, нереально. Отладку этого дела невозможно описать цензурными словами. Или использование нетпакетов для передачи сообщений. Понятно, что это исходно была сеть, и пакеты были собственно сетевыми пакетами. Но в сингле то сети нет, а пакеты остались, просто ходят через всякие очереди в памяти или даже во многих случаях (в частности от клиента к серверу) просто вызывается функция посылки сообщения, ей передаётся нетпакет с аргументами, этот нетпакет тут-же безо всяких очередей распаковывается и вызывается функция, которой эти аргументы передаются. Можно было бы для сингла просто вызвать оконечную функцию и передать ей эти аргументы, при этом было бы невозможно ошибиться с порядком распаковки. Даже для асинхронной передачи сообщений (как например от сервера к клиенту) в сингле можно было бы использовать нормальные очереди сообщений с типизированными параметрами. Это просто пара моментов, а их можно назвать ещё много. В общем, предлагаю высказаться на эту тему. 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 23 Августа 2016 (изменено) @abramcumner, нет-пакет - это просто буфер с удобными методами для записи в него. Какая разница как он называется. Дело не в названии, разумеется, а в подходе. Нет ничего хуже, чем передача параметров через обезличенный буфер, допускающий произвольную последовательность записи/чтения без никакой проверки того, что читается. Вместо этого надо использовать нормальную систему для передачи сообщений с нормальными типизированными аргументами. Можно написать над ним обертки для паковки/распаковки конкретных сообщений. Это костыли, просто заметание проблемы под ковёр. Обмен сообщениями между объектами - это хорошо. Надо и дальше его развивать. Проблема в том, что в нынешнем виде обмен сообщениями диктуется "как бы сетью", а должен диктоваться например такими соображениями, как распределение нагрузки между потоками. При этом многие действия стоило бы сделать синхронными, например обработку хита или смену владельца предметов и т.п. Из-за асинхронности возникают ситуации, когда разные объекты находятся во взаимно противоречивом состоянии: сделал смертельный хит, но непись ещё не помер, помер, но ещё не обработаны все посмертные действия, передал предмет, но клиент ещё не сменил владельца и т.д. Выкинуть g_actor. Ну в сингле всё вертится вокруг актора, так что не видно большого зла в том, что мы храним на него указатель. Оффлайн/онлайн и два вида объектов нужны по-любому. Это очень здравая идея. Это вообще не идея, это навязанная сетевой архитектурой ситуация. Это конечно естественным образом ложится на подход с радиусом алайфа, но это не одно и тоже. Вот допустим никаких серверных объектов нет, есть только клиентские. Тогда для реализации подхода с "выходом в онлайн" надо иметь разные состояния игрового объекта, которые будут меняться в зависимости от расстояния до актора: кроме банальной частоты обновлений будет зависеть также загружен/не загружен визуал, звуки и прочие ресурсы, навигация идёт по одной сетке или другой и т.п. Между прочим, это в принципе дало бы большую гибкость, нежели нынешний выход в онлайн, который по-сути просто эквивалентен двум предельным состояниям: офлайновый функционал / полновесный онлайновый функционал. Большее количество состояний дало бы, к примеру, возможность не загружать визуал для объектов в инвентаре. Вон RoH пилят кооп в сталкере, им выбрасывание сетевой архитектуры совершенно не в кассу. Моё сугубо личное мнение, что это достаточно бесперспективное занятие. Как там кстати дела у Сурвариума? Они уже запилили монстров в свою игру? Луа, с++, шейдеры, конфиги, хмл как-то переживаются. Про Lua и его роль вообще отдельный разговор. В свете работы с открытой архитектурой я бы эту роль очень сильно пересмотрел в сторону урезания. Проблемы в билдере.Сам пробую перенести СДК в студию, пока все печально. На мой взгляд перспективнм было бы построение той части редактора уровня, что отвечает за заселение, на базе игры. Но это, скажем так, очень-очень отдалённая песпектива. Достаточно легко можно собрать один экзешник, но зачем? Во-первых, не легко. Во-вторых, dll в каком-то смысле "заразная" архитектура. Если два модуля сделаны в виде dll и оба использую третий, то его тоже надо делать в виде dll. Пример - идиотский модуль xrAPI, содержащий что-то вроде десятка переменных, но который обязан быть в виде dll, поскольку используется всеми остальными модулями. Это всё крайне затрудняет реорганизацию кода. движок по факту монолитен Ну не совсем так. Даже сейчас вполне просматривается структура: ядро, GUI, AI, звук, физика и т.д. Вообще конечно разбивка на модули - ещё один масштабный разговор, но вот хотя бы экзешник и xrGame - это на самом деле один модуль. Если и выносить что-то оттуда, то по совершенно иным критериям, нежели как это сделано сейчас. Ну вот скажем GUI и AI я бы вынес в отдельные проекты и ещё завёл бы отдельный проект под глобальные абстрактные интерфейсы. В xrGame же на самом деле жуткая смесь из половинки ядра, AI, GUI, каких-то интерфейсов, части сетевого кода и т.п. Но они по-любому будут. Уберешь р1, добавятся как минимум р5(дх12) и вулкан. Не могу здесь судить наверняка, поскольку не очень в рендере разбираюсь. Сужу просто по внешней организации кода. Все рендеры разделяют массу файлов, которые соответственно включены во все проекты. На мой взгляд, это крайне уязвимая к изменениям архитектура. Сугубо моё мнение - надо пилить один проект с вариантами сборки. На гитхабе к примеру пилят опенгл рендер. Главное меню заводилось полгода назад. Можно поинтересоваться, а зачем? Перенести движок на какую угодно иную платформу, где мог бы потребоваться OpenGL, - совершенно нереальная затея. @Дизель, почему же основатели GSC, решили писать новый двиг? Что им этот не понравился? Полагаю потому, что тоже сочли потенциал его развития исчерпанным в его нынешнем виде. Впрочем, идея "переписать всё с нуля" на мой взгляд тоже неправильная. Это никогда не заканчивалось хорошо =) Двиг хорош Так не о том и речь, а о возможности развития или хотя бы разумной модернизации. Я считаю, что в нынешнем виде - это инертная "несдвигаемая" глыба. Там подколупать, здесь поскоблить - это можно, а куда-то сдвинуть - нет. Про очереди сообщений и нетпакеты могу добавить ещё немного лирики. Я насчитал в движке что-то около четырёх или пяти очередей сообщений разного типа и бесчисленное множество разномастных самопальных систем для организации колбеков. Это к разговору об организации полноценной многоагентной системы и всего такого прочего. В первую очередь нужна унификация обмена информацией. Если уж использовать асинхронный обмен сообщениями, то на основе строго одного механизма (и это ни коем случае не должно быть уродство в духе нетпакетов!). Тоже самое касается системы колбеков (делегатов/ивентов/событий). Изменено 23 Августа 2016 пользователем Malandrinus Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 23 Августа 2016 @abramcumner, По-моему нет. Это я пытался намекнуть на перспективы запиливания полноценного кооператива. Кооп - мне кажется, все хотели бы пройти сталкер в коопе =) Речь же не о том, чего бы хотелось. Я пытался сказать, что сетевой режим - это один из факторов, мешающих развитию. Вот я совершенно уверен, что если бы пыс не пытались делать игру на сетевом движке, то у них бы всё получилось на год или два раньше, а может и ещё раньше. Ну примерно как возиться с движком сталкера. Тоже непонятно зачем и бесперспективное занятие при куче открытых развивающихся движков. Не хочу на самом деле обсуждать рендер. Просто не вижу рационального в его смене с точки зрения развития движка. С моей точки зрения это ни хорошо ни плохо. Skyloader делает что-то похожее(на скрине видна сетка и вейпоинты???) на базе встроенного ЗПшного редактора погоды. В моём воображении это выглядит как отдельное окно с редактором. Чтобы можно было на два монитора разнести. Про ДЛЛ. Мне кажется только в рендерах есть проблемы с переносом в статические библиотеки. Если оставить один рендер, то соберется. =) По факту моих экспериментов как раз рендер пришивается относительно без проблем (он практически независим от всего остального). Больше всего проблем при сборке экзешника и xrGame. Короче, "легким допиливанием" там не обойдётся. Идут проблемы линковки, конфликтующих общих данных и функций, разделяемых между проектами модулей и т.п. Проблема в размере проекта. Количество этих конфликтов просто зашкаливает. Чем проект с вариантами сборки, отличается от четырех проектов с общими частями? Я ведь уже сказал. Многочисленные общие файлы между всеми проектами. Это делает общую структуру уязвимой к изменениям. Тронул там - полетело здесь.Про pipes ответ снят? Я веду речь о чём-то вроде делегатов или слотов из boost (идея у колбеков/евентов и очередей сообщений на самом деле одна и та же). Не знаю, как можно не видеть проблемы в использовании нетапкета как контейнера для аргументов сообщения. Меня они напрягают. Когда при отладке в обработчике я вижу безликий буфер, то совершенно невозможно понять, что там на самом деле находится. А то, что прочиталось, - это на самом деле то, что туда было записано? А я не сместился на байт? А что там за ещё данные вслед за теми, что я уже прочитал? А если пакет пересылается дальше с установленной позицией чтения? Я никаким чудом не догадаюсь, что там дальше за данные, пока не поймаю его в очередном обработчике (который ещё найти надо) и не разберу досконально последовательность чтения. Это же мерзость! Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 23 Августа 2016 @abramcumner, Прямого вызова между объектами не должно быть, особенно если вдруг планируется многопоточность на уровне объектов. Представь, что объект непосредственно вызывает функцию у другого объекта, который в это время обрабатывается в другом потоке. Думать о проблемах многопоточности, мягко говоря, слишком преждевременно. Для начала, ни о какой многопоточности сейчас речи вообще не может идти хотя бы в силу использования Lua. И каким боком многопоточность вообще относится к нетпакетам или даже к очередям сообщений? Или так. Каким образом нетпакеты относятся к очередям сообщений? Надеюсь, ты не ставишь знак равенства между этими вещами? Делегаты/сигналы подходят, если у тебя все объекты работают в одном потоке. Иначе ты скоро запутаешься в синхронизациях на каждый чих. Если ты поразмыслишь на досуге, то поймёшь, что это всё об одном и том же - о посылке сообщения. Синхронный при этом сигнал или нет - дело десятое. Вот даже в сталкире есть посылка синхронная (в сингле от клиента к серверу посылка закорочена на прямой вызов обработчика), а есть асинхронная (через очередь, от сервера к клиенту и ещё одна очередь внутри клиента). Но при этом всё делается через нетпакеты. Причина для этого очевидна - в сетевом режиме эти очереди в итоге шли через сеть, отсюда и бинарный буфер с упакованными аргументами, который удобно посылать по сети. Но в сингле в этом нет необходимости. Ещё раз. Синхронный будет сигнал или нет - дело десятое. Допустим, какой-то будет асинхронным, т.е. через очередь, но это должно определяться не тем, что этот сигнал когда-то посылался по сети, а иными соображениями, хотя бы и желанием распределить нагрузку во времени или между потоками. "всё на асинхронных сигналах" - это выглядит как догма. Где-то это надо, а где-то возможно нет. Я даже приводил примеры, где это не очень хорошо. У нет-пакетов простая абстракция: создаю сообщение, записываю все что надо, отсылаю. Ничего ужасного в ней нет. Мне кажется, я достаточно подробно расписал недостатки. Буфер непрозрачен. У нас запредельно сложная система, а мы ещё повышаем её сложность подобным образом. Если бы аргументы передавались через некий класс/структуру или даже просто списком аргументов функции, то возможности для ошибок было бы куда меньше, и удобство отладки выросло бы на порядок. Вот же! Неужели не очевидно, что соображение "это сейчас работает" здесь неприменимо. Я же об этом и толкую. Да, это сейчас работает (хотя сколько усилий было очевидно перерасходовано, чтобы это таки заработало), но это уже никуда не стронуть. Сейчас даже просто понять, откуда и куда идёт одно единственное сообщение и какие у него аргументы, требует до нелепого колоссальных усилий. И это только такой относительно малый аспект, как использование нетпакетов. Там ещё много всего подобного, связанного с сетью. 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 24 Августа 2016 В сталкере попробуй запрыгнуть на деревянный ящик или бочку. Тебя будет пружинить, пока не упадешь, или не упадет бочка Если рассудить, то ничего ведь не мешает поставить, скажем, бочку на бочку. Ничего не падает, не скользит. А актор - тоже физический объект. Если в отличии от другой бочки неустойчивый, выходит дело не в ODE, а в его применении. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 25 Августа 2016 Сами исходники ODE разрабы же тоже трогали под себя. Из того, что я понял, они взяли версию 5 и фактически мало что там поменяли. Однако вместо встроенной системы коллизий использовали свою (что ODE допускает). По идее актор - физический объект. Если оставить физические объкты в покое, то они должны устаканиться после короткого промежутка времени и отключиться, как только мелкие колебания попадут в заданный допуск. С чем связано то, что актору трудно стоять на динамическом объекте, так сразу и не скажешь. Может быть дефект системы коллизий, могут быть параметры дампинга, неправильный выбор массы или параметров автоотключения объектов. Должен р4 Т.е. только p4, я правильно понял? Поскольку совместить их все так сразу не выйдет. Можно, но надо переименовывать классы + менять процедуру переключения. 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 26 Августа 2016 У меня окно игры прицеплено к док панели А какой фреймворк используешь для окошек? Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 26 Августа 2016 Четвертой версии. .NET ? Мне собственно было интересно, какой вообще фреймворк. Забавно, как будто на заказ под разговор, что был здесь пару дней назад про сетевую игру, VOSTOK GAMES выпустил анонс обновления. https://survarium.com/ru/news/prevyu-obnovleniya-survarium-044 Говорят, что запилили таки ботов в сетевую игру. Но пока плюшевых =) Также я пока не понял, там только боты для пострелушек или есть монстры. Монстры - это совершенно иной уровень для синхронизации по сети. Пострелушечные боты в этом смысле куда проще. На мой взгляд, это подтверждает мою мысль: трудом энтузиастов на движке x-ray кооператива не сделать. Если уж у коммерчески мотивированной команды, которая пилит движок строго под кооператив и уже не первый год, до сих пор успехи только в подобном виде. 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 27 Августа 2016 в Survarium отсутствуют боты в принципе А не приходит такое соображение, что они там отсутствуют просто потому, что их нормально не сделать или сделать сложно? Ведь делают те же люди, что делали сталкира. Причём делают на постоянной основе, а не по вечерам ковыряются. Казалось бы, уж они то должны были за много лет запилить то, что не удалось в x-ray. И насчёт того, что "делать с нуля". Это серьёзно?! Это же разрабы сталкира почти в полном составе, включая Ясенева, который как раз и отвечал за весь AI (т.е. по сути почти весь xrGame). О работе с нуля здесь даже речи идти не может, всё уже есть. Если до сих пор не сделали, значит на то есть какие-то иные причины. X-Ray уже есть боты (пусть даже в синглплеере) + весь синглплеер сделан по типу напоминающему клиент-серверное приложение Во-первых, в сингле множество действий происходит напрямую в обход серверной архитектуры. Но на мой взгляд это не главная проблема. При работе по сети главной проблемой будет синхронизация всех персонажей, включая и физические объекты. Здесь начинают гадить задержки сети. Я уверен, что неслучайно в сурвариуме первыми сделали (точнее анонсировали, что сделали) именно мобов-людей для пострелушек. При этом намного легче скрыть дефекты синхронизации. Мне почему-то кажется, что до мобов-монстров им ещё как до луны. Там всё гораздо сложнее, поскольку монстры находятся при атаке в непосредственном контакте с игроком, и любые косяки сети там будут вылезать сразу. кто то еще там работает до сих пор? Пилить, заранее мертвый проект, Не мне судить насчёт "заранее мёртвый", но фирма вроде есть и работает. Вот анонс же свежий. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 27 Августа 2016 .NET, да. Это ведь означает managed код. Или я что-то не понимаю? Как это всё совмещается с чисто С++ кодом игры? Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 27 Августа 2016 C++/CLI а как там с шаблонами C++ ? Движок их использует весьма интенсивно. Собственно вся игровая логика в xrGame строится на них. Плюс на шаблонах вся скриптовая система. Наверное можно это всё выкинуть, но тогда от игры останется голый рендер. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 27 Августа 2016 я бы попросил бы определение "нормально сделанных ботов". Хотя бы как в сингле сталкира. предсказывание траектории движения и т.д. Тоже самое включаем для мобов и все, проблема решена. Не соглашусь. Когда происходят пострелушки, то все эти манипуляции с экстраполяцией малозаметны. Вообще, когда один сетевой персонаж (непись или игрок, неважно) стреляет в другого, то это в сущности как в детской игре или в том анекдоте: "пиф паф, я попал, ты убит". Т.е. если хедшот был по экстраполированному положению, а это положение было неправильное на полметра-метр из-за задержки сети, то никто этого не заметит. Клиент посылает сигнал "я попал, получи хит", сервер сигнал транслирует, хит идёт. Никто ничего не заметит. Совсем другое дело монстр, который: во-первых маневрирует куда быстрее человека, во-вторых его атаки не удалённые, а близкие и основаны на физическом контакте (т.е. это не абстрактное "я в тебя выстрелил, умри", а вполне конкретное движение из конкретной точки в определённую сторону), в-третьих монстров обычно больше, нежели людей (и все они близко к игроку). Здесь уже будет совершенно очевидно, что сеть лагает со всеми вытекающими: внезапные телепортации, хиты из ниоткуда и т.п. Но вообще мне нравится это "проблема решена". пыс делали годами, ВГ делали, а воз и ныне там. А здесь раз - и проблема решена =) Сурвариум именно что "делают с нуля". Посмотри исходники xray 2.0. По слухам сурвариум построен на них. Исходники xray 2.0 - это конечно ни о чём. Но даже если это то, с чего начали сурвариум, и что с того? Я исхожу из того, что там присутствую все ключевые люди, которые отвечали за AI сталкира. Те, что делали рендер, свалили в 4A и, кстати, за пару лет сделали свою игру со своим рендером и своим ai (и вполне очевидно, что даже если делали с нуля, то знали что делать). При таком раскладе я вижу только одну прчину, почему до сих пор ВГ не сделали кооператив с мобами - потому что это таки сложно. @User_X.A.R26, ну вот я попробовал простой файл с шаблонами скомпилить в проекте C++/CLI. Не вышло, вылезла куча ошибок. Фичи C++11 не переваривает точно. Уж не знаю, как можно весь движок сталкира пересобрать под этим. Разве только поудалять большую часть кода на шаблонах. Ну может я что-то не понимаю. Давно с .NET не работал, так что наверное отстал от жизни. 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 28 Августа 2016 (изменено) @User_X.A.R26, Я понял проблему. Нельзя аргументом шаблона сделать слово "event", видимо ключевое слово. Переименовал - собралось. Здесь ранее заходила речь о передаче внутриигровых сообщений через нетпакеты. Вопрос стоял так: "какая альтернатива?" Вот набросал черновой вариант системы асинхронной передачи сообщений. В архиве по ссылке заголовок с классом и служебными макросами. Сперва объявляем типы событий. Они играют двоякую роль. С одной стороны просто отличают одно событие от другого, а с другой - переменная этого типа является аргументом колбэка (для случая, когда используем колбэк с аргументом). Соответственно чаще всего в качестве типа события рационально использовать обычную структуру. Тип должен допускать копирование. Вопросы глубокого клонирования остаются на совести пользователя. struct some_event { int a; }; struct event2 { float f; event2& set(float f_) { f = f_; return *this; } }; struct empty_event {}; Далее создаём очередь сообщений: #include "events_queue.h" EVENT_QUEUE_BEGIN(my_queue) message<some_event>, message<event2>, notification<empty_event> EVENT_QUEUE_END(queue) Здесь my_queue - это тип объявленного класса (просто любой вменяемый уникальный идентификатор. В дальнейшем не потребуется), а queue - имя переменной, по которой в дальнейшем будем обращаться к очереди. Шаблон message задаёт событие с передачей аргументов. В этом случае обработчик такого события обязан иметь вид: void class_type::fun(const event_type& e) В случае notification соответственно обработчик должен быть без аргументов: void class_type::fun(void) Теперь допустим, у нас есть несколько классов, методы которых мы хотим подписать на соответствующие события: class C { public: void fun(const some_event& e) { // этот метод подпишем на some_event int a = e.a; } }; class C2 { public: void fun2(const event2& e) { // этот подпишем на event2 float f = e.f; } void fun3() { // empty_event } }; Теперь выполняем типовые действия с очередью сообщений: C c; C2 c2; // подписали методы на события queue.subscribe(&c, &C::fun); // здесь использовали уточнение типа события. Это в данном случае несколько избыточно, // поскольку тип события неявно следует из типа подписанного метода "void C::fun(const some_event& e)" queue.subscribe<event2>(&c2, &C2::fun2); // однако имеет смысл всегда указывать тип события, чтобы не допускать ошибок //queue.subscribe<some_event>(&b, &C::fun); // <== ошибка: тип указателя на объект не соответствует типу указателя на метод //queue.subscribe<event2>(&c, &C::fun); // <== ошибка: тип сообщения не соответствует типу обработчика // а вот здесь тип сообщения обязателен, поскольку обработчик не имеет аргумента и может быть подписан на любое notification событие queue.subscribe<empty_event>(&c2, &C2::fun3); // теперь посылаем сообщения (т.е. помешаем их в очередь) some_event e1; e1.a = 1; queue.defer(e1); e1.a = 2; queue.defer(e1); event2 e2; e2.f = 1.234f; queue.defer(e2); queue.defer(event2().set(567.89f)); // для инициализации аргументов события можно было бы использовать и конструктор. // в случае сообщения без аргументов надо явно указывать его тип queue.defer<empty_event>(); // теперь в другом месте (обычно в глобальном колбеке на фрейм этого или других потоков), вызываем так queue.process_deferred(); // соответственно здесь в порядке посылки сработают подписанные колбеки. //Также допустимо и синхронное использование (просто вызвать здесь и сейчас все подписанные колбеки нужного события) queue.call<empty_event>(); event2 e3; e3.f = 3.45f; queue.call<event2>(e3); // наконец отписать обработчики от события можно так queue.unsubscribe(&c2, &C2::fun2); queue.unsubscribe(&c, &C::fun); queue.unsubscribe<empty_event>(&c2, &C2::fun3); // аналогично подписыванию надо явно указать тип события 1. Для работы нужны fast delegates. В сталкире они уже присутствуют, но там что-то меняли с соглашениями вызовов. Вот заголовок, который я использовал. 2. Это пока в качестве рабочего прототипа. Здесь нет межпотоковой синхронизации (хотя пока в ней и нет особой надобности). Также надо заменить используемые коллекции и выделение памяти на те, что используются в игре. 3. Даже в таком виде в принципе можно использовать и заменить большую часть случаев использования нетпакетов. 4. В принципе можно развить и получить некоторые дополнительные выгоды. Например добавить возможность посылать сразу по нужному ID, чтобы из всех подписанных объектов сообщение было автоматически передано адресату. Изменено 28 Августа 2016 пользователем Malandrinus 2 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 28 Августа 2016 (изменено) Насколько я понял, Microsoft так и не сделали редактора GUI для C++. И из набора доступных проектов в студии это тоже очевидно. Так что мой вопрос @SkyLoader-у по сути остаётся, что использовалось для GUI? C# ? А как тогда строится взаимодействие с запчастями от игры? Впрочем, вопрос уже чисто теоретический. Лично я так делать бы не стал в любом случае. Взял бы любой из доступных для С++ фреймворков для окошек, скажем wxWidgets, поскольку я с ним знаком, и не парился бы. Изменено 28 Августа 2016 пользователем Malandrinus Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 615 Опубликовано 29 Августа 2016 Создай проект "VC++ для платформы CLR", добавь в него форму Windows Forms, открой и увидишь Дизайнер, аналогичный подобному в VC# и VB. Не работает. Вместо формы появляется страница с сообщением о какой-то ошибке. По сети пишут, что и не должно работать, поскольку мелкософт дескать всех силком переводит под C#. Кто я такой, чтобы спорить с мелкософтом? =) Не хотят - и не надо, есть альтернативы. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение