Сегодня стартовала летняя распродажа в Steam!
Расчехляйте копилки, господа!
P.S. Под последним постом в комментах как раз делились хорошими играми, авось они и скидку получат на распрадаже!
Расчехляйте копилки, господа!
P.S. Под последним постом в комментах как раз делились хорошими играми, авось они и скидку получат на распрадаже!
Steampowered
Steam Store
Steam is the ultimate destination for playing, discussing, and creating games.
👍5❤🔥4🫡2
This media is not supported in your browser
VIEW IN TELEGRAM
Затрону тему геймдизайна баланса, или то, чем еще приходится заниматься разработчикам игр
В моем экспериментальном проекте, под рабочим названием LazyDungeon, я собираюсь делать имитацию боевки. Игра вообще про данжи, где надо захватывать "комнаты" данжа, отстраиваться там, прокачиваться и т.д. Т.к. я нищеброд, то на боевку я решил забить и сделать ее имитацию - таймер по истечению которого будут результаты "захвата" очередной комнаты.
Технически - всё просто. Особенно, учитывая, что на результат кроме рандома влияет всего лишь один параметр: сила отряда. Ну, вернее два: сила отряда игрока и сила отряда врагов в комнате. И вот тут возникает вся магия математики в играх: как сделать так, чтобы результаты имитации боя были хотя бы отдаленно похожи на результат настоящего боя?
Ключевой и стратегический момент в игре - игрок может нести потери. Если потерь нет - то это просто айдл механика, если потери есть - начинается стратегия. А стратегию нужно просчитывать, что и является тем лакомым кусочком игр данного жанра.
Итак, результат боя должен быть в какой-то степени предсказуемым, но не совсем. То есть в зависимости от силы отрядов - можно захватить комнату, или не захватить и понести потери - в каких размерах, пока не понятно. И всё это еще снабдить какой-то долей рандома, чтобы не обязательно если у игрока меньше сил, то он проиграл - слишком прямолинейно, никакая стратегия не нужна.
Поэтому я ввожу градацию сложности: в зависимости от соотношения сил, я выдаю шансы понести потери. Например, если у игрока отряд в два раза слабее вражеского - то он теряет до 80-90% отряда, и если у него кто-то остается, то захват комнаты проходит успешно. Таких градаций несколько, все сводится к тому, что чем меньше сил у игрока - тем больше потерь он понесет, но это еще не значит, что он проиграет. Если в отряде будет достаточно юнитов, что даже при потерях в 99.99% отряда, останется хотя бы один юнит - комната будет захвачена.
Я сделал в итоге 6 отрезков для определения потерь в отряде игрока, в зависимости от соотношения "сила отряда игрока / сила отряда врага". 0-0.5, 0.5-0.75, 0.75-1, 1-1.25, 1.25-1.5, 1.5-2. Минимальное соотношение будет всегда больше 0, т.к. как минимум 1 юнит то в отряде будет, шансы на победу при соотношении сил меньше 0.5 стремятся к 0, потому что потери стремятся к 100% (но никогда не будут 100%, пограничное значение 99.99%). И наоборот, если отряд игрока в 2 и более раз сильнее вражеского, то шансы на победу стремятся к 100%, потому что потери стремятся к 0.
Далее я определяю "корридоры сложности". Например: 0-20% потерь = ваще легко, 20-40% потерь - легко, 40-60% средне и т.д. Это и видит игрок и строит стратегию, готов ли он нести такие потери или нет.
В конце концов, имею две величины: количество потерь в битве, и получившуюся сложность (корридор потерь). Для имитации битвы вычисляю рандомное значение в пределах сложности, отбираю у игрока юнитов (тут еще предстоит додумать, как юнитов отбирать, т.к. они разные, с разной силой и т.д.). И получаю результат: если есть юниты - комната захвачена, если нет, то увы, игрок растерял весь отряд.
___
В крупных компаниях обычно такими задачами занимается отдельный геймдизайнер, он так и называется - геймдизайнер баланса. Такому человеку предстоит много считать, заполнять множество табличек, придумывать множество формул, и чтобы это всё гармонично работало на опыт игроку.
В моем экспериментальном проекте, под рабочим названием LazyDungeon, я собираюсь делать имитацию боевки. Игра вообще про данжи, где надо захватывать "комнаты" данжа, отстраиваться там, прокачиваться и т.д. Т.к. я нищеброд, то на боевку я решил забить и сделать ее имитацию - таймер по истечению которого будут результаты "захвата" очередной комнаты.
Технически - всё просто. Особенно, учитывая, что на результат кроме рандома влияет всего лишь один параметр: сила отряда. Ну, вернее два: сила отряда игрока и сила отряда врагов в комнате. И вот тут возникает вся магия математики в играх: как сделать так, чтобы результаты имитации боя были хотя бы отдаленно похожи на результат настоящего боя?
Ключевой и стратегический момент в игре - игрок может нести потери. Если потерь нет - то это просто айдл механика, если потери есть - начинается стратегия. А стратегию нужно просчитывать, что и является тем лакомым кусочком игр данного жанра.
Итак, результат боя должен быть в какой-то степени предсказуемым, но не совсем. То есть в зависимости от силы отрядов - можно захватить комнату, или не захватить и понести потери - в каких размерах, пока не понятно. И всё это еще снабдить какой-то долей рандома, чтобы не обязательно если у игрока меньше сил, то он проиграл - слишком прямолинейно, никакая стратегия не нужна.
Поэтому я ввожу градацию сложности: в зависимости от соотношения сил, я выдаю шансы понести потери. Например, если у игрока отряд в два раза слабее вражеского - то он теряет до 80-90% отряда, и если у него кто-то остается, то захват комнаты проходит успешно. Таких градаций несколько, все сводится к тому, что чем меньше сил у игрока - тем больше потерь он понесет, но это еще не значит, что он проиграет. Если в отряде будет достаточно юнитов, что даже при потерях в 99.99% отряда, останется хотя бы один юнит - комната будет захвачена.
Я сделал в итоге 6 отрезков для определения потерь в отряде игрока, в зависимости от соотношения "сила отряда игрока / сила отряда врага". 0-0.5, 0.5-0.75, 0.75-1, 1-1.25, 1.25-1.5, 1.5-2. Минимальное соотношение будет всегда больше 0, т.к. как минимум 1 юнит то в отряде будет, шансы на победу при соотношении сил меньше 0.5 стремятся к 0, потому что потери стремятся к 100% (но никогда не будут 100%, пограничное значение 99.99%). И наоборот, если отряд игрока в 2 и более раз сильнее вражеского, то шансы на победу стремятся к 100%, потому что потери стремятся к 0.
Далее я определяю "корридоры сложности". Например: 0-20% потерь = ваще легко, 20-40% потерь - легко, 40-60% средне и т.д. Это и видит игрок и строит стратегию, готов ли он нести такие потери или нет.
В конце концов, имею две величины: количество потерь в битве, и получившуюся сложность (корридор потерь). Для имитации битвы вычисляю рандомное значение в пределах сложности, отбираю у игрока юнитов (тут еще предстоит додумать, как юнитов отбирать, т.к. они разные, с разной силой и т.д.). И получаю результат: если есть юниты - комната захвачена, если нет, то увы, игрок растерял весь отряд.
___
В крупных компаниях обычно такими задачами занимается отдельный геймдизайнер, он так и называется - геймдизайнер баланса. Такому человеку предстоит много считать, заполнять множество табличек, придумывать множество формул, и чтобы это всё гармонично работало на опыт игроку.
👍18🔥6🆒4❤2
Скриншот-суббота
Vol. 136
Праздная (читай ленивая). Если вы это читаете, то я где-то в Златиборе на пути в Сараево
🔠 ProjectLazyDungeon движется: занимаюсь юнитами. Помимо покупки, из можно ещё и выкидывать из отряда с возвращением части монеток. И прорабатываю имитацию боя через формулу. Кстати о ней я и рассказывал вчера в посте
___
Ну и всё! Где-то новости почитал, где-то сценарий почиркал, где-то игру прошел, где-то вдохновился. Кстати, об этом тоже надо рассказать, думаю интересно будет. А вы пока в комментах накидайте своих результатов за неделю, за побольше!
#скриншотсуббота
Vol. 136
Праздная (читай ленивая). Если вы это читаете, то я где-то в Златиборе на пути в Сараево
___
Ну и всё! Где-то новости почитал, где-то сценарий почиркал, где-то игру прошел, где-то вдохновился. Кстати, об этом тоже надо рассказать, думаю интересно будет. А вы пока в комментах накидайте своих результатов за неделю, за побольше!
#скриншотсуббота
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8🆒3
Архитектура_проектов_с_использованием_MVVM_drawio_1.png
96.6 KB
Всем понедельника!
Потихоньку намереваюсь схематично насхематизировать схему ключевых моментов архитектуры в игрострое. Буду делать постепенно с вашими вопросами, а то я как профдеформированный могу не видеть остро важные для понимания моменты. Ну, знаете, это как в учебниках: тот кто составлял учебник всё прекрасно понимает, а тот кто читает - не может связать, что к чему и зачем.
В общем, давайте начнем со входа в игру. Схема простая, но самая важная. Какие вопросы возникают глядя на схемку? Какой момент вызывает больше всего вопросов, вроде "А что это значит? А как это делается?". По вашим вопросам, буду дополнять/изменять, так что заранее благодарю. Вопрошать можно в комментах.
А здесь будет большая абоба, содержащая все схемки и подсхемки. Кстати, да, имеется ввиду архитектура на MVVM:
https://drive.google.com/file/d/1jFBCFzzhSuKG8rdnW-XEPON1HabQl56O/view?usp=sharing
Потихоньку намереваюсь схематично насхематизировать схему ключевых моментов архитектуры в игрострое. Буду делать постепенно с вашими вопросами, а то я как профдеформированный могу не видеть остро важные для понимания моменты. Ну, знаете, это как в учебниках: тот кто составлял учебник всё прекрасно понимает, а тот кто читает - не может связать, что к чему и зачем.
В общем, давайте начнем со входа в игру. Схема простая, но самая важная. Какие вопросы возникают глядя на схемку? Какой момент вызывает больше всего вопросов, вроде "А что это значит? А как это делается?". По вашим вопросам, буду дополнять/изменять, так что заранее благодарю. Вопрошать можно в комментах.
А здесь будет большая абоба, содержащая все схемки и подсхемки. Кстати, да, имеется ввиду архитектура на MVVM:
https://drive.google.com/file/d/1jFBCFzzhSuKG8rdnW-XEPON1HabQl56O/view?usp=sharing
🔥24👍7❤🔥3
Продолжим разбор архитектурных вопросов
Дисклеймер:
Придется потерпеть скучные и местами рваные кусочки информации, потому что я решил собрать всё в кучу, но сделать это постепенно, отслеживая фидбек, чтобы не отойти в сторону. Потом это всё соберется в отдельную видео-лекцию. За вопросы всем заранее спасибо!
Наверное, про игровое состояние знают все (если не все - отпишитесь, в комментах, плез). Но вот что точно знают не все, так это то, как оно должно меняться, чтобы было не больно. Для того, чтобы все работало хорошо, стабильно и легко расширяемо и изменяемо, реализуем тот самый принцип единой ответственности (да, тот что из SOLID).
1. Существуют классы, которые знают КАК менять данные. Знают, потому что вы их написали, конечно. Их называют обработчики данных. На скринах можно увидеть пример обработки добавления предмета в инвентарь. Отдельный класс, он умеет только добавлять предмет в инвентарь и возвращать ответ, на этом всё. Это вынесенно намеренно в отдельный класс, чтобы в случае резкого изменения механики добавления просто выбросить этот класс и написать новый без поисков откуда ноги растут. Если при добавлении предмета что-то работает не так - знаем где искать.
2. Сервисы. Это прослойка, которую могут видеть практически все в проекте. Они в себе собирают обработчики данных и могут ими жонглировать, чтобы менять данные как нужно. В сервис инвентаря можно послать команду добавить предмет в инвентарь, убрать, а можно просто написать метод проверки: есть ли предмет в инвентаре. В хорошем исполнении монобехи не могут видеть сервисы, их видят вьюмодели, контроллеры и т.д. Но даже если видят почему-то, игра будет весьма стабильной, т.к. изменение данных происходит в одном месте, которое управляется из какого-либо сервиса.
На скринах показана связка, для чего нужен сервис и как он взаимодействует с данными (через посредника - обработчика данных). Это, наверное, базовая база. MVVM, MVP, MVC, независимо от выбранной базы архитектуры, связка сервис - обработчик данных останется прежней. Если упороться, можно и в ECS применять, но там это излишне, ECS немного по-другому работает,
Дисклеймер:
Придется потерпеть скучные и местами рваные кусочки информации, потому что я решил собрать всё в кучу, но сделать это постепенно, отслеживая фидбек, чтобы не отойти в сторону. Потом это всё соберется в отдельную видео-лекцию. За вопросы всем заранее спасибо!
Наверное, про игровое состояние знают все (если не все - отпишитесь, в комментах, плез). Но вот что точно знают не все, так это то, как оно должно меняться, чтобы было не больно. Для того, чтобы все работало хорошо, стабильно и легко расширяемо и изменяемо, реализуем тот самый принцип единой ответственности (да, тот что из SOLID).
1. Существуют классы, которые знают КАК менять данные. Знают, потому что вы их написали, конечно. Их называют обработчики данных. На скринах можно увидеть пример обработки добавления предмета в инвентарь. Отдельный класс, он умеет только добавлять предмет в инвентарь и возвращать ответ, на этом всё. Это вынесенно намеренно в отдельный класс, чтобы в случае резкого изменения механики добавления просто выбросить этот класс и написать новый без поисков откуда ноги растут. Если при добавлении предмета что-то работает не так - знаем где искать.
2. Сервисы. Это прослойка, которую могут видеть практически все в проекте. Они в себе собирают обработчики данных и могут ими жонглировать, чтобы менять данные как нужно. В сервис инвентаря можно послать команду добавить предмет в инвентарь, убрать, а можно просто написать метод проверки: есть ли предмет в инвентаре. В хорошем исполнении монобехи не могут видеть сервисы, их видят вьюмодели, контроллеры и т.д. Но даже если видят почему-то, игра будет весьма стабильной, т.к. изменение данных происходит в одном месте, которое управляется из какого-либо сервиса.
На скринах показана связка, для чего нужен сервис и как он взаимодействует с данными (через посредника - обработчика данных). Это, наверное, базовая база. MVVM, MVP, MVC, независимо от выбранной базы архитектуры, связка сервис - обработчик данных останется прежней. Если упороться, можно и в ECS применять, но там это излишне, ECS немного по-другому работает,
👍31❤5⚡2🤓2
Еще день, еще схемка! MVVM подъехал
Дисклеймер: схемка расширяет информацию из предыдущего поста
MVP, MVC, MVVM - распространенные архитектурные паттерны в разработке приложений. Многие говорят, что они фигово ложатся на геймдев, и доля правды в этом есть. Нюанс в том, чтобы понять кто такой View, а кто такой ViewModel/Controller/Presenter, кто из них является монобехом и кто кем управляет. Небольшая путанница, я бы сказал.
На мой скромный взгляд, лучше всего на движок ложится MVVM подход, потому что его легко можно раскидывать в виде дерева зависимостей спускаясь от корневых вьюмоделей и баиндеров и глубоко внутрь во вложенность. Очень хорошо ложится на движок, монобехи, префабы и т.д.
В своем опыте я видел несколько реализации MVVM, из них была плохая только одна: где ViewModel была монобехом. Было жутко неудобно и непонятно зачем так. Самая надежная схема (представлена в скриншоте) - когда модель представлена сервисами и обработчиками данных, вьюмодели могут ссылаться на сервисы, чтобы запрашивать данные или их изенение, а вью, которые представлены баиндерами (монобехами), могут получать данные из вьюмодели (которые доступны только на чтение), подписываться на них и посылать сигналы с запросом на изменение данных (читай Инпут). Вот и всё
Область видимости следующая:
- Данные никого не видят, их могут только обрабатывать снаружи
- Обработчики команд (данных) видят данные и могут их обрабатывать, больше ни о ком не знают
- Сервисы знают про обработчики команд, имеют данные для чтения и методы для запуска изменения данных. В теории могут создавать вьюмодели
- ВьюМодели знают про сервисы, поэтому могут туда посылать запросы на изменение данных. Также они знают о данных (через сервисы), и могут их конвертировать в удобный формат. Например: при изменении количества объектов в инвентаре реагировать внутренним дополнительным флагом IsInventoryEmpty, эти данные торчат наружа (публичные) в виде реактивных свойств. Ну и методы инпута есть, которые прилетают из монобехов
- Вью (то есть баиндеры), знают про их вьюмодель. Она передается через специальный метод Bind(). Таким образом вью может подписаться на изменение данных (даже обработанных вьюмоделью), и посылать сигналы через публичные методы (инпут).
Как-то так. Остались вопросы - обязательно задавай в комментах!
Дисклеймер: схемка расширяет информацию из предыдущего поста
MVP, MVC, MVVM - распространенные архитектурные паттерны в разработке приложений. Многие говорят, что они фигово ложатся на геймдев, и доля правды в этом есть. Нюанс в том, чтобы понять кто такой View, а кто такой ViewModel/Controller/Presenter, кто из них является монобехом и кто кем управляет. Небольшая путанница, я бы сказал.
На мой скромный взгляд, лучше всего на движок ложится MVVM подход, потому что его легко можно раскидывать в виде дерева зависимостей спускаясь от корневых вьюмоделей и баиндеров и глубоко внутрь во вложенность. Очень хорошо ложится на движок, монобехи, префабы и т.д.
В своем опыте я видел несколько реализации MVVM, из них была плохая только одна: где ViewModel была монобехом. Было жутко неудобно и непонятно зачем так. Самая надежная схема (представлена в скриншоте) - когда модель представлена сервисами и обработчиками данных, вьюмодели могут ссылаться на сервисы, чтобы запрашивать данные или их изенение, а вью, которые представлены баиндерами (монобехами), могут получать данные из вьюмодели (которые доступны только на чтение), подписываться на них и посылать сигналы с запросом на изменение данных (читай Инпут). Вот и всё
Область видимости следующая:
- Данные никого не видят, их могут только обрабатывать снаружи
- Обработчики команд (данных) видят данные и могут их обрабатывать, больше ни о ком не знают
- Сервисы знают про обработчики команд, имеют данные для чтения и методы для запуска изменения данных. В теории могут создавать вьюмодели
- ВьюМодели знают про сервисы, поэтому могут туда посылать запросы на изменение данных. Также они знают о данных (через сервисы), и могут их конвертировать в удобный формат. Например: при изменении количества объектов в инвентаре реагировать внутренним дополнительным флагом IsInventoryEmpty, эти данные торчат наружа (публичные) в виде реактивных свойств. Ну и методы инпута есть, которые прилетают из монобехов
- Вью (то есть баиндеры), знают про их вьюмодель. Она передается через специальный метод Bind(). Таким образом вью может подписаться на изменение данных (даже обработанных вьюмоделью), и посылать сигналы через публичные методы (инпут).
Как-то так. Остались вопросы - обязательно задавай в комментах!
🔥31👍12❤🔥5
Еще одна схемка, очень надеюсь, что понятная для тех, кто слышал слово DI или фразу Dependency Injection
На схемке типичная контейнеризация зависимостей, разделенная на разные уровни доступа:
- Уровень игры, где лежат сервисы, существующие всю игровую сессию. Часто это сервисы аналитики, показа рекламы, платежей, время и подобные
- Уровень сервисов сцены, тут тоже лежат сервисы, но исключительно для сцены. Внутрь него кладется контейнер уровня игры, таким образом всё, что регистрируется внутри контейнера сервисов сцены может видеть и сервисы игры. Чтобы например запрашивать рекламу, отправлять аналитику и т.д.
- Уровень вьюмоделей сцены. В него кладется уже контейнер с сервисами сцены, таким образом вьюмодели для отображения данных имеют полный кардбланш для запросов дополнительной и важной информации. Что-то со сцены, например логика инвентаря, что-то из глобального уровня, например локализатор.
На скриншоте кодом показал, как примерно происходит контейнеризация. Она может быть автоматической, как это в ZenJect сделано, а может быть ручной.
Все вопросы, особенно от тех, кто вообще ничего не понял - жду в комментариях, желательно с пояснением, какая часть именно не понятна.
На схемке типичная контейнеризация зависимостей, разделенная на разные уровни доступа:
- Уровень игры, где лежат сервисы, существующие всю игровую сессию. Часто это сервисы аналитики, показа рекламы, платежей, время и подобные
- Уровень сервисов сцены, тут тоже лежат сервисы, но исключительно для сцены. Внутрь него кладется контейнер уровня игры, таким образом всё, что регистрируется внутри контейнера сервисов сцены может видеть и сервисы игры. Чтобы например запрашивать рекламу, отправлять аналитику и т.д.
- Уровень вьюмоделей сцены. В него кладется уже контейнер с сервисами сцены, таким образом вьюмодели для отображения данных имеют полный кардбланш для запросов дополнительной и важной информации. Что-то со сцены, например логика инвентаря, что-то из глобального уровня, например локализатор.
На скриншоте кодом показал, как примерно происходит контейнеризация. Она может быть автоматической, как это в ZenJect сделано, а может быть ручной.
Все вопросы, особенно от тех, кто вообще ничего не понял - жду в комментариях, желательно с пояснением, какая часть именно не понятна.
👍18🔥8❤4🥴2
This media is not supported in your browser
VIEW IN TELEGRAM
Скриншот-суббота
Vol. 137
Схематичная, математичная
🔠 ProjectLazyDungeon движется: разработал формулу симуляции боя, включая вычисление сложности битвы. Получается так, что чем слабее отряд игрока относительно вражеского - тем больше он несет потерь. При этом присутствует доля рандома, так что даже с очень слабым отрядом есть мизерный шанс успешного захвата. Надо будет уже тестить на игроках ошчушчения. Демонстрация в комментах
🔠 Для продолжения цикла роликов проекта #пилиигру надо бы разработать видение архитектуры проекта, и поэтому я на этой неделе упарывался в схемки, к которым я смогу отсылаться, чтобы рассказать всю картину в целом в сжатые сроки. Благодарю за вопросы в комментах, они мне тоже помогут в уточнениях. Схемки глануть можно здесь, здесь, здесь и здесь.
___
Еще играю в Ratchet & Clank: Rift Apart. Будет что рассказать, т.к. намереваюсь пройти. А вы чем занимались на неделе? Кидайте в комменты вашинюдсы гифки, тексты с результатами!
#скриншотсуббота
Vol. 137
Схематичная, математичная
___
Еще играю в Ratchet & Clank: Rift Apart. Будет что рассказать, т.к. намереваюсь пройти. А вы чем занимались на неделе? Кидайте в комменты ваши
#скриншотсуббота
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8⚡6😱2
Продолжаем идти по "кусочкам" архитектурной схемки
Наиболее удобным для управления, расширения, изменения данных способом на моем опыте оказался паттерн команда, используемый через сервисы. В игре существует некий ICommandProcessor, который при старте игры/сцены пичкается набором обработчиков команд. То есть фактически процессор бесконечно расширяемый и не зависит от собственных кишков. Этот процессор раздается всем желающим. И все желающие могут создать команду и послать в процессор для обработки.
Если процессор найдет внутри себя нужный обработчик - он ее выполнит. Не найдет - там уж как захочется разработчику, исключение или просто игнор - не важно. В примере на скрине, я привел фрагмет кода, как может выглядеть смена абилки в определенном слоте у персонажа. Запуск через сервис, обработка - через процессор в обработчике. Сервис не участвует в обработке, он лишь дособирает нужные данные, чтобы отправить их уже на обработку.
Подход с реализацией команды удобен не только расширяемостью, но и мультиплеерной интеграцией. Ту же команду с данными можно просто отправить по сети и на другом клиенте также послать ее на процессор и всё будет синхронизовано
Этим мы уже занимались в #пилимигру, если что. У нас как раз домики так строятся.
Вопросики в комменты, пожалуйста!
Наиболее удобным для управления, расширения, изменения данных способом на моем опыте оказался паттерн команда, используемый через сервисы. В игре существует некий ICommandProcessor, который при старте игры/сцены пичкается набором обработчиков команд. То есть фактически процессор бесконечно расширяемый и не зависит от собственных кишков. Этот процессор раздается всем желающим. И все желающие могут создать команду и послать в процессор для обработки.
Если процессор найдет внутри себя нужный обработчик - он ее выполнит. Не найдет - там уж как захочется разработчику, исключение или просто игнор - не важно. В примере на скрине, я привел фрагмет кода, как может выглядеть смена абилки в определенном слоте у персонажа. Запуск через сервис, обработка - через процессор в обработчике. Сервис не участвует в обработке, он лишь дособирает нужные данные, чтобы отправить их уже на обработку.
Подход с реализацией команды удобен не только расширяемостью, но и мультиплеерной интеграцией. Ту же команду с данными можно просто отправить по сети и на другом клиенте также послать ее на процессор и всё будет синхронизовано
Этим мы уже занимались в #пилимигру, если что. У нас как раз домики так строятся.
Вопросики в комменты, пожалуйста!
🔥19👍8
🎯 Ищем игры на релиз и маркетинг!
Мы ищем партнеров, чьи проекты находятся на стадии активной разработки. Нас вдохновляют игры, которые не только развлекают, но и заставляют задуматься.
Идеальный кандидат:
📌 Сформированная команда (1-30 человек) с доказанным опытом или сильным прототипом.
📌 Проект с четкой дорожной картой, ведущей к релизу в ~2026 году.
📌 Игра, сочетающая сильную тематику (техно/этика/история), новаторский геймплей и выразительный визуал.
Мы предлагаем:
✅ Поддержку,
🤝Партнерство,
💥Издательство,
🔥МАРКЕТИНГ
Присылайте свой проект👉 https://yangx.top/CyberRomGamesBot
📩 https://gamecyber.ru
Мы ищем партнеров, чьи проекты находятся на стадии активной разработки. Нас вдохновляют игры, которые не только развлекают, но и заставляют задуматься.
Идеальный кандидат:
📌 Сформированная команда (1-30 человек) с доказанным опытом или сильным прототипом.
📌 Проект с четкой дорожной картой, ведущей к релизу в ~2026 году.
📌 Игра, сочетающая сильную тематику (техно/этика/история), новаторский геймплей и выразительный визуал.
Мы предлагаем:
✅ Поддержку,
🤝Партнерство,
💥Издательство,
🔥МАРКЕТИНГ
Присылайте свой проект👉 https://yangx.top/CyberRomGamesBot
📩 https://gamecyber.ru
Baldur's Gate III пройден
Играя одну сессию в неделю с друганами, 109 часов геймплея прошлись за полтора года реальной жизни. Впечатляет!
А ведь игра стоит всего $30 (вероятно, где-то подороже, но тем не менее). $30 за 109 часов историй и развлечений, представляете? А говорят, игры дорогие нынче.
Хочу поделиться отзывом об этой игре.
От игрока:
Игра отличная, однако Divinity: Original Sin 2 лучше. В этом мы сошлись во мнении с моими друзьями после завершения BG3. В свою очередь Baldur's Gate 3 взяла награзу GOTY вполне заслуженно. В игре графон, в игре сюжет, в игре тонны интерактивностей, что позволяет не скучать учитывая достаточно однообразную боёвку.
Что понравилось:
- DND с кубиком. Larian показали, как работают механики рандома в ДНД играх буквально подбрасыванием кубика. Это позволило многим игрокам узнать больше о DND (в том числе и для меня) и многих даже побудило поиграть в настолки. Механика классная, и породила множество мемов.
- История. А именно - персонажи. История не про спасение мира, но спасение города, понравилось. Персонажи вообще классные, у каждого своя глубокая история, свои проблемы, страхи, свой характер. Не могу вспомнить персонажей, прописанных лучше, чем в BG 3
- Графоний - завезли. Игра оч красивая
- Сиси и писи - завезли, в том числе романтик и любовные утехи. К тому же все помнят ролик про соитие с друидом в форме медведя. Такое одновременно откровенное и нейтральное изображение темы наготы и секса мне понравилось
- Баланс игры-сюжета, неторопливый геймплей с интересными сюжетными вставками, с большой вариативностью происходящего, плюс зависящего от навыков (в основном харизмы), идеальный кандидат на прохождение в кооперативе под чипсеки
Что НЕ понравилось:
- Прокачка. 12 (вроде) уровней за всю игру, качаются долго и различия между первым уровнем и уровнем после 100 часов игры, не то чтобы не значительны, но хотелось бы больше. Способностей много, но пользуешься 3-4.
- Боевка. Очки действий и навыков перемудрили, как мне кажется. Кто играл, тот поймет. Вроде бы их цель сделать ограничение на использование мощных навыков, но получилось так себе. Сами бои не шибко сложные, чтобы это имело хоть какой-нибудь смысл. Плюс, можно использовать долгий отдых без особых последствий, поэтому после боя можно восстановить все силы. Самое большое разочарование - смещение фокуса с комбинированных атак. Когда разливаешь воду - электризуешь ее, масло - поджигаешь, кровь - мажешь стрелы и т.д. Они есть (комб атаки), но внимания им не уделяется, эффекта от них существенного нет. Стратегия тут скукожилась
- Лут. Тут минус небольшой, за все 109 часов я нашел лишь один плащ на мага, это... Страннова-то
Итог:
BG 3 с точки зрения разработки геймплея и основных механик на самом деле не очень-то большая. Огромная работа была проведена с окружением, с катсценами, с сюжетом, вариативностью и балансом - это правда. Рекомендую ли я в нее поиграть? Наверное, да. Особенно, коопчиком под чипсеки
Играя одну сессию в неделю с друганами, 109 часов геймплея прошлись за полтора года реальной жизни. Впечатляет!
А ведь игра стоит всего $30 (вероятно, где-то подороже, но тем не менее). $30 за 109 часов историй и развлечений, представляете? А говорят, игры дорогие нынче.
Хочу поделиться отзывом об этой игре.
От игрока:
Игра отличная, однако Divinity: Original Sin 2 лучше. В этом мы сошлись во мнении с моими друзьями после завершения BG3. В свою очередь Baldur's Gate 3 взяла награзу GOTY вполне заслуженно. В игре графон, в игре сюжет, в игре тонны интерактивностей, что позволяет не скучать учитывая достаточно однообразную боёвку.
Что понравилось:
- DND с кубиком. Larian показали, как работают механики рандома в ДНД играх буквально подбрасыванием кубика. Это позволило многим игрокам узнать больше о DND (в том числе и для меня) и многих даже побудило поиграть в настолки. Механика классная, и породила множество мемов.
- История. А именно - персонажи. История не про спасение мира, но спасение города, понравилось. Персонажи вообще классные, у каждого своя глубокая история, свои проблемы, страхи, свой характер. Не могу вспомнить персонажей, прописанных лучше, чем в BG 3
- Графоний - завезли. Игра оч красивая
- Сиси и писи - завезли, в том числе романтик и любовные утехи. К тому же все помнят ролик про соитие с друидом в форме медведя. Такое одновременно откровенное и нейтральное изображение темы наготы и секса мне понравилось
- Баланс игры-сюжета, неторопливый геймплей с интересными сюжетными вставками, с большой вариативностью происходящего, плюс зависящего от навыков (в основном харизмы), идеальный кандидат на прохождение в кооперативе под чипсеки
Что НЕ понравилось:
- Прокачка. 12 (вроде) уровней за всю игру, качаются долго и различия между первым уровнем и уровнем после 100 часов игры, не то чтобы не значительны, но хотелось бы больше. Способностей много, но пользуешься 3-4.
- Боевка. Очки действий и навыков перемудрили, как мне кажется. Кто играл, тот поймет. Вроде бы их цель сделать ограничение на использование мощных навыков, но получилось так себе. Сами бои не шибко сложные, чтобы это имело хоть какой-нибудь смысл. Плюс, можно использовать долгий отдых без особых последствий, поэтому после боя можно восстановить все силы. Самое большое разочарование - смещение фокуса с комбинированных атак. Когда разливаешь воду - электризуешь ее, масло - поджигаешь, кровь - мажешь стрелы и т.д. Они есть (комб атаки), но внимания им не уделяется, эффекта от них существенного нет. Стратегия тут скукожилась
- Лут. Тут минус небольшой, за все 109 часов я нашел лишь один плащ на мага, это... Страннова-то
Итог:
BG 3 с точки зрения разработки геймплея и основных механик на самом деле не очень-то большая. Огромная работа была проведена с окружением, с катсценами, с сюжетом, вариативностью и балансом - это правда. Рекомендую ли я в нее поиграть? Наверное, да. Особенно, коопчиком под чипсеки
👍22❤10🤡4
Поделюсь еще одной схемкой. Более непонятно, но уже ближе к проекту #пилимигру, что мы с вами делаем
В посте выше, я уже рассказывал, как устроены взаимосвязи в MVVM. Но то были взаимосвязи "по вертикали", то есть кто кого видит, и за что отвечает. Теперь же нам нужно бы разобраться, как строятся горизонтальные связи. Как условное оружие, которое можно модернизировать отображается и в геймплее и в UI окошке с крафтом, например? Используют ли они одну вьюмодель?
Прежде чем читать далее, небольшой дисклеймер:
1. На схеме выше, а также в проекте #пилимигру мы делаем не бест оф зе бест реализацию MVVM. Потому что идеальная реализация подразумевает то, что баиндеры - это маленькие монобехи цепляющиеся непосредственно к свойствам классов вьюмодели. То есть в редакторе вешаешь баиндер (монобех) на строку, выбираешь вьюмодель к которой цепляешься и реактивное свойство со строкой. Таким образом такой баиндер можно использовать повсюду. Баиндеры могут быть и на спрайты, и на звуки, и ковертеры вроде bool => Sprite, чтобы в зависимости от реактивного свойтсва подставлять нужную картинку и т.д. Этого у нас не будет, но у меня однажды была попытка сделать подобное в ассете Lukomor. Наверное, надо бы его обновить, глядишь, полезным окажется
2. Вьюмодели нужны не для всех объектов в игре. В зависимости от игры, для мировых объектов вьюмодели могут не применяться. Пример: игры вроде Lethal Company, или R.E.P.O. Все объекты с которыми можно взаимодействовать не нуждаются во вьюмоделях, т.к. не содержат необходимости быть соединенными с моделью. Игрок играет сессию, собирает/рушит/перемещает предметы в игре, но это никак не влияет на модель (сами предметы в модели никак не отображаются). Предметы могут нанести урон игроку - но это происходит за счет игрока, соединенного с моделью, а не предметов. Так что не нужно пихать вьюмодели там, где они не нужны.
В остальном, мы получаем некое дерево зависимостей, с входом через 2 точки: для UI и для World, т.е. для мира. Так разделено, потому что UI обычно создается из префаба, а World (то бишь сцена) имеет какие-то заготовки помимо создаваемых объектов. Фабрики вьюмоделей регистрируются в DI контейнере, поэтому в момент входа на сцену после регистрации, мы можем запросить нам выдать корневые вьюмодели - для UI и для World. Тут же в точке входа мы можем вытащить UIRootBinder и WorldRootBinder и выполнить методы Bind(uiRootViewModel) и Bind(worldRootViewModel) на обоих. Каждая вьюмодель может иметь внутри себя ссылки или списки ссылок на другие вьюмодели. Они даже могут пересекаться (несколько вьюмоделей иметь ссылку на одну и ту же модель, см. ViewModel D). Игрок имеет инвентарь, инвентарь имеет ячейку, ячейка имеет предмет - вложенность, я думаю понятна.
Получается каждый баиндер получает свою модель. И (в нашем проекте) каждый баиндер имеет ссылку на вложенные баиндеры. То есть условный баиндер инвентаря имеет ссылку на баиндеры ячеек инвентаря. Баиндер инвентаря получает вьюмодель инвентаря в которой лежит список вьюмоделей ячеек инвентаря. Баиндер инвентаря проходится по этому списку и запихивает каждую вьюмодель ячейки в баиндер ячейки. И так далее. Получается дерево.
Интересный момент, что при такой структуре разные баиндеры могут получать одну и ту же модель и отображать ее по разному. Вспомним пример с крафтовым оружием из начала поста: вьюмодель оружия содержит информацию обо всех "обвесах", мировой баиндер оружия их визуализирует, а UI баиндер показывает иконками, какой обвес в какой слот на оружии добавлен. Меняя обвес в UI, он автоматически меняется и в мире, т.к. биндеры подписаны на одну и ту же модель
Как-то так. Похоже, скоро всё соберется в кучку и выдавится в видеоролик.. Вопросы!
В посте выше, я уже рассказывал, как устроены взаимосвязи в MVVM. Но то были взаимосвязи "по вертикали", то есть кто кого видит, и за что отвечает. Теперь же нам нужно бы разобраться, как строятся горизонтальные связи. Как условное оружие, которое можно модернизировать отображается и в геймплее и в UI окошке с крафтом, например? Используют ли они одну вьюмодель?
Прежде чем читать далее, небольшой дисклеймер:
1. На схеме выше, а также в проекте #пилимигру мы делаем не бест оф зе бест реализацию MVVM. Потому что идеальная реализация подразумевает то, что баиндеры - это маленькие монобехи цепляющиеся непосредственно к свойствам классов вьюмодели. То есть в редакторе вешаешь баиндер (монобех) на строку, выбираешь вьюмодель к которой цепляешься и реактивное свойство со строкой. Таким образом такой баиндер можно использовать повсюду. Баиндеры могут быть и на спрайты, и на звуки, и ковертеры вроде bool => Sprite, чтобы в зависимости от реактивного свойтсва подставлять нужную картинку и т.д. Этого у нас не будет, но у меня однажды была попытка сделать подобное в ассете Lukomor. Наверное, надо бы его обновить, глядишь, полезным окажется
2. Вьюмодели нужны не для всех объектов в игре. В зависимости от игры, для мировых объектов вьюмодели могут не применяться. Пример: игры вроде Lethal Company, или R.E.P.O. Все объекты с которыми можно взаимодействовать не нуждаются во вьюмоделях, т.к. не содержат необходимости быть соединенными с моделью. Игрок играет сессию, собирает/рушит/перемещает предметы в игре, но это никак не влияет на модель (сами предметы в модели никак не отображаются). Предметы могут нанести урон игроку - но это происходит за счет игрока, соединенного с моделью, а не предметов. Так что не нужно пихать вьюмодели там, где они не нужны.
В остальном, мы получаем некое дерево зависимостей, с входом через 2 точки: для UI и для World, т.е. для мира. Так разделено, потому что UI обычно создается из префаба, а World (то бишь сцена) имеет какие-то заготовки помимо создаваемых объектов. Фабрики вьюмоделей регистрируются в DI контейнере, поэтому в момент входа на сцену после регистрации, мы можем запросить нам выдать корневые вьюмодели - для UI и для World. Тут же в точке входа мы можем вытащить UIRootBinder и WorldRootBinder и выполнить методы Bind(uiRootViewModel) и Bind(worldRootViewModel) на обоих. Каждая вьюмодель может иметь внутри себя ссылки или списки ссылок на другие вьюмодели. Они даже могут пересекаться (несколько вьюмоделей иметь ссылку на одну и ту же модель, см. ViewModel D). Игрок имеет инвентарь, инвентарь имеет ячейку, ячейка имеет предмет - вложенность, я думаю понятна.
Получается каждый баиндер получает свою модель. И (в нашем проекте) каждый баиндер имеет ссылку на вложенные баиндеры. То есть условный баиндер инвентаря имеет ссылку на баиндеры ячеек инвентаря. Баиндер инвентаря получает вьюмодель инвентаря в которой лежит список вьюмоделей ячеек инвентаря. Баиндер инвентаря проходится по этому списку и запихивает каждую вьюмодель ячейки в баиндер ячейки. И так далее. Получается дерево.
Интересный момент, что при такой структуре разные баиндеры могут получать одну и ту же модель и отображать ее по разному. Вспомним пример с крафтовым оружием из начала поста: вьюмодель оружия содержит информацию обо всех "обвесах", мировой баиндер оружия их визуализирует, а UI баиндер показывает иконками, какой обвес в какой слот на оружии добавлен. Меняя обвес в UI, он автоматически меняется и в мире, т.к. биндеры подписаны на одну и ту же модель
Как-то так. Похоже, скоро всё соберется в кучку и выдавится в видеоролик.. Вопросы!
🔥15👍8❤2
Скриншот-суббота
Vol. 138
Схематичная, нагруженная
🔠 ProjectLazyDungeon по-прежнемудвижется: симуляция боя полностью готова. Высчитываются потери, высчитывается результат, все это применяется и показывается игроку. Плюс появились награды за захват комнат, которые также можно увидеть до и после боя, ну и забрать их, конечно. Также теперь пока отряд занят на захвате комнаты - нельзя стартовать новый захват. В общем, стратегический геймплей вырисовывается. Результат в комментах
🔠 На этой неделе проработал ещё несколько важных схем для пояснения архитектуры проекта #пилимигру. Если повезет, то на неделе запишу видосик. Надо только всё в кучу собрать. Новые кусочки здесь и здесь
🔠 Ещё Baldur's Gate III завершил, и почему написал небольшой отзыв. К обсуждению можно присоединиться под этим постом
___
Рассказывайте как ваши дела? Как лето? Как проекты? Всё в комментариях!
#скриншотсуббота
Vol. 138
Схематичная, нагруженная
___
Рассказывайте как ваши дела? Как лето? Как проекты? Всё в комментариях!
#скриншотсуббота
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7⚡3