ТОМ - платформа для текстовых игр

Объявление

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

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.



Игра 01

Сообщений 1 страница 30 из 32

1

Название игры не пишу, т.к. находится на стадии написания сюжета и название может измениться. Да и вряд ли получится когда-нибудь релизнуться имея так мало свободного времени и используя не обкатанную платформу ТОМ2 без единой игры на своём счету.
Цель проекта скорее не написание готовой игры, а вылавливание узких мест в процессе попыток написания игры на ней не самим автором платформы.
Тему создал чтобы задавать в ней вопросы по ходу написания кода игры. Можно было бы поместить в раздел "Поддержка, FAQ, Приемы разработки", но там разделы для отдельных вопросов в отдельных темах. А у меня похоже будет много вопросов, и я просто замучаюсь создавать для каждого тему.

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

Вопрос 2.
Один из НПС будет находиться "в голове" у ГГ (что-то вроде шизофрении) и с ним тоже надо будет разговаривать. Как описать такого НПС в коде, чтобы он был и нигде и везде с ГГ? При этом его нельзя было бы увидеть, пощупать и т.д.

Пока думаю хватит. По мере написания кода наверняка всплывут ещё много вопросов.

2

Alexandr написал(а):

Вопрос 1.
Начнём с системы диалогов с НПС. В игре намечается несколько НПС, с которыми можно будет общаться на интересные темы, а не просто просить их что-то сделать или давать/отбирать у них предметы. Поэтому хочется, чтобы можно было переходить из парсерного режима в менюшный при общении с персонажами. Например, набрав команду "поговорить с Дмитрием" мы бы переходили к "менюшному" режиму, где у нас есть несколько вариантов фраз и можно двигаться по "дереву разговора", кликая по этим фразам.

В стандартной библиотеке с разговорами с НПС сейчас бедлам, разговорные функции будут все переделываться. Но менюшный режим с этим ни как не связан и может быть реализован.
Функция "поговорить с <NPC_name>" после всех проверок в итоге будет вызывать метод NPC._разговор, где и нужно формировать диалог в соответствии с текущей ситуацией.
Реакция на каждый вариант диалога должна быть реализована в виде отдельной функции, и рост их количества может быть не очень удобен при разветвлённых диалогах, но это наверное можно решить разнеся функции по отдельным модулям.

Alexandr написал(а):

Будет ещё ситуация, что ГГ (главный герой) не будет знать имени или вообще ничего о том, кто с ним заговорил (например, голос из динамика). Тогда тоже надо будет как-то переходить в режим диалога.

Но автор же знает с кем в данный момент говорит ГГ? Значит в итоге всё равно будет вызван метод NPC._разговор, и далее всё как и выше.

Alexandr написал(а):

Вопрос 2.
Один из НПС будет находиться "в голове" у ГГ (что-то вроде шизофрении) и с ним тоже надо будет разговаривать. Как описать такого НПС в коде, чтобы он был и нигде и везде с ГГ? При этом его нельзя было бы увидеть, пощупать и т.д.
Пока думаю хватит. По мере написания кода наверняка всплывут ещё много вопросов.

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

3

Вопрос 3.
Как и где подключаются дополнительные модули? Что-то вроде "include Room01.tom"? Где писать эту строчку? Ведь если написать в начале файла, то она загрузится до того, как пройдёт инициализация основного модуля. Или это работает не так?

Вопрос 4.
Можно всё-таки как-то поудобнее смотреть классы? Никак не могу обуздать ТОМ2IDE: постоянно всё зависает, строка ввода то не появляется, то съезжает куда-то вниз за границы экрана. Мой проект вообще не открывается в нём: webtom вылетает. Видимо какие-то ошибки в коде, а какие, мне даже не говорит. Приходится с трудом проверять наличие слов и классов в библиотеке, запуская на отладку demo-проект из поставки, часто перезапускать отладку из-за съезжающей строки ввода:
http://s1.uploads.ru/t/A2Zki.png

P.S. В стандартной библиотеке увидел, что стены унаследованы от предмета. А у предмета есть влаг "можно_выкинуть = да". Не получится ли, что игрок сможет выкидывать стены из локации?  :D

4

Опять не могу определить слово Алиса:

Код:
слово Алиса
{ @существительное
	key=#ЖрОд
	defkey=#ИпЕч
	#ИпЕч = "Алиса"
	#ИпМч = "Алисы"
	#РпЕч = "Алисы"
	#РпМч = "Алис"
	#ДпЕч = "Алисе"
	#ДпМч = "Алисам"
	#ВпЕч = "Алису"
	#ВпМч = "Алис"
	#ТпЕч = "Алисой"
	#ТпЕчПс = "Алисою"
	#ТпМч = "Алисами"
	#ПпЕч = "Алисе"
	#ПпМч = "Алисах"
}

пишет "Ошибка синтаксиса". Пробовал и как в старых версиях, и как сейчас в библиотеке. Не хочет принимать, и не говорит где именно ошибка и как надо.

5

Alexandr написал(а):

Вопрос 3.
Как и где подключаются дополнительные модули? Что-то вроде "include Room01.tom"? Где писать эту строчку? Ведь если написать в начале файла, то она загрузится до того, как пройдёт инициализация основного модуля. Или это работает не так?

Подключение: "include Room01.tml". Расширение .tom для модулей лучше не использовать.
Место подключения зависит от назначения модуля.
Если модуль содержит базовые классы, подключать надо в самом начале основного файла.
Если там просто продолжение игры и дополнительные функции, то в конце файла.
Если в модуле описание локации, подключить его можно в момент перехода в локацию.

Alexandr написал(а):

Вопрос 4.
Можно всё-таки как-то поудобнее смотреть классы? Никак не могу обуздать ТОМ2IDE: постоянно всё зависает, строка ввода то не появляется, то съезжает куда-то вниз за границы экрана.

Можно просто обновлять страничку по F5. В хроме таких проблем не проявляется... Можно еще поковырять файлы TOM2IDE.html и TOM2IDE.css. Веб-верстальщик я начинающий, там вполне могут быть грубые ошибки верстки.

Alexandr написал(а):

Мой проект вообще не открывается в нём: webtom вылетает. Видимо какие-то ошибки в коде, а какие, мне даже не говорит.

В проекте обязательно должна быть локация и ГГ внутри неё. Иначе вылетает. Ошибка известна и воспроизводима, просто не успел её пофиксить. Если вылет по иной причине - присылай проект, поковыряю.

Alexandr написал(а):

P.S. В стандартной библиотеке увидел, что стены унаследованы от предмета. А у предмета есть влаг "можно_выкинуть = да". Не получится ли, что игрок сможет выкидывать стены из локации?

Стены обычно описываются как декорации. Если стену сделать объектом, её возможно будет подвинуть, сломать или даже взять, в зависимости от её веса, крепления, прочности и т.д.

6

Alexandr написал(а):

Опять не могу определить слово Алиса


$Алиса
{ @существительное
key=#ЖрОд
defkey=#ИпЕч
#ИпЕч = "Алиса"
#ИпМч = "Алисы"
#РпЕч = "Алисы"
#РпМч = "Алис"
#ДпЕч = "Алисе"
#ДпМч = "Алисам"
#ВпЕч = "Алису"
#ВпМч = "Алис"
#ТпЕч = "Алисой"
#ТпЕчПс = "Алисою"
#ТпМч = "Алисами"
#ПпЕч = "Алисе"
#ПпМч = "Алисах"
}

Да, синтаксис определения слов, классов и объектов "недавно" менялся =)

7

Заготовка раздела помощи, вроде без спойлеров.

Помощь v0.1

Управление
  В игре вы управляете Алисой. Для этого вам надо набирать команды в строке ввода.
  Основные команды, которые действуют практически на каждый объект в игре:
  "осмотреть, осмотри, осм" - Алиса осмотрит объект без прикосновения к нему и опишет что он из себя представляет. Возможно добавит, что она об этом думает.
  "взять, возьми" - Алиса попытается взять объект себе, если возможно. Алиса будет всегда носить взятые объекты с собой, пока вы что-нибудь с ними не придумаете.
  "потрогать, потрогай" - Алиса потрогает объект рукой и попытается описать какой он на ощупь.
  Так-же будут встречаться другие объекты, с которыми можно делать специфические действия.
  Если вы совсем запутались и не знаете что делать, то можете набрать "подсказка" и вам будет показан список некоторых нестандартных действий, которые можно совершить в текущем месте.
    Диалоги
  В игре вам будут встречаться персонажи, с которыми можно говорить.
  Чтобы начать разговор с персонажем, наберите "поговорить с [персонаж]".
  Если с персонажем возможно поговорить, вы попадёте в режим диалога.
  Так-же в диалог вас могут втянуть сами персонажи.
  В режиме диалога вы должны выбирать реплику из предложенных вам вариантов и нажимать на неё.
  На каждую реплику ваш собеседник отвечает вам и снова появляются варианты ваших фраз.
  Некоторые фразы или события в игре могут прервать разговор.
  Так-же вы всегда можете заранее выйти из разговора, выбрав пункт "[закончить разговор]".
  Это будет означать, что вы игнорируете своего собеседника и не хотите продолжать говорить.

Какие команды кроме перечисленных трех можно ещё описать как универсальные?

Можешь написать пример реализации простого диалога и перехода от одних вариантов фраз к другим?

8

Alexandr написал(а):

Какие команды кроме перечисленных трех можно ещё описать как универсальные?

"Осмотреться, осмотрись, осм" - осмотр локации;
"север, с; юг, ю ... вверх, вниз" - перемещение по направлениям;
"инвентарь, инв".

9

Глюк команды "осм"

> осм стену
Неоднозначно: осматривай или осматривайся;

где же здесь неоднозначность? "Осматривайся стену" ведь не скажешь.

Описание двери

Код:
  первая:дверь
  { это @дверь
    prp _полное_описание = "Металлическая дверь без петель, замочных скважин и ручек. \"Наверное, открывается автоматически\" - подумала Алиса."
    prp _описание = "Металлическая дверь"
  }

> осмотри дверь
Металлическая дверь.

Почему у двери не выводится полное описание при осмотре?
И можно ли выводить мысли Алисы ("Наверное, открывается автоматически" - подумала Алиса) как-нибудь особым образом. Как во время диалога, например.

Дверь при осматривании

> осмотрись
Небольшая комната с ровными серыми стенами, здесь есть первая: дверь.

Почему не выводится, например "здесь есть металлическая дверь"?

Рассматривание верха

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

Почему при попытке посмотреть на верх, ГГ пытается туда залезть?

Осмотри себя

Код:
  Алиса
  { это @девушка
    prp _полное_описание = "Девушка, которая забыла всё, {this._внешнее_описание}"
    key = #Ты //обращение на "ты"
    брюки   { снаружи; надето; }
    футболка { снаружи; надето; }
//    мешок   { это @@надевающееся; снаружи; за_спиной }
    pers = this
  }

> осмотри себя
Ты выглядишь как обычно, одето в брюки и нет формы #НаВпЕч для футболка.

Куда пропало моё описание?

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

10

Alexandr написал(а):

Прости, что заваливаю вопросами. Если у тебя нет времени/желания отвечать, то скажи, и мы вместе бросим это неблагодарное дело.

Ха! у меня еще больше недели отпуска, так что до следующего четверга я совершенно свободен  :rofl:

11

Неоднозначно: осматривай или осматривайся;
Почему у двери не выводится полное описание при осмотре?

Это мои косяки, недосмотрел, постараюсь исправить.

Почему не выводится, например "здесь есть металлическая дверь"?

Объекты лучше именовать "по-научному" - "дверь:первая", или даже "дверь_металлическая", потом обязательно где-нибудь пригодится.
Чтобы объект проставлялся во фразах как словосочетание, а не одним словом, для него нужно задать словоформы как для слова:

первая:дверь
{  это @дверь
    #ИпЕч = "металлическая дверь"
    #ВпЕч = "металлическую дверь"
    prp _полное_описание = "Металлическая дверь без петель, замочных скважин и ручек. \"Наверное, открывается автоматически\" - подумала Алиса."
    prp _описание = "Металлическая дверь"
}

И можно ли выводить мысли Алисы ("Наверное, открывается автоматически" - подумала Алиса) как-нибудь особым образом. Как во время диалога, например.

А почему бы нет? Перевод строки может быть внутри строки.  Вот так например:

prp _полное_описание = "Металлическая дверь без петель, замочных скважин и ручек.
- Наверное, открывается автоматически - подумала Алиса."

12

Персонажам лучше принудительно указывать род и одушевлённость:
Алиса
  { это @девушка
    ...
    key = #ТыЖрОд //обращение на "ты"
    ...
  }

Чтобы не получалось так: "Ты выглядишь как обычно, одето в брюки и нет формы #НаВпЕч для футболка."

13

Почему при попытке посмотреть на верх, ГГ пытается туда залезть?

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

В каждую локацию можно добавить что-то вроде этого:
вверх = "Наверху ровный потолок, выложеный белой потолочной плиткой. На месте двух плиток встроены люстры с несколькими люминисцентными лампами внутри, хорошо освещающие комнату." //описание
вверх = fail, "Жаль, ты не умеешь летать." //ошибка

14

ASBer написал(а):

Чтобы объект проставлялся во фразах как словосочетание, а не одним словом, для него нужно задать словоформы как для слова

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

15

ASBer написал(а):

В каждую локацию можно добавить что-то вроде этого:
вверх = "Наверху ровный потолок, выложеный белой потолочной плиткой. На месте двух плиток встроены люстры с несколькими люминисцентными лампами внутри, хорошо освещающие комнату." //описание
вверх = fail, "Жаль, ты не умеешь летать." //ошибка

Сделал так:

Код:
  вверх = "Наверху ровный потолок, выложеный белой потолочной плиткой. На месте двух плиток встроены люстры с несколькими люминисцентными лампами внутри, хорошо освещающие комнату."
  вверх = fail, "Жаль, ты не умеешь летать."

> посмотри вверх
Жаль, ты не умеешь летать.
------------------
> посмотри на верх
Жаль, ты не умеешь летать.

Всё-равно пытается именно залезть вверх, а не просто описать что там наверху.

16

Alexandr написал(а):

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

А он есть =) Я ради простоты не стал его приводить выше.

title = "{$металлическое*$$*#ЖрНд} {$дверь*$$}"

17

Alexandr написал(а):

Всё-равно пытается именно залезть вверх, а не просто описать что там наверху.

Особенность стандартной библиотеки. Пока не понял почему так, но есть разница между командами "осмотреть" и "смотреть" - буду ковырять =)

18

Я уже начинаю сомневаться, что писать проработанные парсерные игры вообще возможно. Вот сейчас обнаружил, что в комнате стоит стул, и ГГ может как просто стоять в комнате, так и сидеть на этом стуле. При этом нужно добавлять условия во многие описания. А что если игрок начнёт просить ГГ встать на стул, залезть под стол (который тоже есть в комнате) или даже под этот стул в конце концов. Это же всё не учтёшь. Да и не нужно это для сюжета, но ведь как-то с этим надо справляться? Лечь на пол/стол тоже можно... блин, я в недоумении сколько разных вариантов можно придумать для такого простого "находиться в комнате".

Отредактировано Alexandr (2016-08-17 17:43:08)

19

"невозможно залезть под стул" - вполне нормальная реакция для этой и других подобных команд. Ясно даёт понять игроку, что он делает не то что нужно.
Более того, реализация команд, которые никак не влияют на сюжет, вредна для игры, т.к. если игрок смог залезть под стул, то он решит что это для чего-то нужно и будет перебором пробовать разные комбинации бесполезных действий. Не надо так =)))))

20

При запуске игры через команду:
start "" "bin\webtom.exe" "/tom2/demo/demo.tom" "w"
игра выводит начальный текст, но никак не реагирует на вводимые команды

21

Alexandr написал(а):

При запуске игры через команду:
start "" "bin\webtom.exe" "/tom2/demo/demo.tom" "w"
игра выводит начальный текст, но никак не реагирует на вводимые команды

Принято. Ошибка воспроизводится.

22

И всё-таки, есть какой-нибудь пример реализации диалогов с персонажами?

23

Под текущую версию нет. Постараюсь что-нибудь набросать.
Есть менюшная игра "Остров", с тех пор принципиально ничего не поменялось (за исключением синтаксиса).

24

Вот доработанная стандартная библиотека.

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

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

25

Пример диалога на меню:

Код:
//Пример диалогов с использованием меню
//ТЕСТЫ
Тест Тест Тест
------------------------------------------------------
location комната
{ человек{}
  pers = человек
  собака{}
  ==_сцена==
  <location>
  Перед тобой сидит собака. Поговори с ней.
  </location>
}
------------------------------------------------------
action(говорить _действие#Пф!е, с, существо _NPC#Тп!е)
{
  --execute--
  _NPC._разговор
  ok
}
------------------------------------------------------
собака
{ prp _статус = 0;
  prp _здоровались = нет;

  --_разговор--
  if(this._статус == 0)
  { ================================================
    1. <a href="#", rel="привет"> - Привет!</a>
    2. <a href="#", rel="как дела"> - Как дела?</a>
    3. <a href="#", rel="где спрятана кость"> - Где спрятана кость?</a>
  }
  else if(this._статус == 1)
  { ================================================

  }
  else if(this._статус == 2)
  { ================================================

  }
  else if(this._статус == 99)
  { ================================================
    Собака не желает с тобой разговаривать
  }
}
------------------------------------------------------
action(здороваться)
{ --execute--
  if(собака._статус == 99) %Собака не отвечает...
  else if(собака._здоровались) собака > "уже здоровались."
  else собака > "и тебе здраствуй."
  собака._здоровались = да
  ok
}
------------------------------------------------------
action(как, дела)
{ --execute--
  if(собака._статус == 99) %Собака молчит...
  else собака > "блохи закусали, сил нет (чешет себя задней лапой)."
  ok
}
------------------------------------------------------
action(где, спрятана, кость)
{ --execute--
  if(собака._статус == 99) %Собака глядит изподлобья...
  else собака > "А вот это не твоё дело! Не буду больше разговаривать!"
  собака._статус = 99
  ok
}
------------------------------------------------------

26

class диалоговый_НИП
{ }
ошибка синтаксиса в конструкторе объекта!

Что я делаю не так?

ASBer написал(а):

Да, синтаксис определения слов, классов и объектов "недавно" менялся =)

Скорее всего дело в этом. Как же классы сейчас определяются?

Отредактировано Alexandr (2016-08-30 09:41:00)

27

Alexandr написал(а):

Что я делаю не так?


@диалоговый_НИП
{ }

28

Код:
action(как, дела)
{ --execute--
  if(собака._статус == 99) %Собака молчит...
  else собака > "блохи закусали, сил нет (чешет себя задней лапой)."
  собака._вывести_диалог
  ok
}

А можно как-то определить, при разговоре с кем было вызвано это действие? В приведённом коде объект "собака" забит жёстко. Но может понадобиться разговаривать с разными НИП-ами, поэтому надо как-то сделать условие в методе execute. Только через глобальную переменную?

Отредактировано Alexandr (2016-08-30 16:11:48)

29

Можно так:

Код:
action(существо _НИП#ИпЗм!е, как, дела)
{

}

Тогда в переменной _НИП будет тот, к кому мы обращаемся.

Второй вариант - завести глобальную переменную Глобал_НИП, которую будем заполняем при начале разговора

Код:
action(говорить _действие#Пф!е, с, существо _NPC#Тп!е)
{
  --execute--
  Глобал_НИП = _NPC 
  _NPC._разговор
  ok
}

И третий вариант, если НПС привязан к локации, можно хранить его в свойстве локации loc._NPC

Код:
location комната
{ человек{}
  pers = человек
  собака{}
  prp _NPC = собака
  ==_сцена==
  <location>
  Перед тобой сидит собака. Поговори с ней.
  </location>
}

Наверное есть еще варианты...

30

ASBer написал(а):

Alexandr написал(а):

    При запуске игры через команду:
    start "" "bin\webtom.exe" "/tom2/demo/demo.tom" "w"
    игра выводит начальный текст, но никак не реагирует на вводимые команды

Принято. Ошибка воспроизводится.

Ещё не пофикшено?