RU

Текстовые РПГ!

Ajenta Moderator 20.02.2014 15:52 205 comments 96372 views

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

За одно тут же варианты сражений, прокачки, параметров… всё, о монстре под названием “текстовая рпг”.

Делимся кодом, наработками, сюжетами!

Storm, мне кажется, что ты заблуждаешься в этом:

Storm:

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

На самом деле, весь код читается из файла на диске один раз и размещается в оперативной памяти полностью (исключение составляют только файлы .qsp, подключаемые оператором ADDQST/ADDLIB/INCLIB - они загружаются в память только после обращения к ним в коде).

Таким образом, следуя твоей логике, можно сказать, что мы храним “в памяти переменные локации, которые не будут использоваться”. И ты проигнорировал мой вопрос о том, что происходит с переменными, которые ты проинициализировал, используя gs, и которые по некоторым причинам больше не нужны.
<sarcasm> Они продолжают “жрать” драгоценную память и надо их убивать KILLVAR-ом. (Кстати, я не уверен, что KILLVAR освобождает блок памяти, зарезервированный под переменную, а не просто обнуляет его). Можно пойти дальше и разбить игру на несколько .qsp-файлов, подключая и отключая (KILLQST/DELLIB/FREELIB) их по мере необходимости с целью минимизировать неэффективный расход памяти. </sarcasm>

Что я хочу сказать - заботиться о расходе памяти в текстовых играх, это последнее о чем следует думать. Не усложняйте себе жизнь. Гораздо важнее заботиться о красоте, удобочитаемости и понятности кода. И если, в угоду этому, следует проинициализировать 100500 переменных, то надо это сделать. :)

evp, наверно ты меня немного не понял. Ты копался в движке Trinity MasterSet`а? Для каждой вещи свой массив со своими переменными, так же и для монстров. У меня же этого всего нет. Речь идет именно о переменных, которые загоняются в память непосредственно в данный момент. У меня их будет меньше. Второе: я написал общий случай меню, а это значит что мне не надо писать для каждого предмета его массив меню, опять-таки это освобождает память от лишних переменных и меня от работы всё это прописывать :)
С удобностью читаемости кода соглашусь, но никогда не ввиду для этого огромное количество переменных, ибо этим мы нагружаем оперативную память. Для меня всегда будет в приоритете именно облегчение работы компьютеру, а не человеку. Делай как тебе удобно, это никто не запрещает.
В плане подключения своих библиотек, то я хочу отделить боевую систему которую буду писать в отдельный QSP файл.
Ещё одно: у меня нету переменных для предметов), у меня есть просто добавка к параметру персонажа, так что сарказм не уместен :)
UPD:

evp:

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

Для предметов у меня нету переменных, есть только выражение, которое увеличивает определенный параметр персонажа. Пример я писал тебе на “Силе”. Похожий механизм будет и для монстров.

Storm,
мне нет никакого дела до Trinity MasterSet. Я говорю только о том, о чем говорю. Где ты прочел у меня о Trinity MasterSet или же о коде, который ты пишешь?

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

И вот еще, компьютер создан для облегчения работы человека, а не наоборот. Но, конечно,

Storm:

Делай как тебе удобно, это никто не запрещает.

PS Сколько гигов занимает твой код?

Storm:

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

Какая загрузка оперативной памяти, о чём вы? Вы под что такое игру делаете, что там оперативки кот наплакал?

Aleks Versus Moderator 10.06.2015 09:45 (10 years ago)

Storm,
ты слишком заморочился. Я только показал, как выглядит моя база. Это просто пример. Квадратные скобочки -текст-двоеточие и наоборот - это просто теги (метки) - так проще и удобнее транспортировать информацию в одной переменной. В остальном: всё практически верно. У меня сооружена система из различных идентификаторов: класс, тип, вид, подкласс, подтип и т.д. Никак не соберусь описать это понятным языком. Про регулярные выражения почитай (они же регекспы, regexp). Облегчают жизнь раза в два, а то и больше. В справке QSP они есть, и даже простые примеры.

К сожалению, у меня временные трудности с интернетом. Появляюсь здесь редко, отвечать могу редко и не так подробно, как хотелось бы.
evp,
ты уверен, что весь файл грузится в оперативку, но не уверен, что KILLVAR убивает переменную, а не обнуляет её. Как такое получилось?
Впрочем не важно. Основная проблема распределения данных в куче переменных заключается в том, что за тридцатью-сорока именами переменных ты ещё как-то можешь уследить, но когда их становится 100-200 - запомнить значение всех нереально. Имена более чем из десяти - пятнадцати символов, сам понимаешь, трудны для написания и провоцируют ошибки. Лично я не оперативную память чищу (хотя дублировать идентичные данные, на мой взгляд, расточительно), а избавляю свой мозг от лишней нагрузки.

Aleks Versus:

ты уверен, что весь файл грузится в оперативку, но не уверен, что KILLVAR убивает переменную, а не обнуляет её. Как такое получилось?

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

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

Aleks Versus, мне интересно каким образом ты вытягиваешь нужные тебе данные из переменной, в которой они записаны. Сам код этого механизма)
UPD: Aleks Versus, немного разобравшись в регулярных выражениях и читая код твоего движка, нашел то, что интересовало. В движке есть локация “get.tag.cont”, которая получает содержимое из любого сдвоенного тега. Немного разобравшись в этой системе, для себя сделал вывод, что это пока самая лучшая система для предметов. С ней намного упрощается взаимодействия с предметами, добавление новых свойств.
Пока ищу в твоём движке код, в котором ты добавляешь новые свойства предмету :)

Aleks Versus Moderator 28.06.2015 09:56 (10 years ago)

Storm,
код довольно простой, но да, он использует регулярные выражения. Можно обойтись без регулярок на одних лишь mid и instr, тогда код выйдет чуть длиннее.

Да, с функциями всё правильно. Честно говоря, я вынес их из движка, поскольку очень часто пользуюсь ими, и перетащил в easy.math. Может быть к концу лета подготовлю адекватное описание работы.

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

[uron: u1:дробящий:u1 u2:режущий:u2 p1:500 p2:2500 u3:огненный_mgc:u3 p3:0 :uron]

То есть одни теги вкладываются в другие и так далее. Перечислены типы уронов и их значения для данного предмета.
Чтобы зачаровать этот меч огнём, нужно изменить значение за p3. Пишется функция, которая получает текст между [uron: :uron], проверяет, присутствует ли огненный_mgc в списке, проверяет/извлекает значение p3, изменяет его согласно дизайну механики (в некоторых играх, например, недопустимо зачаровывать оружие более одного раза, в других можно “дозачаровывать”), после чего уже берёт предмет и заменяет в нём

[uron: u1:дробящий:u1 u2:режущий:u2 p1:500 p2:2500 u3:огненный_mgc:u3 p3:0 :uron]

на допустим такую

[uron: u1:дробящий:u1 u2:режущий:u2 p1:500 p2:2500 u3:огненный_mgc:u3 p3:2500 :uron]

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

Aleks Versus, всё хорошо объяснил, во всём разобрался. Да именно “зачарование” оружия я и имел ввиду. А вот мне интересно если у тебя повышение атаки или защиты против определенных типов врагов? Допустим герой больше урона буден наносить какому-нибудь “великану”, нежели дракону :). На это я пока лишь думал о функции, которая проверяет против какого врага герой проводит атаку, и в зависимости от этого она повышает урон именно на эту атаку, ибо врагов может быть несколько и все разные.

Aleks Versus Moderator 04.07.2015 09:03 (10 years ago)

Storm,
Враги в моём движке тоже являются объектами (пока я, правда, не написал механизм работы с противниками. Скорее всего это будет работать в связке с боевой механикой). И у них те же правила описания (приблизаительно, конечно), что и у предметов. Т.е. можно задать эм… свойством противника некую уязвимость. Допустим есть у нас Скелеты, Вампиры, Зомби. Всех их объединяет один признак: они - нежить. Прописываем уже в самом механизме боя бонус: если оружие наносит огненный урон и противник обладает признаком “нежить”. Или, скажем, у оружия есть свойство “серебро”. Это будет тоже бонус при взаимодействии с нежитью. В общем работает всё примерно как в “Doodle God”. Если два объекта обладают необходимыми свойствами - они взаимодействуют. Если необходимых свойств не наблюдается - реакции либо нет, либо она стандартная, опционально.)))

Aleks Versus, к подобным выводам пришел и я. Сейчас стою на неком распутье). Поясню в чём суть: пока я используя для описания персонажа переменные, допустим

$имя[n]='Главный герой'
здоровье[n]=100

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

$charname[n]='[name:Главный герой:name][HP:100:HP]'

где тег “name” - имя героя, а “HP” - здоровье, n - индивидуальный номер героя в партии. И вот здесь у меня появился вопрос: какую систему описания персонажа использовать для манипуляций данных именно для боя? Если мы используем переменные, то они заданы ещё до боя и манипуляция с ними будет легкая. Если же использовать теги, то каждое действие в бою будет сопровождаться изменением определенного тега, а для этого нужна уже своя функция), в принципе написать её не сложно :). Но а если мы храним достаточно большую строку данных в переменной $charname[n]? Получается при каждом боевом действии компьютер будет её обрабатывать, даже при простом обновлении экрана боя для изменения показателя переменных, допустим здоровья. Стоит учитывать ещё то, что таких переменных $charname[n] не одна($charname[0], $charname[1], $charname[2] и т. д.).
Есть ещё вариант использования временных переменных, то есть перед боем из тега вынимается его значение и присваиваться временной переменной, примерно так

!Предварительно вынули из тега "name" значение Главный герой, из тега "HP" значение 100.
$temp_name[n]='Главный герой'
temp_HP[n]=100

И уже дальше пользоваться этими временными переменными. В какой-то степени это решит проблему, после боя все переменные с “temp” можно удалить.
Но всё это просто размышление над тем какую систему использовать целесообразно)
Огромный плюс теговой системы, как я считаю: нет засорения переменными, которые могу возник из-за особенностей движка, когда несуществующая переменная, если она вызвана приравнивается к нулю. Минус: сложнее манипулировать такими данными. Если использовать систему переменных, плюс: легкая манипуляция в формулах, минус: засорение нулевыми переменными, которые придется подчищать.
Вопрос целесообразности системы возник ещё по этим причинам: допустим мы захотим оставить какого-то персонажа на время, тогда хранение всех данных о нём в одной строчке $charname[n] будет самым лучшим вариантом, так как эта строка не будет засорена нулевыми переменными. Вторая же причина связана с добавлением всевозможных тегов в строчку $charname[n], допустим разных навыков или чего-нибудь ещё. Этим мы увеличиваем саму строчку, и как я думаю, затрудняем её обработку. Хотя, может я по своему незнанию просто всё преувеличиваю :) .

Aleks Versus Moderator 10.07.2015 13:10 (10 years ago)

Storm:

какую систему описания персонажа использовать для манипуляций данных именно для боя

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

Storm:

Этим мы увеличиваем саму строчку, и как я думаю, затрудняем её обработку.

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

Aleks Versus, за два дня тоже пришел к выводу, что лучше хранить такие данные в числовых переменных). Реализовал подсчет инициативы, теперь передача хода конкретному персонажу на игровой доске будет легкой. Сейчас мучаюсь над задачей как правильно выводить персонажей на игровую сетку. С одной стороны выгодно использовать строки под координаты допустим так: $charname_loc[0]=‘0,3’. А с другой лучше так: x[0]=0, y[0]=3. Строковые данные лучше при выводе сетки, а числовые когда нужно рассчитывать по кому именно возможен удар. Боюсь, придется использовать оба варианта :)

Вот мой взор на ХОРОШУЮ RPG!
…Механика

Все же, ограничение на уровень нужно, к примеру.

Вы получили новый уровень, у вас 5 очков характеристик, и 2 очка навыков(перки). И, вот игрок потратил последние очки, и теперь у него все изучено. Конечно, можно оставить возможность получать уровень и дальше, для очков характеристик. Но, тогда у игрока будет танк. Потому как, в игре открытый мир, и качаться можно где угодно, к концу(если он будет) игрок моментально уничтожит главного злодея(да это решается подниманием характеристик мобам, на уровень игрока, а то и выше) но тут уже как разработчик решит.
…Открытый мир
Несомненно это нужная часть для игры данного жанра, ведь играть становиться интересней. Но, нужна динамика, нужно чтобы города со временем менялись(слава рандому), это могут быть как и незначительные изменения(умер торговец которому вы должны, потому, что он изменял жене, и она заказала убийцу), так и значительные(Данные город захватил владыка Алекс, а потому и налоги другие, и отношения к путешественникам, а может Алекс вас ненавидит, тогда стража вообще на вас нападет). Поэтому, пустой мир, не кому, не понравиться.
…Квесты
Поистине они должны быть разнообразны, и не нужны убей N врагов, принеси N камня. А как в ТЕС, ага убей Петю, и принеси мне его кольцо, тааак мы его убили, вернулись, а Вася убит, и теперь нам нужно расследовать это тайну. Так, и огромные, и значительные, влияющие на саму игру квесты.
…Свобода выбора и действий
Нужная, но мало где появляющиеся привилегия. К примеру: Вы прошли долгий путь героя, победили множество монстров, и вдруг захотелось власти. И тут два пути: Нанять наёмников, и штурмом взять замок, перед этим составив план. Или построить свой, создать армию, экономику, пожениться и прочее. А, потом захватить все имеющиеся земли, на каждую землю своя история, и выбор.

Думаю, если создать такую текстовую РПГ, у автора будет слава, и богатство.

А вообще на qsp кроме хранителя старграда и куртуазной баллады есть хоть какие нибудь рпг?

Log in or Register to post comments.