Skip to content

Latest commit

 

History

History
2976 lines (1919 loc) · 279 KB

Blog.md

File metadata and controls

2976 lines (1919 loc) · 279 KB
/*
Author: Gudakov Ramil Sergeevich a.k.a. Gauss 
Гудаков Рамиль Сергеевич 
Contacts: [[email protected], [email protected]]
See for more information LICENSE.md.
*/

Дата создания 2011.12.01

"DONE"
"TODO"
"BUG"
"Future BUG"
"INFO"
"IDEA"
"PARADIGMA"

"DONE"

2025.01.20: Глобальные объекты это не зло. И так же синглтоны.
Нужно создать условия для подменяемости объектов. В таком случае будет возможность создавать условия для тестирования. Если есть глобальная функция GetXXX() то и должна быть функция SetXXX(XXX). А в случае синглтона - должен быть базовый класс и класс-обертка, который будет использоваться для доступа в SingletoneManager().

2025.01.09: Стоит подумать зачем вообще нужен отладчик в редакторе. Какие задачи будет решать. По MVP его даже не нужно реализовывать сейчас.
Как обычно ведется отладка в VS code:

  • Пишутся юнит-тесты и интеграционные тесты для гарантии того, что все работает предсказуемо.
  • Логируются события и по ним строится картинка того, что произошло.
  • Ставится breakpoint и, может задаваться условие для сработки. Если дело дошло до breakpoint, то дело совсем плохо. Так не должно быть.
    То есть лучше бы сделать не отладчик, а тестировочный интерфейс в редакторе, в котором прописываются тесты систем и хендлеров.
    На крайний случай потом реализовать вывод окна gizmo - SystemViewer и ComponentViewer. Также запись события с возможностью просмотра по временным точкам. Запись событий заменит логирование. Не нужно расставлять везде строки с записью в файл. Например, запускаем приложение с параметрами отладки
    и происходит запись событий добавления, изменения и удаления компонентов с timestamp. В редакторе можно будет посмотреть в реальном времени
    как происходит процесс работы. Но логировать все же можно. Есть такой модуль - Modules()->Log()->AddWarningEvent.

2024.11.28:

  • Ядро грузит проект через Scene/Prefab/Resource manager как и задумано. Редактор заводит свои Scene/Prefab/Resource manager и удаляет/добавляет.

2024.11.26:

  • Уже доделал зоны (не успел написать). Теперь нужно вспомнить какие идеи были в SceneManager. Понять где и какой тип подпроцесса использовать. Не забыть про инстанцирование префабов.

2024.03.01:

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

2024.01.08:

  • Наконец-то доделал Zones - для описания графа состояния сцены.
  • Уволиться из Яндекса? Оказывается я ничего не делал. Все Женя сделал. Вместе обсуждали как делать. Потом Женя оформил, и он все сделал. Я рыбу для ПР подготовил за выходные (на фига тратил время?). И на фига я там нужен? Злость аж берет. Может, мое усердие в Касперском будут ценить? Вроде стараешься. Ну, скорректируй меня чуть-чуть, направь, поправь и я горы сверну. Нет, надо сказать, что я "ничто" и "ничего не сделал".

2023.11.06:

  • Для варианта Guid остаются такими же. Но если создавать новый префаб оригинал на основе другого префаба, то нужно менять все Guid для избежания неожиданного перехвата событий хендлером.
  • Хелперы для настройки хендлеров, потому имеет место наследование.

2023.09.18:

  • Даже если сцена грузится частями, то не страшно что системы буду работать разроненно. Пускай будет сцена со всей логикой, которая грузиться вначале. Далее логика грузит все остальное.

2023.09.17:

  • Для восстановления состояния игры можно создавать патч для сцены и при загрузке игры патчить сцену.
  • Для модулей передавать настройки при запуске движка. В виде std::string strConfig. Передавать настройку в модуль. Например, для графического движка передвать разрешение окна вывода, битность цвета, даже параметры теней и т.д. Для звука можно настравить качество звука и т.д. Хотя как альтернатива - хранить в виде префаба настройки модулей.

2023.09.12:

  • Загрузка из сцены 3 объектов в Debug - 1.5 .. 4 мс, Release - 300 us.

2023.06.20:

  • Изначально хотел делать тестовый проект для GUI. Проверить как все работает и добавить необходимые компоненты и системы для полной поддержки ImGuiWidgets. Но давно хотел доделать поддержку префабов с вариантами и original. На это может уйти до 2-3 недель. Но оно того стоит.

2023.05.11:

  • Как оказалось сделать Injector с поддержкой логирования трафика тяжелая задача. Проще использовать наработки других людей. Ссылки: 1, 2, 3.

2023.04.07:

  • Основное применение движка - серверная составлюящая игры. Конурировать с Unreal, Unity, Godot в принципе невозможно. Нужно искать другую нишу. Одна из таких ниш - ломать протокол известных сетевых игр и писать эмулятор сервера.

2023.02.18:

  • ImGuiWidgets не корректен. При вызове снаружи настройки какого-либо свойтва будет вызван callback изменения этого свойства. Хотя этот вызов должен был быть только при изменении самим модулем.
  • Сделал блокировку Begin до вызова ModuleWork. И разблокировка после End. И очистка событий для систем Begin. То есть теперь можно использовать Transfrom для разных частей Entity - для графики, физики, звука. Вначале происходит сброс изменений в модуль в Begin. Когда модуль отработал, в End произойдет сброс в ECS из модуля, и сам модуль не будет реагировать на эти изменения.

2023.01.22:

  • В связи с подготовкой к собеседованию по теме сетки и криптографии изучал MMOEngine. Исправли уязвимость процесса подключения в SessionManager. При передаче от сервера клиенту зашифрованного ключа указывалась CRC8, по которой была возможность брутфорсом найти изначальный пароль (вероятность 1 к 256). Убрал CRC8.

  • Все таки нужно в PropertyOf указывать конкретное property. Потому что если есть два класса, которые используют одно и тоже свойство, то к какому из них кастовать?

2022.12.29:

  • Проблема с одинаковыми именами решилась. в настроках каждого проекта нужно прописать в поле компилятора Object Filename $(IntDir)\anyname%(RelativeDir) Таким образом каждый объектник будет созда в соотвествующей директории и пересечения по именам не будет.

2022.12.13:

  • Думаю решается так: меньше "матрешек" (вложений фич друг в друга).

2022.12.12:

  • Вся проблема с системами в C++ в том, что нельзя называть файлы одинаково даже если разные namespace. А хотелось бы создать в одной фиче одну систему и в другой фиче с таким же именем. Но делали бы эти системы разные вещи. Это мега проблема для ECS в C++!

2022.11.28:

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

2022.11.23:

  • Нужна карта для описания покрытия кодогенерации в ядре и проекте.

2022.11.11:

  • Недопустимо чтобы в ImGuiwidgets рендер-класс содержал данные, данные туда поступают через наследование. Получается как бы примешивание. В ядре потом данные из компонентов поступаю через эти классы.

2022.10.24:

  • Совсем забыл, что нельзя системы наследовать в случае Add и Update Collector. Можно ли или нельзя? С одной стороны наследоваться от Init и Execute можно. Например для инициализации и тут же начать работать. Тут нельзя смешивать AddCollectSystem и UpdateCollectSystem - в каком порядке давать события?

2022.10.14:

  • В случае сетевого или ММО движка нужно обмениваться объектами как замена вызовов методов у объектов. Например: создали из префаба клиента ММО. Чтобы подключиться к серверу нужно инстанцировать к нему из префаба заготовку с компонентом, например, TLoginClientComponent { ip = 1.1.1.1; port=1234; }. Он этот объект увидит, обработает и уничтожит. Логика внутри модуля MMOEngine обрабатает этот компонент в Begin. То же касается и отправки данных. Создаем из префаба объект и цепляем к нему пользовательский компонент. Проблема в том что нужны заготовки делать на уровне редактора, так чтобы было видно внутри проекта. Проще портировать в проект редакторские префабы как ресурсы при создании проекта. EditorPrefabs/ModuleName/.... Если будет несколько клиентов (или несколько транспортов), то различать и искать глобально можно через TAG. Например, два клиента. Один связывается с кластером (помечаем TClusterTagComponent), другой с сервером обновлением (помечаем тегом TUpdateServerTagComponent). Теперь чтобы найти тот или иной клиент нужно использовать Has() или Has();
  • События от клиента можно получать либо через Handler (локально) либо через Entity (глобальной) с новым компонентом. Вопрос: как лучше?

2022.10.05:

  • Размышления на тему переделки системного конвейера (по сути описание условий задачи, постановка и решение).
  • Временное разделение: в каждом модуле есть Begin и End. В Logic внутри Work есть еще одна точка для вызова дерева конвейера.
Module -> Graphic Logic ...
SystemConveyor Begin/End Begin/Work/End Begin/End
  • По типу события реагировать можно по разному.
Add Update Remove
Instant/Collect Instant/Collect/Execute every frame Instant
  • Взаимодействие между частями:

Module <------> ECS (ORM) <-----> Developer

  1. Графика через действия пользователя меняет размер и позицию юнита. Нужно синхронизировать с ECS.
  2. Разработчик меняет размер юнита через ECS. Нужно опять синхронизировать данные внутрь модуля.
  • Пример для Window:

2022.10.04:

  • Подходы в ECS отличается от ООП. В ECS нужно продумать конвейер исполнения и как обрабатывать в нем данные. Не нужно думать кто кому принадлежит и как потоки будут идти от к объекта к объекту как это делается в ООП.

2022.09.20:

  • Если у главного компонента есть свойство, то оно должно быть всегда в объекте. Например, если это фокус, то должен быть флаг. С обработчиками все по другому, потому что наличие или остуствие.
  • Так испугался ночью вчера когда была гроза. Яркие вспышки и громкий звук. Было очень похоже на взрывы ракет. Как же жители Харькова каждый день такое выдерживают? Мозгом то я понимаю что до фронта далеко, но все равно было страшно.

2022.09.15:

  • Главный компонент не должен знать о Handler-ах. При добавлении главного компонента настраивается сам главный компонент и свойствам прописывается указатель. Handler указывает точечно на тип.

2022.09.13:

  • HandlerComponent может существовать независимо от главного компонента.

  • HandlerComponent настраивается только напрямую на класс, который представлен главным компонентом. Но время жизни должно быть внутри рамок жизни главного компонента.

    Тип \ Событие Add Update Remove
    MasterComponent Apply Ignore Apply
    Property Apply Apply Ignore
    Handler Apply Ignore Apply

2022.09.09:

  • Центральная идея для написания логики обработки события создания/обновления/удаления компонентов.

  • Все компоненты делятся на 2 категории:

    1. Первостепенный - содержит указатель на объект из других подсистем, например, указатель на кнопку или сетевой движок.
    2. Свойства - параметры первостпенного компонента. Например: у кнопки есть размер и позиция. При создании кнопки компонент TButtonComponent ищет среди компонентов текущего Entity TSizeComponent. Что бы отвязаться от первостпенного компонента в системах обработки событий свойств, нужно сохранять указатель на первостепенный внутри каждого из свойств.

    Как реагируют системы на действия с компонентами в зависимости от категории:

    Тип \ Событие Add Update Remove
    MasterComponent Apply Ignore Apply
    Property Ignore Apply Ignore

2022.09.08

  • Выкладываю multiplayer на github для истории (удобнее смотреть как менялись исходники). До момента появления MMO-Framework. Задачи:
    • Добавить в ядро компоненты и системы для GRID и Layouts.
    • Добавить в ядро компоненты и системы для TexturedFrame.
    • Кодогенератор (-_-) делать его долго, но очень нужно. Повысит репрезентабельность отображения компонентов в редакторе.

2022.09.05:

  • Доделал GRID -_-.
  • Проблема в том, что в буффере кадра текстура перевернута (flipped Axis Y) по оси Y. Надо как-то перевернуть, иначе формат не совпадает с загруженной текстурой. И imgui рендерит не то же самое. Как вариант попробовать Vulkan. Если там по-другому, то создать новый контекст и поддержать там Vulkan. Иначе придется "костылить". Вот этого делать совершенно не хочется.

2022.08.10:

  • Код в TFrame ужасен. Надо заново провести анализ и переписать. Неструктурировано. По какому принципу так сделано? Где ключевая идея? Три категории: Unit or frame, Grid or not grid, with anchor or without anchor. MinDistanceToParent - используется в NotGrid.

Условия применения MinDistanceToParent:

  1. (Left && !Right) - Left.
  2. (!Left && Right) - Right.
  3. (Top && !Bottom) - Top.
  4. (!Top && Bottom) - Bottom.
  5. !IsAnyAnchor().

2022.08.02:

  • Почти доделал grid и layout. Осталось доделать случай grid с ячейками размером больше 1 х 1 и с пустотами. Сейчас расчет неправильный. Нужно доделать. Потом TexturedFrame.

2022.07.25:

  • Grid режим работы Frame.

2022.07.22:

  • ??? TProjectionToUniverseComponent - проекция объекта в другую вселенную. Но появляется лишняя зависимость одних компонентов от других. В объекте же кроме него есть еще и другие компоненты - TUniverseGuidComponent и TUniverseIndexComponent. Либо делать отдельные компоненты, в которых указаны вселенные, где инстанцироваться. Например: TCameraToUniverseComponent

2022.06.16:

  • Может перенести весь генерируемый код из ядра в проект. Тогда ядро не будет знать что какой-то редакторе генерирует код. Что в принципе правильно. Но тогда увеличится время компиляции в первой сборке проекта.
  • TCameraTextureTagComponent, TTextureFromCameraComponent, TTextureFromFileComponent.
  • Нужно заменить THieararchyHelper на TGameObject.

2022.02.04:

  • Удалить Load из Prefab и SceneManager. Оставить Save. Использовать в редакторе конвейер для редактирования.

2022.01.19:

  • Universe Index - для каждой вселенной контекст для каждого движка: Graphic, Gui, Sound, Physic. TUniverseIndexComponent {uint16_t value;}

2022.01.15:

  • Создал проект BigJack для аппробирования новой версии Ogre. SDL2 будет доставаться из conan. imgui-docking будет отдельно, но тоже как зависимость.

2022.01.12:

  • Чтобы загрузить сцену или префаб нужна другая камера. Чтобы не было мешанины. Для загрузки редактор должен настроить графический движок. Как вариант можно делать дальше вставку объектов графики и физики, но лучше сделать апгрейд огра сразу. Из этого вывод, что нужно переходить сразу на Ogre-Next и рисовать архитектуру. То есть релиз редактора пока откладывается. За 1-2 месяца нужно реализовать камеру и применение Ogre-Next.

2022.01.07:

  • Осталось добавить отображение объектов внутри сцены и префаба. Потом инспектор для выделенного объекта. Собрать в релизе и первая версия редактора 0.01 готова.

2022.01.03:

  • В очередной раз нужно прояснить ситуацию с обменом данными между модулем и ECS. На примере Position. В модуле меняется позиция окна -> сброс в ECS (с уведомлением!) через событие callback. Программно меняется позиция -> реагировать через коллектор в BeginSlot. Так сделать везде и переделать для позиции и размера! По сути реактивных систем мгновенного действия должно быть только для удаления компонента.

TODO: Callback от Geometry.

2021.12.30:

  • Проблема уничтожения объектов сцены. EntityManager уничтожает компоненты в абсолютно рандомном порядке. Но в движке важен порядок. Потому что к моменту реакции должны существовать какие-то еще компоненты. Поэтому нужна реактивка на уничтожение Entity. Но тогда как разделять по системам зоны кому и на что реагировать?

2021.12.26:

  • Идея сделать на чистом ImGui окно (или лучше на Prefab'е) окно просмотра всех Entity и Feature просто вызвав Modules()->EntityViewer()->Show(entMng()), Modules()->FeatureViewer()->Show(EntMng()). Для этого расширил возможности кодогенератора - GetByHas. GetByValue и GetByUnique нельзя потому что конфликт с определнием методов IComponent. Не обязательно хранить префаб внутри проекта. Можно конструировать в движке.

2021.12.12:

  • Рефакторинг. Пишу общий класс для связки GUI компонента и обработчика.
  • Далее сделать обработчик смены видимости окон и диалога. В случае диалога если это инстанс от префаба - уничтожать инстанцию.
  • Видимо у boost скоро выйдет обновление (conan заглючил), и boost 1.77 не скачивается. В будущем нужно предусмотреть свой свобственный сервер, что бы оттуда скачивать. (дело в settings.yml, нет секции для msvc).

2021.12.11:

  • Исправил баг с RunTimeTypeIndex. Из разных DLL тела методов с тем же типом разные. Поправил с учтом глобального map.

2021.12.08:

  • Проблема в настройке инстанцированного префаба. Создали и что дальше? Как его настроить? Позию выставить, части ориентировать как-то и т.д.
   PrefabMng()->Instatiate("prefabGuid", [](){});// - ловить лямбдой?

Настраивать можно до инстанцирования. С помощью PrefabObjectConstructor.

2021.12.06:

  • 2 варианта: Load Scene -> Instance Prefab Instance Scene -> Instance Prefab

  • Потом перенести в Wiki.

SceneRoot - только у корня сцены. SceneGuid - guid сцены, есть у всех объектов сцены. SceneInstanceGuid - guid инстанцированной сцены, есть у всех объектов сцены. SceneOriginalGuid - старый guid объекта до инстанцирования, есть у всех объектов сцены.

PrefabRoot - только у корня префаба. PrefabGuid - guid префаба, есть у всех объектов префаба. PrefabInstanceGuid - guid инстанцированного префаба, есть у всех объектов префаба. PrefabOriginalGuid - старый guid объекта до инстанцирования, есть у всех объектов префаба.

Можно ссылаться на сцену через SceneReference. Или ссылаться на объект сцены через SceneObjectReference. Можно ссылаться на префаб через PrefabReference. Или ссылаться на объект префаба через PrefabObjectReference.

2021.12.04:

  • Загрузка Feature из сцены. Проверка при добавлении Feature в конвейер - если такая фича уже загружена, то не добавлять повторно.

2021.11.28:

  • Добавить кнопку для выгрузки текущей сцены и проверить ка работает терминатор.
  • Updater.

2021.11.25:

  • Список обязательных компонентов для любого объекта сцены: Guid, Parent, Transform, Name

Каждый объект сцены имеет SceneGuid, корень SceneRoot. Каждый объект префаба имеет PrefabGuid, корень PrefabRoot.

Когда создается инстанция для Scene, то каждому entity добавляется SceneOriginalGuid со старым Guid, а новый Guid генерируется заново. При этом Parent подменяется на новый Guid.

Когда создается инстанция для Prefab, то каждому entity добавляется PrefabOriginalGuid со старым Guid, а новый Guid генерируется заново. При этом Parent подменяется на новый Guid.

Добавить класс для хранения GuidConstants: NONE, NULL, ....

2021.11.05:

  • Нет гарантии, что коллектор событий создания или изменения компонентов не даст несуществующий entity или же не будет дубликатов. Пока только так. Иначе слишком долго реализовывать. Проблема вот в чем: если изменять компонент в двух разных местах до вызова системы реакции, то будет 2 срабатывания (дублирование). Вторая проблема: создали объект (реакция на добавление), но до вызова системы удалили entity.

2021.10.30:

  • Добавить для результата генерации ImGui возможность выбора уровня доступа к GUI: READ_ONLY, READ_WRITE, READ_WRITE_DELETE.
  • None -> NONE в ECS.
  • Правило: класс глобального модуля не должен знать способ доступа к другому через синглтон. Если и получает доступ, то через указатель.

2021.10.29:

  • Нельзя создавать объекты через initialize list если есть в классе/структуре есть виртуальные методы! Не быть синтаксическому сахару в EntityManager. Блин.

2021.10.25:

  • original namespace -> nsOriginWrapper {Components, Features, Handlers, MenuItems}

  • nsImGuiWidgets -> nsImGuiWidgetsWrapper

  • nsGraphicEngine -> nsGraphicEngineWrapper

  • nsMMOEngine -> nsMMOEngineWrapper

Plan:

  1. ReflectionAggregator for component
  2. Загрузка Scene
  3. Components and Features for nsImGuiWidgetsWrapper
  4. Editor design
  5. ImGuiGenerator
  6. Editable scene
  7. Reflection aggregator generator
  8. Ogre-next portation
  9. ImGui portation, Camera
  10. Render to target
  11. View project

2021.10.15:

  • Наконец-то доделал редактирование узлов TreeView по F2!

2021.10.11:

  • Dock пока оставляю в текущем состоянии. Осталась проблема докинг с MainWindow (бывает так что окно скукоживается до минимума). Все равно API ImGui изменится в будущем. Какой смысл делать то, что все равно изменится и вообще будет работать по другому?
  • Доделаю редактирование TeeView и может быть Drag-n-drop.

2021.10.03:

  • Осталось доделать следующее: легковестное дерево, которое хранит созданное снаружи копию дерева. Каждый кадр создавать легковестное дерево и сравнивать с созданным выше. В случае изменения нужно уничтожить тяжелое дерево и создать заново аналогично структуре легковесного созданного в этом кадре. Легковестное дерево, которое хранит созданное снаружи копию дерева, создасться автоматически.
  • Потом нужно доделать редактирование названия узла в TreeView.
  • Сохранение и загрузка сцены.
  • Фичи для создание ImGuiWidgets при создании соотвествующих компонентов.
  • Кодогенератор ImGuiCodeGenerator.
  • Рендер текстуры.
  • Обновить OGRE-Next. Работа с камерами.

2021.09.26:

  • Пытаюсь создать класс для сериализации и обработки события изменения дерева docking. И тут выяснилось что в версии imgui, которая используется сейчас есть баг. Нужно обновляться до 1.85 WIP. Обновился - в результате шрифты поехали (Obsolete ImGuiFreeType::BuildFontAtlas). Проблема. Пришлось лезть в OgreOverlay и искать путь решения проблемы. Просто закомментировать вызов ImGuiFreeType::BuildFontAtlas.

2021.08.06:

  • Концептуальная проблема, связанная с GUI. Суть ее в том, что если пользователь будет менять что-то в GUI (например, позицию или размер окна), то ECS не узнает об этом и будет рассинхрон. Это опасно тем что по концепту программист меняет ECS и все остальное под это подстраивается. Например в физике эта проблема решается путем подстройки ECS к трансформу всех объектов каждый кадр. Но если в GUI так делать, то как программно менять? Что менять программно: ECS или сущность модуля? С физикой та же проблема. Приоритет изменений программисты выше чем системные (те что в ядре). Решение (взято из Wiki (Engine: Event model)): После работы любого модуля все изменения в модульных объектах должны сбрасываться в ECS (без Update). Модули должны быть настроены так, чтобы при изменении в ECS модульные объекты синхронизировались. То есть ECS == Module objects.

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

2021.07.07:

  • Анализ исходного кода Ogre. Вчера то imgui docking заработал в Ogre. До этого ни в какую работать не хотел. Потом что-то произошло, и стало работать (???).
  • После анализа нужно перенести input в проект.

2021.06.02:

  • В Github добавил канбан для todo списков. Получается для каждого проекта нет необходимости создавать todo.md.
  • Для GUI должно быть: вызов контекстного меню и понимание где фокус и позиция мышки.

2021.05.31:

  • Обновить MyGUI до 3.4.1 + Tools.
  • Написать контейнер для формочек.
  • MathTools - тестировать и вообще придумать что делать с математикой. Она нужна в будущем для проектов.

2021.05.30:

  • Проблема парсинга вида: Type x, y; Такая запись может встретиться и тогда парсер упадет.

2021.05.27:

  • Modules - должен содержать все модули. Для EntMng должно быть 2 указателя: EntMng и EntMngEditor.

2021.05.10:

  • Интерфейс для DLL: Какой был плюс информация о контейнерах.

2021.04.29:

  • Нужно дорабатывать парсер (баг с распознованием функций). При попытке распознать в исходниках самого же парсера. Доделать json и binary: TSerializer без namespace.

2021.04.26:

  • BinaryMarshaller изменить интерфейс на void Pack(T*, TContainer& c);

2021.04.10:

  • Низкий порог вхождения (мало основных компонентов, нужно минимум знаний, чтобы написать простенькое приложение).
  • Все написано на C++, а значит очень быстрое и отзывчивое.
  • Just for fun.

2021.03.13:

  • Парсер готов.
  • Сделать кодогенератор для поддержки возможности использовать компоненты: json для хранения (bin до кучи), entExt для вставки в ECS, MyGUI (но потом), TypeInformation для поиска по имени typeIdentifier.
  • Новая концепция конвейера кодогенератора.
  • Генератор контейнеров.

2021.02.28:

  • Добавлена поддержка enum/enum class для парсера.
  • Осталось доделать поддержку методов и написать тесты для method/member/type pragma.
  • Изучаю Intellij idea JAVA.

2021.02.04:

  • Тест для парсера.
  • Declaration for TornadoEditor: Just for FUN. Only C++ in code. CodeGeneartion, ECS exists in Core.

2020.10.22:

  • Добавить фильтр наследование от класса/структуры. Например class A : public B{}; а не #pragma ASDSD

2020.10.16

  • Blog перевожу в формат markdown. Смена формата отображения даты и порядок записей сортировка по возрастанию устаревания даты.

2020.10.15

SingletoneManager<TComponentReflectionContainer>
SingletoneManager<TFeatureReflectionContainer>
SingletoneManager<THandlerReflectionContainer>

TComponentReflectionContainer : TReflectionContainer
class TReflectionContainer {IJsonSerializator* Get/Set, IBinaryMarshaller* Get/Set, ...};
class IJsonSerializator { virtual void Serialize() = 0; ... };

2020.10.14

  • MyGUI 3.4.0, OGRE 2.2.4.

2020.10.01

  • Идея Editor: как Unity3D, но все на ECS.

2019.10.08

  • Update OpenSSL 1.1.1d

2019.10.04

  • Под Windows 10 с 500 клиентами время цикла на сервере 500 мс! Если 300 клиентов - 0.05 мс. Это как так-то? Надо проверять под Ubuntu. Если под Линуксом будет все хорошо, то забить на то что под виндой происходит.

2019.10.02

  • ECS - какое имя придумать? Mercutor. Смесь "ртути" и "аппарата" (что-то механизированное и сложное) + Меркатор - способ отображения карты. MMOEngine - Melissa, GameEngine - Tornado, ECS - Mercutor.

2019.07.30

  • TypeIdentifier, для первых 4 типов быстрый способ (они чаще всетраются), для более чем 4 - более медленный, но хотя бы реализуемый. Если перебарщивать с template можно положить компилятор на лопатки.

2019.03.02

  • Entt testing
  • Core i5 4430,
  • create with struct TFreshComponent {} 12 ns
  • destroy 11 ns

2019.02.26

  • Reactive system for MappedComponent - ???
  • SuperServer отслеживает повторную авторизацию, значит, при любом разрвые связи будь клиент в группе или нет SuperServer должен знать что клиент отвалился. Если клиент зайдет в этот же кластер, то мастер поместит его в группу, если в другой кластер - то клиент будет уже без группы.

2019.02.13

  • Use only _DEBUG!

2019.02.01

  • RoadMap.

2019.01.31

DllExport для Parser. + ComplexType. json push + ComplexType. json pop + ComplexType. binary push + ComplexType. binary pop +

2019.01.27

  • Игра по дизайну и стилистике должна чем-то отличаться от картошки. Это нужно для самоидентификации игры. Чтобы пользователь мог их отличать. Игра должна врезаться в сознание игрока. Это тоже самое, когда женщина отличает одного мужчину от другого. Важно знать источник удовольствия. К примеру, собаку кормят и в это время звучит Моцарт. Собаку бьют и в это время звучит Бетховен. Когда просто включить Моцарта - собака автоматически получит удовольствие и захочет покушать.

2019.01.14

  • Crowd - не может нанести урон по сокомандникам. Rabble - может и ему за это ничего не будет.
  • Таким образом он понизит шанс выиграть своей команде. Или нанося урон сам снимает с себя столько же. Правило "Око за око".
  • Crowd VS Rabble: Evolution of war machines
    1. Crowd, 2. Rabble, 3. Rabble VS Rabble. 4. Crowd VS Crowd. 5. Random. 1 уровень - Классические танки + слегка модифицированные (стоимость модификации низкая). 2..10 - градация по цене модификации.

2018.12.22

  • Два вида динамической защиты: синяя и рыжая - по урону и по толщине пробития. По толщине снижает скорость подлета снаряда (на кумулятивы не действует). По урону снижает на % урон. Модуль дин защиты switch между двумя режимами. Синий - по хп, рыжий - по пробитию. Когда наводится на танк видно использует враг - синий или рыжий (???). Во время активации - куполообразный пузырь с отблеском.
  • boost::program_options

2018.12.12

  • Нужна предсказуемость. Например я выезжаю на танке против соперников, но не знаю увидят ли они меня или смогут ли мне что-то сделать. У меня есть динамически активириуемый экран и в случае чего я им смогу воспользоваться. Или создам броню, которую спереди они не смогут пробить. То есть нужен расчет как в шахматах. Это и есть тактика. Выезжая на кого-то я точно хочу быть уверенным в том, что имею козырь в рукаве. Просто так зачем выезжать? Вот это и бесит в WoT.

2018.12.07

  • Активируемая динамическая защита. Активируем модуль и на 0.5 секунды вокруг танка появляется экран. Потом модуль перезаряжается. Есть идея перевести CodeGenerator на ECS (???).

2018.08.06

  • Требуется добавить ODB в MMODependencies.

2018.08.03

  • Решена проблема с помощью SingletonManager().

2018.08.02

  • Скрытая опасность от TSingletonPattern и от static inline (который применяется в EnTT). Если в заголовочном файле какой-то библиотеки будет использован синглтон, то внутри библиотеки в cpp адрес синглтона будет другим.

2018.08.01

  • Если сущеуствует ProducerSystem и ConsumerSystem, работающие по одному компоненту, то недопустимо существование нескольких ProducerSystem и перемежение системы по типу: P-C-P-C, лучше: P-P-C-C. Но такая ситуация может возникнуть в данном примере: Recv -> HandleRecv -> Send -> HandleSend ent имеет одинаковый компонент при Recv и при Send.

2018.07.25

  • Требует серьезной доработки работа логики Мастера (nsMMOEngine::TMaster). Ситуация#0: когда клиенты ожидают в очереди и место освобождается, то Мастер помещает не в тот Slave (высоконагруженный). Ситуация#1: большая скорость подсоединения клиентов. Мастер неправильно распределяет клиентов по Slave-ам. Нужно придумать схему, учитывающую такую ситуацию.

2018.07.18

  • Добавлен libuv для определения внешних ip локального хоста.

2018.07.09

  • Нельзя добавлять из нескольких потоков в TDataExchange2Thread! TryConnectDown работал неправильно.

2018.07.05

  • Нет такого события как выход Клиента из Кластера на уровне Мастера. TLogoffEvent.

2018.07.02

  • Всегда возникает событие TryConnectDown - что бы либо выставить пароль для сессии через Accept, либо отвергнуть соединение через Reject. Пока так, хотя можно провести через сценарии. Но через сценарии будет слишком долго реализовывать. Потом можно. Событие ConnectTo от SessionManager. Нужно делить логику внутри сценарием. Раньше было: id = Connect(); Send( id, ... ).
  • Теперь будет разделено по разным методам, потому что сразу после вызова Connect Send вызвать нельзя. Это перебор всех сценариев.

2018.06.29

  • Wrapper не нужен. Удалить.

2018.04.31

  • Сериализовать объекты в JSON можно с помощью boost::property_tree::ptree.

2018.03.05

  • Задачи:

    1. Тест истории TCP ( высокие скорости приема ).
    2. 3 байта под заголовок истории TCP.
    3. Wrapper - ???. ----
    4. Бинарный Marshallizator. +
    5. Marshaller на базе JSON.
    6. Constraints (Bullet).
    7. CodeGenerator на основе T4 (C#).
    8. Начало работы сессии только с использованием AES ( без RSA ). Новая схема.

2018.01.31

  • Переход на VS2017. Осталось только собрать OGRE_dep. Из-за старой версии zzip загрузка под Windows 7 архива SdkTray.zip для OGRE заканчивается крашем. Выводить в ангаре соотношение ботов к героям для стимуляции выбора кем играть. И коэффициент доходности бота.

2018.01.07

  • Блин. Написать целый враппер на C++. А оказалось что MSIL конфликтует с #include <boost/pool/pool.hpp>. С другой стороны враппер скрывает все лишнее. Проще и понятнее работать с движком.

2018.01.01

  • Такой вопрос: если выделить память в native C++ и передать указатель в C#, то отвечать за свобождение памяти будет все равно native C++? И наоборот, если выделена память в C#, можно ли освободить память в native C++?

2017.12.30

  • OpenSSL версии 1.2.0 очень сильно отличается от 1.0.1. Поэтому нужно оставаться на старой версии. Unity использует 64 битные dll. То есть нужно собрать 64 битную версию врапперов и библиотек.

2017.12.25

  • При написании враппера используется x86 managed C++, поэтому нужно использовать в C# тоже x86.

2017.12.18

  • Процесс создания закрытого канала можно до предела упростить. Не нужен RSA ( честно говоря он нужен только в связке с сервером сертификатов, но это уязвимая стратегия ).
  • Отправка клиентом рандомной последовательности нужны, если хакер просто повторит пакет от клиента. Тогда можно будет проверить сможет ли дальше хакер работать в этом канале.
    Иначе хакер займет канал и обычный клиент не сможет войти. Попытка многократного входа и блокировки будет фиксироваться в логе разработчиком.
    Client MD5(Login) -> Server Client <- AESMD5(Password) Server Client AES[AES_Key](Random(512байт), CRC16) -> Server Client disconnect если CRC16 не совпала.

2017.12.16

  • Изменил интерфейс TBreakPacket. Тестировал MMOEngine. Все работает. Теперь нужно перейти на TBreakPacketFast.

2017.12.14

  • Marshallizator benchmark. Скорость сериализации увеличена с 8 мкс до 0.5 мкс. TBreakPacket оставить в интерфейсе PushFront/Back copyData для совместимости. Потом по каждому случаю провести анализ. Не должно быть стековых переменных.

2017.11.03

  • Идея о разных сложностях. Напомню: выбираешь перед началом боя уровень сложности. Это влияет на геймплей и коэффициент, который влияет на заработок серебра в конце боя. легко | сложно Выигрыш 0.3 | 3.0 Проигрыш 0.1 | 1.0

  • Если игрок за бой сделал 3 фрага, набил 1500 хп. Это в общей сложности дало, например, 1000 очков. То заработок будет выглядеть так:

      легко  | сложно
    

    Выигрыш 300 | 3000 Проигрыш 100 | 1000

  • Главное: игроки с разными уровнями сложности в бою должны быть в разных командах. Значит пускай будет команда из 2-4 игроков легкой сложности и 4-10 игроков тяжелого уровня. Причем тяжёлой будут раскиданы по карте. Что бы им победить нужно найти друг друга и скооперироваться. Назовем игроков с легким уровнем Героями, с тяжелым Ботами. Герои начинают бой вместе. Причем могут переговариваться. Боты между собой связи не имеет (хотя читеры смогут это обойти). Типичный бой 2 Героя против 5 Ботов. Режим можно назвать или Кампанией или Хардкор режим.

2017.10.29

  • И каждую неделю статистика должна сбрасываться. Да, действительно. А то будет получать каждый раз по 100 золота. А так чтобы подтвердить свой статус нужно еще раз хорошо показать себя в бою (еще 100 боёв провести ). Может вместо процента боёв использовать боевой рейтинг.

2017.10.28

  • В начале игры будет пустая таблица. По вертикали будет номер места в недельной статистике. По горизонтали максимальный уровень кастомизации, который использовался при создании/модификации танка. Так вот, игрок создаёт свой танк. Использует для этого определенный уровень кастомизации (например 6). Играет более 100 боёв. Потом берётся статистика всех танков с уровнем кастомизации 6 и выбирается максимальный по проценту побед. Этот танк занимает 1 место в таблице (в таблице будут первые 5 мест). Игрок получает золото. Его танк попадает в таблицу. Но в данной конфигурации танк должен сыграть более 100 боёв. Если что-то будет меняться (уровень кастомизации изменится или даже малейшая деталь поменяется), то статистика будет собираться с самого начала.
  • Поэтому если игрок жмёт сохранить модификацию, то его спрашивают точно ли он хочет сохранить изменения в танке. Так же будут танки вне этой таблицы. Как пример от разработчиков. Например, Т-34-85 и т.д. Некоторые из них можно модифицировать, некоторые нельзя. Какие-то будут иметь уникальные части (это будет прем техника). Таблица от разрабов и таблица эволюции.
  • Игрок жмёт "В бой", попадает в подготовку. Выбирает уровень сложности. То есть зная какая карта игрок сам решает как он сможет играть (?).

2017.10.15

  • Уровни кастомизации танка. Нулевой - начало для игры. Далее 1 уровень - можно создать свой танк. 2 - выбор башни (как пример для уровня). И т.д. До полной настройки танка. Может выбирать уровень боёв по уровню кастомизации?

2017.10.14

  • Ведь огромная проблема создать ММО. Надо создать программный каркас для обеспечения кластера. Потом железо арендовать. А ведь можно написать на торнадо логику поведения Slave, Master и SuperServer, и отдать на сервер. Там фирма обеспечит кластер. Нужно всего лишь указать кол-во Slave в кластере и кол-во кластеров. В итоге получить IP всех кластеров и прошить их в клиенте. Вот такая схема для быстрого развертывания ММО для разработчиковв можно сделать на TornadoEngine. Минимум затрат. И это преимущество получаешь только за счет использования загрузки Dll в движке. Значит это была хорошая идея!

2017.09.25

  • Изучаю C#, Unity и Entitas.
  • Почему бы не перенять идею из Far cry о метках врагов на карте. Биноклем находить врагов. Помечать сразу всех союзников зеленым. А врагов помечать только если нашли биноклем (или нет?). Есть ведь nightvision (в игре будет называться SenseVision) и видеть врагов можно только ограниченное время.
  • Помечать на карте, а видеть только через какой-то бинокль (есть заряд бинокля, который садится). То есть на карте красная метка, а возможность визуально отличать на фоне ландшафта например секунд 30. Потом ждать пока бинокль зарядится.
  • В Entitas очень хорошая идея всю логику поведения помещать в System. А игровые объекты хранят только данные. Но в Tornado есть разделение объектов по типу подвижности.
  • Вообще если игрок помечает врагов и уничтожает, то давать ему меньше серебра. То есть чем сложнее играть и условия сложнее, тем больше поощрение. Если игрок ни разу не воспользовался биноклем и SenseVision, то это должно поощраться. А если все было просто (для уничтожения цели) и физика проста, и подсказки, то игрок мало получит - баланс. SenseVision сложно для реализации. Потому что игрок на стороне клиента может применить мод, который может подсвечивать игровые объекты в обход нативной логики программы. Таким образом нужно постоянно контролировать ход выполнения программы, и при запуске программы проверять модификации.

2017.08.30

  • Консервация проекта. Как минимум до января 2018. 1-4 января можно будет доделать констрейнты и поведение танка в качестве примера.

2017.08.23

  • Активно изучаю Python 3.4. Узнал о декораторах, итеративном проходе с помощью генераторов и yield. Список, корежи, словари и множество. Объём информации колоссален.

2017.08.02

  • Родитель вращает ребенка. Для Cart_S.

2017.08.01

  • В Буллет заносится транспонированная матрица. Раньше заносилось неправильно. Также синхронизация была некорректной. Угол поворота в противоположную сторону (как следствие транспонирования). Поэтому оценка результата математики на экране была недостоверной.

2017.07.30

  • Cart_S при вращении крючка Plate глюк проявляется.

2017.07.27

  • Символьный метод не позволяет найти точно чему равна ось и угол. Возникают неопределённости. Неопределённости решаются численными методами. Подставнока и проверка по предположению. X,Y и Z - для каждого два варианта. Кроме угла в Пи и 0. Но для Пи и 0 легко ищется численно. Самое сложное когда углов два +- Alpha. Когда близко к ПИ - решение тупое. Берем точку и вращаем. Ось лежит между результатом и исходной точкой. Нормализуем - готово!
  • 2^4 - 16 решений для x,y,z и угла. Перебором сравниваем что дала исходная матрица и наша формула. По идее должно сойтись только два варианта. Но они оба работают.

2017.07.26

  • Если угол поворота 180 градусов, то определить по кватерниону вокруг какой оси вращать невозможно. Главный недостаток кватерниона. Если угол не равен 180 и находится в окрестностях, то все окей.

  • Думаю, надо переходить в расчетах на матрицы. А повороты крючков и тел описывать с помощью оси вращения и угла.

    1. Замена в XML кватернениона на ось и угол.
    2. Замена в математике кватерниона на матрицы 16.
    3. Но прежде надо протестировать технолгии расчета.
    4. В Bullet можно передавать через матрицу 9.
    5. В Огре только через кватернион. Вот тут проблема. В билде и синхронизации проверять какой градус. Если равен ПИ-+Sigma, то заменять на ПИ-+2*Sigma. Но прежде ищем в матрице угол и ось. Формируем кватернион для Огра и Буллета, но слегка косой. Данное решение идеально и повышает стоимость продукта как минимум на 20%.
  • Расчеты производить в матрицах. А выводить на экран и в физику в кватернионах.

  • При повороте матрицей нет требования ортогональности. Просто умножаем вектор на матрицу.

2017.07.25

  • Какого-то хрена Ogre и Bullet удваивают угол когда применяют кватернион.
  • Нарушено правило при повороте точки вокруг оси. Вектор точки должен быть ортонормирован.
  • Переделать расчет глобальных координат узлов и крючков.
  • Ох уж этот float. Для расчета ортонормированного вектора нужна реальная ось вращения, но при переходе к ней могут возникнуть проблемы. Если Угол очень мал или близок к Пи. То есть возникает ситуация, когда синус угла почти ноль и сам кватернион содержит мусор в виде 1e-8 и т.д.

2017.07.24

  • Повторный рефакторинг постройки модели. Что должна сделать модель.
  1. Инициализация своих данных.
  2. Создание всех вариантов и частей.
  3. Соединить все части в соответствии с иерархией.
  4. Настройка списка крючков (без локализации).
  5. Расчеты: Всегда расчитывать свои локальные позиции и крючков, причем начинать с самого низа, пока не попался тип eShape.
  • Увидел набор тел. Но располагаются они кривовато. И еще как передать настройки внутрь паттерна от другого паттерна-владельца? Сделать виртуальный метод.

2017.07.22

Идея для постройки модели Entry Point (from GameObject) | | Pattern<---- /или\ | / \ | Shape Model-->

Переход от Pattern к Shape или Model - геометрическая итерация Переход от Model к Pattern - ранговая итерация.

Произвожу рефакторинг Build Logic Model. Опять всё забыл. Освежаю память.

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

2017.07.14

  • Геометрическое и ранговое измерение для строения модели.

2017.07.12

  • Вот думаю что можно одной пробежкой по итерации в логике можно рассчитать положение и ориентацию нодов и их крючков. Надо продумать как. Неа, не получится так сделать. Сначало нужно итеративно создать все ноды всех моделей. Это нужно для расчета локальных позиций и ориентаций крючков. И потом уже можно расчитывать глобальные параметры. Причем так и останется метод IsGameObject у паттерна. Также паттерн должен вернуть ExternalJoint.

2017.07.11

  • После рассчёта всех координат частей и вариантов создаются физ. и граф. объекты. Причем граф. объекты SetVisible(false), а физ. объекты не добавляется в World. В PostBuild() анализируется что добавлять в World и SetVisible(true).
  • Математика реализована и протестирована в классе TNodeLocation_Model! Все реально работает.

2017.07.07

  • Отладка сборки модели. Крючок состоит из вектора направления V(1,0,0) и вектора верха UP(0,1,0). Таким образом кватернион крючка применяется именно к конкретным векторам. Вектор UP нужен для стыковки крючка родителя с крючком ребенка. Причем стыковка происходит так: вектор направления ребенка соосен вектору направления родителя, вектора верха родителя и ребенка тоже соосны. Те есть однозначно можно определить по позиции и ориентации крючка родителя ориентацию и позицию крючка ребенка.
  • Начинаем с родителя: у него есть глобальная позиция и текущий кватернион. Откуда эти параметры взялись уже неважно, либо от его родителя, либо это глобальные параметры игрового объекта. Далее это позволит расчитать глобальные позицию и ориентацию крючка одного из ребенка. Параметры самого соединения позволит расчитать параметры стержня, начало которого в глобальной точке крючка родителя, а конец в крючке ребенка. Крючок ребенка тоже ориентирован по отношению к ребенку, поэтому можно расчитать параметры ребенка.
  • Крючок родителя смотрит на крючок ребенка. Первое что знаем: векторы Up у них одинаковые.
  • Если есть кватернион крючка ребенка, то нужно расчитать вектор Up, далее создать на основании этого вектора кватернион Q(Up,PI) и домножить на этот кватернион. Потом уже можно применять к объекту-ребенку. Это и есть глобальный кватернион этого объекта.

2017.07.03

  • Надо собрать в XML моедль тележки из моделей для устранения неоднозначностей. Позиции и ориентации чётко расчитать. Так будет удобнее отлаживаться.

2017.06.26

  • То, как одна часть крепится к другой, должно базироваться на одном крючке базы и одном крючке присоединённой части. Причём кол-во констрейнтов неограничено (то же что Link).
  • Убрать позицию и ориентацию Корня из иерархии? Это упростит разработку. Это ведь не несёт особой цели и не даёт преимуществ.

2017.06.24

  • Неправильно сделал Formation в ModelItem. Должно быть: одной части всегда соответствует один Link крючками. План на понедельник: переделать ModelItem::Formation Base и Branch с учётом расположения крючков. Иначе подмена на другие варианты будет невозможна.

2017.06.22

  • Проблема: Допустим есть редактора: карты, молели, формы и материала. При изменении параметров карты и объектов будет происходить сохранение только TMapItem::Object и PatternConfig для объекта карты. При редактировании модели нужно сохранять изменения только в ModelItem. При редактировании формы нужно сохранять изменения только в ShapeItem. При редактировании материала нужно сохранять изменения только MaterialItem.
  • Решил передавать в UpdateGameItem, SaveGameItemOnHDD и SaveOutDataOutOnHDD тип игрового итэма.
  • Пускай сам паттерн решает что делать. К тому же логика лучше знает какой тип итэма сохранять.

2017.06.21

  • Переношу код из Pattern_Model в Сценарии.

2017.06.17

  • Планы на завтра: эксперимент с примером из BulletEngine с настройками constraint. Доделать диаграмму свойств constraint. Cart_S состоит из пластины и 4 колёс. Сначало нужно расположить их в пространстве. Потом соединить точки через констрейнты.

2017.06.10

  • Первый этап: перенести из Pattern_Model построение в сценарий. Второй этап: соединять Shape в модели. Третий этап: соединять Model в модели. При этом появляются требования к интерфейсу Pattern_Model.

2017.06.08

Как оказалось ModelItem не содержит описания крючков для внешней сцепки. В ShapeItem это уже есть. Состав итэмов. ShapeItem: Крючки, окраска, геометрия, материал. ModelItem: Паттерн, набор частей, иерархия, внешние крючки.

2017.06.06

  • Теперь нужно делать модель. Корень владеет позицией и ориентацией самого объекта.

2017.06.02

  • Сохранение карты. Сохранение как.

2017.06.01

  • Делаю диалог для выбора и сохранения из списка. Открытие карты через список возможных.

2017.05.31

  • Готово. Главное играться с minBatchSize и maxBatchSize. minBatchSize и maxBatchSize примерно равны terrainSize.

2017.05.30

  • Irrlicht - стоит обратить на него внимание в качестве замены Ogre. Вроде как Terrain Ogre исчезает при вызове removeAllTerrains().

2017.05.29

  • В ходе экспериментов выяснилось: при считывании данных карты высот из файла (формирует Ogre) и помещении их в btHeightfieldTerrainShape - физика и графика расходятся. Причем расходятся по оси Z зеркально. По оси X все сходится. Это значит что Bullet и Ogre по разному интерпретируют карту высот. Предположение: Bullet - данные начинаются с отрицательных значений Z, а Ogre с положительных. Попробую переставить местами точки по оси X.

2017.05.28

  • Генерализация внутренних методов Pattern_Terrain. Совсем забыл, что должна быть такая операция как Синхро.

2017.05.25

  • В MyGUI нет SpinBox. Его можно создать только комбинацией EditBox и 2-х Button.
  • Ogre при задании рендерить ландшафт с размерами 1000 на 1000 полностью соответвует Bullet при тесте установке объектов (ставятся адекватно графике). Но сам Bullet создаёт ландшафт меньшего размера.
  • То есть localScaling для btHeightfieldTerrainShape расчитывается неправильно.
  • Формула расчета scaling = ws/(s-1). ws - размер ландшафта, s - кол-во точек в ландшафте. Ееее, физика при таком соотношении полностью адекватна графике!

2017.05.24

  • Положение и ориентация камеры сохраняются и загружаются из файла-настроек.

2017.05.23

  • Работаю над TSettings.

2017.05.22

  • Если подвижный объект упал на землю, и его скорость равна нулю после падения (покоится), то при смене или модификации земли объект так и остаётся лежать неподвижно. В самом Буллете я не нашел способов сказать движку, что земля поменялась и нужно перепроверить на коллизии все подвижные объекты. Значит, нужно дать маленький импульс на все подвижные объекты, которые покоятся. Хороша ли такая идея? Ключевые слова: rest, repose, touch.
  • Проблему решил так: появился метод для активации всех btRigidBody из модели. Правда активацию всех моделей в игре в бою делать не надо, а только те, что находятся над изменившимся ландшафтом. В редакторе карты активируются все модели. Под отладкой падает фпс при активизации. Под релизом все гладко, падений нет.

2017.05.21

  • Пытаюсь доделать: после загрузки если состояние карты "Пауза", то у всех объектов позиция и ориентация по-умолчанию равна нулю. Хотя уже заданы другие значения.

2017.04.29

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

2017.04.28

  • Сделал сохранение данных, созданных при загрузке физической составляющей Terrain. Далее графика. Для графики нет данных(!). Так-то они есть, но они находятся в качестве указателей TrrrainGroup и TerrainGlobalOptions в графичекском движке. Правильно ли это? С другой стороны инициализировать эти объекты Огра надо именно в самом начале. По другому никак не сделать.
  • Модификация физики и графики. Задание новых размеров (форматирование).

2017.04.26

  • Когда создаётся карта, и добавляется новый Terrain, не существует файла, в котором есть карта высот. Так как добавление, изменение и сохранение файла карты высот происходит только в редакторе, то это зона ответственности редактора карт. Поэтому при добавлении Terrain редактор карт обязан проинициализировать и создать файл карты высот (через Modify_Terrain). Еще: при редактировании карты или модели на клиенте, пересылать готовый результат на сервер в виде файлов. А не пересылать команды на сервер. Не имеет смысл создавать протокол и инфраструктуру по командам. Корректность результат редактирования сервер проверит и сообщит клиенту. В случае успеха сохранит в БД.
  • После загрузки данных из файла карты высот, сразу запоминать созданные объекты и данные или в методе End()?

2017.04.25

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

2017.04.21

  • Занимаюсь TPattern_Terrain, нужно сохранять ресурсы, созданные в физике и графике. Еще нужно продумать механизм обмена данными между HelperOperations - объекты, которые осуществляют основные операции с ресурсами паттерна (Build,Destruct,Modify,UpdateResources,UpdateByResources). Сам паттерн - это просто хранилище данных, которые используются в операциях.

2017.04.20

  • Идея: Копить изменения в ресурсах паттерна (Копия ресурсов извне) при вызове методов паттерна. То есть это те же самые итэмы, но копии внутри паттерна. Потом при апдейте внешних ресурсов - копировать ресурсы паттерна во внешние. Еще есть проблема: знать созданные паттерном ресурсы Ogre, Bullet, OpenAL. Для высвобождения ресурсов и для манипуляции.
  • Есть интересный язык Squirrel по интерфейсу - смесь С++ и Lua. Скриптовый язык похожий на C++. Мне он больше нравится, чем Lua, хотя Lua очень хорошо. Порог вхождения у Lua очень низкий. Но вот потом его изучать очень сложно, потому что понятия Класс как такого не существует. Класс там предлагается реализовать с помощью метатаблиц, а это такой пиздец. Это как зубы чистить через дырку в жопе. Нет, технически ты конечно почистишь их, но каким-то неудобным и странным образом. Но в Squirrel тоже есть понятие метатаблиц, но есть и ключевое слово class. Такое ощущение, что создатели Lua начали писать язык и было все замечательно, идеи сыпались как из рога изобилия, а потом кокс закончился и пошла какая-то хрень. У Squirrel тоже есть самописный IDE, но он еще далек от совершенства. Надо звезду ему поставить на githib.com.

2017.04.19

  • Вместо TGameMapParameter ввел паттерн MapParameter. Таким образом в сцене есть только объекты. При создании новой карты обязательно присутствует один объект паттерна TPattern_MapParameter. Плюс здесь в том что можно это поведение переопределить в GameImpl.

2017.04.18

  • Паттерн копит и учитывает вызовы методов, влияющих на результат апдейта внешних ресурсов (вариант решения). То есть ответственность возлагается на сам объект и его паттерн. Что вполне логично. Поменяли через паттерн, потом спросили поменять ресурсы. Можно наоборот поменять ресурсы и попросить объект сделать апдейт. Но тогда при изменении ресурсов возможно изменение объектов, ссылающихся на эти ресурсы. Надо ввести класс для ответственности за параметры игровой карты. Для обновления и освобождения ресурсов. TGameMapParameter.

2017.04.17

  • Если можно менять внутреннее состояние объекта через Паттерн, то все равно нужен UpdaterResources.

2017.04.16

  • GameObject грузится из GameItem и ресурсов, на которые ссылаются GameItem. Менять GameObject можно через интерфейс паттерна. Менять GameItem и ресурсы можно напрямую. Изменения в GameObject через паттерн можно скидывать в GameItem и ресурсы. Потом сохранять в файл.
  • Модули из GameImpl и ShareDev передают события в Логику через интерфейс класса (глобальный объект). А другие модули из сторонних библиотек через синхроточку (SynchroPoint).

2017.04.14

  • Все мысли путаются. Какая-то стагнация. Может я заболел?

2017.04.13

  • Доделывал класс для конвертации текста в Unicode и обратно. Задача: изменить параметры Terrain на горячую в редакторе карты. Брать параметры по-умолчанию (3x3, 3x3, 3x3, Текстура травы).

2017.04.12

  • Режимы работы редактора карты: Полёт, Объекты, Параметры карты, Земля. Настроить камеру: SHIFT+KEY - высокая скорость, KEY - обычная скорость. Делаю форму для Редактора Карт. Добавить новый функционал. Старый (формы) надо выкинуть. Намучаюсь я с MyGUI.

2017.04.11

  • Как смена позиции в Контексте может повлиять на реальную позицию в физике? Получается что это модель, а не контекст. От Модели наследуются классы поведения (например, Танк, Башня) и дополняет свои PatternConfig своими ключами.

2017.04.10

  • Хрень какая-то. Сейчас разделение поведения на модель и контекст не имеет смысла.

2017.04.09

  • Суть: игровая карта - сумма игровых объектов и параметров карты. Параметры находятся в MapItem. Игровые объекты формируются из TMapItem::TObject и особой надстройки в виде ObjectMapParam. ObjectMapParam - содержит информацию, характерную для паттерна, указанного в свойствах TMapItem::TObject.

2017.04.07

  • Писать графический или физический движок - удел Богов (вроде Джона Кармака, Тима Суини и т.д.). Поначалу нужно попытаться использовать чужие наработки (Ogre, Bullet). Так ты поймешь чего ждать от движков, что тебе нужно. А вот уже потом можно самому писать. Венгры, вы меня слышите? И что за тупая идея использовать DirectX12? Это же развод для лохов. Производительность карт увеличится??? Что за бред. Mantle и на Windows 7 работает и выдаёт даже больше фпс. Майкрософт совсем уже границы не видят. Всё сделают для распространения Windows 10. И кто играть сможет с DirectX 12? Мясо должно остаться. А у него либо 9, либо 11.
  • На данный момент данные для игрового насыщения поступают из MapItem. Если данные самого игрового насыщения изменить и требуется сохранить это в MapItem тогда что?

2017.04.04

  • Собрал. Переделал GameProcess. Сейчас нужно разделить по задачам BuilderGameMap.

2017.03.21

  • Есть ли разница между агрегацией клиента и слейва? Думаю, нет. Будет агрегация для манипуляций с картой и игровыми объектами.
  • Разхерачил весь GameProcess :D Собираю по частям, как будто движок от машины по болтикам и шайбам. Полный пиздец. Теперь даже карту не загрузить.

2017.03.27

  • Перешел от GLSL на HLSL. В файле OgreGpuProgramParams.h находятся в AutoConstantType. Причина: быстрее загрузка Terrain, шейдер на HLSL эффективнее и удобнее. В линукс будет только сервер, клиент там не имеет смысла.

2017.03.24

  • Не нужно делать масштабирование. Достаточно указать setCcdSweptSphereRadius и setCcdMotionThreshold. Даже не нужно делать FixedTime в Физике (хотя следовало бы указать 1/60 константу). setCcdSweptSphereRadius для каждой формы арсчитывается отдельно + 0.1f - допуск. При setCcdMotionThreshold = 0.1f есть хороший результат даже для цилиндра радиусом 0.2 и скорости больше 20 м/с. Хотя возникает проблема: как выяснить энергию удара при коллизии танка об камень? И будет ли ехать танк при таких параметрах. Если написать систему репликации между сервером и клиентом не в Урхе, а в этом движке, то Урха потеряет всё преимущества.

2017.03.20

  • Нет соответствия физики графике. Цилиндр может вдавиться внутрь другого. Это из-за того, что изначально формы в построителе Огра создавались не по центру координат, а только при положительных значениях вдоль оси Y. Если лист очень тонкий (0.05 м) то он пролетает сквозь землю. Если взять пластину толщиной 1 метр и разогнать до 1000 м/с тоже происходит пробитие. В графике много не сделать. За RAGE или CryEngine угнаться невозможно. А вот GamePlay и физику вполне можно выдать. RAGE и CryEngine - это nextgen. Что бы такое сделать надо лет 10. Физику и GamePlay сделать проще.

2017.03.17

  • Запрет на многопоточность. Game Engine сохраняет возможность работать в многопоточном режиме. Но сама игра и инструменты должны работать в однопоточном режиме.
  • Сначала синхронизация графики с физикой, потом огромный, глобальный рефакторинг. Реафкторинг: названий FromThread->ByModule, GameProcess->SingleThread mode. ModuleLogic, ModuleDev etc -> SingleThread mode.

2017.03.15

  • Изучаю Буллет.

2017.03.14

  • Файл->Открыть и загружаем карту.

2017.03.09

  • Загружать без инициализации Огра, используя классы Огра, нельзя. Поэтому придётся изобретать велосипед и разбирать файл самостоятельно. Фуу, немного продвинулся. Пришлось лезть в исходники Гоблина и искать как создать поток данных. В файле есть упакованные части, я подумал, что их распаковать можно только тем способом, каким они туда и попали. Другого способа нет. Какой же Огр негибкий. Ужас. Один и тот же класс может иметь несколько поведений (или несколько задач для одного объекта).

2017.03.06

  • Загружать карту высот из файла Ogre, где сохранились данные о terrain.

2017.03.05

  • Надо менять структуру TerrainItem под требования Ogre.

2017.03.03

  • Добавил сохранение результата работы derivedUpdate terrain. GraphicEndWork() добавил вызов TEditorMapLogic::CheckTerrainGroupUpdateForSave.

2017.03.02

  • Купил видеокарту ASUS Radeon R7 240 2Gb. Проверю будет ли виснуть драйвер видеокарты. Основная жопа связана с террейном в Огре. Он постоянно пытается сохранить настройки террейна во втором потоке. Поэтому когда нужно закрыть приложение, то происходит ожидание и программа виснет. Так мало того еще и фпс падает. Вот нахрена мне как программисту это? Это не дает прироста производительности. Зачем в Огре это сделано? Это либо надо выключить, либо скрыть процесс от пользователя. Ха, шейдер для металла написать на GLSL это легко. Как террейн побороть? Вот это проблема. Потому что шейдер - это математика. А я для этого и рожден, что бы математику побороть. Террейн - логика, спагетти код и запутанность идей разработчиков. Вот это сложно. Но решаемо.

2017.03.01

  • Сделал туман. Настройка тумана добавлена в MapItem. Нужно еще добавить SkyDome, SkyPlane паттерны.

2017.02.28

  • Готов цилиндр с внутренним радиусом. Теперь террейн.

2017.02.27

  • Оказывается замощать в Огре не надо. Всё что больше 1.0 Огр сам замещает. То есть все что сделано для этого просто потеря времени. Программист отвечает только за геометрию. Ну, в таком случае цилинд закончен. Теперь земля.

2017.02.20

  • Почему Wargaming не придумало ловушки в игре? Можно взрывать бензовозы или обрушивать груды камней на танки. "ЛОВУШКИ". Круглые камни на склоне, катятся когда сбиваешь опору. Выстрелом можно пустить с горы валун.

2017.02.17

  • Не париться по поводу стыков на форме, возникающих из-за материала. Рисовать так. Но на будущее накладывать требования к рисунку текстуры материала. Рисунок должен быть с повторяющимся узором. Следующее что нужно сделать: отрисовка цилиндра и terrain-а. Потом можно экспериментировать с физикой.

2017.02.16

  • Использовать только GLSL. При этом теряется возможность запуска с помощью DirectX, да и хрен с ним. Сделал куб, подгрузил текстуру и с помощью шейдера на GLSL нарисовал грани. Надо, задав параметры куба, нарисовать его. Параметры: размеры.

2017.02.14

  • Задавать шейдер для каждого материала. Тип шейдера: vertex, geometry, fragment.

2017.02.13

  • Хватит заниматься оптимизацией! Делаем графику: куб, шар и т.д.

2017.02.12

  • Провёл такой эксперимент: запуск движка в одном потоке. Нагрузка 100% от ядра процессора. Запускаем приложение, нагружающее другое ядро на 100%, и происходит снижение нагрузки ядра потоком Огра до 0..15%. FPS падает с 1300 до 650 (а бывает и 80). То есть дело не в движке, а в Огре. Точнее в OpenGL.

2017.02.09

  • Снял второе видео с дикторской озвучкой(Пинаевский Александр). Идея: существует история. Только меньше пафоса! Например, герой истории создаёт машину во время войны, чтобы выбраться из окружения. Действие происходит в будущем. Есть аппараты (SmartBuilder), которые собирают аппарат по чертежам и тратятся ресурсы (например, кВт энергии). Это лишь кампания. Проходишь - получаешь медаль или еще что-то. Есть целая вселенная, персонажи. Но можно просто так играть в стандартную игру. Кампанию можно добавить потом. А сейчас просто 10 квадратных танков против 10 на простой карте.

2017.01.28

  • Тестировал производительность многопоточности на разных процессорах. На Core i3 она ниже чем Core i5. Для 4-х ядерного i3 167%. Для i5 4 381%. Если 4 модуля в одном потоке используют процессорное время по 25% каждый, то при использовании 4-х потоков в i5 процессорное время для одного модуля увеличится и составит (381/400)*100%=95% от потока, а было 25%. Но если время одного модуля было 96%, то в 4-х потоках производительность этого модуля даже уменьшится на 1%, а других увеличится. То есть главное соотношение времен модулей в одном потоке. И все еще зависит от процессора. То есть стоит ввести в conveyer.xml название процессора. Каждый раз при загрузке проверять название процессора и сравнивать с сохраненным. При не совпадении или отсутствии записи проводить тест мультипоточности и записывать в Conveyer.xml. Исходя из потребности модулей распределять модули по потокам.

2017.01.21

  • Оптимизировал TDataExchange2Thread. В одном потоке выделить память, в этом же потоке и освобождать. Будет быстро с помощью boost, но только под релизом.

2017.01.15

  • Исследую boost::pool. Пытаюсь внедрить в lockfree и повсеместно в проект. В одном потоке все предсказуемо быстро, но в мультипоточном режиме нельзя предсказать. Требуется исследование в дальнейшем. За 7 часов работы так ничего и не сделал. Далее исследование OgreThread. Запись звука и реализация моделей в Pattern(пока только в TPlane_Test).

2017.01.13

  • LockFree здесь совершенно не при чем. Дело в том, что помимо потоков модулей есть еще другие потоки, которые отбирают процессорное время. Поэтому для 2-х ядерного процессора должен быть 1 поток, для 4-х, соотвественно, 3 потока и т.д. N-1 потоков. Глубокий анализ lockfree класса, перекачка файла ( больше 1 Гб ) с проверкой md5sum. Стресс тест для lockfree.

2017.01.11

  • Упростил, записал видео, надо наложить звук и скомпилировать видео для youtube. Под Release lockfree очередь глючит. Добавил __asm{sfence} после записи в переменную. Глюк пропал, но фпс упал в 2 раза.

2017.01.04

  • Пишу инструкцию как собрать под виндой и под линукс проект. Есть способ упростить: создать в переменных средах DEP_PATH_MMO_FRAMEWORK - где будет прописан путь распаковки dependency.rar/zip.

2016.12.30

  • Совсем забыл поместить в OgreMain.dll файл ресурсов. Придется выложить Dependency.rar еще раз.

2016.12.24

  • Скомпилировал и добавил в Dependency. В коде, который использует Ogre: char* resLocale = setlocale( LC_ALL, "");

2016.12.21

  • Появилась проблема: OgreTerrain содержит зависимость от GetTickCount64 (KERNEL32.DLL). Но под Windows XP такой функции там нет. Пытался редактировать таблицу импорта в OgreTerrain.dll, но результат плачевный: падения примера из Samples для Ogre. Все же решился скомпилировать Ogre 1.9 и создать солюшн.

2016.12.19

  • Удалось настроить перенаправление портов и соединиться через ip 31.133.207.46. ASUS роутер -> Интернет -> Переадресация портов: Включить переадресацию портов - Да Добавить список переадресованных портов ServerUbuntu_Slave 1234 192.168.2.57 1234 Both ServerUbuntu_Master 2235 192.168.2.57 2235 Both Хотя, можно указать диапазон портов, а локальный порт оставить пустым: ServerUbuntu 1200:3000 192.168.2.57 Both

2016.12.09

  • Идея для формы: создаём меш (MainMesh) и указываем те меши (ListLodMesh), которые дейтсвуют при определенных расстояниях от камеры (CurrentMesh). Любой из ListLodMesh состоит из SubMesh-ей.

2016.12.07

  • Используем версию огра 1.9. Сам настрою систему мешей. 2 способа оптимизации: уменьшать кол-во точек полигональной модели (геометрическое огрубление) и уменьшать размер текстуры (текстурное прореживание).

2016.12.06

  • Не получилось. Пришлось компилировать Ogre 2.1. Суть вот в чем: скачиваем исходники огра 2.1 с bitbucket.org. Еще скачаиваем зависимости для огра. CMake gui прописываем в окне источник и место сборки. Указываем boost и папку с зависимостями. Скачать rapidjson. Тьфу ты! Гадость какая! Все должно быть проще.

2016.11.28

  • Тест на выбор кнопки: в комнате 10 человек, включая тестируемого. Есть выбор: нажать кнопку А или В. Кнопка А - с каждого из 9 человек снимается по 1$ и отдается нажавшему. Кнопка В - всем дается по 1$. Спрашивается что нажмет тестируемый? Если все нажмут кнопку А, то никто ничего не получит. Если все нажмут кнопку В, то все получат по 10$. Но если все нажмут кнопку В, кроме тестируемого, то тестируемый получит 18$, а остальные по 8$. Если договориться со всеми, что нажмешь кнопку А, а сам нажмешь В, то можно хорошо выиграть. Но в то же время другие тоже выиграют, но меньше чем ты. Тут есть принцип баланса.
  • Так, а по проекту: есть интересная версия Ogre 2.1. Попробую взять работу с лодами от туда и реализовать на коде Ogre 1.9. Если не получится, то нужно будет скомпилировать Ogre 2.1 и добавить в Dependency.

2016.11.26

  • Информацию о том, какой вариант использовать передавать через PatternConfig. Нужен свежий исходный код OGRE. Метод generateAutoconfiguredLodLevels класса ProgressiveMeshGeneratorBase. Там идет настройка Mesh. Я так понял что мешу даётся указатель на меш и расстояние от камеры. Нужно посмотреть как он это делает. Понижает ли полигональность или качество текстуры. В примере мне не очень понравилась его работа. Либо понижает почти на 100%, либо вообще не трогает. Бывало что вообще примеры наичанает колбасить. сырой ли это огр, или примеры сырые?

2016.11.25

  • Сегодня наконец-то начинаю работать с Ogre! Думаю формы сделать за 3-4 месяца (это с учетом натяжения текстур и LOD).

2016.11.23

  • Для материала можно расчитывать карту нормали в случае ее отсутствия (на этапе создания материала). Учет шероховатости. Есть такая проблема: как текстуру материала натянуть на форму произвольной геометрии? На это влияет геометрия.

2016.11.22

  • Упаковку и распаковку для Игрового итэма сделал только для материала (в качестве примера как делать). Остальные можно потом доделать, т.к. нет в этом острой необходимости. Буду делать контекст и модель для Модели и Shape.
  • Кто регламентирует кол-во вариантов в части модели? Паттерн или пользователь этой модели. Зачем имя паттерна указано в части модели? При создании новой модели паттерна будет создана заготовка с именами частей и подсказкой какую модель выбрать (по паттерну). Кол-во вариантов неограниченно.

2016.11.21

  • Сохранять изменения в xml после удаления GameItem (метод RemoveItem). В тот раз раз в кэше не было игрового итэма потому, что информация обновилась только в кэше. Изменения не были сохранены на жесткий диск. Достаточно сложная тема, потому что здесь 3 уровня кэширования: HDD->MarkUp->MngCache->GameItem. На будущее надо предусмотреть систему кэширования и доступа к бинарному файлу. Так как, возможно, файл с игровыми элементами будет весить гигабайты."ВАЖНО!"

2016.11.13

  • По сути механизм Игрового процесса не зависит от протокола Клиент-Сервер и др. Протоколы должны быть зависимы от устройства Игрового процесса.

2016.11.10

  • Привожу в соответсвие практику с теорией (Модель-Контекст-Игровой объект). Проблема: несогласованность протокола Client/Server с GameProcess. Может прийти пакет от Сервера об изменении/удалении Игрового итема, когда идет процесс загрузки карты.

2016.11.03

  • Запрещать ли использование Model и Shape одновременно в Model? Если Модель оперирует Моделями, так пускай ими и занимается. Смешивать - значит усложнять.

2016.11.02

  • PatternConfig прописывается только для данного паттерна. Если паттерн А владеет паттерном В, то при передаче данных для главного паттерна А, происходит следующее: обработка производится только паттерном А. То есть описание PatternConfig знает только об интерфейсе паттерна А. Можно давать имя варианта PatternConfig для паттерна В в данных паттерна А. Например, .
  • v_B содержит описание для паттерна В. Это позволяет делать описания независимыми.
  • Можно создать паттерн модель Танк. Пронаследоваться от него и создать паттерны ПТ, СТ, ТТ, ЛТ, САУ. Таким образом переопределив некоторые свойства танка, можно влиять на ход боя.

2016.10.17

  • В паттерне должна быть фабрика по созданию паттернов. Например, для паттерна моделей должна быть возможность создавать модели, которые входят в состав другой модели. И так дальше по итерации. Что делать если модели и формы будут дублироваться?
  • PatternModel владеет набором PatternData, PatternData владеет GameObject. PatternModel{PatternData(GameObject)}
  • При создании игрового объекта, сначал нужно создать Модель паттерна. Если такой Паттерн модели уже есть, то не надо создавать. Паттерн модели создаёт новый Паттерн данных. Паттерн данных связан 1 к 1 с игровым объектом.

2016.10.06

  • Начинаю с создания графической формы в Ogre по описанию из модели и формы.

2016.10.04

  • Добавить в графический движок выбор области clip cursor под нужды разработчика! - сделано.

2016.10.03

  • Баг с падением при использовании OpenGL исправлен. При вызове StopEvent вставил строку mGE.reset(NULL); Видимо, освобождение ресурсов происходило в другом потоке.

2016.10.02

GeForce 710 (1 Gb), Intel Core2Duo E4400 (2.4 GHz) Замеры для 4 танков FPS: Debug: DX9: 27, OpenGL: 22 Release: DX9: 1100, OpenGL: 700


Замеры для 100 танков FPS: Debug: DX9: 1, OpenGL: 2 Release: DX9: 126, OpenGL: 98


Radeon R7 240 (2 Gb), Intel Core2Duo E4400 (2.4 GHz) Замеры для 4 танков FPS: Debug: DX9: 126, OpenGL: 104 Release: DX9: 820, OpenGL: 552


Замеры для 100 танков FPS: Debug: DX9: 7, OpenGL: 6 Release: DX9:60, OpenGL: 101


Замеры для 400 танков FPS: Release: DX9:13-15, OpenGL: 27


Radeon HD7850 (2 Gb), Intel Core i5 4430 (3GHz) Замеры для 4 танков FPS: Debug: DX9: 81, OpenGL: 78 Release: DX9: 2400, OpenGL: 1789


Замеры для 100 танков FPS: Debug: DX9: 5, OpenGL: 4 Release: DX9: 430, OpenGL: 386


Замеры для 400 танков FPS: Release: DX9: 98

2016.09.30

  • Важно! Внутрь видеокарты загонять мало текстур, а шейдером "разрисовывать" бикубической интерполяцией картинку из текселей. Побольше нагрузка на ядро ГП, но меньше гнать данных на видеокарту. FPS будет расти. Также следует изучить Сплайны (как использовать в шейдерах).

2016.09.29

  • Интересная проблема: с появлением новой видеокарты FPS движка не повысился (GF 6600GT->GF 710). Та же самая ситуация и в игре Mafia. А вот в FarCry FPS вырос и значительно. Видимо дело в шейдерном конвейере. А это значит, что надо внедрять в движок шейдеры. Но как? Какой план? Также при использовании OpenGL MyGUI валится.

2016.09.25

  • Класс "TControlCamera" завершён.

2016.09.23

  • Прежде чем делать загрузку объекта в Ogre, надо научиться управлять камерой. Пока сделаю в Логике карты, потом можно перебросить получившийся код в класс и использовать "TControlCamera" в других классах Логики. План: 1. Управление камерой, 2. Загрузка модели, 3. Загрузка света. В таком виде уже можно будет играться сценой и отдать на тест Шухрату. Тем более что потом уже можно делать GUI редактора Карты и Модели.

2016.09.18

  • Самая главная задача - реализовать загрузку графической части игрового объекта. В пучине раздумий...

2016.09.16

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

2016.09.15

  • Обвязку вокруг загрузки доделал (направления потоков). Сейчас нужно сделать загрузку паттерна Модели. Пока только в физике и графике.

2016.08.25

  • Вчера гроза сожгла сетевое оборудование в подъезде. А заодно, возможно, и порт роутера. Что делать в случае коммерциализации проекта? Надо иметь запасной способ выйти в интернет, часы задержек - потери в миллионы рублей. Вместо метода сценария IsBlock будет IsActive, активен ли на данный момент сценарий. Блокирующие сценарии (Билдер, Деструктор) меняют во времени возвращаемое значение. Неблокирующие всегда возвращают false.
  • Агрегат Клиента готов. Дальше интереснее - надо описать методы Сценариев. Начнем с Builder. Потом встраиваем Агрегат в Логику (см. схему работы GameProcess) и тестируем загрузку.

2016.08.24

  • Убил целый день из-за warning "С4250". Решил забить на него. Есть базовый класс А с чистым виртуальным методом F(). От него виртуально наследуются классы B и C. В классе B метод имеет тело, в С тела нет. От классов B и C наследуется класс D. И компилятор ругается на то, что в классе D нет определения метода F и будет использовать B::F. Это типа подсказка для программиста, на которую можно забить. Что я и делаю. Интересно как на это отреагирует GCC?

2016.08.23

  • Вызов метода интерфейса одного из Сценариев активирует сценарий, но можно активировать и через метод агрегата сценариев. Контекст не нужен. Некоторые сценарии не могут деактивироваться вызовом снаружи. Нужно дождаться события End. Может сделать активацию только через агрегат? Тогда если получится активировать, то метод агрегата вернет true и можно давать задание для сценария и он сам перенаправит потоки для своих нужд. сценарий: Activate, Disactivate. Агрегат: CB_End, CB_Progress<type,procent>

2016.08.18

  • Должна быть, потому что есть обратная связь в протоколе Client-Slave, так же в инструментарии нужно знать прогресс загрузки карты. Стоит заняться Протоколом Client-Slave и Агрегатом сценариев. Точнее описать понятия.

2016.08.17

  • Добавить в Сценарий: тип сценария (все типы должны быть описаны), контекст сценария. Должна быть обратная связь с агрегатом сценариев. Статус прогресса перенести в General (так чтобы и агрегат мог его реализовать). Заметки о Кватернионах: вращать вектор V1 вокруг другого вектора V2 можно только если:
    1. Вектор V2 нормирован. 2. V2 и V1 ортонормированы друг относительно друга. Как: 1. Сформировать кватернионы Q1(V1.x,V1.y,V1.z,0) и Q2 = SetQuaternionRotationAxis(V2,angle*2).
    2. Умножить Q3=Q1*Q2. 3. Разложить Q3 на вектор и, как побочный продукт, угол. Q3 => SetQuaternionToAxisAngle(V3,a). Должна ли быть обратная связь в протоколе Client-Slave и в интерфейсе Агрегате Сценариев?

2016.08.16

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

2016.08.14

  • Доработка JusticeBalance: Auto, Easy, Hard - выбор для игрока. На Auto система сама выбирает какой уровень исходя из процент побед и КПД на данном виде техники(или вообще на любой за 1000 игр). "Кто-то что-то теряет, но что-то приобретает". Получив моральное удовлетворение от выигрыша, игрок получает мало кредитов, если он имеет высокий процент побед и высокий КПД. Баланс: много кредитов - мало выигрышей, мало кредитов - много выигрышей. Но с другой стороны хороший игрок будет покупать прем, но это плохо скажется на балансе. Плохой игрок, даже купив прем, не сможет приблизится к хорошему по КПД.
  • JusticeBalance пока не использовать, применять картошечный баланс. Хватит и пользовательских карт и техники.

2016.08.12

  • Кто должен создавать ID физического мира в Клиенте и Slave? И кто должен передавать в TBuilderGameMap. Исходя из этого кто еще нуждается в получении в ID физического мира кроме Builder?

2016.08.11

  • Передача идентификатора физического мира для Паттерна при загрузке.

2016.08.10

  • Сценарий полностью руководит Паттерном через Игровой Объект. Вызывает нужные функции в зависимости от состояния паттерна.

2016.08.09

  • Property - атрибут GameObject, Parameter - атрибут Pattern. Property загружаются из GameItem, Parameter меняются Pattern-ом.

2016.08.08

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

2016.07.26

  • Решил построитель и разрушитель игрового объекта поместить в отдельные классы, которые будут принадлежать игровому объекту. В архитектуре почти ничего не меняется, но тот код, который написан в TBuilderGameMap слегка меняется. Builder, Destructor и Updater - используют общий инструментарий для манипуляций над игровым итэмом (загрузка, выгрузка, обновление).

2016.07.25

  • По сути корректировка объекта и update from pattern - одно и то же.

2016.07.24

  • Задачи паттерна: внутренняя и внешняя синхронизация, модификация, манипуляция и частное использование объекта(игровой момент, e.g. повысить мощность двигателя в игре). Игровой объект - данные, паттерн - модель поведения. Проблема: сделать так, чтобы тип объекта карты упоминался один раз в коде. Потому что он может упоминаться еще в паттерне и в пребилдере построителя карты. ManagerNameTypeObjectMap - хранилище для имен типов.

2016.07.22

  • Внутренняя синхронизация паттерна. Физика внутри паттерна, получив квант от Сцены направляет по трубе графике и звуку события для синхронизации. Потом можно начать делать загрузку. Далее внешнюю синхронизацию. Внешняя происходит по кванту от потока логики. Это значит, что пришел пакет от Сервера и требуется его применить к физике.Возможно, что-то пришло для графики и звука.

2016.07.14

  • Идея от Шухрата: анимация солдат, ремонтирующих слетевшую гусеницу.

2016.07.13

  • Пришла в голову идея карты. В начале одна из команд разделена (допустим это команда А). Если команда Б захочет уничтожить одну из групп разделенной команды А, то есть вероятность того, что вторая группа команды А может зайти в тыл. Возникает интрига, идти ли в атаку команде Б. Потому что вторая группа может и стормозить. То есть требуется организованная атака, но и это может не спасти. "Тревожная карта". Карта большая 3000х3000 метров. Второе: если создавать роты, то почему бы не создать 3 команды? 10 против 10+10. Две другие также будут биться против 20. Месиво из команд. Причем карта маленькая 600х600 метров. Ники врагов надо скрыть, что бы не было договорных игр.

2016.07.10

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

2016.07.09

  • Клиентская комната (Room) обрабатывает коллизии Сцены для реакции в виде Графических и Звуковых эффектов.

2016.07.07

  • Идея для карты: Выбор: -- Стандартная(те что в списке Сервера), -- Оценка новых карт игроков, -- Только топовые карты игроков, Случайный выбор карты игроков. Рейтинг карты складывается из статистики (ее оценивает сервер) и оценке, которую ставят игроки. Причем если игрок ставит оценку новой карте, то игроку дается больше серебра с учетом коэффициента. Для старых карт коэффициент оценки ниже. Т.о. выгоднее оценивать новые карты. Если карта набирает очень много низких оценок, то она выкидывается из списка. Игрок покупает новую карту - 1000 золота. Измения в карте - за серебро. Хочет выложить на Сервер - 500 золота. Если карта имеет высокий рейтинг - игроку дают серебро. Если карта очень высоко оценивается - даже золото. Если игрок хочет сделать копию со своей карты - 1500 золота. Копия с чужой карты - 3000 золота. Есть слоты под карту. Карту можно удалить. Если карта выбирается и становится Стандартной, то игроку дают золото и Карта содержит в описании имя автора и т.д. (то есть слава и гордость для игрока - "волшебная кнопка" в действии :) ). Копию со стандартной карты тоже можно делать - 4500 золота. Игрок покупает слот под карту за золото. Называет её как-то. Входит в режим редактирования. За серебро расставляет здания, деревья, кусты, меняет ландшавт. Решает сохранить. Выкладывает на сервер. Сервер, прежде чем принять карту, анализирует карту на адекватность (нужен алгоритм). Карта попадает в реестр карт игроков. Копия - это новая карта. Если игрок сделает изменения в карте, которую уже выложил на сервер, и захочет выложить еще раз (будет стоить дешевле, с каждым выкладыванием еще меньше), то карта в реестре заменяется, её рейтинг сбрасывается и она опять становится новой для сервера. Так же можно отдавать карты на конкурс Карт. Но это дороже - 10000 золота. В случае выигрыша - золото, но все зависит от рейтинг. Когда карта выиграет и её рейтинг: 10/10 - 100000 золота, 5/10 - серебро, 1/10 - ничего.

    • Для техники схема похожа. Игрок создает свою технику. Любой игрок может сделать копию при просмотре статистики другого игрока - 2000 золота. Сделав копию, технику можно менять. Таким образом, вся техника и карты полностью создают игроки. Сервер же только контролирует правила игры и служит собственно самим сервером.

2016.07.01

  • Обнаружил косяк TBreakPacket, точнее особенность использования в циклах. Стековый объект, помещенный в TBreakPacket, не копируется, а значит в следующем цикле имеет другое значение. Решение: функции PushBack и PushFront дополнить флагом bool copyData, если требуется скопировать данные внутрь bp. Требуется связать понятие Паттерн, Сцена и Агрегация Сценариев в одну схему. Но для этого надо продолжить цепь требований от InterpretatorGameImpl.

2016.06.30

  • В задачи Паттерна также теперь входит обмен данными для Модификации GameObject и применение данных из FGI в случае модификации так, чтобы InternalState не менялся.

2016.06.29

  • Разделение модели, слияние моделей и форм, модификация модели.Задать возможность.

2016.06.26

  • По-умолчанию используется Паттерн для каждого типа объекта из ShareDev, только как узнать какой использовать? Modify -> InternalState от одного объекта к другому - ??? Например для Terrain на Сервере или через инструментарий для редактирования карты.

2016.06.22

ВАЖНО! Задачи Паттерна: 1. Сериализация физической модели (Сервер->Клиент, Реплей и т.д.). 2. Визуализация физической модели на Клиенте. 3. Реакция Паттерна на изменение параметров Графическими и Звуковыми эффектами.

  1. Паттерн создаёт пакет, который описывает его для воспроизведения на другом объекте того же класс - сериализация. Для этого Паттерн Игрового объекта опрашивает все Паттерны, которые отвечают за модели, входящие в состав Модели Игрового объекта. Так по итерации вниз для всех моделей, входящих в состав других моделей. Значит Игровой объект должен хранить Иерархию Модель-Паттерн. По сути 2 и 3 задачи имеют одно и то же события для начала в реализации. Физика передает пакет Графике и Звуку, причем это происходит в одном объекте, но в разных потоках.

2016.06.19

  • Пакеты обрабатываются в PCS_HandlerXXX. Пакет для ePacket_CorrectGameObjects на Slave формирует Developer, потому что возможно требуется знать какие объекты Клиент должен обновить, а про какие он знать не должен.

2016.06.15

  • Пришло время описать Протокол Client-Slave. Уровни для пакетов - Game, GameImpl.

2016.06.14

  • Интересная идея от Шухрата: хранить игровые параметры в отдельной БД. Параметры используются для чтения. Читают только Slave-ы для пересылки Клиентам и использования в процессе игры. Удобно менять. Сама БД получается ненагруженной. Игровые параметры: мощность двигателя, пробитие снаряда, скорость поворота и т.д.

2016.06.02

  • Решение 3 проблемы: паттерн поведения определяет что отдать Физике от Физики (Сервер-Клиент, Реплей-Клиент и т.д.), от Физики к Графике и Звуку. Есть базовый пакет + пакет адресуемый одинаковому паттерну (на Сервере это один объект отправляет Клиенту, в Клиенте (реплей,синхронизация физики) один и тот же объект отправляет сам себе). По сути базовый пакет - игровой процесс, доплнительный - часть Конкретной игры. Например, мощность двигателя - дополнительный; ID, pos, rotation, список субъектов (вместо имени можно использовать unsigned char id), паттерн сам себя поймет, по сути базовый паттерн может формировать свой собственный пакет, и движку все равно что передавать. Все же напрямую игровой объект не должен передавать пакеты, должен быть посредник. Во-первых это можно использовать для оптимизации при использовании этих пакетов на Графике (если камера слишком далеко, то пакет можно не применять), во-вторых все равно при передаче используется ММО, а это уже внешний объект. Решение второй проблемы тогда слегка меняется. TContainerRise используется в двух случаях:

    1. Сервер-Клиент, серверный паттерн отдает указатель на свой TContainerRise с пакетом,
    2. Клиент-Клиент, набор из TContainerRise.

2016.06.01

  • Основные проблемы:
    1. Минимизация задержки при возникновении события клавиатуры и мыши и отправка их через ММО на сервер. (требует решения по ходу реализации, некритично).
    2. Оптимизация обмена пакетами между Физикой с Графикой и Звуком, чтобы реже использовать оператор new. Решение: на каждый объект игры заводится очередь отправленных(volatile bool flgAppliedInGraphic, можно ли использовать повторно) и зарезерованных пакетов. Эти очереди хранятся в GP_HandlerThread_Physic как map_id_list.
    3. Структура пакета при обмене Физики с Графикой и Звуком: ID,pos,orient,InternalState. Так вот, что такое InternalState в понятиях этого обмена? Важная проблема. По сути это id_subject,pos,orient. id_subject - идентификатор субъекта в GameObject, но id_subject должен совпадать в ФГЗ.

2016.05.28

  • ВАЖНО!
  • Вот результат умственных страданий: поток Логики с помощью списка для обмена пакетов (Труба) отправляет Задания для потоков Физики, Графики и Звука (ФГЗ). Причем объект этого класса отправляет самому себе. Модуль Логика перенаправляет управление от WorkEnd потоков ФГЗ и там происходит разбор пакетов. ФГЗ в свою очередь, когда это критично, может отправить событие перехода из одного сценария в другой (например, началась загрузка Карты и надо дождаться пока все потоки начнут загрузку и когда загрузка закончится). Физика после расчетов должна собрать пакет, описывающий подвижные объекты или объекты изменившие свои свойства (игровой момент), и отправить его Графике и Звуку. И так каждый цикл. Также Физика отдает управлению объекту (GP_HandlerThread_Physic), который анализирует коллизии с точки зрения Игры (то есть это должен быть полуабстрактный класс, полностью реализованный в DeveloperDLL). Этот объект может менять свойства объекта и накапливать какую-то статистику, влияющую на его состояние (например, ХП у танка и т.д.). Но это больше характерно для Сервера. Клиентский GP_HandlerThread_Physic выполняет малую роль. Но пускай он будет. Также есть GP_HandlerThread_Graphics - отправка событий на Сервер - нажата кнопка В бой или клавиша W (вперед) и т.д. Особенности протокола GP_AggregationScenario_Client - для отправки пакетов от Физики - Графике и Звуку: избегать операцию new - использовать повторно пакеты с флагом, который описывает использовали ли его в Графике и Звуке. В принципе проблема решаема. Но вот надо понять можно ли сделать пакет фиксированной длины. ID, position, orientation - const длина. А вот что такое InternalState - можно ли его зафиксировать? Логика отправляет на Графику и Звук какие эффекты воспроизвести. А Физика для Звука - скорость, позицию и ореинтацию, и также события коллизий. Для Графики - скорость, позицию и ореинтацию, также события коллизий и InternalState.

2016.05.26

  • Пока слишком много абстрактных идей. Непонятно даже с чего начинать, нужно больше конкретики - и для того, чтобы понять правильно ли я выбрал направление, и для того, чтобы вспомнить куда я шел (для этого нужно прошерстить написанный код Builder/Destructor ). Инициатором всегда выступает Logic. Начало ли это загрузки карты, пришли пакеты от Сервера ( Сервер - частный случай, ведь данные могут придти от Реплея или самого Клиента). GP_HandlerScenario_Client находится в Логике.

2016.05.25

  • Вместо слоя лучше подходит понятие Агрегация Сценариев. GP_AggregateScenario, GP_Scenario_XXX.

2016.05.24

  • Для Клиента есть 3 слоя сценариев - Графический, Физический и Звуковой. Для каждого слоя существует свой текущий Сценарий. У Сервера 3 типа сценарных плана (ну соответственно Slave, Master, SuperServer).

2016.05.23

  • Начинаная отсюда Черновые записи - возможно эти идеи тупиковые. Для Клиента: в главный поток (MainThread) поступают события от других потоков. MainThread дает задания для выполнения в конце выполнения потока EndEvent(). Задания зависят от Текущего сценария. Текущим сценарием владеет MainThread. От того какие события поступают от второстепенных потоков зависит выбор нового сценария. На Сервере Сценарии могут чередоваться, то есть не нужно событие снаружи (там только один поток). HandlerScenarioGameProcess, ScenarioGameProcess. Например: идет синхронизация Графики по результату работы Физики. Тут приходит пакет от Сервера о новых координатах, ориентации и внутренним свойствам объектов на карте. Значит нужно скорректировать Физику. Процесс синхронизации Графики как шел, так и идет. Эти сценарии не пересекутся(???).
  • Проектирование GameProcess имеет одну из целей - продумать структуру GameObject.

2016.05.20

  • Основная проблема сейчас - большая нагрузка на работе. Не хватает сил и времени для проектирования GameProcess. Нужна ясная голова для такого рода деятельности. Для написания кода много ума не надо - сиди и вбивай его. Правлю саму структуру GameProcess дело от дела.

2016.04.28

  • Есть одна особенность использования перекоммутации (RCM). Всегда инициатором RCM является Клиент. И вот почему и как это происходит. Клиент отправил запрос Slave на вход в бой. С этого момента Клиента может отправить Slave только запрос на выход из ожидания Боя. Slave теперь уже не может отправлять пакеты Клиенту, потому что не знает когда начнется RCM (и начнется ли вообще). А если начнется, то пакеты для Клиента просто пропадут. Когда группа сформирована Slave получается событие RestoreContext (но это только если произошла смена Slave). Если смена Slave не произошла, то FindSlaveSessionByGroup() - отправить данному Slave список Клиентов (отправлять независимо от того, произошло ли RCM). Slave сам проверяет наличие Клиентов у себя и начинает Бой.

2016.04.26

  • В очередной раз пытался "вылизать" код MMOEngine. Пытался докапаться до безопасности каналов при Авторизации и Перекомутации. При Авторизации Slave создает событие ConnectDown и в нем содержится MITM информация о канале. Чтобы проверить нужно считать из БД Логин, пароль и проверить надежность канала. При перекомутации проверять канал не нужно.

2016.04.24

  • Все-таки идея выбора игроком уровня сложности еще выстрелит. Тот, кто проиграет даже на сложном уровне, получит серебра все равно больше того, кто выиграет на легком уровне. Но при условии, что он хоть что-то делал. Фраг, попадания, засвет, активность в виде пройденого пути и т.д. Уровень сложности - аркадный или реалистичный. И не будет этого постоянного нытья про баланс. Все в выигрыше. Причем в одном бою могут играть с разными уровнями сложности.
  • JusticeBalance - система балансировки. Именно должно существовать название для ассоциации с самой игрой. Существует еще балансировка частей танка - по цене и ремонту. Но это уже другая история.

2016.04.11

  • Провел чистку, GCS->Mutex, убрал TD_WINDOWS. Теперь надо собраться под Ubuntu и протестировать.

2016.04.10

  • Нужен белый IP. В Internet точно есть технологии создания Сервера в "домашних условиях". Скорее всего нужно будет звонить в Рустелеком. Сейчас нарисую граф сценариев для процесса игры Клиента и Сервера, чтобы понять для чего нужен игровой объект.
  • Описываю сценарии игрового процесса Клиента и Сервера (Slave). Этап Достаточности.
  • Рустелеком за даром и очень быстро дал белый IP.

2016.04.08

  • Тест скорости TDataExchange2Thread (микросекунды на операцию добавления): Windows XP 32 bit Intel Core 2 Duo E6600 BOOST volatile без volatile Release: 0.70 0.61 0.63 Debug: 3.08 1.54 1.54

2016.04.07

  • Консервация продлилась 2 дня. TDataExchange2Thread лишён мьютекса! Только volatile (atomic для C++11). При взаимодействии потоков используется TSynchroPoint. Если только 2 потока, то можно использовать TDataExchange2Thread.

2016.04.06

  • Одна идея (потом консервация). Логика может собрать со всех объектов данные в один пакет, потом отдать в Графику, Физику и Звук. Таким образом можно избежать огромного кол-ва блокировок. Экономия составит 30-100 раз (в зависимости от кол-ва объектов).
  • Вполне реально избавиться в TListMultiThread от мьютекса. Но там есть косяк с указателями. Их надо будет сделать или volatile или atomic. Но тогда нужно будет переименовать класс в TList2Thread. LatencyRemove, а вызов Remove - пометить флагом, что нужно удалить.
  • Добавляющий поток по флагу удалит его позже. Нужен ли Below?

2016.04.05

  • Поломал TQueue2Thread со своими экспериментами. По сути бесполезный класс. Проблема многопоточного взаимодействия сводится к простой задаче: есть создатель данных и есть использующий результаты. Сколько бы потоков не было бы - все можно свести к этим условиям. Если потоков N, то можно разбить на пары (как совбственно и делается в TSynchroPoint/TSynchroAbonent) и дать каждой паре для обмена объект. То есть существует только два потока. В C++14/C++11 есть много вкусностей. Думаю перейти на Visual Studio 2015, но тогда не смогу писать на работе. Скачал с Хабра статьи об lock-free. Почитаю, подумаю. Пока консервация проекта.

2016.04.04

  • Потенциально можно менять налету (с сервера данные идут клиента) внутреннее состояние даже Terrain, Light, etc. (Дает возможность место взрыва менять на углубление в Terrain). Но главная цель - смена состояния Model. У паттерна должен быть метод Get и Set - для обмена пакетов. Паттерн принадлежит TGameObject, но как будет менять состояние внутренних составляющих TGameObject? У клиента много потоков - физика, графика, звук. Формировать задания для каждого потока? Данное событие происходит достаточно редко (максимум 2-3 события в секунду для одного объекта).
  • Pattern не нужен для Клиента! Он нужен только для Сервера. Pattern - игровой момент. Он описывает реакцию объекта на действия пользователя и объектов сцены. То есть Клиент синхронизирует физику с графикой и корректирует физику с данными от Сервера. Но корректировка все же требует Pattern для Клиента.

2016.04.02

  • Поведенческий паттерн? PrototypeScene -> TScene.

2016.03.31

  • Начнем с самого простого - графика Модели, Земли и Источник света. Самое сложное правильно натянуть текстуры на формы. Источник света это вообще самое простое.

2016.03.29

  • Пытался добавить вызов функции из потока Логики. Так нельзя делать. Сам же это задумал, сам же напоролся на это. Компоненты шлют в логику пакеты. Логика задает компонентам задание выполнить функцию из потоков компонента.

    Теперь, когда компоновка TBuilderGameMap готова, следует начать делать Task_XXX. Builder работает с интерфейсом Task, PreBuilder задает содержимое внутри Task. Task зависит от GameItem и той библиотеки с которой работает (Ogre, Bullet, OpenAL).

    1. Task_XXX.
    2. PreBuilder.
    3. Builder.

2016.03.26

  • Кроме сборщика карты/объекта нужен так же уничтожитель. Для него такая же схема - PreDestructor, TaskForDestruct_XXX, только кроме OpenAL - кешированный звук выгружать не надо. Выгрузка звука делается с помощью звукового движка.

2016.03.23

  • Вылизыаю интерфейс класса TBuilderGameMap. Интерфейс готов. Заполнить и создать недостающие классы (по Notes.eap->GameMap).

17.03.2016:

  • Делаю обвязку вокруг загрузчика карты. Кратко: есть построитель (Ogre, Bullet, OpenAL), ему на вход подается задача (Task). Task формируется посредством PreBuilder, для каждой задачи из MapItem он свой. Есть 7 типов игровых объектов. Каждый тип может формировать PreBuilder для своего типа сам.
  • После обвязки остается дописать Builder_XXX. Потом делать синхронизацию физики с графикой.

2016.03.13

  • Суперское название. Все честно и по делу. Никакого Диснейленда, никаких розовых соплей. Длинно, но солидно (см. название игры).

2016.03.08

  • Избавился от последнего наследия Тирады и МР. NetSystem (aka ns). Убогий сишный стиль. Переделал в класс.

2016.03.05

  • Посмотреть для роутера таблицу маршрутиризации IP_out:port -> ip_inner:port, как настроить.

2016.02.28

  • В рамках эксперимента проверить настройки Ubuntu для повышения открытых сокетов на один порт. Для этого поставил Ubuntu 14 server 64 bit. Далее sudo apt-get install xinit sudo apt-get install kubuntu-desktop sudo apt-get install kde-workspace-randr - выбор разрешения экрана sudo apt-get install synaptic

    В synaptic установить: mc, gcc, qt4, boost, openSSL, Максимальное кол-во 25000. Но если выключить клиент, но не выключать сервер, могут возникать ошибки подключения при повторном запуске с 25000. 12-15 тысяч держит без вопросов (цикл выключать/включать). Может и 18-20 тысяч тоже, просто еще не пробовал.

2016.02.22

  • Клиент настраивает сцену и ставит на паузу физику в Комнате Клиента (TRoomClient). Сервер же делает все то же самое в Комнате (класс TRoom). Вставил задание нагрузки процессора для MMOSlave (почему-то этого до сих не было сделано(???)). Более тонкая настройка физики для каждого мира - пауза, реальное время, контроль времени. Для Клиента коллизия - звуковой и визуальный эффект (пока только есть таблица звуков, но визуальных - нет).

  • Для Сервера коллизия - правила игры задают изменение физических показателей и других параметров (например, ХП).

    Не раскрыто понятие TGameObject!

    Порядок реализации по Сцене (ВАЖНО): 0. Понятие TGameObject.

    1. Загрузка, создание объектов.
    2. Отображение после загрузки (Show() ?).
    3. Синхронизация между Физикой и Графикой.
    4. Синхронизация (Update) между сценами.

2016.02.16

  • ЭТАП СОЗДАНИЯ ИНСТРУМЕНТАРИЯ Условия достижения цели:

    1. Разделять объекты внутри Сцены по типу подвижности (оптимизация).
    2. Как делать сериализацию между сервером и клиентом (UDP - полная синхронизация, TCP - частичная).
    3. Загрузка карты в Сцене должна идти в нескольких модулях (а возможно и разных потоках, все зависит от кол-во ядер CPU), потому что нельзя данные графики загружать в другом потоке. Квантовать объекты карты на группы и давать потокам загрузки постепенно грузить их.

    Для данных работ выбор на "Объект игры (событийная модель)". Для физики предусмотреть понятие "Пауза". Во время загрузки вся физика находится в состоянии Пауза.

    Задача сцены: синхронизация объектов, выдать коллизии, выдать информацию по объектам, контроль за событиями внутри сцены.

2016.02.13

  • Доделал все итэмы. Но для полноты красоты движка не хватает: воды и травы (реализовать с помощью Зон?). Пока для игры данного набора итэмов достаточно. Потом можно нанять специалиста по Ogre и переделать конвейер графики, добавив туда эффектов графики (Блюр, лучи бога и т.д.). Визуализация: буду идти по двум напрвлениям. Сверху - анализ и синтез понятий (Сцена, комната, подвижные и неподвижные объекты и т.д.) и снизу - сборщик геометрических форм Ogre и Bullet.

2016.02.12

  • Для TableSound map не подходит. Потому что например для одной и той же скорости 0 и 0 могут быть разные углы, и ключ получается один и тот же.

2016.02.03

  • Достаточно лишь: масса, материал, скорость и угол атаки. Масса и материал - парные, поэтому их можно отзеркалить (повторить).

2016.02.01

  • Таблица звуков является отдельным итэмом. Карта ссылается на какую-то таблицу. Внутри таблицы для каждой комбинации существует набор звуков и их параметров. Что бы на одну и ту же коллизию возникал разный звук из набора.

2016.01.31

  • Продумал структуру TMapItem, далее нужно сделать загрузку и сохранение в xml. Существуют звуки: 1. Описанные в сценарии, 2. Результат работы паттерна, 3. Прописанные в карте и 4. Те, что возникают в результате взаимодействия материалов, форм. Первые два формально можно сделать на данной базе понятий. Вторая существует только на словах, нет описания в данной системе понятий. Звук - файл зависит от: 1. Материалы, 2. Вид взаимодействия (трение, удар и т.д.), угол атаки, 3. Скорость взаимодейтсвия, 4. Размеры форм. Это с т.з. классификации (наука).

2016.01.17

  • EditorTerrain не нужен, потому что этим редактированием занимается EditorMap. Как таковой Terrain находится полностью в его владении.

2015.12.28

  • Каждый объект владеет своей физикой. Объектами владеет сцена.

2015.12.27

  • BuilderXXX_Ogre и BuilderXXX_Bullet - вот в чем вопрос.

2015.12.24

  • Доделал сериализатор из XML в описание-структуру для создания модели. Следующее: визуализировать с помощью OGRE Shape и Model.

2015.12.10

  • Доделал сериализатор из XML в описание-структуру для создания геометрической формы.

2015.12.06

  • В последней версии Newton нет танка. Но есть в какой-то из предыдущих. Проблема с разными моделями физики и использования/не использования графики на сервере и клиенте. Решается разными FactoryPattern для клиента и сервера. Таким образом поведение танка при создании будет разным. Вауля! И вся проблема в корне очень красиво решается. Физические движки бывают разные: Jiggle (малая Penetration error и быстрая обработка Constraint), True Axis (почти то же самое что и Jiggle, только EULA), Bullet, Newton.

2015.11.29

  • Доделал загрузку Factory. Возникла другая проблема: я спроектировал формат Модели. но там нет места для гибкой ленты гусеницы танка. Как её реализовать непонятно. В Newton Physic есть пример с танком. Надо скачать последнюю версию и разобраться.

2015.11.26

  • Делаю FactoryGameItem. Работы много (скорее рутины доведения до красоты класса). Дня за 2-3 доделаю.

2015.11.24

  • Давать имя танку при его создании. Имя - имя модели на сервере. 4 слота в начале игры. Далее новый слот - 100 золота. Единицы - "Золото" "Серебро" "Опыт" (опыт тратиться либо на прокачку экипажа, либо на прокачку 4 танков, доступ к деталям Эволюции и новым элементам карты). Конкурс на лучший танк -> купить формулу танка победителя конкурса. Конкурс на лучшую карту. Отправить видео заявку на конкурс. В этом видео показать бой. Кубок на лучший танк в ценовом диапазоне 100.000 серебра и т.д. Далее победитель получает золото. Танк становится доступным в магазине. Там описана история его победы(дата), автор и фото. 1 раз в 3 месяца.

2015.11.22

  • За премиум аккаунт давать возможность создавать свою собственную карту (один слот) и приглашать туда друзей.
  • За 5 побед подряд на сложном уровне физики давать плюшки - серебро, прем или золото (?).

2015.11.21

  • Впринципе вся картинка складывается. Какая часть модели учавствует в физике - решает объект.

2015.11.18

  • В BulletEngine есть implicit shapes (неявные формы - шар, куб и т.д.). Есть идея не хранить модели в виде набора точек, а в виде параметров. А потом восстанавливать в виде данных, которые "скушает" Bullet и Ogre.

2015.11.12

  • Сделал форму-заготовку для редактора форм. Два дня потратил на то, чтобы понять как сделать Меню в MyGUI.

2015.11.07

  • По поводу баланса: можно по желанию игрока менять настройки физики (легкий - как в картошке, сложный - как в War Thunder). В соответствии со сложностью разный коэффициент серебра.

2015.11.03

  • Черновой вариант названия MetaMorf (Metamorfus). На работе есть тетрадь, в которой хранятся все записи по игре. Думаю, что должна быть она одна. Суть игры: существуют два режима в игре Classic и Evolution. Classic: в начале игры даются на выбор один из 4 танков: ИС-2(122 мм), Т-34-85, Panter(88 мм), KingTiger(105 мм). Игрок прокачивает постепенно все. В процессе прокачки открывается доступ к некоторым элементам следующего этапа игры Evolution. Evolution: в этом режиме возможно сконструировать танк собственной конструкции. Сначало выбираешь базу танка - его размер и ходовую часть (ее можно потом усилить, но это будет дороже). Далее нижняя часть каркаса. Компоновка частей - двигатель, трансмиссия, баки, расположение башни (ее может и не быть, а может быть и 2-3), радио, БК и т.д. Потом рассаживаем членов экипажа. Чем больше серебра отдашь, тем лучше компоненты (КПД двигателя выше, калибр и кол-во пушек больше и т.д.). Постепенно играя, зарабатываешь серебро и опыт для получения новых компонентов. Потом получаешь доступ к изменению геометрии и составу сплавов. Керамика, композитные материалы. Слои материалов, динамическая броня, дымовые шашки и т.д. Наращивать броню (падает удельная мощность). Возможность сбрасывать листы брони сразу в бою. Скидывать башни и т.д. Система повреждений: существует HP у каждого танка. При попадании снарядом - снимается ХП в соответствии с уроном снаряда. Но на сервере помечается зона вокруг пробития. При попадании в эту зону урон наносится в размере 50%(?) от урона снаряда. Возможно поджигание масла и топлива в трансмиссии, баках. Подрыв БК. Уничтожение членов экипажа. И т.д. Не нужно создавать 300-400 танков как у картошки. Все внимание уделяется компонентам и изменению геометрии танка.
  • Физика будет ближе к War Thunder. Чем сложнее деталь, сложнее сплав, методы создания (сплав, штамповка, расскатка)- тем дороже её создание и ремонт(10% от стоимости). Поэтому будет какой-то баланс. Слишком крутой танк будет дороже в эксплуатации. Сами же игроки и будут искать оптимальный вариант. Покупка слотов, т.о. можно будет создавать много конструкций. Полигон будет доступен в премиум аккаунте. Доступ характеризуется Классом (категория) игрока. Можно ввести звание. Балансить технику можно по стоимости компонентов. Хотя будет забавно, если очень дорогой танк будет откровенной шляпой и сдуется сразу. Но на это есть разум самого игрока. Получается, что игрок 10 уровня будет биться с игроком 1 уровня. Но танки у них буду стоить одинаково. Но у танка чуть-чуть какие-то детали будут другие (экономия на размерах).
  • В Classic у танков есть своя цена, поэтому они могут конкурировать с определенным ценовым диапазоном.

2015.10.10

  • Добавлен скрипт на lua для создания гибких и сложных пакетов. Также добавлены классы для удобного доступа. IMarkUpContainer, TMarkUpContainer и TBasePacket. Описание структуры пакета хранится в xml-файле.
  • ВАЖНО! ИДЕЯ ИГРЫ СФОРМИРОВАНА. ЦЕЛЬ ИЗВЕСТНА - ИДЕМ ДО ПОСЛЕДНЕГО.

2015.09.12

  • Для обмена данными между потоками все готово. Добавил: методы CallBackModuleParam. Применяется: создаем данные для добавления объекта и указываем какую функцию вызвать и передать в качестве параметра созданные данные. После вызова в потоке (например Граифики или Физики), созданные данные уничтожаются. Очередность создания/уничтожения/изменения для каждого компонента строгая. Поэтому коллизий не должно возникнуть. Единственное что может возникнуть: например Логика дала команду для создания объекта в Физику и Графику. До физики данная команда дошла раньше и объект создался. После создания прошло время и объект поменял свои координаты - нужно переслать информацию о координатах в Графику. Команда передается от Физики к Графике - а в Графики еще объекта нет. Поэтому либо Графика должно инициализировать процедуру обновления координат(это медленно), либо Графика должна отложить команду о новых координатах и применить её потом(лучшее решение).

2015.07.19

  • Шарнир я описал, осталось описать форму физического тела.

2015.06.21

  • Начал дорабатывать XML формат игровой модели. Описал общую структуру (Version 0.5). Осталось описать свойства шарнира, соединяющего части между собой, и свойства физических тел. В общем задачи следующие:
  1. Узнать как описываются и какие свойства имеют шарниры (в понятиях Bullet это Constraint).
  2. Какие свойства имеют физические тела.
  3. Как загружать тела произвольной формы. В Bullet это ConvexHull Shape.

2015.06.07

  • Возникла проблемка: если у графического движка возникало событие закрытия окна, то это событие тут же уходило в игровой движок и происходило закрытие приложения. В логике происходила попытка освободить ресурсы, которые должны были быть освобождены графическим двжиком. Долго думал как решить эту проблему, и вот что вышло: дополнить те модули, что требуют освободить ресурсы (графика, физика(может быть?)) CallBack функциями, вызываемыми в StopEvent.

2015.05.03

  • Все что писал про это баг - неправда. На самом деле это возникает из-за того, что в SynchroPoint у каждого списка есть мьютекс. Из-за этого и возникает блокировка потоков.
  • Придумал какой-то интерфейс для физики. Думал, а что если физика закончила цикл работы, то как она сможет делиться с логикой результатами своей работы? Пакетами? Неее, не вариант. Все в пакет не засунешь, а если брать квант времени физики, то слишком долго. Можно сделать коллбэк функцию события окончания работы. Но тогда уж для всех модулей предусмотреть.

2015.04.21

  • Если модуль не нагружен и отдает управление в поток тут же, то нагрузка на процессор всего ~50%, но если нагрузка есть (физика, графика), то КПД ~= 100%, поначалу это был баг, но я думаю скорее фича. Подстраиваемый под нагрузку движок.

2015.04.18

  • Баг: если в синхро-точке оставались пакеты, то при уничтожении игрового движка происходило падение, потому что пакеты были созданы в Dll разработчика, а т.к. Dll уничтожается когда движок прекращает работать, то и указатели на пакеты были мусорными. То есть нужно уничтожать синхро-точку до освобождения Dll.

2015.04.03

  • Клиент не смог принимать новые соединения. Решил эту проблему путем закрытия и удаления Acceptor-а. Далее заново открывать и настраивать TCP_Up, потом настроить Acceptor. Решил проблему транспорта, но теперь если произошло разъединение с верхстоящим транспортом, то на момент попытки соединиться транспорт теряет функцию приема соединений снизу. Интервал времени мал, но нужно это учитывать. То есть, если транспорт выступает в роли Клиента (только если повторно), то перестает быть сервером.
  • Следующим этапом будет сборка под Ubuntu всего проекта.

2015.04.02

  • Вчера нашлась очень неприятная проблема на клиенте, точнее сетевом транспорте. Когда идет сценарий авторизации клиента в систему, по сценарию происходит разрыв соединения по инициативе мастера. Клиент пытается присоединиться к Slave, но порт, с которого он соединяется другой (не тот что открыли). Этот порт выбирается из незанятых (58000-64000). НО если Slave будет отправлять клиенту пакеты по UDP, то клиент не получит пакет, потому что порт другой (тот что был при открытии). То есть есть два порта для TCP (59999) и UDP (1234). Slave получает информацию о порте TCP. Порт для UDP для Slave такой же. Проблема еще в том что под Ubuntu нельзя открывать TCP_up позже чем Acceptor. Сделал так: в Disconnect TCP_Up.reset(NULL), а потом в Connect заново создал и открыл порт. Такое прокатывает под виндой, а вот под Ubuntu думаю не прокатит. Надо проверяться. Сделал так что и под Ubuntu все работает. Но надо проверить будет ли клиент принимать новые соединения (работает ли Acceptor).

2015.03.28

  • Доделал движок. Логика отправляет модулям адрес функций (через TCallBackRegistrator) для вызова из потока модуля. Вот как делать вызовы из формочек MyGUI?

2015.03.27

  • Boost видите ли запрещает копирование сигналов! поэтому нельзя его использовать для копирования TCallBackRegistrator :(

2015.03.24

  • Не сделаю. К центра(Логика) идут классические пакеты, к периферии идут указатели на TCallBackRegistrator для вызова методов из других потоков, но для этого нужно хранить указатели на модули в логике и переделать пару TSynchroPoint+TSynchroAbonent. В описании конвейера для игрового движка нет теперь необходимости описывать кто кому пересылает события.

2015.03.23

  • Сделаю пакеты для работы с таймером. 3 пакета Start, Kill, TimeOut.

2015.03.22

  • Под виндой обнаружилась одна неприятная особенность: объект-поток из области памяти игрового движка вызывает Work модуля (библиотека разработчика). Если будет 2 и более потоков, то процессор с двумя ядрами используется не на 100%, а на 50%, такое ощущение что есть дверь между движком и разработчиком и эти два потока пытаются втиснуться туда (войдя в область памяти разработчика, поток должен вернуться обратно). Так как потоки молотят с малой нагрузкой в Work, то коллизии происходят постоянно. Одно из решений - нужно прописать прототип потока в движке и реализовать его в библиотеке разработчика. Решил забить на эту проблему, потому как: если Work внутри нагружена, то нагрузка поднимется до 100%. Видимо баг будет фичей, адаптивный характер движка. Как только используется больше кванта времени в Work, то процессор начинает использоваться на все 100%.

2015.03.21

  • Только 9 модулей будут переопределяемыми (Активные модули):

    ServerLogicSlave, ServerLogicMaster, ServerLogicSuperServer, PhysicEngineClient, PhysicEngineSlave, AloneGUISlave, AloneGUIMaster, AloneGUISuperServer, GraphicEngine.

    Как общаются модули: id_sender - от какого модуля type - тип пакета модуля sub_type - тип пакета протокола разработчика для данного модуля Input(id_sender) id_sender == MMO HandleMMO(type) type == message HandleMessage(sup_type) sub_type == text_message или coord_object

    У Клиента должно быть ядро для управления модулями. От него уходят пакеты для конкретного модуля. Ядро зарегистрировано на получения событий ото всех компонентов. У Сервера точно так же. Протоколы взаимодействия Сервера с Клиентом так же находятся в Ядре.

2015.03.18

  • Смотрел отзывы об MySQL, PostgreSQL. Положительных отзывов больше о PostgreSQL. Он поддерживает больше стандартов, более надежен. Есть libpqxx и libpq++ для связи с БД с помощью C++.

2015.03.17

  • Вчера второй раз ездил на машине. Пока на автодроме. Учусь играться сцеплением для лучшего контроля скорости. Разхерачил библиотеку разработчика. Ядро я доделал. Осталось проверить как оно работает.

2015.03.13

  • Начал переделывать ядро под многопоточную модель. Есть потоки с модулями, а что делать с потоком ядра? Куда его девать?

2015.03.09

  • Доделал GE_Impl, но осталось сделать класс для удобного использования скелетона. Есть проблема: если создать форму MyGUI после создания GE_Impl, то позиция формы та, что была в дизайнере, но не в соответствии с выравниванием.

2015.03.06

  • Для настройки конвейера ядра игры думаю использовать Conveyer.xml (задает DevTool).

2015.02.22

  • Пишется сам Грфический движок (надстройка), тестируется в OGRE_Tech. Все вполне удобно. Интерфейс я прописал, осталось проследить как будет выполняться конвейер GE.

2015.02.08

  • Работа адаптера: 1.Input, 2.Work, 3.Output. Многопоточный движок (обобщение):{Thread1 {Adapters},..., ThreadN {Adapters}}. GraphicEngine - единственный модуль, который имеет несколько частей - каждая отвечает за работу под разными операционными системами. Все остальные движки не требуется адаптировать под разные ОС.

2015.02.07

  • Проблема первая: как загружать ресурсы. В первом (MyGUI) и втором (pure OGRE) случае по-разному. Найти общее и вставить в класс GE. Библиотека разработчика загружает Resources.xml и далее, пробегаясь по всем адаптерам, настраивает пути ресурсов.

2015.02.02

  • Начал описывать интерфейс графического движка. Для его реализации все есть: класс, в котором работает MyGUI (уже есть в примере работы самого MyGUI) и класс примера работы OGRE. Надо только их соединить, выкинуть события клавиатуры и мыши наружу (только те, что не были использованы GUI) и вуаля! Потом научиться добавлять и изменять характеристики объекта сцены.

2015.01.22

  • TBaseGamePacket - базовый пакет в ShareDev.dll. Указывается ushort type, по нему определяется тип пакета. Но это должно быть в Dev lib. В адаптаре графики создан интерфейс для 3 типов пакетов и доступа к OGRE.

2015.01.21

Пока начну с проекта /test/OGRE_Tech. Потом перенесу созданные файлы в Developer. Поначалу даже не знаю с чего начать. Должен быть класс, в котором можно будет добавить скелетон в сцену и менять параметры этого скелетона, удалить из сцены. Есть объект 1 уровня, он говорит какого типа: Add, Change, Remove. Внутри него храниться описание (2 уровень). Для Add структура дана полностью. Add: unsigned int mID_Object, unsigned int mID_Model, TObjectProperty mObjP, TModelProperty mModelP Change: unsigned int mID_Object, TObjectProperty mObjP, TModelProperty mModelP Remove: unsigned int mID_Object То есть вырисовывается 1 структура для первого уровня и 3 структуры для второго уровня. Также 2 структуры: описание игровых модели и объекта.

2015.01.04

  • Возникла идея много-поточности ядра: с применением точки синхронизации, но для этого пришлось бы полностью переделать ядро и библиотеку разработчика. Думаю эта идея преждевременна. Сначало нужно доделать одно-поточную модель ядра. А потом переделать. Пока между делом доделаю SynchroPoint-SynchroAbonent.

2014.12.24

  • Требования к графическому движку:

    1. Поддержка MyGUI.
    2. Загрузка скелетона.
    3. Манипуляции со скелетоном ( + возможность сериализации).
    4. Горячая и холодная загрузка моделей.
  • Что выливается во вполне конкретные пункты:

    1. Загружаю модель танка из XML, вращаю башней в реальном времени (с помощью форм MyGUI),

2014.12.18

  • Добавил Стресс тест ММО движка. Поймал баг: забыл unlock в Recv поставить перед return. Стресс тест - это постоянный процесс логина и выхода из системы клиента.

2014.12.05

  • Добавил CallBackRegistrator без использования boost, только с помощью stl.

2014.11.17

Тестил CMarkup под Ubuntu, все работает. Видимо, глючило только под МСВС. BD So T Ne Gr Ph

2014.10.08 Поправил глюк TConatinerRise, при вызове Realloc при старом размере равным нулю не происходило выделение памяти. Задачи на октябрь:

  1. Тест CMarkUp под Ubuntu.
  2. Сборка всего проекта под Ubuntu.
  3. Центр синхронизации OGRE-Bullet-OpenAL

2014.09.24

  • Почему-то под Ubuntu не всегда удается сделать TCP::bind(). acceptor::set_option(reuse) не отрабатывает. Еще выяснилось, что происходит вызов Disactivate сценария, хотя активного сценария нет.

2014.09.17

  • Реорганизовал файловую структуру проекта, теперь есть отдельная папка Resources. Сам проект содержит только исходный код, документацию и тесты.

2014.09.02

  • Тестил MMO, под Windows XP 1Гб - 156 соединений, а для Windows 7 8Гб - 1170 соединений. Отладил кучу багов.

2014.08.29

  • Думаю MD5(LP) заменить на Login, а SHA256(LP) заменить на Password. Это позволит избежать коллизий MD5 и SHA256. Тогда будет Login( ip, port, subNet, pLogin, sizeLogin, pPassword, sizePassword) ConnectUp(ip, port, bp, subNet, pLogin, sizeLogin, pPassword, sizePassword) Теоретики хреновы. Их метод не подходит. Он не учитывает разделения на уровни: транспорт и сущность, знающая о БД.

2014.08.26

  • Добавил функцию конвертации utf-8 -> cp1251. DemoKeeper из MyGUI совершенно не подходит.

2014.08.25

  • DXUT умер. Да здравствует, DXUT! Запустил MyGUI, но пока только в одном потоке, правда. Осталось разобраться с ресурсами (настроить расположение, продумать названия папок). Выложусь на GitHub.

2014.08.23

  • Цель на данный момент - запуск клиента с окном MyGUI.

2014.08.22

  • Начал осваивать OGRE. Все для этого подготовлено. Ядро переделал. Mingun, спасибо за инвайт!

    Lair не прав на счет надежности ММО. Эта задача не ММО. За надежность должен отвечать кто-то другой. А именно - физически организованный кластер (например, пара компьютеров). Нельзя на одну сущность возлагать сразу несколько задач.

    Нашел недоработку. Если создать два объекта (например Slave и Client) в одном процессе, то статический объект в транспорте будет замещен и первый объект будет пользоваться транспортом второго. Исправил.

    Только сейчас начинается работа над движком. Связка OGRE c Bullet-ом. Многострадальное ядро, которое я уже 5-й раз правлю.

2014.08.19

  • При таком подходе достичь главной цели - Игра, будет невозможно. Надо постепенно идти к плану Прототип-Адаптер-Модуль. Пускай пока будет прямой доступ к ОГРУ и Буллет у разработчика. Главное что делать с синхронизацией общих объектов (блин, вот почему я назвал IBaseObjectCommon). Это самая главная проблема над данный момент. Physic-Graphic-Sound синхронизация.

2014.08.15

  • На сайте приняли только статью о ММО. Думаю дальше написать LoadSaveModel.dll, в котором будет загрузка моделей. Перенести из ядра и Share.dll. Далее AdapterGraphicEngine_OGRE.dll. Потом AdapterPhysicEngine_Bullet.dll.

2014.08.11

  • В общем все работает. Далее - коррекция описания в EA ядра. Потом хочу написать статью в Хабрахабр. Думаю написать 2 статьи. О ММО движке и игровом движке. Все таки у меня больше гордости вызывает сетевой движок, там я написал полную документацию, кроссплатформенность и большие возможности. Сам же игровой движок у меня особо не вызывает восторгов.

2014.08.07

  • Проверил Qt и MMO для серверов. Работает. Осталось проверить MMO для клиента, графику и MyGUI. MyGUI отрабатывает.

2014.08.06

  • Скомпилировал и запустил. Правда, все упало. Но это уже близко в финальному виду.

2014.08.01

  • Prototype<----Adapter<>----Module Загрузкой ресурсов должно заниматься Ядро. Графика должна отображать, Физика просчитывать взаимодействия.

2014.07.31

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

2014.07.30

  • Возникает проблема привязки к MyGUI: если из графического движка выкинуть поддержку MyGUI - разработчику придется переписывать все что он написал под другой GUI. Как способ решения этой проблемы (и не только этой, но и еще и Qt) - дать разработчику реализовать интерфейс GUI для графического движка самостоятельно. Или как вариант указывать графическому движку какой GUI использовать.

2014.07.29

  • NetTransport является вспомогательной частью MMOEngine. Сам TNetTransport должен находиться в модулях. А INetTransport - в адаптерах.

2014.07.25

  • Ядро новое готово, осталось проблему решить с Адаптерами. А именно: непонятно почему появляется зависимость Графического движка от Камеры и GUI. Что, может быть, вполне логично. Но как это должно выглядеть в конечном итоге?

2014.07.23

  • Придумал как избавиться от различий между Клиентом и Сервером в ядре. Теперь есть только одна сущность. Ядро имеет pure virtual методы и IDevTool.
  • virtual int AdapaterBaseModule::GetModuleID() = 0;

2014.07.21

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

2014.07.15

  • Ядро пишется в AE. Основные механизмы описаны. Все вроде в норме. Надо еще описать как происходит запуск и работа ядра.

2014.07.14

  • Придумал идею механизма "почкования". То есть можно будет обойтись без создания объекта модуля, а запросить экземпляр модуля у самого модуля.
  • virtual AdapaterBaseModule* NewExample() = 0;
  • virtual void DeleteExample(AdapaterBaseModule* ptr) = 0;

2014.07.11

  • Разработка концепции ядра идет полным ходом. Исправил глюк в MMOEngine (сценарий авторизации клиента при попытке соединиться с мастером отсылал пустой эхо пакет, что противоречило системе поиска хака) и MathTools (умножение матриц было напрямую через pOut, а нужно было через временную переменную).

2014.06.14

  • Убрал зависимость от Directx функций из ShareLib. Часть переписал сам, часть взял из исходников Wine.

2014.04.21

  • Мастер оценивает безопасность сессии с Клиентом, а вот при коннекте Клиента со Slave - нет. Поэтому требуется доделать сценарии Авторизации Клиента и Перекоммутации Клиента с учетом этих правок. Также добавлена возможность проверки сессии SuperServer-ом и Мастером - метод IsSessionSecurity перемещен из TMaster в TBaseServer.

2014.03.27

  • Сформировать фронт работ для определения ServerCore.dll в качестве модуля. Соответственно должен быть интерфейс для данного модуля. Вот одна из основных проблем: когда Клиент хочет вступить в бой - он отсылает запрос Slave. Тот в свою очередь транслирует этот запрос мастеру. Мастер принимает решение сгруппировать Клиентов. Существует два варианта развития событий:

    1. Клиент переходит на другой Slave
    2. Клиент остается на том же Slave.

В незавимости от варианта далее Slave передает событие создания группы разработчику и тот в свою очередь формирует на сервере группу для проведения боя (Комната, Сцена). Предположим один из клиентов не захочет дожидаться окончания боя и выйдет из MMO-группы. ММО движок исключит его из группы, а вот серверная реализация не должна этого делать. Серверная часть хранит образы Клиентов, по которым она можно сделать запись в БД или оповестить о событиях. Потом клиент захочет зайти в новый бой. Его могут переместить на другой Slave или оставить на старом. Создаться новая ММО-группа и он попадет в новую Комнату на сервере. Физическая составляющая и БД должны быть представлены лишь интерфейсами (Фасад библиотеки). Так будет проще. Далее встает вопрос создавать ли отдельный модуль ServerLib?

2014.03.25

  • Скорректировать правильные английские названия. Common - общественный, публичный, а вот General - общий, общего характера. То есть IBaseObjectCommon => IBaseObjectGeneral и т.д.

2014.01.20

  • Все готово.

2014.01.14

  • Пока реализовал на стороне Клиента в сценарии алгоритм. Завтра сделаю Серверную часть.

2014.01.13

  • На хрен X.509. Нашел способ решения проблемы MITM. Но для её решения нужно чтобы была запись о клиенте в БД. Алгоритм:

    1. Клиент отсылает Серверу RSA public key. В ответ AES ключ. Все как обычно.
    2. Сценарий Авторизации: Клиент отсылает MD5(LoginPassword), AES(RSA public key). AES зашифрован ключом SHA1(LoginPassword). MD5(LoginPassword) нужен для поиска записи о Клиенте в БД.

    То есть для реализации алгоритма всего то надо добавить дополнительную функцию в Сценарий и новый ответ Сервера IsSessionSecurity.

    1. RSA
    2. MD5(LP), AES(RSA), key for AES is SHA1(LP)

2014.01.10

  • Прочитал тут про атаку man-in-the-middle. А ведь моя реализация уязвима. Как вариант решения данной проблемы - сертификация сообщений RSA public key. А точнее X.509.

2013.12.21

  • Проблема утечки памяти. Не зависит от объема трафика, но зависит от кол-ва пересланных пакетов. Растет 1 Мб на одно соединение (каждые 100 мс) за 5 минут на Slave. На Клиенте поменьше в 2-3 раза. Решено. Надо было Clean для AES после каждого шифрования.

2013.12.18

  • Перекоммутация завершена! Осталось провести тесты, когда Дисконнект любого компонента может произойти в любой момент. И потом можно даже на GitHub выложить.

2013.12.16

  • Существует две стороны вопроса о безопасности:
    1. Безопасность Клиента. Что бы нельзя было украсть данные и чтобы нельзя было перехватить управление.
    2. Безопасность Сервера. Что бы нельзя было уронить Сервер и запороть работу Сервера. Первая проблема успешно решена. Используется RSA и AES. Вторая проблему несколько шире. Во-первых, можно использовать исходный код Клиента и отправлять некорректные пакеты (проблема Взломанного Клиента). Во-вторых, пакеты, которые летают между компонентами Сервера, можно перехватывать, подменять, менять. Проблема Взломанного Клиента решается просто: проверять размер и корректность пакетов Клиента в каждом сценарии отдельно. Вторая проблема решается невозможностью подмены пакетов. Вставка в начало пакета до шифрования счетчика, который увеличивается при отправке. На той стороне контролируют корректность пакета по этому счетчику. Таким образом отправить повторно зашифрованный пакет не получится. Либо его не дешифруют, либо счетчик не подойдет. Далее еще один момент Флаг использования шифрования - действует на всю систему в целом. Либо он используется и везде в Клиенте, Мастере и т.д. либо нигде. Шифруется только TCP. Передавать данные по UDP и пытаться их шифровать - глупо. Управляющие команды по UDP не передают. НО есть такой сценарий как ScenarioFlow. В нем используется как TCP, так и UDP. В остальных сценариях используется только TCP.

2013.12.14

  • Сделал шифрование. Теперь никто не сможет:
    1. Узнать какими данными обмениваются участники MMO. +
    2. Подменять данные своими (фактически получить управление). +
    3. Уронить сервер. ??? Но не обошлось и без проблем: генерация ключа для RSA очень интересный процесс. Скорость создания ключа варьируется от 200 мс до 7-8 секунд. Таким образом задержка коннекта Клиента к Slave может быть разной. Иногда у Мастера таймаут может закончиться. Решение: создание RSA ключа во время запуска приложения. RSA ключ один на весь Менеджер ManagerContextCrypt.

2013.12.12

  • Как в TCP определить наачало и конец пакета? Ведь если прописать в пакете в начале размер и зашифровать, то можно подменить размер и тогда транспорт не только потеряет этот пакет, но и вообще потеряет связь.

2013.12.11

  • Технология RSA и AES из openSSL освоена. Замеры скорости шифрования в doc. Вот как это будет:
  1. Этап обмена ключами. На уровне транспорта при попытке соединения происходит генерация RSA ключа (Клиент). Потом Клиент отсылает в открытом виде публичный ключик Серверу. Сервер генерирует AES ключ и шифрует его публичным ключом RSA Клиента и отсылает Клиенту. Клиент дешифрует пакет и теперь ключи AES есть у обоих.
  2. Обмен пакетами, шифрованными с помощью AES. Т.к. AES не скажет была ли попытка подмены, то пакет должен быть дополнен MD5 суммой. То есть sizePacket + 16 байт. Осталось дооформить замеры и написать классы, реализующие RSA, AES и MD5 для удобства.

2013.11.29

  • Добавил поверхность в устройство с помощью SetDepthStencilSurface. И проблема решилась.

2013.11.27

  • Глюк при отрисовке на видеокарте GeForce 7600 GS, как будто части отрисовываются без применения теста Z буфера. Хотя на встроенных Intel-вских картах и Radeon все отрисовывается изумительно.

2013.11.25

  • Правил глюки. Доделал сценарий авторизации Клиента с учетом если Клиент не успел подконнектиться.
  • Остался только сценарий Перекоммутации Клиента сделать и все.

2013.11.23

  • В движке сделал фокус (управляю танком с сервера на клиенте), думаю всем понравиться. Не очень понравилось. Ну, если я физику сделаю и им не понравится, это будет уж слишком.
  • Сделал сценарий рассылки списку Клиентов пакета из любой точки системы (SendByClientKey).

2013.11.15

Для завершения работ над MMOEngine нужно: I Реализовать класс статистики по Клиентам, которые находятся в группе и существуют в системе, поместить этого класса в: AddSlave, DeleteSlave, AddClient, DeleteClient, CreateGroup, LeaveGroup, DestroyGroup. + II 1. Обмен для клиентов при формировании Группы на конкретном Slave производится таким образом: если Клиент Группы находится не на своём Slave, то он перекоммутируется, а какой-то другой Клиент, который находится на целевом Slave, копируется туда, где находился Групповой Клиент. То есть производится обмен, что бы нагрузка была неизменна. Если там нет Клиентов, то не копируется. 2. Обмен производится для Клиентов не состоящих в Группе только если: - контекст Клиента не занят в выполнении сценария перекоммутации. 3. Поиск Slave, на котором будет находится Группа надо производить по минимуму занятых в Группе Клиентам (см. TStatisticaClientInGroup ). III Доделать сценарии SendToClient и RecommutationClient (он должен быть реализован примерно так же как и LoginClient). В этих сценариях не хватает определения что Клиент не успел подконнектиться к Slave.

2013.11.14

  • Оживил Конвертер Меш. При загрузке Клиента Танков загружается Ангар и Тигр II.

2013.11.12

  • Доделал сценарии DisconnectClient для Клиента и Slave. Сценарий LoginClient доделал с учетом надежности (например что делать при дисконнектах на любой стадии сценария). Осталось перекоммутация и проверка в интернете.

2013.11.08

  • LoginClient готов! Осталось проработать варианты обрыва связи на разных этапах выполнения сценария. Потом доделать сценарии Дисконнекта клиента. И останется только перекоммутация клиента и все, движок ММО закончен! И еще, надо протестировать в интернете авторизацию клиента.

2013.11.07

  • Отладка багов работы сценариев. Подкручиваю болты.

2013.10.30

  • Косметические изменения в проекте. Изменил типы модулей с lib на dll, поменял имена с неосмысленных Melissa на MMOEngine и т.д.

2013.10.26

  • Идея поместить в ScenarioLoginClient 4 части: Client, Slave, Master и SuperServer, каждая из которых отвечает за обработку пакетов, предназначенных, соответственно, тезкам. Есть базовый класс, от которого наследуются эти классы, в нем должны быть определены все пакеты, а базовый пакет должен быть в ScenarioLoginClient, в нем появляется поле char where, то есть кому предназначен пакет, т.о. ScenarioLoginClient определяет по нему какой из частей отдать пакет. Далее внутри контекста опять таки должно быть 4 части (C,S,M,SS). Данное решение имеет своей целью лишь повышение читабельности кода и понижение сложности класса ScenarioLoginClient.

2013.10.10

  • Переделываю ScenarioLoginClient, с учетом добавление в очередь ожидания клиента, если нет места на серверах.

2013.10.09

  • Привести в соответствие сценарий LoginClient. ScenarioLoginClient->ColdMaster->HotMaster->Accept или Reject Accept -> Queue или Accept (в зависимости от нагрузки серверов) -> Context->ScenarioLoginClient Проект на Github.com :). Надеюсь, кому-то проект понравится. Но лучше все писать на английском, по крайней мере перевести.

2013.10.07

  • Доделан Таймер. Поправил ядро с учетом Таймера. Убрал Refresh за ненадобностью. Ладно, доделываю LoginClient. Самый тяжелый сценарий, еще тяжелее будет перекоммутация, но это фактически 90% всей работы.

2013.10.03

  • Доделать модуль "Таймер"!!!

2013.09.27

  • Все довожу до ума QtLib. Сделал вызов кванта времени из потока Qt для функции. Теперь когда нужно что-то изменить в форме, просто вызвать с указанием функции и произвести изменения в потоке Qt в какой-то из функций.

2013.09.26

  • Добавил модуль QtLib, теперь для отладки можно использовать GUI. Вместо 3 функций использовать 5, заменить GetServerDeveloperTool на GetSlaveDeveloperTool, GetMasterDeveloperTool, GetSuperServerDeveloperTool. Завтра сделаю.

2013.09.24

  • Правлю ядро. Добавляю GUI в сервер. Появляется дублирование кода. Это дублирование надо потом свести в IGame. Хехе, fps для сервера то 10! Больше и не надо! Все равно данные обновляются не чаще.

2013.09.23

  • Вернулся из Турции 18 сентября, пишу только сейчас О_о. Есть реальная проблема для визуализации результатов работы движка. И сейчас она ощущается очень остро. Сначала сделаю отображение консоли, которая отображается по ключу -c. Потом хочу серваку привинтить GUI. GUI можно будет управлять непосредственно через DevTool, но модуль графики будет не таким каким он является в клиенте. В таком виде отладка Мелиссы будет эффективней, и работа над проектом будет идти быстрее.

2013.09.05

  • Кое-что о сценариях. Сценарий - модель, контекст сценария - данные. Сценарий это своего рода машина состояний, логика. Мне совершенно не нравится такой тесный симбиоз (слишком много контекстных функций вызывается внутри сценария). Надо бы часть этих вызовов объединять и вынести в функции контекста. Ну что бы было больше кода в самом контексте, меньше вызовов типа Context()->.

2013.08.30

Что бы сразу разобраться по сценариям: 1. Сначала была идея создания сценария для одной цели. То есть уровни, владеющие сценариями не знают о типах пакетов. Пакеты передаются объекту, который решает какому сценарию предназначен пакет. Далее сценарий решает что делать с пакетом. То есть возникает идея Контроля событий сценариев TControlScenario 2. Далее возникла сложность. Т.к. прием пакетов идет только в сценарии, то создание нового сценария, ассоциированного с данным соединением, невозможно. Возникла идея создания контекста сценария - IContextScenario. Т.о. сценарий существует всегда, он лишь является моделью поведения. А контекст это данные, с которыми работает сценарий. Эти данные привязаны к сессии(хотя могут быть привязаны к чему угодно). 3. Далее возникает проблема как различать активен ли сценарий? Например, перекоммутация клиента. Началась перекоммутация (сократим название - RCM). Контекст ей задан - это C1. Возникла задача объединения в группу, значит понадобилась еще одна RCM. Вызвали Begin, спросилил активен ли он. Как различить активность? Контекст тот же, сценарий тот же. Ведь вопрос активности может задать другое выполнение с тем же контекстом. Решение: bool Begin(IContextScenario* pCSc)

2013.08.29

  • Для сценариев решил переделать механизм обмена пакетами. Модель Self-To-Self, то есть один класс сценария передает данные тому же классу, т.о. владелец сценария не знает о типе пакета, а знает лишь какому сценарию предназначен пакет. Доделать контекст сценария, продумать.!!!!!!

2013.08.27

  • Вход Slave в состав кластера готов. Завтра надо будет сделать авторизацию клиента.

2013.08.14

  • BOOST_FOREACH нельзя работать с map и set, если нужно менять содержимое внутри. Проблема решена: использовать BOOST_FOREACH(TMapClass::value_type& bit, mMap) bit.second->Func();

2013.08.07

  • CPU x8 Xeon X5550HT 2666 MHz стоит 1600$, но это для многопроцессорных систем. Думаю Intel Core i7 (1000$ с 6 ядрами) хватит, 32 Гб памяти.

2013.08.06

  • С помощью boost asio под Windows XP максимальное кол-во соединений - 156, под Windows 7 - 500 (и это не предел). Перешел с async_connect на connect, теперь стало 220, но думаю дело не в этом, либо памяти мало либо ОС другую надо. Странно поведение CPU Intel Core2Duo E6400. Не тянет(до 100%) даже 100 UDP 1000 мс 1 пакет по 1350 байт, хотя Intel Core2Duo E8400 и Core2Duo E7400 тянут хоть 220, даже не напрягаясь (2-5%). И не понятно то ли дело в процессоре, то ли в ОС, то ли в объеме памяти. Дома то у меня Win7, 4 Гб и все тянет спокойно. В любом случае движок уже на что-то да способен.

    Будем считать что транспорт готов. Главное что бы комп держал 20 пакетов по 1350 байт с задержкой 100 мс на 500 клиентов (что эквивалентно 10000 клиентам на 1 пакет на 100 мс). Что для пакета в 1350 байт ооочень много, обычно пакет размером 100-200 байт(то есть запас в 10 раз, а это вообще 100 000 клиентов). "Держать" - значит нагрузка 10-20% от одного ядра. Что бы оставалось время на другие задачи. То есть для 4 ядерного процессора надо примерно 5% от общей нагрузки. Для сервера использовать CPU x8 Xeon X5550HT 2666 MHz (надо стоимость узнать).

2013.07.25

  • С вводом boost можно полностью отказаться от glib и GBaseLib. Сократит кол-во исходников, но в то же время будет жесткая завязка на boost.

2013.07.24

  • Boost использует Completion Port под Windows (очень мощная штука). Пока сделал транспорт на WSAWaitEvent, теперь добавлю транспорт, основанный на Boost(но старый транспорт оставлю). Использую Boost 1.54. Т.о. будет 3 вида транспорта (Boost, TCP_UDP(Win32) и UDP(Win32/Linux)).

2013.07.22

  • На фиг WSAPoll. С помощью потоков и событий ждать события от сокета. MainThread владеет hEvent, другие рабочие потоки сообщают с помощью SetEvent о получении пакета.

2013.07.19

  • Ха! В очередной раз охреневаю от MS. Есть такая функция WSAPoll, но она доступна с Windows Vista. Аналог poll, надо смотреть сколько можно сокетов отслеживать. Если будет достаточно много (хотя бы 500), то можно будет под Windows XP использовать многопоточную схему, а под Windows 7 WSAPoll.

2013.07.18

  • Вроде транспорт сделал, а сейчас гляжу - максимум то для функции WSAWaitForMultipleEvents сокетов равен 64. Под Windows XP это точно. Надо посмотреть как под Windows 7 и под Linux (poll). Как выход - либо опрос сокетов частями по 64 сокета, либо через RegisterWaitForSingleObject.

2013.07.11

  • Все таки решил использовать BulletPhysics.
  1. Код Bullet более качественнее. В Newton-е код сырой, хотя фич по отладке больше. То же самое что выбирать между мониторов с плохим качеством отображения, но с закрепленным на нем зонтиком, открывашкой для пива и ручкой на веревке, и качественным монитором, но без подставки. В движке главное качество кода и возможность для наращивания функционала, а в Newton эти возможности уже нарастили, но код сырой.
  2. Bullet используется в GTA 5, а это уже что-то да значит. Более шикарных аварий при столкновении автомобилей в играх я никогда не видел.
  3. Взгляд больше цепляется за Bullet, приятнее разбираться - скорее как бонус, не сильный аргумент.

2013.07.08

Менеджер сессий готов. Теперь надо найти общее между всеми сценариями и поместить в TBase.

2013.07.07

Проанализировал кучу сетевых движков, ни одного нормального. Во всех исходниках нет даже std::map, не то что Boost-а. RakNet вообще кидалово. Cloud за 100$ в месяц.

2013.07.04

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

2013.07.03

  • Поправил TNetTransport_UDP. Заменил TArrayObject на std::map. Код стал меньше и понятнее. Вдобавок я избавился от зависимости от GBaseLib. Этот класс можно будет использовать там, где нет TCP. Думаю завтра начну править серверный конвейер, сегодня спал с 23-00 до 6-20. Голова лучше соображает, чем вчера :). Мысля копится, думаю скоро разрожусь.

2013.07.02

  • Я на распутье. Дело в том, что в качестве Графического движка можно использовать кучу бесплатных движков. С физикой дела обстоят так же. MyGUI я уже использую. А вот сетевых движков нет. Либо они платные, либо кривые и бестолковые. Таким образом все что от меня требовалось, так это написать игровой и сетевой движок. Но графический движок написан. На данный момент нет такой необходимости в выборе между графическими движками. Самое главное сейчас доделать Сервер, Melissa и внедрить физику.
    1. Доделать серверный конвейер (тяжко, спать охота) с учетом назначения Slave, Master, SuperServer.
    2. Доделать Melissa. Тут вся проблема в критерии готовности библиотеки. Нет тестов для точного понимания того, что все готово. Балуюсь Newton и Bullet(хотя нужно другим заниматься!). Они конкуренты, надо бы еще раз скачать ODE (она мне в первый раз не понравилась).

2013.06.28

  • Делаю конвейер сервера, точнее Slave реализацию. Наконец-то сдал ИТОК. Спать охота, часто засыпаю, когда никого нет. Зато после сна часто возникают интересные идеи.

2013.06.21

  • Проблема решена. Все дело в том что надо было отслеживать готовность отправить пакет по возвращаемому значению функцией send. Пакеты не затирались, они не были отправлены. Готовность к сборке Melissa. Но сначала надо собрать каркас серверного конвейера. Это я не учел. На это может уйти до 2-3 недель. Тут надо учесть возможность использовать в разных воплощениях. Как только конвейер будет готов, можно будет делать внутренности Melissa.

2013.06.16

  • Сетевой транспорт готов. Но не обошлось и без проблем. Дело в том что, при малом размере буфера на прием при передаче данных по TCP пакеты перетираются свежими пакетами. Думаю проблема в использовании на localhost или в WSA. Пока это неважно. Оставляю проблему до 17 июня. А сейчас Melissa (СМО).

2013.06.14

  • Более того можно открывать один и тот же порт для listen и для connect. Надо использовать флаг reuse для сокета.

2013.06.09

  • Два последних дня был в прострации. Думаю подсознание перезагружалось.
  • Значит так: открывать один и тот же порт для TCP и UDP можно. connect под Windows работает с блокировкой. WSA_XXX может отслеживать события на Socket-ах. Осталось выяснить можно ли писать и читать в сокет из разных потоков.

2013.06.07

  • После долгого и нудного обдумывания прихожу к выводу что нужно строить транспорт на TCP/UDP. В TCP десятилетиями апробировались технологии управления трафиком. Поэтому изобретать велосипед не буду. Стоит лишь научиться управлять TCP таким образом что бы контролировать процесс и подстраивать его под свои нужды. На высоких скоростях отрабатывал "вдумчивый" TCP, а на низком трафике быстрый и без инерционный.

2013.06.03

  • Фактически транспорт готов

2013.05.07

  • Для переключения транспорта TNetTransport в быстрый режим надо прописать в свойствах проекта FAST_NET_TRANSPORT. Он выключит логирование, тем самым повысит скорость обработки пакетов.
  • Проблема нагруженности сервера при получении пакетов на высоких скоростях (более 100 Мбит/с). Не так критична, поэтому решаться должна после написания Melissa. Идеально для 100 Мбит 10 мс задержка и 150-250 пакетов в одной посылке (для NetDoser эта информация будет полезна).
  • Идея для Дозера: при попытке отправить решать больше ли пакет определенного размера. Если больше, то будить поток и отправлять с помощью него так, что бы не перегружать трафик и сервер. Если меньше то просто отправить.

2013.05.04

  • Требуется реорганизация Share и GBaseLib (сделать после Melissa):
    1. удалить неиспользуемые файлы.
    2. сделать прослойку между внешним пользователем и glib.
    3. переименовать библиотеки.
    4. переместить файлы в соответствующие библиотеки (Share<-->GBaseLib).
  • Доделать NET_Transport, Melissa и добавить DBLib (декабрь 2013).

2013.04.30

  • Разработка интерфейса Мелиссы закончена. Теперь надо удалить текущую Мелиссу из проекта и заменить на Melissa.dll и NET_Transport.dll.
  • По плану нужно релизовать абстрактные классы интерефейса.
  • Для Melissa все-таки придется использовать классическую схему, которую используют при разработке Qt. То есть вся иерархия классов не чисто абстрактная.

2013.02.28

  • Пока правлю транспорт. Систему массового обслуживания прежде надо разработать верхушку. Потом двигаться сверху в низ, выставить требования к интерфейсу транспорта. А не наоборот.

2013.02.23

  • Правлю транспорт. Проблема в том, что максимальный размер пакета по UDP 1,5к. Значит если потребуется отправить пакет большего размер, нужно будет использовать либо класс-дозатор (дробление пакета и сборка) либо TCP канал. Еще существует проблема эффективного использования канала: либо засорить его полностью (когда пакеты отправляются без ожидания отправки предыдущих пакетов), либо неэффективно использовать (ожидание отправки предыдущих пакетов). Эта проблема может иметь место как на сервере (чаще всего) так и на клиенте.

2013.02.13

  • Освоил кватернионы. Применил в камере вместо корректировки по нормали к Земле. Всего 2 строчки кода заменяют огромное кол-во формул и расчетов. Очень удобно.

2013.02.11

  • Делаю клиент-серверные отношения.

2013.02.08

  • Добавил в камеру привязку к объекту, перемещение свободной камеры с заданием скорости.

2013.02.07

  • Client знает о неком протоколе общения с абстракцией "сервер". Сервер-Slave о таком протоколе ничего не знает (требуется только переопределить чистые виртуальные методы).

2013.01.30

  • Читаю boost. Тут есть все, что нужно. Подумываю над внедрением технологии. Можно заменить TMapDual на boost::bimap, TStateMachine на boost::msm.

2013.01.29

  • Конечный автомат готов. Для мэппинга клавиатуры(системные события) и HotKey.
  • Гибкий контейнер готов. Нужен в будущем для упаковка пакетов прикладного уровня. в нем сначала нужно описать схему контейнера (задать вектор). Далее, получив доступ по имени к памяти, назначить содержимое. В случае изменения кол-ва полей вызвать Update().

2013.01.18

  • Составил План работ.
  • Сделал настройку путей к ресурсам движка (модули).

2013.01.16

  • Наконец-то работает LookAt у камеры. Теперь, задав вектор нормали к Земле, можно управлять Roll камеры.

2013.01.15

  • Основная проблема сейчас - непонятно поведение реализации класса TCamera. Нужно четкое определение. Думаю, лучше разделить на мелкие части с простым описанием и, комбинируя этими маленькими методами, реализовывать крупные.

2013.01.13

  • Сделать orient и учет координат и углов камеры. Учет больших изменений (list<>).

2013.01.11

  • Какие-то результаты по камере.

2013.01.09

  • Заменил все классы типа TMakerXXX на макрос.
  • Новогодний застой заканчивается. Все каникулы занимался поеданием еды, играми и ничего-неделаньем.
  • Пусть будет имя "TornadoEngine"

2012.12.27

  • Делаю камеру. Для этого надо подготовить классы матриц (оптимизация). Оптимизирую: по сути в памяти у DX и Struct3D одно и тоже. Это можно применить в операциях над классом. А вот преобразовывать из Struct3D в DX и наоборот придется что-то еще придумать.

2012.12.26

  • Добавил класс контроля за кол-вом создаваемых объектов одного класса. Теперь если нужно ограничить кол-во создаваемых объектов нужно пронаследоваться от TOnly_N_Object и указать в конструкторе макс. кол-во объектов и макросом NAME_CLASS прописать имя класса.
  • Перевожу GBaseLib, Share из Lib в Dll (надо так же и проект модулей конвертировать в Dll).
  • Потом нужно править архитектуру.

2012.12.25

  • Мысль назвать игровой движок FullMaster или Tornado. Танки - это всего лишь пример использования. Надо поправить заголовок файлов.

2012.12.22

  • Блин. Когда создавал проект MyGUIEngine это был Dll-проект. Потом я его переделал в Lib. А вот EditorFramework был изначально как Lib. Надо было не менять тип проекта, а создавать заново. В проекте прописать define MYGUI_BUILD_DLL и все.

2012.12.21

  • Исправил глюк с некорректным ResizeGUI. Дело в том что DXUT вызывает Reset до реального изменения размера окна. Мне кажется так и должно быть. Reset так и должен себя вести. Сырость DXUT в том что нет события "переход в из оконного режима в полно экранное и обратно".

2012.12.20

  • Доделал GUI. Столкнулся с одной проблемой, но решил ее. Дело вот в чем: если использовать статически скомпилированную библиотеку типа lib для Exe и DLL, то это будет два разных адресных пространства. Поэтому нужно компилировать MyGUI в виде DLL.
  • Есть одна недоделка - при переходе в full-screen происходит ResizeGUI, но когда обратно ResizeGUI не проходит.
  • Задача - глюк с Tools GUI, resize, Camera, конечный автомат,

2012.12.19

  • Встраиваю GUI.lib в проект. Структурировал solution.

2012.12.15

  • До сих пор делаю GUI. Все несколько сложнее чем казалось. Не хватает TManagerGUI. Static GetComponent.

2012.12.14

  • Тестовый пример собран. Заметил что обработка событий съедает львиную долю времени (до 12-15 мс) от кадра. Если вырубить обработку событий будет под 1000 fps.
  • Потрачу время на Wrapper_MyGUI_Export. Мне кажется в этом что-то есть. завтра буду доделывать внедрение MyGUI. Потом Камера.

2012.12.11

  • За два дня скомпилировал и слинковал MyGUI!
  • Все работает и не тормозит в отличии от CEGUI.
  • Осталось придумать как это внедрить в multiplayer.

2012.12.08

  • Вчера принял решение о переходе на MyGUI. Для освоения этой технологии необходимо:
    1. Собрать самостоятельно MyGUI_Engine.lib(dll). - от 1 недели до 1 месяца.
    2. Собрать Platform. - 1 неделя
    3. Собрать BaseManager (прослойка для работы с MyGUI). 1-2 дня
    4. Собрать пример для подтверждения того что владею технологией (демонстрация). 1-2 дня Заменять ли DXUT на MyGUI будет ясно на 2-3 этапе.
  • Данную версию считать свежей. Эксперименты здесь я пока не проводил. Ясно одно что настоящий костяк конвейера клиента останется нетронутым. Добавится лишь GUI.lib, ну или еще заменится ли DXUT на Platform.lib.
  • Архитектура точно будет известна после 2-3 этапа (как раз когда будет известно будет ли жив DXUT).

2012.12.07

  • Мысли:
  1. Камера должна быть в GameLib(Композиция). ICamera находится в Share. Звук и графика владеют как агрегацией камерой.
  2. У объекта три сущности - графика, физика и звук.
  • Пока разбираюсь с выбором GUI. На выбор: MyGUI, CEGUI, Antisphere, librock, GWEN, Janella(мать этих испанцев итить) и еще куча всякой хрени.

2012.11.29

  • Конвейер графического движка работает. Главный конвейер клиента тоже работает.

2012.11.28

  • Интерфейс GameLib.lib:
    1. Client-Оффлайн,
    2. Client-Онлайн,
    3. Slave-Master,
    4. Slave,
    5. Master,
    6. SuperServer.
  • путь к *.dll
  • Скомпилировал и слинковал :)
  • Начинаю делать DLL.

2012.11.27

  • Будет каркас у сервера. Разработчику надо будет переопределить методы сервера.

2012.11.26

  • Massive-Online - Система MasterServer-SlaveServer. Оптимизация. Распределение нагрузки и создание общей точки синхронизации. Задачи Master - 1. Первичная точка доступа при регистрации соединения с абонентами. 2. Распределение нагрузки среди Slave. 3. Поиск по запросу у MasterServer и SuperServer соединения с Клиентом по его нику. 4. Решения о синхронизации.
  • Муть с архитектурой. Пока GUI и GE доделаю. Совершенно не понятно что должно быть предоставлено разработчику и как все это реализовать.

2012.11.25

  • Типы игр: Local, Online, Massive-Online. К слову о Master-Server, Slave-Server и Client. Local - в одном процессе, остальные в разных потоках.

2012.11.23

  • См. Architecture v0.4.eap и Architecture Included Headers.eap.
  • Game.exe -a s/c -p client.dll --p start with param ip=0.0.0.0 port=1000 Т.е. Игровой движок один. параметры разные. Как то так:
 if(argv[1]=='s')
   new TClient
 else
   new TServer

2012.11.21

  • Нафиг Python. Пишется DLL. У нее три функции GetClientDeveloperTool(), GetServerDeveloperTool() и Done(IDeveloperTool*). Функции возвращают объекты, интерфейс которых определен в движке. IClientDeveloperTool и IServerDeveloperTool. Не понимаю смысла в использовании Python. Все пишется на C++. Просто необходимо обрабатывать события в данных объектах. Также Developer должен переопределить поведение объектов на сцене(наследуется от IBaseObjectGeneral) и способ их создания (IMakerObjectCommon). Тот объект, который активно участвует в сцене, наследуется от IActor. Далее для работы с GUI Developer наследуется от IGrahpicEngineGUI. В конструкторе вызывает Load(путь к XML). Далее Connect(компонент,событие,обработчик).
  • Далее мышь и клавиатура: у IClientDeveloperTool есть метод int ConvertKeyEvent2Value(...) и int ConvertMouseEvent2Value(...). Значение, полученное от этих функции подается на логический уровень. Механизм конечного автомата по значению найдет ключ. Данный ключ для обработки передается в обработчик этих ключей.

2012.11.12

  • Была идея создания TankLib(классы, которые характерны для игры танки), но считаю в этом необходимости нет. В идеале все пишется на Python и "превращается" в С++ классы в менеджере Компонентов. Но пока я не освоил эту технологию, буду все классы держать в GameLib (например, TMakerObject, метод NewByID_Behavior()). Потом уберу оттуда в Python.

2012.11.08

  • Для всех классов GUI DXUT сделать виртуальным деструктор.
  • Разобраться с технологией GUI DXUT.

2012.11.06

  • Qt+DXUT = R.I.P. Время на выполнение слишком велико. На WinXP 30 мс, а на Win7 200 мс (!!!). Но это для первого способа. Есть второй способ. Но это не исправит ситуации. Конвертации Qt->DXUT и наоборот слишком медленны. Виден только один способ - DXUT Native GUI. Но прежде надо продумать архитектуру с учетом источников событий. NET, GUI, LoadFromHDD, Key+Mouse и т.д. Есть модуль управления(МУ) движком игры. Он имеет определеный интерфейс, МУ берет настройки для конвертации внешних событий из файла в зависимости от внешнего воздействия. Надо проанализировать схему работы с DGUI, подумать над интерфейсом МУ и связи с MOC. Но завтра надо доделать ОПП.

2012.10.05

  • Возникла идея по симбиозу Qt и DirectX. Суть идеи (всего две, надо определить ту что быстрее):
  1. Берем буфер из DXUT вставляем его в QImage и отдаем на QWidget. Далее рендерим GUI с параметрами Alpha. - так думаю что будет медленнее.
  2. Рендерим элементы GUI и отдаем в DXUT. Там средствами DirectX происходит альфа-смешивание и окончательный рендер. Время выполнения:

2012.10.31

  • Переделка архитектуры. Идея: События генерирует Qt класс (точнее происходит перехват WinApi и отсылка в Qt обработчик, далее событие обрабатывается ManagerEvent). Т.о. стало возможным перехватывать и GUI события. В общем достаточно пронаследоваться не от Qt, а, например, от ругого GUI.

2012.10.04

  • Пытался научить движок делать объекты прозрачными. Не получилось сразу.Дело в том, что прозрачность разных объектов определяется порядком их построения. Рендер прозрачных нужно производить в самую последнюю очередь. Причем кол-во прозрачных объектов в движке ограничено (если больше выглядит не очень красиво). Проблема решается сортировкой по расстоянию от камеры. Но данная проблема не критична. Если понадобится - решу в будущем.

2012.10.02

  • Добавлено отображение фпс.

2012.10.01

  • Сделал Менеджер ресурсов. Осталось Довести до ума шейдерный стек и камеру. И движок будет закончен.

2012.09.27

  • Добавлена поддержка XML формата. Чтение, запись. Через CMarkup.
  • Перенаправил поток событий на Qt от DXUT.

2012.09.20

  • Умею вращать башней и двигать пушкой у танка.

2012.09.16

  • Болею, голова вообще не соображает. Потом Tree доделаю.
  • Модели в ВОТ зеркальные.

2012.09.10

  • Анимация: разделение объектов на чисто анимированные и "грязно".

2012.09.03

  • ЛОЛ в WOT XZ находятся внизу, а Y это стрелка уходит вдаль.

2012.08.31

  • Разбираюсь с матрицами. Думаю как сделать привязку частей модели друг к другу по-умолчанию.

2012.08.30

  • Перешел с формата *.obj на *.bj, убрал лишнюю загрузку текстур и компиляцию шейдеров и снизил время загрузки с 5 секунд до 73 мс. *.bj - бинарный формат хранения Mesh. BigJack формат.

2012.08.29

  • Перешел на DXUT. Теперь поток Qt работает в DXUT.
  • BigJack заработал. Дело было в том, что Subset в DrawSubset был равен 0, а должен быть равен 1.

2012.08.20

  • Улучшил TCallbackRegistrator, добавил std::set<...>.

2012.08.15

  • Почти запустил BigJack. Осталось доделать IBaseObjectDX::SetModel - установить матрицы.

2012.08.08

  • Оживил Клиента и Сервер. С новой архитектурой. (doc/Общая архитектура.EAP)
  • Версия v0.040

2012.08.07

  • Общая архитектура в Enterprise Architect.

2012.07.19

  • Консервация. Серьезные архитектурные изменения. Приводится в порядок модульная структура проекта. ITBaseObject, TanksLib.lib, TManagerGUI, TBaseGUI_DX.
  • Нашел простые редакторы моделей OBJ. По идее EditorModel пока не нужен.

2012.07.05

  • Добавлена возможность Qt + DirectX Qt4.5.0.
  • Консервация проекта с веткой на основе DXUT. Развитие ветки Qt+DX.

2012.06.14

  • Проект под лицензией GPL.
  • Melissa - транспорт, BigJack - графика, Robert - физика, Клиент(GUI) -- для лучшего понимания архитектуры
  • Основное положение для протокола: сервер на прикладном уровне управляет Клиентом и BigJack. Т.о. это как бы два прикладных протокола.

2012.06.11

  • Добавлен SelfTank, думаю о изменении интерфейса класса ManagerDirectX.

2012.05.21

  • Вчера скачал программку для конвертации из primitives в x формат.
  • Загрузчик надо переделать под этот формат. Теперь надо нарисовать хотя бы танк.
  • 3D Object Converter
  • Конвертируем из primitives в *.obj (WaveFront). Далее используем для помещения в Mesh класс
  • Порядок действий при конвертации:
    1. Загрузка модели.
    2. Options->Export->WaveFront поставить галочку Export Vertex Normals
    3. Tools->Flip Scene UV Map Vertically.
    4. Save as WaveFront.
    5. Подправить *.mtl и привести примерно к такому виду: newmtl Material_1 Ka 0.4 0.4 0.4 Kd 0.587609 0.587609 0.587609 Ks 0.171744 0.171744 0.171744 illum 5 Ns 8.000000 map_Kd PzVl_Tiger_I.dds
  • Консервация проекта.

2012.05.18

  • Заработал графический движок. Нарисовал первый объект :)

2012.05.17

  • Работа над Editor. Загрузка данных из ini-файлов.

2012.05.14

  • Добавлен EditorModel.

2012.05.11

  • Работа над ModelDX, ManagerModelDX.

2012.05.10

  • Обнаружил странный глюк в Visual Studio 2008: иногда сервер может падать из-за того что CRT обнаруживает запись в память после закрытия сервера. В ~TGarage(). Помогает ребилд проекта.

2012.05.09

  • Доделал транспорт(все тесты проходит). Думаю над графикой.

2012.05.05

  • Доработка TRoom.

2012.05.03

  • Логирование DirectX.
  • Кольцо работает. DirectX и транспорт обмениваются данными.
  • Подвод данных к комнате.
  • Отсылка запроса корректирующего пакета.

2012.05.02

  • Угу, лучше.

2012.05.01

  • Отдыхал. Не мог даже смотреть на проект. Похоже, что на работе рабочее место лучше. Определенно лучше.

2012.04.28

  • Реализовал TA_In_Fight. Этот класс готов для масштабирования.

2012.04.22

  • Мучаюсь с TA_In_Fight. Разная длина sNick и cnt Tank.

2012.04.21

  • Вставить время в Queue.

2012.04.20

  • Появился ManagerGUI. Он управляет окнами клиента. Также управляет загрузкой компонентов для проведения боя и обрабатывает ответы от сервера.

2012.04.19

  • Проверка ClientMain +
  • Проверка GameRoomPrepare +
  • Проверка WaitForm +

2012.04.18

  • Корректирующий пакет отправляется группой не более 5-10 событий в пакете. Пакеты помещаются в TransportMain в независимости от кол-ва пакетов.
  • Придумал как будут взаимодействовать потоки DX и Transport Main при обмене корректирующих пакетов и стрима.
  • Будут меняться непосредственно параметры объектов MultiThreadQueue.

2012.04.17

  • Переделываю протокол общения Клиент-Сервер с учетом графа сценария поведения. Я думаю это дня на 2-3.
  • Установка Git. Это предложение тест для него. Пока работает. Но муть полная. Думаю, можно привыкнуть.

2012.04.15

  • Симбиоз DirectX и Qt4 для графики - там все просто TBaseDirectX с функциями отрисовки и событий.

2012.04.14

  • Начал реализацию архитектуры на основе DirectX

2012.04.12

  • DXUT + DirectX + Qt4

2012.01.25

  • Обратный отсчет перед боем на сервере.
  • Обратный отсчет перед боем на клиенте.

2012.01.21

  • Думаю над зонами и картами, физикой и боем. Это все надо как-то увязать.

2012.01.19

  • Стрим для начала боя

2012.01.18

  • Форма ожидания боя и запрос на бой.
  • Запрос на бой обработан и сформирована команда.
  • Зачатки балансера.

2012.01.17

  • Выбор танка в гараже.

2012.01.16

  • Загрузка списка танков в гараже.

2012.01.15

  • отладка: вывод в файл процента нагрузки главного потока сервера.

2012.01.14

  • Лог транспорта, события.
  • Список ожидающих отправления и список ожидающих подтверждения mArrWaitSend и mArrWaitCheck.
  • Очередь на отправку у транспорта.

2012.01.13

  • Блин, разрушил транспорт :(. Неувязки с многопоточностью. Разобрался: Клиент отправляет по неизвестному транспорту адресу, но не получит от НЕИЗВЕСТНОГО. Сервер наоборот: отправит по известному, но получит от неизвестного. Поэтому не возникнет ситуации когда будет добавление из двух потоков.

2012.01.11

  • тестирование транспорта с 220 клиентами.+
  • тестирование транспорта с 450 клиентами.+

2012.01.10

  • отладка транспорта
  • добавлено управление клиентом с помощью скрипта.
  • лог стрима.
  • лог клиента по нику.

2012.01.07

  • контроль соединения - разрыв на клиенте и сервере,
  • клиент: разрыв по 1. отсутствию пакетов от сервера 3 секунда и 2.по событию Disconnect от транспорта.
  • сервер: разрыв по отсутствию пакетов от клиента 1 минута -> 1.событие Disconnect от транспорта. Всегда отсылка раз в минуту Эхо.
  • Стрим для гаража.
  • время для массива клиентов сервера: отсылка и прием. раз в минуту отсылка Эхо.

2012.01.06

  • уведомление о приеме Stream и Packet.

2011.12.30

  • Сервер: список клиентов перевести в "TArrayObject" для повышения скорости.
  • свежесть пакета при потере соединения synchro.
  • два типа CN - стрим и пакетный в транспорте.

2011.12.28

  • асинхронный вызов списка клиентов в окне сервера.

2011.12.27

  • транспорт контроль свежести пакета.
  • механизм дисконнекта.

2011.12.26

  • версия при попытке соединиться.

2011.12.25

  • первый ответ от сервера.
  • произошел коннект между клиентом и сервером.
  • логирование и отладка транспорта.

2011.12.21

  • "TList". Список с блокировкой, для операций над элементами из разных потоков.
  • отладка транспорта.

//---------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------- "INFO" - идеи (без реализаций) 1). Вода на танке. При выезде из воды, она стекает с корпуса. При движении по суше и воде, вода вылетает по радиальной траектории с траков. 2). Easter eggs. Пасхальные яйца: строй фрицев (советских) стоит перед командиром. При подъезде к нему танка, отряд либо разбегается(слышно как говорят, кричат), либо исчезает из виду. Появляется в начале битвы среди строений. 3). Реализм световых лучей в лесу. Инфо: возникает из-за оседающей пыли. При проезде по траве пыль поднимается вверх. 4). Грязь. Комки грязи на корпусе. Поведение похоже на воду, но грязь оставляет след на танке после высыхания (может поменять цвет). 5). Эффект шероховатости поверхности. У разных танков разная технология создания брони. Для литой характерна шероховатость, для катанной такого эффекта нет. Для катанной - блеск металла. 6). Если взять как танки двигаются в War Thunder и совместить с процессом игры WoT - будет вообще супер. Когда управляешь танком в War Thunder - получаешь настоящее удовольствие. Но вот сам геймплей полный отстой. WT - чувствуется МАССА танка, его тяжесть. А в WoT - как будто танки пластмассовые, ничего общего с реализмом. 7). Дрожь танка от выстрела и столб пыли от земли (возникает от разряжения воздуха после выстрела (когда плотный воздух порождает волну высокого давления - взрыв)). Именно что - дрожь, отдача как таковая это и так понятно. 8). Движения танка - медленные, плавные. Не должно быть "пластмассовости" как в WoT. 9). При попадании в танк - учитывать соотношение масс танка и снаряда. Как такового толчка быть не должно. Инерционность танка велика. Единственный эффект - переход кинетической энергии в тепловую - искры, вспышка света и нагрев металла. //---------------------------------------------------------------------------------------------------------------- "IDEA" Название игры - "Evolution of war machines". Компании - "Only C++ Company" Альтернативное(?) - "Evolution of metal" Эволюция металла - спорно, потому что неоригинально. Есть интересная аллюзия: при запуске играет спокойная классическая музыка, а при входе в гараж начинает играть зубодробительный металл, который постепенно стихает. Камера плавно двигается к зданию гаража, играют скрипки, виолончели. При подлёте к гаражу слышно пробивающиеся сквозь стены басы и тяжелые риффы. Потом камера попадает внутрь слышим музыку в стиле металл, лязг цепей и звон металлических частей. Музыка стихает, удаляясь. Слышно только "цеховую тишину".

Реклама №1: (сомнительно, только как "критика третьих лиц")

Реклама по ТВ: мамаша стоит на перекрестке и кричит своему сыну (не может к нему перейти, много машин) дёргается перейти, оглядывается: "Андрюша, стой! Вернись! Хватит играть!" Камера оказывается ближе и мамаша оборачивается. Кричит в камеру (как будто узнала людей, которые ее снимают). Агрессивно: "Верините моего сына! Гады..." Надпись в конце ролика: "Evolution of war machines"! Здесь двусмысленность, вроде как ребенок играет и родителям это не нравится. Но это та ли игра, в которую играет Андрей? Ролик не говорит прямо что это именно та игра.

Реклама №2:

Мимо камеры проходит стройная блодинка в короткой юбке и садится рядом с мужчиной (справо от него) на диван. У мужчины видна клавиатура и мышка. Слева от него сидят еще две девушки. Брюнетка по левую руку, рыжая в ногах. Все девушки трогают мужчину. Кто за руку, кто за ногу. Но не тискают, а скорее прикасаются. Мужчина увлечён игрой за компьютером. Сам монитор не показан. Девушка слева смотрит с желанием на мужчину, трогает мужчину за руку, говорит: "Какой классный танк ты придумал." Мужчина быстро отвечает: "Я знаю", довольно улыбается. Далее показывается заставка "Evolution of war machines".

Реклама №3: (требует доработки)

Заставка наезжает на камеру. Закадровый голос: "Вы готовы к интересным приключениям и большим открытиям?" "Вас ждёт захватывающее путешествие". "От простого и примитивного до сложного и неповторимого!" "Но не все так легко, Вам предстоит сражаться за право выжить" "и создать свое творение..." (для каждой фразы своя музыка и фон)

Серверный конвейер:

После загрузки карты оставлять физику на паузе. Вызывать stepSimulation внутри каждый комнаты. При этом при получении пакета помещать в очередь на исполнение и запоминать время получения пакета. И учитывать время пакета при вызове stepSimulation: делать вызов с расчитанным интервалом. Например, 10 событий по 10 мс. То есть 100 разбивается на 10 частей = 10 мс, stepSimulation(10, numMaxSubStep, 1/100.0f). После каждого такого вызова применять пакеты к физике и делать вызов дальше.

Репликация:

Схема на сервере. После получения пакета о событии на клиенте - разослать данное событие другим клиентам, включая сам источник данного события. Это будет EventAction. Причем на сервере фиксируется время прихода пакета для учета в конвейере. Клиент сам не применяет события от себя же, а ждет подтверждения пакета от сервера. Поэтому всегда видит картинку с сервера с временем запаздывания в свой пинг. Каждые 100 мс (время импульса корректировки) сервер шлёт корректирующие пакеты всем клиентам EventCorrect. Клиент, получив корректирующий пакет должен скорректировать параметры игровых объектов.

Гусеница (может где и было написано в блоге):

Гусеница не имеет физики. Она чисто графическая. В шейдере текстура смещается и возникает иллюзия движения гусеницы. Так же в шейдере изменяется геометрия в соответствии с положением катков. //----------------------------------------------------------------------------------------------------------------

PARADIGMA

  1. Дублирование данных и кода - зло.
  2. Многозадачность для программиста - зло.
  3. Если пишешь код для других программистов, то пиши кроссплатформенный.
  4. Код должен быть по возможности общим. Формализовать группу классов, искать общие черты и свойства. Лучше написать и исправить 5%, а не 100%. При этом одно действие порождает множество воздействий(когда код общий), и, наоборот, приходится делать много действий для одного воздействия.
  5. Количество базовых классов и файлов должно быть минимально. Но в то же время они должны порождать множество возможностей.
  6. Не старайся писать общий код. Хотя это и противоречие. Это инженерное искусство. Лавировать, тогда, когда нужно писать общий, когда частный. Тут надо думать.
  7. Один класс - одно поведение, один объект - одна задача.
  8. Этапы создания интерфейса: 1. Достаточность. 2. Избыточность. 3. Непротиворечивость.

//----------------------------------------------------------------------------------------------------------------