Рубрика развивается при поддержке
Gamedev
Serge Zaigraeff
1793

Как сделать игровые конфиги силами одного гейм-дизайнера

и не умереть под ворохом данных.

В закладки
Аудио
Неравная битва гейм-дизайнера и игровых конфигов. Конфиги побеждают.
(с) Носорог

Привет! Меня зовут Сергей, я работаю гейм-дизайнером и люблю изобретать велосипеды. Так уж получается, что обычно я работаю в маленьких командах, даже когда в больших компаниях. И в маленьких командах почти невозможно отвлекать разработчиков на такую ерунду как админка для создания и хранения конфигов. Вот только игры надо как-то конфигурировать, где-то хранить все эти несметные тыщи игровых сущностей и желательно в человекочитаемом виде. Нужны конфиги! :(

Ну, например, у меня в игре есть 42 посоха, 11 зелий восстановления маны, 33 зелья лечения, 100 мечей ... и всё это с разными параметрами и собираются из фрагментов, каждый фрагмент обладает своими параметрами и добывается из сундуков, сундуки лежат в данжене, а данжен расположен на локации, в лесу потерянных гейм-дизайнеров. Все это добро надо как-то внятно описать, иметь возможность удобно редактировать (удобство редактирования это супер важно!) и интегрировать в игру.

Видел случай, когда ГД, бедолага, руками, путаясь в скобках, собирал json, а потом мы правили баланс и выяснялось, что нужно поправить примерно пару-тройку десятков файлов. К слову, именно у этого ГД я подсмотрел, а потом развил идею с конфигами в гуглодоках (Никита, привет!). Я слишком ленив для такой работы, хочется больше времени заниматься ГД, а не правкой бесконечной кучи файлов.

Знакомая для боль? Тогда читайте дальше, в общих чертах расскажу как я справляюсь с этой болью. Если же будет интерес, то расскажу в деталях и про сам подход и про подготовку к экспорту и про сам экспорт.

Так как же я делаю конфиги?

В гуглотабличках! Использую всю силу луны и гугля. Делаю таблицы с сырыми игровыми данными, в тех же таблицах заворачиваю данные в промежуточный, мною изобретённый формат (подозрительно похожий на json), потом забираю из гуглотаблицы питонячим скриптом (опять же, минутка рекламы, самописным!), который конвертит мой формат в полноценный json хоть и с некоторыми ограничениями и сохраняет на рабочий комп. Полученные файлы можно заливать на сервер или включать в билд. Кстати, на сервер мой скрипт заливать тоже умеет :)

Про сам промежуточный формат и как он конвертится к json можно посмотреть в этой краткой инструкции. Совсем кратко я расскажу ниже.

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

Например, строка:

9.1, 6.0, 6 | zero = 0, one, two = {2, dva}, tree = 3 | a, b, f

Будет конвертирована в json как:

[ [ 9.1, 6, 6], [ "one", { "zero": 0 "two": [2, "dva"], "tree": 3 } ], [ "a", "b", "f"] ]

Очевидно, что внутри гуглотаблички первую строку собрать сильно-сильно проще и она более человекочитаемая.

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

Есть и еще ограничения. Из самых очевидных — словарь (это в терминах питона либо объект в терминах json) у меня всегда заворачивается в список. Сделано это, опять же, ради простоты формирования. Чаще всего словари идут пачками. Например, цена это список словарей с указанием типа валюты и её количества.

Если я хочу продавать меч тысячи истин не только за золотые, а за золотые, жабьи лапки и два хвоста крыс, то мне нужен список. Что бы не помечать отдельно когда список нужен, а когда нет, то проще всегда заворачивать словари в список, а программистов поставить перед фактом (аргументируя тем, что раз они не захотели писать админку для конфигов, то пусть и не возмущаются). У меня прокатило :)

Отдельно на конвертор в json можно посмотреть в моём репозитории. Там же есть наглядные примеры.

А вот так выглядит реальный конфиг (подразумеваю, что читатель уже заглянул в инструкцию). Это сундуки, самая простая реализация. Если будут желающие, могу рассказать идею подробней.

В чем выгода?

Простота и быстрый старт! Можно сразу (сразу!) начать работу и без дополнительных телодвижений получить приемлемый результат. И не нужно идти на поклон к программистам!

Гейм-дизайнер просит программиста об админке для конфигов.
(с) Носорог

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

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

В моём случае с таблицами активно работают ПМ и тестировщик, не отвлекая меня, когда нужно внести изменение для тестов или для добавления нового контента.

Кстати, у меня экспорт настроен через телеграм бота . Это тоже есть в репозитории.

В чем недостатки?

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

Нет версионности, сложно контролировать целостность документы, иногда отваливаются кастомные гуглоформулы. Сложно (но можно!) иметь разные конфиги если нужно поддерживать сразу несколько серверов, особенно с разными версиями конфигов.

Но даже со всеми этими недостатками это сильно проще чем писать свою супер-секси админку для редактирования и экспорта конфигов. И, повторюсь, самое важное, это можно сделать вот прям сейчас и сразу, силами одного ГД! И да, не факт, что своя админка будет лишена всех этих недостатков.

Как готовить конфиги?

Конфиги надо готовить. Совсем простые, формата "ключ = значение" делать легко, достаточно двух колонок: в одной ключи, в другой, как не сложно догадаться, значения. Навороченные уже сложней, нужна структура, понимание как оно будет заворачиваться с промежуточный формат и как оно будет разворачиваться в конечный json.

Пожалуй, проще всего разобрать на примерах.

Совсем простой случай

Начнем с совсем простого случая — нужен только словарь с параметрами. Например, какие-то игровые константы, пускай скорость это будет время восполнения единиц жизни \ маны за секунду и максимальные лимиты жизни и маны. Тогда создаем примерно такую табличку.

Первая строка зарезервирована под заголовки либо служебные метки. В нашем случае, это системные метки "key" и "value", по ним конвертор понимает что из этого нужно сделать словарик, и будут экспортированы только эти два столбца.

В остальных столбцах может быть что угодно, например комментарии или расчеты. Столбцы с данными могут даже не находится рядом! В строках ниже идут данные, в key находятся название переменных, в value — значения. На выходе будет валидный json документ.

ВАЖНО! Между строками не должно быть пробелов. Они создадут пустые словари!

Можно заполнять таблицу по другому. В первой строке расположены ключи, в строках ниже — значения. В общем случае строк со значениями может быть много. Важный момент, в странице для экспорта ключи должны быть именно в первой строке! Если хочется дополнительных данных, то всегда можно завести дополнительные страницы с "калькуляторами", там делать все расчеты, а результат складывать во вкладку для экспорта.

Вот так мы плавно подошли к чуть более сложному способу хранения данных.

Внутренний редактор ломается на символе "#". Пример альтернативного заполнения во вкладке @general2.json

Более сложный случай

Обычно в игре много сущностей одного типа, очень хочется их как-то аккуратно хранить и меть возможность редактировать. Попробуем на игрушечном примере — это уже страница для экспорта. Для каждого предмета у нас есть набор параметров. Первая строка, как всегда, заголовки, остальные — строки значений, по одной строке на предмет. Вот только это уже довольно сложный конфиг, хочется большей свободы, поэтому вкладка экспорта при помощи двух формул собирается из данных в "калькуляторе" на соседней вкладке. Это удобно, можно допускать вольности в форматировании.

Сам пример во вкладке @swords.json

ВАЖНО! В станице экспорта между строками не должно быть пробелов!

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

Есть набор простых параметров, на них акцентироваться не будем, они заполняются руками, либо как результат формул. Есть более интересные параметры, состоящие из сложной структуры. Например, для некоторых мечей мы хотим сделать спец. способность, а то и несколько способностей на один меч! Это возможно!

Каждая спец. способность состоит из имени абилки и силы её действия, записей может быть несколько. На каждую абилку придется заводить свою строку. Тут важно разделять предметы пустыми строками и следить чтобы запись для одного предмета не выползли в зону другого. Сами же абилки задаются вполне интуитивно, в первом столбце имя, во втором сила. А вот собираются в одну строку уже немного сложней (помним, у нас должна быть всего одна строка на один предмет). Для этого у меня подготовлены кастомные функции в гуглотаблицах, самая востребованная — toConfigBlock. Описание и примеры как она работает можно найти на странице калькулятора если ткнуть в формулу под заголовком extra_power.

К слову, вложенная структура может состоять из произвольного числа столбцов. Это не усложнит работу.

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

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

Общие рекомендации по работе с конфигами

У меня есть набор рекомендаций, которым я следую при работе с конфигами. Пройдусь по ним кратким списком:

  • Вкладки на экспорт я отмечаю красным, рабочие документы — зеленым, справочники — голубым;
  • Ячейки которые вбиваются руками — зеленые, собирающиеся при помощи формул светло-красные, ячейки в которых находится формула — красные;
  • Обязательно оставлять себе будущему комментарии, это супер важно! Тот будущий чувак обладает очень плохой памятью и иногда страдает слабоумием, пожалейте его!
  • Данные, которые будут использованы более чем в одном документе, лучше хранить в отдельной таблице и подгружать в рабочие документы как справочник, так можно избежать множественных редактирований по всем документам если у вас изменились базовые константы на которых строится баланс.

Начало работы

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

Можно и не копировать, а создать свой, но советую таки скопировать, там уже подготовлена база, в том числе и из кастомных функций, которые знатно облегчают жизнь при работе со сложными конфигами. Каждая функция документирована. Не ленитесь залезть в редактор скриптов (Tools \ Script Editor) и посмотреть что там есть. Из одного документа в другой функции можно копировать либо подключать как библиотеку.

Внимательно посмотрите на файл с настройками для конфигов. Стоит начать со вкладки "read.me!" и пройтись по остальным вкладкам читая комментарии. Я старался подробно всё описать.

ВАЖНО! Названия страниц, которые экспортируются, должны начинаться с символа собаки "@", иначе они не будут забираться скриптом экспорта.

Итак, конфиг готов. Пойдем дальше!

Настроить доступ к гуглопапке с конфигами

Я делал по этой инструкции. Там всё просто.

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

Простой вариант

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

Да, подразумеваю, что читатель либо немного знает питон либо под рукой есть тот кто его знает. Тут всё реально просто. Правда-правда!

  1. Склонируйте или скачайте файло из репозитория
  2. Установите все зависимости для работы срипта из файла config/requirements.txt
  3. Отредактируйте bot/local_lite.py дописав туда ID таблицы с конфигом и путь до файла с токеном авторизации к гуглодрайву.
  4. Запускайте скрипт, он должен достучаться до гуглтаблиц и сохранить все вкладки которые начинаются с "@".

ID таблицы можно найти в урле до этой самой таблицы, это многосимвольный фрагмент, что-то типа "1cbNBO69iUcX7CIx6E55Hy1XDdQ9IJp9mWF3u6g8CDpY"

Сложный вариант

Сложный вариант будет описан в следующих сериях :)

Заключение

Это было кратко и сумбурно, но, надеюсь, понятен основной подход к созданию конфигов. Резюмирую в несколько строчек:

  1. Использую гуглотаблички;
  2. Собираю все данные в плоскую таблицу, используя свой промежуточный формат;
  3. Забираю данные из таблиц питонячим скриптом;
  4. Преобразую в json;
  5. Сохраняю на локальную машину или сразу на сервер.

Спасибо за внимание! Надеюсь, было полезно :)

ЗЫ: Во избежание душевных травм заранее предупреждаю, я не настоящий сварщик, код пишу от любви к велосипедостроению и безысходности :)

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

Написать
{ "author_name": "Serge Zaigraeff", "author_type": "self", "tags": [], "comments": 42, "likes": 42, "favorites": 196, "is_advertisement": false, "subsite_label": "gamedev", "id": 74093, "is_wide": false, "is_ugc": true, "date": "Thu, 10 Oct 2019 01:22:37 +0300", "is_special": false }
0
{ "id": 74093, "author_id": 77, "diff_limit": 1000, "urls": {"diff":"\/comments\/74093\/get","add":"\/comments\/74093\/add","edit":"\/comments\/edit","remove":"\/admin\/comments\/remove","pin":"\/admin\/comments\/pin","get4edit":"\/comments\/get4edit","complain":"\/comments\/complain","load_more":"\/comments\/loading\/74093"}, "attach_limit": 2, "max_comment_text_length": 5000, "subsite_id": 64954, "last_count_and_date": null }
42 комментария
Популярные
По порядку
Написать комментарий...
2

рекламировать упрощение работы ГД через гуглодокументы, вставляя нерабочие ссылки на эти гуглодокументы. Ирония :)

Ответить
0

Спасибо, поправил. Внутренний редактор ломатеся на символе "#" в адресной строке.

Ответить
2

За то, что запилили решение под свои нужды полностью сами — респект и уважуха. Вообще молодец. И в этом смысле очень жизнеутверждающая статья.

Как программист скажу, что решение слишком сложное и не особо хорошее. Подобная штука делается через скачивание и парсинг csv с помощью пары скриптов на питоне примерно за пол дня. Оно будет более гибкое и расширяемое. Я бы все-таки рекомендовал достучаться до программистов ))

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

Ответить
0

Спасибо! 
Этот велосипед тоже не сильно долго писался. Суммарно, вместе с разворачиванием в докере и прикручиванием к телеграму около 5-8 рабочих дней силами одного меня.

Статей именно по ГД довольно много, а вот по деталям реализации и инструментам почти нет.

Ответить
1

Отличная статья как делать не надо )))

Ответить
0

А как надо делать? :)

Ответить
1

Вот, к примеру, бесплатный редактор для Unity, но он работает standalone без юнити через браузер. Сохраняет в JSON (XML, итд), для программистов генерит C# код, для других языков можно запилить кодогенерацию на основе существующих шаблонов. Импорт/Экспорт в Excel и другие ГД заморочки типа локализации.
https://assetstore.unity.com/packages/tools/visual-scripting/game-data-editor-charon-95117
дока https://gamedevware.com/docs/pages/viewpage.action?pageId=65573

Ответить
0

Вы можете быть не правы.
Дело не в том, что просто неудобно вводить данные, дело в том, что таблички - удобный вариант их сохранения и работы с ними (формулы для вычисления рядов, удобное взаимное расположение, цветами помечать важные/не важные/регулирующие/контрольные данные, производить валидацию, может работать несколько человек). Сам по себе инструмент поможет в работе с данными, а просто предоставит более удобный, чем json формат настройки. Все равно придется копировать-вставлять. Скрипт, который потрошит гуглодоки в конфиг может быть удобнее.

Впрочем сохранил ссылочку.

Ответить
0

Никто не мешает хранить в DB (любой, а не только то что я скинул вверху), и эскпортить в Excel для обработки/перерасчетов и импортить обратно. Эксель, если что, умеет ссылаться на соседние файлы.

Да, ГД, любят таблицы (Excel, Google Spreadsheets...), но это только промежуточная среда для расчетов. В экселе не выразить структуру данных отличную от таблицы, не выразить связи, не получить  валидацию этих данных и многих других фич. Без этих фич работа с игровыми данными становится адом. Как пример, никто уже не ведет бухгалтерию организации  в Экселе, это реально, но это не удобно. Переходите на профессиональные  инструменты.

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

Ответить
1

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

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

Нужно понимать, что и для чего используется.
БД - это техническое решение для работы с данными, направленное на скорость и масштабируемость, но не на удобство редактирования.
Для нескольких десятков разнородных элементов (десяток разных оружий, десяток персонажей) таблицы подойдут значительно лучше, а формулы позволят отлично выразить связи. Обслуживание похожих таблиц в БД может быть дороже. БД сама по себе без квалифицированного обслуживания не выразит связи, не провалидирует данные и не табличные данные тоже может показать только через отношения.
В лучшем случае это будут те же таблицы.
А экспортеры и импортеры, кастомные экраны и скрипты - это тоже имеет свою цену при создании и обслуживании, для этого требуются другие люди (программисты), что затрудняет коммуникации и т.д.

Ответить
0

БД - это техническое решение .. направленное на скорость и масштабируемость, но не на удобство редактирования.

БД сама по себе без квалифицированного обслуживания не выразит связи

И да, и да. Спорить не буду БД это не легкое и доступное для всех решение. Как и кастомный Google Spreadsheets с пачкой скриптов.

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

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

Надо просто поискать подходящий под свою платформу, язык программирования.

Ответить
0

Тут вопрос скорее в том, что нужно тщательно подумать, будет ли это решение масштабируемым. Возможно, для данных сущностей масштабирование не наступит никогда и платить за сложность БД не нужно будет никогда.
Я не в смысле противник БД, просто мы реально застали процесс вынесения данных из БД обратно в json.
Речь про сервер небольшой игры. Пользователи, их достижения и прочее, разумеется, остались в БД. А вот все настройки дизайна игры, от оружия до свойств кланов, вернулись в обычные json.

Основных минусов, помимо удобства, было 2 - простота обслуживания (изменения в бд против блокнота) и у БД были проблемы с версионированием, а json прикреплялся к текущему коммиту сервера и легко переносился.
Позже всплыл еще один факт - json был удобнее для аб-тестов, но это уже наши костыли.

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

Ответить
0

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

Не обязательно пересчитывать по формулам все показатели (прогрессии, уровни опыта, зависимые стоимости итд) и заталкивать в JSON и в игру

Это не всегда удобно. Не все зависимости описываются одной гладкой функцией. Иногда надо менять зависимости, а иногда и вовсе вставить костыль в виде завышенного значения на 6м уровне развития :) Табличными данными это удобней делать.

Ответить
0

Возможно, я не совсем понял что вы подразумеваете под связями. Например, использовать ид ресурсов в награде это связи? Вроде связи. Валидацию средствами гуглотаблиц сделать довольно просто даже штатными инструментами.

Ну к примеру есть описание ачивки, за достижение ачивку дают награду, в награде ссылка на предмет и шанс:

{
   id: "Winner"
   reward: [
       { item: "sword", chance: 0.1 },
       { item: "armor", chance: 0.2 },
       { item: "kek", chance: 0.5 },
       { item: "chest", chance: 0.2 },
   }
}

В виде таблицы это уже сложно выразить, еще сложнее будет, если вложенность перевалит за 2. И хочется быть уверенным что "sword", "armor", "chest" существуют, для этого надо ручками на каждую такую колонку писать проверку. А завтра придёт новая мета, что ачивки реварда не дают, и это надо будет обратно зачищать.

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

Ответить
0

В виде таблицы это уже сложно выразить, еще сложнее будет, если вложенность перевалит за 2.

Хех, если сложность перевалит за 2, то это будет сложно упихать не то что в табличку, но и в голову ГД который конфигурирует игру :) Как ни крути, наше мышление 2-3 мерно (за исключением некоторых уникумов), в целом хорошо ложится на таблички и плохо во всякие вложенные друг в друга структуры. А конкретно пример с наградой за ачивку превосходно описывается моими конфигами, и полная аналогия есть в в примере с абилками и ценой.

И хочется быть уверенным что "sword", "armor", "chest" существуют, для этого надо ручками на каждую такую колонку писать проверку. А завтра придёт новая мета, что ачивки реварда не дают, и это надо будет обратно зачищать.

Но так тут и БД мало поможет, ручного труда никак не избежать. Придется зачищать и переделывать.

У нас дискуссия немного странной становится, я не утверждаю что предложенная мной система идеальна, вовсе нет. В ней много недостатков и я с радостью её либо доделаю либо вовсе откажусь. Одна из целей выложить свои наработки это надежда что в процессе обсуждения всплывет что-то более интересное :)

Очень хотелось бы повернуть дискуссию в русло "ваша система стрёмная, мы используем такое" и немного подробностей, по которым можно понять вашу идею и стать чуть-чуть лучше :) Или что-то в духе: БД надо использовать не потому что она лучше в вакууме чем таблички, а потому что такие-то вещи удобней сделать в БД. 

Сжальтесь над сирыми, расскажите как ваш пример с ачивками будет реализован в БД и как его потом поддерживать?

Ответить
0

Сжальтесь над сирыми, расскажите как ваш пример с ачивками будет реализован в БД и как его потом поддерживать?

1) Иду и качаю последнюю версию: https://www.nuget.org/api/v2/package/GameDevWare.Charon/2019.3.8
2) Распаковываю в C:\work\charon
3) Создаю пустой файл "c:\work\charon\mygamedata.json"
3) Запускаю C:\work\charon\gamedevware.charon.2019.3.8\tools\Charon.exe SERVE "c:\work\charon\mygamedata.json" --launchDefaultBrowser
4) Браузере накидываю сущность Achievement, RewardItem, Item
5) Заполняю ачивку
6) получаю mygamedata.json с ачивками

по желанию можно сгенерить еще C# код, для загрузки этого JSON и доступа к ачивкам:

Charon.exe GENERATE CSHARPCODE "c:\work\charon\mygamedata.json" --output "c:\work\charon\mygamedata.cs"

Потратил реально минут 10 на это, пришлось в доку посмотреть.

Ответить
0

Ммм, а теперь для большинства ачивок (к этому времени у нас их скопилось 2 сотни) надо увеличить вероятность выпадения деревянного сундука на 20% а для оставшихся на 40%? Нужно будет каждую ткнуть и отредактировать? 
Умозрительно, в таблицах эта операция убьёт меньше нейронов в голове ГД :)

Ответить
1

Там есть кнопка "Экспорт" -> "XLSX", потом редактирование всех шансов уже силами Excel. И есть импорт обратно. Все есть в UI.

ГД же не каждый 30 секунд это делают, так что не обломаются нажать на пару кнопок. Для совсем ленивых можно сделать 2 батника с экспортом всего в Excel, и импортом обратно. В доке есть описание CLI.

Ответить
1

Прочитал с интересом. Спасибо.
Мог бы помочь какой-то другой инструмент, например Использовал для мокапов апи.

Ответить
1

Я делаю вот такой экспорт сразу в json. Вид формул получается криповый, зато без питончика. После этого безо всякой автоматизации выделяем весь ряд, копипастим в конфиг и форматируем. Это при том, что Я то программист, и мог бы написать и инструмент для работы с данными и экспортер. Но лень матушка.

Но Я согласен, что гуглодоки (как и excell) выдающийся инструмент. Те, кто рекомендует БД и окошки в игре могут быть правы с технической стороны, но со стороны ГД самое важное ведь не просто перетирать числа.
В таблицах можно использовать формулы для построения рядов, представлять данные в удобном виде, выносить контрольные переменные в специальное место, размечать цветами важные/не важные/управляющие/результирующие параметры, удобно сводить данные (отображая, к примеру урон оружия в списке со свойствами оружий и вместе с тем - используя по ссылке эти данные в расчетах повреждений и вычислении сложности противника), удобно проверять данные (написать столбик со специальными формулами, проверяющими, что данные не вылезли за критические значения).
То есть это - рабочий инструмент построения данных, и задача других инструментов - приблизить результаты работы в гуглодоках к конфигурациям игры.

Ответить
0

Да это вообще все вкусовщина, кому как удобно, тот так и делает, благо плейнтекст форматов организации данных и не только плейнтекст уже великое множество. А вообще вам действительно проще любую бд с экспортом в джсон развернуть и надежнее будет и удобнее в разы.

Ответить
0

Ключевой вопрос, как это потом удобно редактировать? Особенно когда данных много и есть калькуляторы на основе которых эти данные рассчитываются.

Ответить
1

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

Ответить
0

А префабы тогда зачем?

Ответить
0

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

Ответить
0

А какую субд лучше использовать под игры?(просто интересно)

Ответить
0

Ох, на эту тему много споров. Кто-то советует nosql базы (там все хранится по ключ-значение), я вот юзаю Postgress базу (классическая, с таблицами. Бесплатная кстати) и сервак написанный на C# ASP Net Core + Entity Framework (да, серверные технологии эта гребанная бездна всяких штук которые надо копать и учить)

Ответить
0

Мне просто интересно в чём их принципиальное отличие друг от друга? Я вот MySQL баловался несколько лет назад. Она как будет для игрушек?

Ответить
0

Для игр (большинства) если говорить о конфигах, достаточно и cfg/ini файлов.

Ответить
0

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

Ответить
2

Да все от задачи зависит, завит от того для чего она используется, для конфигов она по сути вообще не нужна, там достаточно плейнтекста, для серверной части уже реальнее использование бд, и там опять же кто на что горазд и какие вообще требования предъявляются. В общем все достаточно индивидуально как и везде.

Ответить
2

По опыту могу сказать, что "никакую" не надо использовать для игр (это не касается бек-энда). Нет кейсов, где клиентская часть игры получит хоть какой то бенефит от СУБД, который превысит цену внесенной сложности.

Ответить
0

9.1, 6.0, 6 | zero = 0, one, two = {2, dva}, tree = 3 | a, b, f

Очевидно, что внутри гуглотаблички первую строку собрать сильно-сильно проще и она более человекочитаемая.

Я бы поспорил с тем, что ваш формат более удобен чем json.
Если есть проблемы, существует куча сервисов для подсветки синтаксиса и форматирования.

Главное преимущество гуглтаблиц - возможность работать с ними параллельно более чем 1 человеку. В остальном - ваш подход не для всех. 

Ответить
0

Не удобней, его проще собирать внутри таблиц, он сильно проще.

Ответить
0

А что, XML-конфиги уже не в почете?

Ответить
0

Вопрос формата вторичный. Плоскую таблицу можно с одинаковым успехом собирать и в xml и в json. Дело вкуса, мне приятней с json работать, он привычней для человека с питоном головного мозга :)

Ответить
0

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

Как это делать с твоими конфигами?

Ответить
0

Если специально не ставить такой задачи, то никак. У вас есть такой инструмент? Расскажите, очень интересно.

ЗЫ: Мне всегда казалось что это делается немного по другому, целенаправленно ставятся и тестируются гипотезы. И по факту выводов из гипотез фиксируются изменения.

Ответить
0

По-разному бывает, но анализ изменений - это стандартная задача. Так что некая система версий нужна. 

Ещё хорошо иметь некую систему контроля ошибок в конфигах, чтоб случайно не залить ошибку в уже выпущенную игру. Чтоб можно было видеть изменения перед тем как и выложить. Вдруг там цена IAP удалилась и деньги стали бесплатными - это может дорого стоить (можно даже компанию похоронить). 

Ответить
0

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

Ответить
0

Я Никита (не уверен, что тот самый), и я спокойно работаю как с гуглодоками, так и с json.
Автоматизировать изменения "руками" на самом деле достаточно легко: notepad++, мароксы и регэкспы творят чудеса

Ответить

Комментарий удален

Прямой эфир

[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox_method": "createAdaptive", "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fizc" } } }, { "id": 4, "label": "Article Branding", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "p1": "cfovz", "p2": "glug" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfk" } } }, { "id": 6, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjog" } } }, { "id": 10, "disable": true, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "disable": true, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "createAdaptive", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-250597-0", "render_to": "inpage_VI-250597-0-1134314964", "adfox_url": "//ads.adfox.ru/228129/getCode?pp=h&ps=clmf&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid10=&puid21=&puid22=&puid31=&puid32=&puid33=&fmt=1&dl={REFERER}&pr=" } }, { "id": 15, "label": "Баннер в ленте на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byudo", "p2": "ftjf" } } }, { "id": 17, "label": "Stratum Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fzvb" } } }, { "id": 18, "label": "Stratum Mobile", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fzvc" } } }, { "id": 20, "label": "Кнопка в сайдбаре", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "p1": "chfbl", "p2": "gnwc" } } } ]