LINUX.ORG.RU

Разработка трёхмерного игрового движка

 , , , ,


1

2

Уже долгое время пишу игровой движок общего назначения (т.е. не исключительно для какого-то одного жанра). Естественно, под GPL. Естественно, онтопик – гражданин перого класса. Использую инфраструктуру Qt. Сейчас проект состоит из:

  • Библиотеки libKawaii3D, предоставляющей классы для построения одной или нескольких трёхмерных сцен.

  • Библиотеки, облегчающей создание различных Renderer плагинов libKawaiiRenderer.

  • Renderer плагина libMisakaRenderer. Использует OpenGL 4.5 Core + ARB_bindless_texture.

  • Renderer плагина libKurisuRenderer. Использует Vulkan, Glslang и SPIRV-tools.

  • Плагина загрузчика ассетов libKawaiiAssimp. Загружает модели, меши и сцены из файловой системы, используя библиотеку libAssimp. Примеры передаваемых строк: "models/preCombinedCastle.fbx", "file:///usr/share/somegame/character.dae", "/home/user/models/helicopter.obj".

  • Плагина загрузчика ассетов libKawaiiFigures3D. Загружает некоторые простые меши – куб, сферу, тетраэдр, октаэдр, икосаэдр, тор, квадрат и плоскость. Примеры передаваемых строк: ":/cube_x5", ":/octahedron_x0.33", ":/torus".

  • Библиотеки libKawaiiWorlds. Игровой движок. Отвечает за загрузку и хранение ассетов, физику, переходы между локациями, сетевой мультиплеер, воспроизведение музыки и звуков, обработку пользовательского ввода, ландшафты с картами высот и вот это вот всё.

  • Библиотеки libKawaiiWorlds_qml. Поддержка QML и JavaScript для libKawaiiWorlds. Предоставляет классы обёртки над классами и структурами движка.

  • Приложения KawaiiWorldsViewer. Загружает игры, читая специальный json файл. Таким образом избавляет большинство игр от необходимости иметь собственный бинарный исполняемый файл и обеспечивает независимость от ОС и, до определённого предела, архитектуры CPU. Предполагается, что такие игры-миры будут использовать JSON файл для указания используемых моделей, текстур, шейдеров, материалов и прочего; JavaScript для игровой логики и QML для разметки GUI.

Повесточка:

  • Пишу игру – пошаговую мультиплеерную стратегию. Цель сделать так, чтобы у соперника не осталось городов (либо штурмануть, либо уйти в глухую оборону и ждать пока монстры спушат супостата по самые уши). Осаду городов планирую сделать в стиле TowerDefence, драку между юнитами – исключительно на глобальной карте. В целом имеется достаточно подробная задумка и лимитированный скоуп. Слишком сильно распространяться сейчас не хочу – пока не доделаю играбельный прототип.

  • Как придумать название игре? Может ли ЛОР помочь с этим? :)

  • День после. С достаточно большой уверенностью, могу сказать, что до играбельного прототипа я дотолкаю игру довольно скоро. А что дальше? Работает ли краудфандинг для движков / игр? Если да, то что на него нужно предоставить? На каких площадках? Если нет, то как найти патронов / инвесторов? Понятно, что в этой стране геймдев мёртв и посыпан токсичной радиоактивной пылью мобилькерами, так что искать нужно среди интернационалов. Интересны ли энтузиасты, например Valve, или они только место в Стиме продадут? Кому бывают интересны?

  • Было бы классно обрасти командой единомышленников – художников, композиторов, левел дизайнеров, программистов, девопсов и прочих. Сейчас тащу в одно, в меру отъетое, лицо :D

  • Средства для локализации / интернационализации игр-миров на уровне движка – нужно ли и в каком виде?

  • Позиционный звук – что для него вообще использовать? /*в игре юзаю QML-ский AudioEngine, но понятно, что это "ну такое"*/ Первым в голову приходит OpenAL, но он в последних версиях спроприетарился и скурвился. Использовать старые версии? Или есть современные решения?

  • Поддержка языков кроме C++ и JavaScript – на сколько нужно? Сейчас поддерживается C++, так как сам движок написан на нём, так что достаточно было не превращать его в монолитное монструозное. А JavaScript, так как Qt имеет всю необходимую инфраструктуру для этого, ну и сам язык довольно простой, да. Пока склоняюсь к тому, не особо приоритет, а всякие пайтоны, lua и прочие расты могут подождать.

  • Сейчас есть PKGBUID-ы под этот наш Арч и они хороши. Но что бы придумать с поддержкой других десктопных дистров? Есть скрипты и даже CMakeLists.txt, чтобы скачать все модули движка в уютный хомячок и там же собрать. Нужно ли подобное? Стоит ли их поддерживать / обновлять и т.д. или лучше сделать разбиение на пакеты также как для Арча, с использованием, например CPack?

Скриншотики: https://imgur.com/a/zhHhcnw

Исходники: https://gitlab.com/KawaiiGraphics

★★★★

Ответ на: комментарий от crutch_master

Пока что не целиком :P

.import "balanceValues.js" as Balance

function getVacantPopulation()
{
    let workers = 0
    for(const resName of Balance.resources)
        workers += Number(world.selectedTownEntity.getMetadata(resName+"_workers"))

    return Number(world.selectedTownEntity.getMetadata("population")) - workers
}

function setWorkers(num, res)
{
    if(!world.selectedTownEntity) return

    const delta = num - Number(world.selectedTownEntity.getMetadata(res+"_workers"))
    if(!delta || (delta>0 && delta > getVacantPopulation())
            || num > Number(world.selectedTownEntity.getMetadata(res+"_maxWorkers"))) return

    world.gui["income_"+res] += delta //* res+"Efficacy"
    world.setMetadata("p"+world.getMetadata("currentPlayer")+"."+res+"_income", world.gui["income_"+res])
    world.gui["town_"+res+"Workers"] = num
    world.selectedTownEntity.setMetadata(res+"_workers", num)
}

function openTownScreen(townEntity)
{
    if(world.selectedTownEntity !== townEntity)
    {
        if(townEntity && townEntity.getMetadata("owner") !== world.getMetadata("currentPlayer"))
        {
            if(townEntity)
                townEntity.detachObj()
            return
        }
        if(world.selectedTownEntity)
            world.selectedTownEntity.detachObj()
        world.selectedTownEntity = townEntity
        if(world.selectedTownEntity)
        {
            world.gui.town_population = Number(world.selectedTownEntity.getMetadata("population"))
            for(const resName of Balance.resources)
                world.gui["town_"+resName+"Workers"] = Number(world.selectedTownEntity.getMetadata(resName+"_workers"))
            world.gui.state = "townScreen"
        } else
            world.gui.state = "turnProcess"
    }

    if(townEntity)
        townEntity.detachObj()
}
function openTownScreenByName(townName)
{
    openTownScreen(world.getEntity(townName))
}
function closeTownScreen()
{
    if(!world.selectedTownEntity)
        return

    world.selectedTownEntity.detachObj()
    world.selectedTownEntity = null
    world.gui.state = "turnProcess"
}

Вот ещё кусочек:

{
"name": "WRLD",
"cameras": [
    {
        "name": "cam0",
        "position": [0,0,0],
        "view_direction": [0,0,1],
        "up_direction": [0,1,0]
    }
],

"main_camera": "cam0",
"resources": {
    "models": [
        { "name": "cube", "path": ":/cube_x5" },
        { "name": "octahedron", "path": ":/octahedron_x0.33" },
        { "name": "castle", "path": "models/preCombinedCastle.fbx", "set_major_side": 2.5, "rotate": [-90,0,0] }
    ],
    "cubemaps": [
        {
            "name": "environment",
            "path": "textures/skybox.png"
        }
    ],
    "textures": [
        {
            "name": "globalLand",
            "path": "textures/globalMap.png"
        },
        {
            "name": "townLand",
            "path": "textures/townMap.png"
        },
        {
            "name": "landscape_color",
            "path": "textures/land_color.png"
        },
        {
            "name": "castle_color",
            "path": "textures/castle.png"
        }
    ],
    "shaders": [
        {
            "name": "external_cubemap_shader",
            "vertex_path": "shaders/materialCubeTexture.vs.glsl",
            "fragment_path": "shaders/materialCubeTexture.fs.glsl"
        },
        {
            "name": "scaled_image_shader",
            "vertex_path": "shaders/materialImageScaled.vs.glsl",
            "fragment_path": "shaders/materialImageScaled.fs.glsl",
            "illumination_name": "PBR"
        },
        {
            "name": "colored_shader",
            "vertex_path": "shaders/materialColored.vs.glsl",
            "fragment_path": "shaders/materialColored.fs.glsl",
            "illumination_name": "LightAbove"
        }
    ],
    "solid_materials": [
        {
            "name": "bricks",
            "shader": "scaled_image_shader",
            "buffer": [
                {
                    "type": "float",
                    "value": 1
                },
                {
                    "type": "texture2D",
                    "value": {"name": "tex", "texture": "castle_color" }
                }
            ]
        },
        {
            "name": "p0_color",
            "shader": "colored_shader",
            "buffer": [
                {
                    "type": "vec3",
                    "value": [1, 0.1, 0.1]
                }
            ]
        },
        {
            "name": "p1_color",
            "shader": "colored_shader",
            "buffer": [
                {
                    "type": "vec3",
                    "value": [0.1, 0.1, 1]
                }
            ]
        },
        {
            "name": "p-1_color",
            "shader": "colored_shader",
            "buffer": [
                {
                    "type": "vec3",
                    "value": [0.7, 0.7, 0.7]
                }
            ]
        }
    ],
    "skybox_materials": [
        {
            "name": "skybox",
            "shader": "external_cubemap_shader",
            "buffer": [
                {
                    "type": "textureCube",
                    "value": {"name": "tex", "texture": "environment" }
                }
            ]
        }
    ],
    "landscape_materials": [
        {
            "name": "landscape",
            "shader": "scaled_image_shader",
            "buffer": [
                {
                    "type": "float",
                    "value": 24
                },
                {
                    "type": "texture2D",
                    "value": {"name": "tex", "texture": "landscape_color" }
                }
            ]
        }
    ]
},

"locations": [
    {
        "name": "GlobalMap",
        "entities": [
            { "name": "box", "material": "skybox", "model": "cube", "physic": "none", "click_opacity": true },
            { "name": "p0_start", "material": "bricks", "model": "castle", "physic": "none", "position": [-21, -0.25, 0], "rotation": [0,-90,0], "metadata": { "isTown": true, "owner": 0 } },
            { "name": "p1_start", "material": "bricks", "model": "castle", "physic": "none", "position": [21, -0.5, 0], "rotation": [0,90,0], "metadata": { "isTown": true, "owner": 1 } }
        ],
        "landscapes": [
            { "name": "globalLand", "material": "landscape", "height_map_texture": "globalLand", "position": [0, -3.5, 0], "size": [50, 2.5, 25] }
        ]
    }
],

"illumination_models": [
{
    "type": "pbr",
    "name": "PBR",
    "dot_lights": [
        { "color": [1.25], "ambient": [0.0], "position": [0,0,0], "quadratic_attenuation": 0, "const_attenuation": 1 }
    ]
},
{
    "type": "pbr",
    "name": "LightAbove",
    "dir_lights": [
        { "color": [0.75], "ambient": [0.0], "direction": [0,-1,0.5] }
    ]
}
],

"qml_file": "gui/main.qml"
}
robus ★★★★ ()
Ответ на: комментарий от robus

Типа скинчики?

Ага. У тебя же онлайн она. Если там есть хороший соревновательный элемент, можно прикрутить ладдер и игра без кнопко/пингодрочева, то вполне может взлететь. Сорцы даже не будут иметь особой ценности, потому что рейтинг и шляпы на конкретном сервере.

crutch_master ★★★★★ ()
Последнее исправление: crutch_master (всего исправлений: 1)

Посмотрел скрины, у тебя либо вертексное освещение чисто или к diffuse текстурам идут ещё и specular. Карту ты генерируешь из heightmap понятное дело.

1 - внеси для всей карты attribute текстуру в зависимости от значений цветов котрой на карту будут миксоваться разные текстуры поверхности самый низ трава, выше земля, ещё выше снег и тому подобное.

2 - Внеси карту нормалей для адекватного освещения без затрат, так не будет ланшафт бликовать как будто это большой кусок лакированной поверхности.

Вопрос. Можно ли для произвольного объекта написать шейдер так что-бы он был выполнен в промежутке между определённым этапом рендеринга?

Частицы есть? Если да то в виде спрайтов или в виде gl_points? И если что-то из этого да то имеется поддержка анимированных спрайтов из spritesheet?

Можно ли произвольной текстуре произвольной модели задать движение? Ну например я хочу водопад на заднем плане, делаю трубу, натягиваю на неё текстуру воды с пеной и теперь двигаю uv координаты текстуры что-бы у меня был водопад?

Как дела с кубическими картами, например есть герой у него шлем я хочу что-бы шлем отражал откужение. Можно ли задать явно части модели кубическую карту? и/или можэно ли делать динамическую кубическую карту которую можно задать части модели (шлему) что-бы ещё интерактивные объекты были в шлеме отражены? Но зеркальный шлем не нужен так что хочется размыть отражения через карту нормалей можно-ли смешать их? Тоечсть можно ли для части модели описать кастомный шейдер в виде пре/пост отработки?

И вот ещё есть ли из коробки возможность делать визуальный трекинг падающих предметов? Тоесть включить что-то и за всеми движениями предмкетов будут появляться 3д-линии.

А так, похвально. Удачи.

anonymous ()

Выпускайся в стиме и всё. (ещё можно в гоге,ithio,хамблбамбл и прочих) Не важно что ты делаешь, в играх важно что-бы о твоей игре хоть кто-то что-то где то услышал. Инди разработчики да и даже средние студии, даже на торренты свои игры сливают намеренно со словами, «ну хоть кто-то, ну пожалуйста поиграйте в нашу игру, хоть 5 минуточек, вот торрент, вот демки в стиме, вот в гоге вот везде, ну пожалуйста хотя бы палочкой потыкайте, мы старались может быть вам понравится».

anonymous ()

Нужно ли подобное? Стоит ли их поддерживать / обновлять и т.д. или лучше сделать разбиение на пакеты также как для Арча, с использованием, например CPack?

Для такого всегда должен быть вариант full.tar.gz где просто всё есть и не надо шаманить, кому надо выкинут лишнее, кто не знает что лишнее тот оставит как есть, а в случае разбиения нужное на найдёт.

anonymous ()
Ответ на: комментарий от anonymous

тебя либо вертексное освещение чисто или к diffuse текстурам идут ещё и specular

Вертексное освещение не поддерживается игровым движком. В ближайшем будущем планирую опцию для отложенного освещения и GBuffers – в теории на больших сценах, да ещё и с тенями, frametime должен снизиться после этого.

1 - внеси для всей карты attribute текстуру в зависимости от значений цветов котрой на карту будут миксоваться разные текстуры поверхности самый низ трава, выше земля, ещё выше снег и тому подобное.

Зойчем атрибут текстуру, если можно в шейдере? Но за идею для расширения сампла и улучшения картинки в игре, сенкс )

2 - Внеси карту нормалей для адекватного освещения без затрат, так не будет ланшафт бликовать как будто это большой кусок лакированной поверхности.

Нормали для ландшафтов сейчас генерит шейдер. Чтобы не бликовало, думаю достаточно будет roughness повысить, а metallic понизить (или вообще в управляющие текстуры засунуть). А ещё тени включить, да (сейчас выключены, чтоб можно было за моим убогим AMD A12 9700P + Radeon R7 M440 тестировать, не подключая Multi GPU вулканского рендерера).

Вопрос. Можно ли для произвольного объекта написать шейдер так что-бы он был выполнен в промежутке между определённым этапом рендеринга?

Мне не совсем понятно, что тут спрашивается..

GBuffers и многопроходный рендеринг в libKawaiiWorlds пока не поддерживаются.

Можно для этого объекта написать материал эффект (пара вершинный + фрагментный шейдер)..

Частицы есть? Если да то в виде спрайтов или в виде gl_points? И если что-то из этого да то имеется поддержка анимированных спрайтов из spritesheet?

Частиц пока нет, но, учитывая что libKawaiiWorlds использует instanced rendering для сущностей, думаю в клиентском коде не будет больших проблем.. кроме того, что, ради производительности вероятно придётся отключить коллизии для частиц и считать «давление потока» в скриптах. Поэтому я говорю, что частиц пока нет. Когда будут, будут с кастомными мешами и шейдер эффектами.

делаю трубу, натягиваю на неё текстуру воды с пеной и теперь двигаю uv координаты текстуры что-бы у меня был водопад?

Делай что хочешь в shader effect. Можешь хоть Illumination Models переизобрести. И уж точно можешь двигать texcoords (UV) в зависимости от таймстампа. Если очень хочешь, могу добавить сэмпл про водопад :)

Как дела с кубическими картами

Поддерживаются.

Можно ли задать явно части модели кубическую карту

Части – нет, только целиком на материал. Нуу.. никто не говорит, что материал не может быть для единственного шлема.

можно ли делать динамическую кубическую карту

Да. В движке это называется EnvMap – штука которая рендерит кубмапу из некоей точки.

зеркальный шлем не нужен так что хочется размыть отражения через карту нормалей можно-ли смешать их

Функций для IBL в «стандартной библиотеке шейдеров» пока нет (планируются, средне низкий приоритет), так что придётся всё ручками в shader effect прописывать.

И вот ещё есть ли из коробки возможность делать визуальный трекинг падающих предметов? Тоесть включить что-то и за всеми движениями предмкетов будут появляться 3д-линии.

Нет

robus ★★★★ ()
Ответ на: комментарий от crutch_master

js код, конечно в c-style

Проблема в том, что мои знакомые настоящие JS-еры предпочитают управлять гипертекстом, а не трёхмерными сценами, да ещё и не сильно больше 6-8 часов в сутки.

конфиг мне нравится

Сяп. Ради того, чтобы игры описывались подобного образца конфигами и «имели кроссплатформенность в крови», KawaiiWorldsViewer и затевался :) Так бы можно было либой обойтись )

robus ★★★★ ()
Ответ на: комментарий от robus

frametime должен снизиться после этого.

C тенями да ибо два раза меши рендерить в карту цвета и карту теней, а вот чисто GBuffers наоборот именно в больших сценах даст ту производительность которую получить от прямого рендеринга уже нельзя будет.

Зойчем атрибут текстуру, если можно в шейдере? Но за идею для расширения сампла и улучшения картинки в игре, сенкс )

Затем что можно в 4 каналах текстуры хранить например 4 вида поверхностей, нарисовал карту высот, затем также нарисовал тут снег, тут трава, тут деревья, тут камни. Если 1 канал разбить ещё на 2 то уже 8 видов поверхностей. В Gimp можно целую локацию нарисовать, из heightmap будет terrain из 1 RGBA текстуры будет минимум 4 типа поверхности terrain`а. Можно будет генерировать типа что-то noise perlin если хочется и на лету генерировать разнообразное окружение. Можно просто рисовать на 3d поверхности переводя координаты мышки в 3d шные а татем в координаты чанка терраина а из координат чанка терраина в координаты текстуры карты высот, и эти же координаты использовать для изменения текстуры атрибутов, а из неё в заисимости от цвета (яркости каналов) выбирается текстура или модель (трава дерева) которая по обратной цепочуке преобразования координат размещяется на 3д терраине.

Вот для этого, это дико удобно. Ты всю карт местности можешь храть в двух текстурах. Карта высот одноканальная и обычная RGBA для всего другого. Можно туже RGBA разбить на 4 квадрата и тоже получить 4*4 типов чего угодно, в щейдере только текстуру сдвинуть умножив на нужную координату и разделить на два потом обе растянув при этом текстуру получается. Как фичу запилить можно всё это.

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

Ну, успехов и упорства, удача тут не нужна.

Самое главное можно кастомные шейдера писать, а не юзать просто как лего двиг.

anonymous ()
Ответ на: комментарий от anonymous

Но есть минус это исключительная GPL. Пользователи твоего движка

  • Первые - Просто сделают что-то для себя интерактивную виузализацию чего-то и ни тебе ни кому ни было не сообщат. Вклад делать не станут.

  • Вторые не знаю что будут делать.

Вводи двойное лицензирование. Если кому то твой двиг реально зайдёт и он захочет что-то сделать действительно цельное и может даже у него получится что-то достойное, то он с это достойное сунет в ящик по итогу работ и всё. А он бы захотел выложить куда то или даже продать. Я сторонник GPL, но в геймдеве и так черезвычайно сложно жить, там до сих пор как в 90стые нужно выживать что-то предлагать, конкурировать жестоко, твоя программа если дай бог станет популярна то это 1 или 2 месяца пика интереса, а затем он уходит, словил момент ты жив и может продолжать работу, не словил то всё твоё дело труп. (частные единичные везения инди не в счёт) А если на тебе GPL ярлык то всё ГГ ВП, получить даже 1% игроков от аудитории например 0ad катострофически сложно. Если у тебя есть правовая возможность вводи двойное лицензирование по запросу просто так по факту запроса или за деньги.

Повторюсь я GPL фанбой, но одновременно против GPL для случаев частной разработки игр на начальном этапе. Кроме случая когда игра пишется чисто для себя и в целом на неё насрать. К сожалению GPL в геймдеве это смерть. Разве что если ты публичная личность и у тебя на патреоне 1000 человек по 100 долларов в месяц присылают, такие перцы любят затирать про то какие возможности, как всё просто, нужно лишь только хотеть и прочие бла бла бла. По факту ты нахер никому не нужен, а если ещё и ограничен (нельзы выложить демку что-бы просто потыкали, а ты оценил спрос и решил есть ли смысл делать дальше) твою демку если она реально годная так как GPL возьмут и зафигачат аналог в 100 раз лучше, зальют на ith.io где можно и просто скачать и заплатить сколько хочешь, а твою уже готовую игру будут воспринимать как клон той. Такое уже было и не раз.

Это я просто мысли в слух со стороны.

anonymous ()
Ответ на: комментарий от anonymous

C тенями да ибо два раза меши рендерить в карту цвета и карту теней, а вот чисто GBuffers наоборот именно в больших сценах даст ту производительность которую получить от прямого рендеринга уже нельзя будет.

Нуу.. я же и говорю – снизится время отрисовки (т.е. производительность улучшится). А ещё можно будет всякие ништячки в пространстве экрана делать (типа SSAO), но вот как оптимизация это работать будет сразу.

Самое главное можно кастомные шейдера писать, а не юзать просто как лего двиг.

Выигран «бой», но перспективы в «войне» туманны..

That sound like a reasonable plan!

However, it’s been a while and I mostly gave up on getting approval of this (it was a hobby project anyway) and I’m not sure when I would have sufficient time to progress it any further, so @RikoOphorst, in case you would like to have further progress on this you may have to take matters into your hand (sorry).

robus ★★★★ ()
Ответ на: комментарий от robus

Ну да, а ещё жопа костыльная с полупрозрачными объектами. Есть и плюсы и минусы.

Хотя если на экране менее сотни объектов то отложенный рендеринг нафиг не особо то и нужен. А вот если больше (или 1 модель из большого количества субмоделей итого на 20 можелек 2000 мешей тоесть 2000+ дравколов то даааа)

Выигран «бой», но перспективы в «войне» туманны..

Не сыпь мне соль на рану :( Туман как в сайлент хилле.

anonymous ()
Ответ на: комментарий от robus

Он хочет что-то типа видимо.

MainClass::Foo.Bar::((obj)=>{ register(bla) ,promise(()=>{ callback(this.__ext.bla( .this.regiser_callcack((get_gxt())=>{ ;gioasfhghijeiugwshaewgeouitghiurchnweri-e*wgc-+*-9})))}) })

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

anonymous ()
Ответ на: комментарий от anonymous

Хе-хе. А QMLEngine такое вообще съест? И можно ли будет потом из гуя звать эту логику? А вообще, ИМХО, объекты, классы, события, потоки, мутексы и прочие QHash<QString, std::function<void(const QJsonValue &val, std::vector<std::byte> &content, KawaiiGpuBuf *buf, size_t &byteIndex)>> customUboElementLoaders; пусть в движке остаются, а в скриптах игры всё будет максимально просто.

robus ★★★★ ()
Ответ на: комментарий от robus

Так и я про то же, в кишках оно может быть как угодно та то они и кишки, водовороты упороротых комбинаций языковых конструкций в десятках вложенных switch управляемых битовыми сдвигами через прыжки по goto норма, если то требуется для работы кишков ибо там местами приходится извращаться. А вот на уровне уже так сказать рычагов, если не везде то как можно больше должно быть просто декларативные вещи, типа вот функция она каждый тик обрабатывает физику например и точка, а не. Вот функция регистрации коллизии которая отпряаляет событие о коллизии объектов в пулл событий коолизий после чего вот функция в которую передаются обекты вокруг объекта порождающего коллизию что-бы быстро обсчитать наиболее вероятные столкновения первыми, после чего вот каллбек который обрабатывает какие объекты вне frustum камеры и их не надо образабываать вот 4 тхреад лока котроые нужно дождаться и только после этого можно джобавить новый объект в пулл физических объектов и не забудте в пулл эффектов от столкновений передать событие для вашего эффета пробросив через объект свойства класса движка позицию и время коллизии что-бы проиграть эффект партиклов, но перед этим убедитесь что эффект был пордготовлен в фоновом треде дял этого ААААААААААААААААААААААААААААААААААА

anonymous ()
Ответ на: комментарий от robus

потому, что никто в здравом уме не примет такой кодстайл, потому, что всё должно быть «нормальным».
если я так пишу при объявлении функции, то и в ветвлении должен такую мудянку наводить. (для примера if-else, чтобы не придумывать ничего полезного):

if (!a)
{
  some.thing()
}
else
{
  specific.thing()
}

это выглядит как кусок говна. а применять правила только для определённых вещей никто не будет или забудет или перепутает. это никому не нужно.

с другой стороны, я хоть в сях и не разбираюсь, но по ссылке https://gitlab.com/KawaiiGraphics/KawaiiWorlds/-/blob/master/src/lib/ResourcePack.cpp видно, что ты вообще не думаешь о том, чтобы работать в команде или что код будут править.

for(auto i = el->second.begin(); i != el->second.end(); ++i)
    if(i->front()->getInstanceCount() < global_config::maxPackInstances - 1)
      return *i;

for(uint16_t i = 0 ; i < 6; ++i)
    {
      if(w < colorTex->getImage(i).width())
        w = colorTex->getImage(i).width();

      if(h < colorTex->getImage(i).height())
        h = colorTex->getImage(i).height();
    }

где логика при оформлении этих двух кусков скобками? это не нормально.

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

system-root ★★★★★ ()
Ответ на: комментарий от system-root

никто в здравом уме не примет такой кодстайл, потому, что всё должно быть «нормальным»

должно быть в кодстайле прописано

Ааа. Вот оно что :D

Ну, ок чо. Уже бегу принимать кодстайл, CoC, и устав корпорации для команды из ОДНОГО ЧЕЛОВЕКА. Ну или давай так – я до конца недели (на всякий случай приблизительный срок на завершение играбельного прототипа, но стоплю всё – СКОБОЧКИ НЕ ТАМ ЭТО ВАЖНЕЕ), а ЛИЧНО ТЫ тогда присоединяешься к разработке и садишься за что-то с чем я справиться (пока) не могу. Вроде автоматического генератора фотонных карт для всякого рода каустик (по образцу KawaiiShadowMapper-а, но для фотонных карт) или ещё лучше – допиливания glslang для поддержки Linkable SPIRV, там же Кронос писали – у них же гайдлайны и скобочки где надо стоят, так что часа за 3 думаю осилишь разобраться, тыж не я ) Ну или хотя бы пропатчишь QQmlEngine так, чтобы QJSValue::call можно было звать из соседнего потока без того, чтобы когда придёт GC (в НОРМАЛЬНЫХ языках же garbage collector обязательно должен быть) схватить SEGFAULT.

ты вообще не думаешь о том, чтобы работать в команде

А знаешь о чём ещё не думаю? О том, как оно будет работать в VR / с пробросом через сеть (как Google Stadia) и на квантовых компьютерах. Нет смысла оптимизировать сценарий невозможный (маловероятный) на практике. Помогать мне с плюсовым кодом уж точно вряд ли кто сядет. И не в скобочках тут дело ;)

robus ★★★★ ()
Ответ на: комментарий от robus

Да ппц, тебе человек, который вообще не бумбум говорит, что твой код не готов к колективной работе над ним и к измненениям, потому, что это будет просто адок переписывать и перефарматировать на каждый чих, а тебе пофигу. Ещё таким тоном, мол «лично ты хуёмоё».

Было бы классно обрасти командой единомышленников

Это тебе на двач, штобы по уровню токсичности и ЧСВ подходили.

system-root ★★★★★ ()
Ответ на: комментарий от system-root

Ещё таким тоном, мол «лично ты хуёмоё»

В этом твоя проблема. Смотришь на форму, не на содержание.

Ответь, вот честно. Если бы не скобочки, ты бы сел добавлять фичи / улучшать API / оптимизировать производительность? Мне кажется, что нет.

и к изМНенениям, потому, что это будет просто адок переписывать и перефАрматировать на каждый чих

Что-то код уже переписывался, можешь в историю коммитов заглянуть, если хочешь (но ты не хочешь). И это не был «адок». А «адок» был как раз таки при взаимодействии с «правильным» и «нормальным» кодом. С glslang, например. Когда в один прекрасный момент они линовку шейдерных програм похерили. Зато скобочки везде правильно в коде стояли. Или с amdgpu + radeonsi, когда на Raven Ridge при рендеринге в текстуру, для которой существует резидентная ссылка (resident handle, расширение GL_ARB_Bindless_texture) случался GPU hang. Зато отступы в их кодовой базе приятны твоему глазу были бы (ну или нет, как то не обратил внимания, когда код их мельком читал). Заметь, адок не потому, что в glslang и amdgpu отступы со скобочками по гайду расставлены. Просто то, что отступы со скобочками НИКАК не влияют на качество кода.

Алсо – ты знаешь, что допускать орфографические ошибки не нормально, форма ведь важнее содержания? Я едва-едва понимаю что ты пишешь. Кого ты собираешься перефармливать? За чем ты «мнёшь» кодовую базу? О чем ты вообще?

тебе человек, который вообще не бумбум

А куда же менторский тон, как в

где логика при оформлении этих двух кусков скобками? это не нормально.

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

делся?

P.S. Объясню очевидные вещи – в ответ на тролинг я всегда стараюсь плеваться максимально едкой кислотой. Твоя, с позволения сказать, «критика» – абсолютно явный и неприкрытый тролинг, а не что-то продуктивное. Ты говоришь что-то вроде «расставленные как попало скобочки делают код не готовым к командной работе над ним». Ну т.е., значит, что расставить скобочки «правильно» и «нормально» решит проблему «нехватки кадров» для разработки именно ядра движка. Я говорю – нет, не решит. Лично ты, не сядешь улучшать плюсовый код – потому что «как то сложно», «дофига его», «дофига он чего делает», «да и вообще не платят». Так же и остальные мыслят. И скобочки тут не причём. Т.е. расстановка скобочек «как в нормальном языке», не решит никакую проблему, только сожрёт N-ное количество времени – значит сейчас, на данном этапе это просто контрпродуктивно.

Средства для локализации / интернационализации игр-миров на уровне движка – нужно ли и в каком виде?

Позиционный звук – что для него вообще использовать? Первым в голову приходит OpenAL, но он в последних версиях спроприетарился и скурвился. Использовать старые версии? Или есть современные решения?

Сейчас есть PKGBUID-ы под этот наш Арч и они хороши. Но что бы придумать с поддержкой других десктопных дистров? Есть скрипты и даже CMakeLists.txt, чтобы скачать все модули движка в уютный хомячок и там же собрать. Нужно ли подобное? Стоит ли их поддерживать / обновлять и т.д. или лучше сделать разбиение на пакеты также как для Арча, с использованием, например CPack?

Оставить по этим вопросом мнение проще, чем писать или читать плюсовый (или любой другой) код, а также реально поможет в развитии, но эти вопросы ты проигнорил, троляшка, так что не обижайся уж, что на твоём троллийском наречии ЛИЧНО С ТОБОЙ (написанная капсом эта фраза тебя ведь триггерит, значит и в этот раз будет эффективно, я полагаю) говорю :P

robus ★★★★ ()

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

С достаточно большой уверенностью, могу сказать, что до играбельного прототипа я дотолкаю игру довольно скоро

Ты лжёшь себе и нам.

Если нет, то как найти патронов / инвесторов?

Для начала реши для себя что ты хочешь делать:

  • Если зарабатывать, то ты идёшь неверной дорогой. Тут берут готовый движок, делают играбельный прототип и идут клянчить деньги на полноценную игру и читать документацию по продвижению.
  • Если делать свободную игру, то ты идёшь неверной дорогой. Тут берут готовый движок, делают играбельный прототип и идут показывать на ЛОР и искать единомышленников, а на деньги не отвлекаются, потому что ничего не заработаешь, время потратишь и угробишь уникальные идеи в угоду рыночку

Ни для одного из двух вариантов ты не выполнил базовые пункты, потому что твоя цель - заниматься писаниной «движка». Который ещё минимум год будет уметь и выглядеть на уровне убогого примера из статьи по компьютерной графике, а потом тебе надоест. Так и говори.

Есть скрипты и даже CMakeLists.txt, чтобы скачать все модули движка в уютный хомячок и там же собрать

У нормального проекта который можно будет опакетить должен быть CMakeLists.txt который ничего не качает, а собирает твои исходники с зависимостями из системы. Больше ни на что тратить время разработчик не должен.

slovazap ★★★★★ ()