Как я могу реализовать умные сценарии в моей игре?

18

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

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

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

Натан
источник
Только для описания сущностей вы можете использовать только xml или что-то подобное, нет необходимости в скриптах. Для сценариев я бы использовал C #, но только если ваш движок находится в .NET ...
Кикаймару
@Kikaimaru C # Это не язык сценариев. Лучше было бы использовать lua или другой язык, который может быть встроен в ваш движок.
JDSweetBeat
@DJMethaneMan «C # не является языком сценариев» ничего не значит, нет абсолютно никаких проблем с написанием сценариев на C # в игре, написанной на C # и использованием чего-то вроде Roselyn для компиляции ... Но через 4 года я бы использовал json a Javascript вместо XML и C # :)
Кикаймару

Ответы:

17

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

ENTITY:"Goblin"
{
    description="It's currently their age."
    commonname="goblin"
    pluralCommonName="goblins"
    childname="gob'in"
    pluralChildName="gob'ins"
    active=Nocturnal
    tags=Mobile
    baseAttributes="OrganicMobileCreature"

    [Model]{
            meshname="Goblin"
            texturename="GoblinTexture"
    }

    [Motion]{
            maxvelocity=0.01:0.015
            locomotion=Walk,Swim
    }

    [Skills]{
            ALL=0.01:0.05,Mine=8.3:8.8,PlaceCube=8.3:8.8
    }

    [Inventory]{
            maxItems=2
            Allow=ALL
            Disallow=NONE
    }
}

Многое из этого самоописывается, но вот некоторые основные моменты:

  • Первый раздел описывает общую информацию для объекта. Это включает в себя описание и отображаемые имена для различных аспектов объекта.
  • В baseAttributesссылках тегов другой файл сценарий , который определяет общие компоненты , которые я не хочу , чтобы переопределить несколько раз. Он содержит такие компоненты , как position, liferequirementsи так далее. Если какой-либо компонент определен здесь снова, этот компонент перезапишет общий.
  • Каждый [NAME] { }набор определяет новый компонент, который будет добавлен к этим объектам.
  • Это описание предназначено не только для одной сущности , но и для всех созданных гоблинов. Вы увидите, что некоторые значения имеют диапазоны (то есть 0.01:0.015), когда создается новый гоблин, он создается с компонентом, который имеет случайное значение в этом диапазоне. Таким образом, у каждого гоблина будут немного разные навыки и немного разные скорости. Эта установка определяет, что все гоблины начнут с действительно хороших навыков размещения кубов и майнинга, что на самом деле только для моих собственных целей тестирования. Но, как я уверен, вы можете догадаться, очень легко изменить значения на то, что я хочу.

Все это включает в себя создание собственного синтаксического анализатора, какую-то структуру для хранения определений сущностей (я называю мой Лексикон!) И фабрику для получения этих определений сущностей и генерации новых сущностей. Для меня эта система все еще находится на ранних стадиях, но получается очень, очень хорошо. Это довольно мощная система для быстрого определения сущностей и позволяет создавать любые сущности, которые вы хотите, используя созданные вами компоненты. Если вам неудобно создавать свой собственный парсер, я думаю, XML будет работать нормально. Я конвертировал свой из рекурсивного синтаксического анализатора с возвратом назад, который я написал для немного выдуманного языка программирования.

Как видите, это определяет сущность. Я упомянул, что это не определяет поведение напрямую. Однако он может легко определить такие вещи, как ненавистные враги и то, как агрессивно реагировать на этих врагов. Это было бы так же просто, как определить любой компонент, который вы используете для управления таким поведением. Мои сущности также имеют компонент интеллекта (не показан), который определяет такие вещи, как:

  • Как они находят путь (простое движение по линии прямой видимости, простое A *, прогнозирующее A * и т. Д.)
  • Насколько они агрессивны / оборонительны. У сущностей могут быть домашние зоны, которые будут защищаться, но, возможно, не агрессивные вне этих зон.
  • Технологическая осведомленность (открыть двери, использовать гаджеты, избегать ловушек и т. Д.)
  • И более...

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

MichaelHouse
источник
Спасибо, что поделился. Я действительно думаю, что я собираюсь попытаться сделать это, используя формат XML. Я много думал об этом (спасибо AbstractChaos btw), и это должно отвечать моим потребностям (по крайней мере, для описания сущностей).
Натан
1
@nathan Я согласен, ты должен пойти с XML. Причиной моего сообщения было больше, какие данные включить в ваш XML и как его использовать. Формат данных может быть любым, что вам нравится. Данные, которые вы решите включить, и то, как вы реализуете их использование, гораздо важнее.
MichaelHouse
@ Byte56 Я знаю, что этот пост старый, но как бы вы справились с отношениями родитель-потомок? Скажем, у нас есть дерево навыков, и вам нужно 10 баллов в навыке A [0], чтобы включить A [1], и 10 баллов в этом, чтобы включить A [2] и т. Д. Должен ли я их вложить, или сгладить их и набрать на клавиатуре ParentId? Очевидно, что они логически эквивалентны, но я надеялся, что у вас была какая-то реальная проницательность.
Superstringcheese
@Superstringcheese if player.hasPoints(10) then i++ end skillTree[i]будет псевдокодом. Однако я понятия не имею, насколько этот вопрос относится к этой должности.
JDSweetBeat
4

Если все, что вам действительно нужно, это способ определения компонентов Monster, тогда XML будет работать хорошо, и C #, и Java имеют молниеносную реализацию этого.

Ваш XML может быть

<?xml version="1.0" encoding="UTF-8"?>
<mobs>
  <mob>
    <personality>Aggressive</personality>
    <intelligence>20</intelligence>
  </mob>
</mobs>

Тогда ваш класс мобов может выглядеть так. (Джава)

public class Mob {
  private IPersonality personality;
  private Integer intelligence

  //**  Getters & Setters **//
}

Где IPersonality - это интерфейс.

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

например, проанализировать значение личности в PersonalityFactory, который просто:

public IPersonality getPersonality(String personalityName) {
  if(personalityName.equals("Aggressive")) {
    return new AggressivePersonality();
  }
  else if(personalityName.equals("Passive")) {
    return new PassivePersonality();
  }
  else {
     //Maybe allow for no personality (We all know monster like that ;) )
     return null; 
  }
}

Тогда вы можете настроить моб, как так

Mob mob = new Mob();
mob.setPersonality(getPersonality(xmlValue));
mobList.add(mob);

Ключ в том, что ваш движок знает формат xml и имеет фабрику для всего, что ему нужно.

Одним из преимуществ xml является то, что вы можете определить свою собственную схему, чтобы убедиться, что формат всегда правильный, см. Здесь .

Надеюсь это поможет

AbstractChaos
источник
На самом деле мне нужно найти способ легко создать новую сущность в процессе разработки игры. Будет ли XML достаточно гибким? В любом случае мне нужно будет добавить сценарии для внутренней логики игры.
Натан
Если вы читаете класс Mob как Entity, то вы создаете новый Enitity (Mob), используя XML с различными компонентами (IPersonality, Intelligence [пример данных для этого моба)). И, к сожалению, я не могу ответить, будет ли он достаточно гибким, поскольку я не знаю, что еще вы хотите от него делать, кроме того, что вы указали. Однако XML - это формат, в котором единственными границами является то, как вы интерпретируете каждый раздел. Обновите свой Вопрос подробным примером, и я покажу xml, который справится с этим. Внутренняя логика игры звучит так, как будто она должна быть внутренней?
AbstractChaos
0

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

Вы можете использовать XML для описания поведения ваших монстров, это может включать некоторое кодирование в реальном игровом коде, потому что вы сохраните только «имя» или некоторые атрибуты в соответствии с поведением (скорость, тип оружия, которое использует монстр, и т.д.) поведения, используемого в вашем игровом коде.

Если вы используете Scriptengine (например, LUA), вы можете перенести этот код из предварительно скомпилированной программы в файлы сценариев, которые загружаются во время выполнения. Чтобы сделать это, вы должны выставить API ваших "монстров" на скрипт. Это позволяет вам вызывать методы кода игры-монстра извне.

Aron_dc
источник
API моего монстра? Я имею в виду, я должен быть в состоянии создавать новые компоненты из сценария (инстанцирование). Является ли это возможным?
Натан
Афайк, это должно быть возможно. Вы также можете использовать смешанный подход внешнего хранилища (как упомянуто abstractchaos или byte56) и языка сценариев (LUA, Python ...). Основное преимущество, например, LUA, заключается в том, что вы можете изменять свой код во время выполнения, и он мгновенно доступен в вашей запущенной игре / движке
Aron_dc
Хо серьезно? Это действительно огромное преимущество. Также у меня есть хотя LUA (или другой язык сценариев) для "игровой шкалы времени". Я имею в виду, что для создания некоторых сценарных сцен, где игрок должен быть заблокирован, этот спрайт должен перемещаться здесь, освещаться здесь и там ... Так что, возможно, я мог бы также использовать язык сценариев для загрузки сущностей? Также я собираюсь опубликовать еще один вопрос, чтобы раскрыть мой нынешний способ управления сущностью / компонентами над тем, что я называю «менеджером», чтобы увидеть, хорошо ли я себя чувствую.
Натан