Часто Задаваемые Вопросы и Ответы о системе RTADS

Мультимедиа

Вопрос от Zargo:
Подскажите, пожайлуста, как можно подключить графику и звук в игру и можно ли вообще это сделать на RTADSе.

Можно, для интерпретаторов с поддержкой мультимедиа. Это проигрыватели для систем Windows, Macintosh и Linux. Выглядит и реализуется как HTML верстка с некоторыми ограничениями. Графические/музыкальные ресурсы можно зашить в файл игры или распространять отдельными файлами. Графика: jpg, png, mng. Последний позволяет отображать анимированные изображения. Также можно воспроизводить анимацию из последовательности jpg, динамическим контентом или псевдографикой. Поддержка Gif не была реализована по причине ограничений лицензии.


Вопрос от ifn00b:
Касательно мультимедийных возможностей - какие типы аудио-файлов можно подключить к RTADS? И каким образом происходит их проигрывание - интерпретатор вызывает внешнее приложение, которое зарегистрировано в системе для файлов данного типа?

Midi, wav, MP3 и Ogg Vorbis. Для проигрывания используется DirectX.

Подробно обо всем этом можно узнать здесь (увы, на английском языке): http://www.tela.bc.ca/tads-manual/tads-12.html

P.S. По мнению большей части сообщества, избыток графики и звука уводит от настоящего IF. Будьте очень осторожны и используйте эти возможности тогда, когда это оправдано.

Сборка и компиляция

Чем отличаются debug и release версии игры?

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

Вывод: при выпуске игры в свет не забывайте компилировать и выкладывать release версию.

Отладка

Есть ли в ТАДС способы автоматического тестирования библиотек и игр?

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

Подробно это описано в пока непереведенной главе мануала: Параграф "Testing Your Game"

Вкратце:

mygame.exe -o walkthru.in  - записывает в файл команды по мере прохождения
mygame.exe -i walkthru.in -l walkthru.log  - запускает игру и вводит список команд, 
а выходящий текст записывает в файл.

Файл с выводом из предыдущей и новой версии можно сравнить с помощью специальных программ, типа WinMerge.


Синтаксис

Почему индексация массивов и строк начинается с единицы?!

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


Никак не могу привыкнуть к этому полупаскальному-полусишному синтаксису. Можно ли как-нибудь привести его к единой форме?

Да. Существует специальная директива #pragma C+. Она включает режим соответствия языку C для файла, в котором упомянута, поэтому вы сможете использовать привычные == для сравнения и = для присваивания. А директива #pragma C- возвращает все к стандартному виду.

Совет: если вы разрабатываете модуль, который затем может быть использован другими людьми, директивой #pragma явно указывайте стиль, используемый в файле, чтобы авторские настройки не повлияли на работу вашего модуля.


Как создать список (list) из одного элемента?

Если вы задали переменную "a" без указания какого либо типа, т.е.

local a;

то присвоить ей список из одного элемента

a := [b];

не удастся.

Нужно либо изначально указать что это список

local a=[];

либо поступить так:

a := [] + b;


При вызове метода foo() без аргументов возникает ошибка компиляции.

Если метод не принимает аргументов, то сотрите скобки при его вызове.

bar.foo(); //ошибка
bar.foo;   //вызов метода

При объявлении метода скобки все-равно нужны!

Неочевидные приемы

Почему не наследуются лексические свойства (sdecs, noun и пр.)?

В стремлении упростить жизнь авторам игр, TADS не делает особых различий между классом и объектом (экземпляром класса). Однако отличия есть, хоть и небольшие. Во-первых, класс нематериален в игре — вы никак не сможете взаимодействовать с ним. Во-вторых (уже догадались?) лексические свойства (sdesc, ldesc, noun, adjective) наследуются только от классов, а от объектов нет.

Пример:

coin : item
    desc = 'золотая/1пж монета/1ж'
    ldesc = "Золотая монета с изображением профиля Императора. "
    isHer = true
;

coin1 : coin
    location = treasury
;

coin2 : coin
    location = chest
;

coin3 : coin
    location = purse
;

В таком виде пример работать не будет, потому что лексические свойства объекта coin не наследуются потомками. Соответственно, вы просто не найдете монет в игре, потому что к ним никак нельзя будет обратиться (свойство noun-то не заполнено!). Уже догадались, как исправить? Правильно, пишем в первой строке:

class coin : item

и все встает на свои места.

Примечание: на момент написания заметки библиотека находилась в состоянии активной разработки и desc, к примеру, стал наследоваться нормально, просто дублируя словоформы много раз. Несмотря на это, рекомендуется ВСЕГДА использовать классы, если требуется наследовать лексические свойства.


Как динамически изменить ldesc (и другие свойства с двойными кавычками)?

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

vase : item
    gdesc = 'ваза/1ж'
    ldesc = "Хрупкая фарфоровая ваза. "
...

    doDrop(actor) =
    {
        "Ваза была так тонка, что разбилась при падении. ";
        self.ldesc := "Теперь ваза представляет собой лишь груду черепков. ";
        pass doDrop;
    }
;

Так как метод «двойные кавычки» ничего на самом деле не возвращает, ldesc в данном примере перепишется пустым значением и описание исчезнет вообще. Для решения этой проблемы следует переписать определение ldesc вот так:

vase : item
    gdesc = 'ваза/1ж'
    ldesc = 
    {
        if (not self.broken)
            "Хрупкая фарфоровая ваза. ";
        else
            "Теперь ваза представляет собой лишь груду черепков. ";
    }

    broken = nil
...

    doDrop(actor) =
    {
        "Ваза была так тонка, что разбилась при падении. ";
        self.broken := true;
        pass doDrop;
    }
;

Ещё один способ - вставить в строку с двойными кавычками вызов изменяемого свойства. Например:

vase : item
    gdesc = 'ваза/1ж'
    ldesc = 
    {
        if (not self.broken)
            "Хрупкая фарфоровая ваза. ";
        else
            "Из-за <<negodyai>> ваза превратилась в груду черепков. ";
    }

    broken = nil
    negodyai=''
...

    doDrop(actor) =
    {
        "Ваза была так тонка, что разбилась при падении. ";
        self.broken := true;
        negoyai:=dToS(actor,rdesc); 
        // функция dToS перехватывает вывод на экран "двукавычного" 
        // свойства rdesc и присваевает переменной negoyai
        pass doDrop;
    }
;

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

Усложнение принимаемых фраз

Как заставить понимать команду с тремя существительными, ввести наречия, сделать несколько проходов в одной стороне света и т.п.

Большинство таких нестандартных подходов не стоят затрачиваемых усилий для их реализации. Постарайтесь упростить те случаи для которых вы хотите их использовать.

Например, по порядку:

  1. привязать лошадь веревкой к забору = привязать веревку к забору и привязать веревку к лошади
  2. тихо открыть дверь = смазать петли салом и открыть дверь
  3. на юге вы видите три пещеры. Кровавый след тянется в ту, что западнее, а из восточной выползает вязкий белесый туман