jarg

Форум для проектов, находящихся на стадии Альфа и Бета. В них ещё не реализована вся задуманная автором функциональность, а значит идёт активная разработка.

Модераторы: Sanja, Максим Кич

Аватара пользователя
Cfyz
Сообщения: 759
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: jarg

Сообщение Cfyz » 09 сен 2013, 13:05

Oreyn писал(а):В базе или хранилище мы их так и храним в связке "имя свойства" - "значение" <...> класс "предмет" предполагает наличие переменного списка из N именованных полей/свойств
Своеобразный вариант stringly-typed кода =)

А если серьезно, у этого подхода есть существенный недостаток в том, что нет эффективного механизма гарантировать наличие, тип, корректность применения тех или иных свойств. В упрощенном примере выше я упомянул как структура программы (контейнеры, типы переменных) автоматически обеспечивает корректность набора полей. Ошибки при добавлении и использовании новых полей быстро выявит компилятор, ну а банальные опечатки и вовсе IDE подчеркнет. Причем строго говоря, в подходе с ассоциативным массивом "каша из полей" никуда не девается, полей просто не видно. У вундеробъекта, есть и Item.Damage, и Item.Nutrition, в зависимости от некоторого Item.TypeFlags, просто поле используешь или нет. У ассоциативного массива потенциально есть и Item["Damage"], и Item["Nutrition"], в зависимости от некоторых Item["Weapon"] и Item["Food"], просто поля запрашиваешь или нет.

В итоге что так, что эдак, объект выходит нетипизированным (с точки зрения кода/компилятора) и вынуждает проверять и проверять наличие необходимых в конкретном месте полей. Быстрое добавление-удаление полей из объектов -- сомнительный в общем-то плюс. Желание "вот тут по-быстрому что-то прикрутить" это признак плохо продуманной архитектуры, и как правило означает, что в скором времени в одном месте программы что-то будент работать чуточку не совсем так, как во всей остальной части. По-моему, такой подход можно использовать, скажем, для скриптования событий или квестов, но не для самого приложения.

Оговорка: вышесказанное касается строго-типизированных ЯП (мейнстрим, то есть). Если ЯП сам по себе скрипт и подобная методология разработки там норма, то почему бы и нет.
Cfyz теперь - наглая морда.

Аватара пользователя
Oreyn
Сообщения: 297
Зарегистрирован: 07 авг 2013, 14:59

Re: jarg

Сообщение Oreyn » 09 сен 2013, 16:20

Cfyz писал(а):
Скрытый текст: ПОКАЗАТЬ
Oreyn писал(а):В базе или хранилище мы их так и храним в связке "имя свойства" - "значение" <...> класс "предмет" предполагает наличие переменного списка из N именованных полей/свойств
Своеобразный вариант stringly-typed кода =)

А если серьезно, у этого подхода есть существенный недостаток в том, что нет эффективного механизма гарантировать наличие, тип, корректность применения тех или иных свойств. В упрощенном примере выше я упомянул как структура программы (контейнеры, типы переменных) автоматически обеспечивает корректность набора полей. Ошибки при добавлении и использовании новых полей быстро выявит компилятор, ну а банальные опечатки и вовсе IDE подчеркнет. Причем строго говоря, в подходе с ассоциативным массивом "каша из полей" никуда не девается, полей просто не видно. У вундеробъекта, есть и Item.Damage, и Item.Nutrition, в зависимости от некоторого Item.TypeFlags, просто поле используешь или нет. У ассоциативного массива потенциально есть и Item["Damage"], и Item["Nutrition"], в зависимости от некоторых Item["Weapon"] и Item["Food"], просто поля запрашиваешь или нет.

В итоге что так, что эдак, объект выходит нетипизированным (с точки зрения кода/компилятора) и вынуждает проверять и проверять наличие необходимых в конкретном месте полей. Быстрое добавление-удаление полей из объектов -- сомнительный в общем-то плюс. Желание "вот тут по-быстрому что-то прикрутить" это признак плохо продуманной архитектуры, и как правило означает, что в скором времени в одном месте программы что-то будент работать чуточку не совсем так, как во всей остальной части. По-моему, такой подход можно использовать, скажем, для скриптования событий или квестов, но не для самого приложения.

Оговорка: вышесказанное касается строго-типизированных ЯП (мейнстрим, то есть). Если ЯП сам по себе скрипт и подобная методология разработки там норма, то почему бы и нет.
Да, тут есть с чем согласиться, и есть с чем нет. Под "каша из полей" подразумевалось, что объект хранит/записывает/выделяет память для ненужных ему полей. И этого как раз происходить не будет с ассоциативным массивом. Если мы не объявили тег, лишних полей у этого экземпляра нет/память не выделяли/не сериализовали ничего лишнего. Если же мы объявили тег, значит он и его поля нам нужны.
Да, и плюс то не в том, чтобы быстро добавлять/удалять поля на ходу или чего-то быстро прикручивать. Добавляться они будет в шаблонах предметов и при процедурной генерации. То есть вопрос - как изначально построить гибкий конструктор предметов и прописать доступные кирпичики которые то как-раз и строго определены дизайном.
По поводу опечаток - Jesus05 правильно отметил, константы дефайны и среда намекнет на неправильное написание.

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

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

Аватара пользователя
Cfyz
Сообщения: 759
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: jarg

Сообщение Cfyz » 10 сен 2013, 13:31

Oreyn писал(а):То есть вопрос - как изначально построить гибкий конструктор предметов и прописать доступные кирпичики которые то как-раз и строго определены дизайном.
Я предлагаю посмотреть на проблему несколько более широко.

1. Существенные изменения структуры данных вынуждены сопровождаться симметричными изменениями алгоритмов, их обрабатывающих. Так введение "питательности" в игре, где ее раньше не было, не ограничится одним описанием поля в файлике и одной функцией в коде. Будут затронуты многие части игры, изменится баланс, игровая механика.

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

3. Если желаемый объект в текущую модель данных не лезет, то практически гарантированно он и обработан будет неверно (ошибочно, неполно, вообще не будет), ведь алгоритмы сами по себе не напишутся, а текущие заточены под текущую же модель [данных]. В этом случае надо взвешенно проработать модель заново и решить, отказаться от задумки или расширить модель и перейти к п.1, воплотив ее в коде.

Однако, излише свободная структура данных (в частности, ассоциативный массив) провоцирует пропустить шаг "взвешенно проработать модель" и перети сразу к "воплотить в коде". Завести новое поле или новый тип объекта легче легкого, осталось вставить пару if-else в одну или две функции и вроде работа сделана. Что сказывается позже, когда становится ясно, что изменение затронуло еще несколько мест, тянет за собой еще пару полей, требует пересмотра правил игры и вообще убило баланс.

Еще раз: изменения в структуре данных это тревожный звоночек, тут маловероятно отделаться одной маленькой правкой. Поэтому использовать инструмент, допускающий подход "изменим сейчас, а с последствиями разберемя потом", нерационально.
Oeryn писал(а):В общем, если в дизайне фиксированное количество типизированных предметов, конструктор с тегами тут ни к чему. Если нужна гибкая процедурная генерация и настраиваемые внешним "скриптингом" шаблоны, добро пожаловать.
Не фиксированное количество типизированных предметов, а фиксированное число типов предметов. Класс предмета (который вероятно будет отражен одноименной конструкцией в коде) это не сам предмет, это и есть тот самый шаблон предмета, который должен настраиваться внешним скриптингом.
Cfyz теперь - наглая морда.

Аватара пользователя
Oreyn
Сообщения: 297
Зарегистрирован: 07 авг 2013, 14:59

Re: jarg

Сообщение Oreyn » 11 сен 2013, 07:41

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

Да, тут еще такой нюанс, действую по принципу - для каждого класса, экземпляры которого создаются динамически (предметы, монстры и т.д.), предусматриваю объект-менеджер, который управляет их временем жизни. Фактически это "базы/коллекции" которые умеют создать экземпляр объекта из шаблона и корректно удалить/очистить память. Что удобно реализуется когда, например, все возможные предметы это один и тот же класс и управляются одним менеджером.
В случае когда предметы представлены разными классами, как корректно сделать менеджер для них? Отдельно создавать менеджер для каждого класса и один менеджер, который хранит списки для каждого класса?
(Да, это не выпад и не спор по поводу классы/теги. Интересуюсь самой реализацией.)

Аватара пользователя
Cfyz
Сообщения: 759
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: jarg

Сообщение Cfyz » 11 сен 2013, 08:52

Oreyn писал(а):для каждого класса, экземпляры которого создаются динамически (предметы, монстры и т.д.), предусматриваю объект-менеджер, который управляет их временем жизни. Фактически это "базы/коллекции" которые умеют создать экземпляр объекта из шаблона и корректно удалить/очистить память.
А какой это ЯП и что входит в "управление временем жизни" и "корректно удалить/очистить"?

(Я надеюсь топикстартер не против того, что мы тут развели.)
Cfyz теперь - наглая морда.

Аватара пользователя
Максим Кич
Администратор
Сообщения: 1559
Зарегистрирован: 03 дек 2006, 20:17
Откуда: Витебск, Беларусь
Контактная информация:

Re: jarg

Сообщение Максим Кич » 11 сен 2013, 08:55

Oreyn писал(а): Да, тут еще такой нюанс, действую по принципу - для каждого класса, экземпляры которого создаются динамически (предметы, монстры и т.д.), предусматриваю объект-менеджер, который управляет их временем жизни. Фактически это "базы/коллекции" которые умеют создать экземпляр объекта из шаблона и корректно удалить/очистить память. Что удобно реализуется когда, например, все возможные предметы это один и тот же класс и управляются одним менеджером.
В случае когда предметы представлены разными классами, как корректно сделать менеджер для них? Отдельно создавать менеджер для каждого класса и один менеджер, который хранит списки для каждого класса?
(Да, это не выпад и не спор по поводу классы/теги. Интересуюсь самой реализацией.)

А разве объект не должен сам за собой подчищать память? В том плане, что идея деструктора как раз в этом и состоит. Тогда на совести «менеджера» остаётся: вызвать деструктор объекта (который по умолчанию у него есть вне зависимости какому классу он принадлежит) и удалить из коллекции ссылку, которая после вызова деструктора ведёт в никуда.

Потом, если у нас в одной коллекции оказываются экземпляры разных классов, то эти классы в любом случае имеют хотя бы какую-то общность. Я не большой знаток C#, но в любом случае, либо это потомки одного предка, либо они «крякают похоже», либо им была сделана одна и та же инъекция. Т.е. требование к таким классам одинаково реагировать на требования менеджера — более чем выполнимо. А как они убивают свои ресурсы и какие события порождают при этом — это должно быть отдано на откуп самим объектам.

Опять же, я бы разделил Фабрику (то, что создаёт экземпляр объекта) и Коллекцию (то, что хранит экземпляры объекта). Потому что они чисто архитектурно могут захотеть жить в разных местах. Чаще всего Фабрика — это синглтон, а Коллекций может быть много. Скажем, монстр может таскать с собой Коллекцию своих предметов. Убиваем монстра, его деструктор отправляет указатель на Коллекцию в соответствующий сеттер клетки, в которой монстр убит, и освобождает остальные свои ресурсы. Как результат, Коллекция лежит на полу. С другой стороны, мы когда мы генерируем уровень, мы обращаемся к Фабрике монстров, которые, при рождении могут при необходимости обращаться к Фабрике предметов чтобы наполнить себе карманы. Создавать персональную Фабрику для каждого монстра нет смысла — поэтому она у нас либо просто одна и мы знаем где её искать, либо это синглтон, и нам даже искать её не надо.
Dump the screen? [y/n]

Аватара пользователя
Максим Кич
Администратор
Сообщения: 1559
Зарегистрирован: 03 дек 2006, 20:17
Откуда: Витебск, Беларусь
Контактная информация:

Re: jarg

Сообщение Максим Кич » 11 сен 2013, 09:26

Cfyz писал(а):(Я надеюсь топикстартер не против того, что мы тут развели.)
Где-то была подходящая тема, если что, я просто перекину сообщения туда.
Dump the screen? [y/n]

Аватара пользователя
ishellstrike
Сообщения: 37
Зарегистрирован: 21 авг 2013, 21:50
Откуда: Москва

Re: jarg

Сообщение ishellstrike » 11 сен 2013, 12:57

Cfyz писал(а):Я надеюсь топикстартер не против того, что мы тут развели.
Конечно не против, я очень много для себя вынес из обсуждения

Аватара пользователя
Oreyn
Сообщения: 297
Зарегистрирован: 07 авг 2013, 14:59

Re: jarg

Сообщение Oreyn » 11 сен 2013, 14:16

Cfyz писал(а):А какой это ЯП и что входит в "управление временем жизни" и "корректно удалить/очистить"?
Максим Кич писал(а): А разве объект не должен сам за собой подчищать память? В том плане, что идея деструктора как раз в этом и состоит. Тогда на совести «менеджера» остаётся: вызвать деструктор объекта (который по умолчанию у него есть вне зависимости какому классу он принадлежит) и удалить из коллекции ссылку, которая после вызова деструктора ведёт в никуда.
Язык С++. Посмотрел, действительно и тут можно же объявить массив указателей на базовый объект и наполнять его ссылками на новосозданные производные объекты.
И да, все верно, про роль менеджера и вызов деструкторов. Оценил идею разделить "фабрику" и "хранилище".

Аватара пользователя
ishellstrike
Сообщения: 37
Зарегистрирован: 21 авг 2013, 21:50
Откуда: Москва

Re: jarg

Сообщение ishellstrike » 03 окт 2013, 17:12

Попал в ступор с генерацией дрог, карта бесконечная, генерируется по шумовой сглаженной функции. Практически даже нет идей. Разве что нагенерировать заранее очень большой массив с дорогами, скажем [1000, 1000] секторов (не 1000000 элементов конечно, разреженный), для бесконечной карты зазеркалить его, а потом при генерации очередного сектора сверяться с ним. И с городами так же поступить?

Аватара пользователя
Максим Кич
Администратор
Сообщения: 1559
Зарегистрирован: 03 дек 2006, 20:17
Откуда: Витебск, Беларусь
Контактная информация:

Re: jarg

Сообщение Максим Кич » 03 окт 2013, 21:21

ishellstrike писал(а):Попал в ступор с генерацией дрог, карта бесконечная, генерируется по шумовой сглаженной функции. Практически даже нет идей. Разве что нагенерировать заранее очень большой массив с дорогами, скажем [1000, 1000] секторов (не 1000000 элементов конечно, разреженный), для бесконечной карты зазеркалить его, а потом при генерации очередного сектора сверяться с ним. И с городами так же поступить?
На самом деле, тут не хватает вопроса. В чём проблема?

Проблема с тем, что карта бесконечная? Генерить по мере необходимости. Всё равно бесконечную карту игрок всё не обойдёт. Генерить вместе с городами, а точнее сразу после городов. Города, по хорошему, надо расставлять вдоль рек/озёр/морей, но этим можно и пренебречь — вон, ZAngband кидал как RNG на душу положит и никто не жаловался.

Проблема с тем, что каждый тайл дороги надо описать? Кривые Безье нам в помощь. Или сплайны. Или и то, и другое.

Проблема провести дорогу по карте — ну тут уже надо смотреть, что там твоя «шумовая сглаженная» выдаёт на-гора.
Dump the screen? [y/n]

Аватара пользователя
ishellstrike
Сообщения: 37
Зарегистрирован: 21 авг 2013, 21:50
Откуда: Москва

Re: jarg

Сообщение ishellstrike » 03 окт 2013, 22:42

Проблема в том, что при генерации очередного сектора карты мы должны знать есть ли в нем дорога (не опрашивая соседние сектора), наример, и где она проходит, а сделать граф дорог или что-то подобное на бесконечной карте нельзя (или можно?)

Аватара пользователя
Shirson
Сообщения: 427
Зарегистрирован: 03 окт 2011, 13:52

Re: jarg

Сообщение Shirson » 03 окт 2013, 22:54

Да, задачка занятная. Если не получается в лоб, попробуй с другой стороны.
Генери дороги, а к ним привязывай города. Например, если генератор выдаёт конец дороги, пристыкуй к ней хутор. К пересечению дороги и реки - деревню. К пересечению дорог - город и т.д.

Аватара пользователя
Oreyn
Сообщения: 297
Зарегистрирован: 07 авг 2013, 14:59

Re: jarg

Сообщение Oreyn » 04 окт 2013, 07:23

Вариант с генерацией относительно дорог, как по мне правильный.

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

Аватара пользователя
Shirson
Сообщения: 427
Зарегистрирован: 03 окт 2011, 13:52

Re: jarg

Сообщение Shirson » 04 окт 2013, 12:56

Вообще, я мыслил себе это более "лениво" :) Т.е. есть, допустим, генератор шума, у которого коеффициенты выставлены так, что он геренирит крывые на определённой высоте.

(как на последней картинке, например)
Изображение

Соответственно, для следующего сектора он автоматически нагенерит сеть дорог, которая УЖЕ совмещена с со всеми окружающими :) Даже не опрашивая соседние зоны можно генерить сектор.

Ответить

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 3 гостя