Оглавление Сообщение об ошибках Ваше мнение о проекте E-Mail автору

v    Организация AL Engine (Искусственная жизнь)

AL Engine разрабатывалась для управления скриптами создающими игровой антураж в Х2-Вселенной, такими как корабли патрулирующие родные сектора, лайнеры везущие пассажиров, ударные группы ведущие мониторинг Президентского Рубежа и т.д.  Использование AL Engine значительно облегчает организацию работы AL скриптов управляющих этими процессами, и позволяет в фоновом режиме производить их запуск, остановку, инициализацию и прочие действия. А сам движок Х2 позволяет оперативно отказаться или наоборот подключить нужный AL plugin используя меню настройки искусственной жизни.

Все AL скрипты находящиеся под управлением AL Engine должны быть устроены по определенной схеме. Строится она из последовательности состоящей из трех основных скриптов каждый из которых выполняет определенную задачу.

 

1.      Регистрационный скрипт – этот скрипт производит необходимую регистрацию AL Plugina в системе. Сообщая ей какой скрипт необходимо взять под управление AL Engine. Запускается автоматически.

2.      Контроллер событий – этот скрипт обеспечивает соответствующую реакцию на переданные от AL Engine флаги событий и указывает какие действия необходимо произвести в ответ на них.

3.      Скрипт таймер – это основной скрипт осуществляющий всю работу с AL объектом. Этот скрипт вызывается системой периодически, в зависимости от действий игрока и предварительной настройки AL Engine сделанной в «Контролере событий».

Обратите внимание на то, что любой скрипт из этой группы работает в системе как глобальный, так что в них не допустимо использовать константы [THIS], [OWNER], [SECTOR] и подобные, т.к. они привязаны к объекту на котором выполняется скрипт. А глобальный как вам известно, не имеет привязки к объектам.

 

Регистрационный скрипт

            Это самый простой скрипт из группы AL Engine скриптов. Его задача зарегистрировать plugin в движке AL Engine. Обязательным условием является определенный формат имени. Имя должно начинаться с al.plugin…, далее идет имя самого plugina. Это имя сообщает ScE что данный файл следует загрузить автоматически. Учтите что AL plugin загружаются самыми последними, даже не после загрузки всех init и setup скриптов, а спустя некоторое время. Для удобства, имена  для всех остальных скриптов относящихся к вашему AL plugins, именуйте например вот так al.<ваш ник>.mainPlug, а регистрационные скрипты, например:

!al.plugin.tpliners или al.plugin.racepatrol . 

Дальнейшее рассмотрение принципов организации AL plugin на  встроенном в игру AL Plugin «TP Лайнеров» Вот регистрационный файл из этого пакета:

Script !al.plugin.tpliners

Version: 1
for Script Engine Version: 25

Description

AL plugin TP Liners

Arguments

Source Text


001   
002   al engine: register script='!al.tpliners.main'
003   
004   return null


signed

 

Здесь наглядно видна простота его устройства, всего одна строка регистрирующая !al.tpliners.main как AL Plugin. Получив эту команду AL Engine зарегистрирует данный AL plugin и запустит соответствующий скрипт с флагом ‘init’ или ‘reinit’ (от чего зависит флаг см. далее), а после инициализации сразу с флагом ‘timer’.

 

Контроллер событий. (Event Handler)

В скрипте контроллера событий должно быть предусмотрено два строковых аргумента значения которым будут переданы самой AL Engine. Первый аргумент это уникальный идентификатор plugina по которому AL Engine будет обращаться к нему (как идентификатор AL Engine использует имя скрипта «контроллера событий»). Второй аргумент это флаг типа событий. Возможные варианты флагов событий прописаны в самой  AL Engine. Все возможные варианты приведены в таблице ниже:

Событие

Описание

‘init’

Происходит при старте новой игры или если AL Engine зарегистрировала первый запуск данного pluginaa.

'reinit'

Происходит при загрузке сохраненной игры.

'start'

Происходит если игрок выбрал опцию «Вкл.» в меню настройки искусственной  жизни.

'stop'

Происходит если игрок выбрал опцию «Выкл.» в меню настройки искусственной  жизни.

'isenabled'

Происходит когда формируется меню настройки искусственной жизни. Для чего нужен этот описатель см. далее.

‘timer’

Происходим каждый раз по истечении временного интервала установленного инструкцией set plugin timer interval. Служит для определения частоты запуска данного AL plugin.

 

 

Прежде всего о том как работает AL Engine в общих чертах. Все элементарно просто, вся ее функция заключается в периодическом вызове скриптов зарегистрированных как AL plugin и формировании соответствующих флагов-событий. И обязательно запомните следующее, сама по себе AL Engine понятия не имеет выполняется в данный момент какой либо plugin или нет. Это очень важный факт, т.к. обеспечивать правильные реакции вашего plugin’на флаги-событий придется вам самим, используя разные вариации разного рода флагов и переменных.

Так как AL Engine не ведет контроля за тем активен в данный момент plugin или нет, рассмотрим почему необходим и как мы можем использовать флаг-события “isenabled”. Этот флаг AL Engine выставляет для всех зарегистрированных plugin (для зарегистрированных, а не для активных), в момент когда игрок открывает меню настройки искусственной жизни. Так же в этот момент стартуют контроллеры событий всех зарегистрированных plugin. Задача контроллера событий, при обработке флага-события «isenabled» вернуть системе флаг текущего состояния plugin, т.е. активен он в данный момент или нет. И в зависимости от того, что вернул контроллер система сформирует соответствующее состояние выключателя для данного plugin в меню. Система воспринимает значения как [TRUE] – plugin активен и выполняется, [FALSE] – plugin отключен, но учтите что несмотря на это  AL Engine  продолжит производить его запуск с флагом «timer» по истечении каждого временного отрезка установленного командой al engine: set plugin <Var/String> timer interval to <Var/Number> s. Заметьте что интервал выставляется не в привычных уже миллисекундах, а в секундах.

Условия формирование флага-события «timer» очевидна. После инициализации plugin, а именно  тогда происходит назначение временного интервала для данного plugin, будет происходить вызов контроллера событий с установленным флагом «timer» по истечении назначенного временного отрезка. Вызов будет происходить и в случае если plugin находится в состоянии остановки, и здесь вы сами должны обеспечить правильное поведение вашего скрипта-plugin.

Флаги событий “stop”, “start” формируются когда игрок устанавливает выключатель AL plugin в соответствующее положение. Установив выключатель, и нажав <Enter> игрок дает указание AL Engine произвести запуск скрипта контроллера событий с выставлением ему соответствующего флага.

Значение флагов “init” и “reinit” понятно из описания в таблице, первый выставляется при старте новой игры или при первом запуске AL plugin, а второй при загрузке сохраненной игры.

Теперь, когда мы рассмотрели сам принцип работы AL Engine и флагов-событий, приступим к рассмотрению того как это организовать в вашем скрипте. Самый удобный способ добиться четкого взаимодействия частей нашего plugin это обеспечить между ними обмен необходимыми данными. Сделать это можно по средствам использования глобальных переменных. Может оказаться так, что объем передаваемых данных может быть очень большим и создавать такое количество глобальных переменных крайне не удобно. Решением этого является использование массива, записанного в глобальную переменную.  На самом деле ScE не хранит в переменной сам массив, а только указатель (pointer) на область памяти где размещаются эти данные, что в нашей ситуации более удобно, так как не придется перекидывать массив данных от одного скрипта к другому, достаточно передать этот пойнтер. Еще, есть некоторая договоренность о формате этого массива, которая облегчит работу с вашим plugin другим скриптописателям, но она не обязательна, и заключается в следующем:

1.      Первым значением в массиве, индекс [0], стоит версия вашего AL plugin, если вы делаете универсальный и самообновляющийся скрипт (желательно чтобы таким был любой скрипт), то наличие в переменной версии будет очень полезно.

2.      Второе значение это флаг состояния AL plugin, [TRUE/FALSE] индекс [1]

Остальные значения используются на ваше усмотрение.  Вы не обязаны следовать этому правилу, но это определенный шаг к стандартизации дополнительных AL plugin, и значительное облегчение для тех кто будет разбираться с работой  вашего скрипта.

И так, мы рассмотрели основные теоретические аспекты, и можем перейти к практическому разбору AL plugin. Для примера я выбрал встроенный в игру AL plugin Межгалактических лайнеров, и так рассмотрим его:

Script !al.tpliners.main

Version: 1
for Script Engine Version: 25

Description

AL plugin main tp liners

Arguments

  • 1: plugin.ID , Var/String , 'plugin ID'
  • 2: plugin.Event , Var/String , 'plugin event'

 

 

Этот скрипт был за зарегистрирован в AL Engine при помощи регистрационного файла !al.plugin.tpliners в момент старта новой игры или загрузки сохраненной. После регистрации движок AL Engine запустил скрипт контроллер событий !al.tpliners.main с флагом “init”,reinit” соответственно, поместив их во второй аргумент  plugin.Event. В первый аргумент было помещено имя нашего plugin. Далее за обработку полученных данных берется сам контроллер событий.

 

Source Text


001   
002   * global variable stores plugin state und data
003   $plugin.Vars = get global variable: name=$plugin.ID
004   if not $plugin.Vars
005   * setup new data structure and init it
006    $plugin.Vars =  array alloc: size=32
007    set global variable: name=$plugin.ID value=$plugin.Vars
008   * data structure version
009    $plugin.Vars[0] = 0
010   * plugin enabled
011    $plugin.Vars[1] = [TRUE]
012   * other elements store ships, created via timer event
013   end

 

 001-003 Получаем значение глобальной переменной, одноименной нашему plugin, название было передано в переменную-аргумент $plugin.ID самой AL Engine.

004-006 Если такой переменной не существует (возвращенное значение null), то заготавливаем нужную нам матрицу, то есть массив содержащий необходимое нам количество элементов.

007 Создаем соответствующую глобальную переменную и помещаем в нее указатель (пойнтер) на пока еще пустой массив. Теперь передавая пойнтер другим скриптам, мы сможем использовать и изменять данные в этом массиве.

008-013 В согласии с негласными правилами помещаем в соответствующие ячейки версию скрипта (в данном примере автор не использовал команду <RetVar>=get script version, вероятно для обеспечения совместимости скрипта с предыдущими версиями ScE, до 1.4, где эта команда отсутствовала и прибегнул к собственной нумерации. Но вам настоятельно рекомендую пользоваться этой командой.). Итак, в ячейку [0] помещается версия AL plugin, а в [1]  флаг текущего состояния выставленный [TRUE].

Далее начинаем анализ выставленных флагов событий $plugin.Event.

014   
015   * handle plugin events
016   
017   if $plugin.Event == 'init' OR $plugin.Event == 'reinit'
018    $desc = sprintf: pageid=2023 textid=200nullnullnullnullnull
019    al engine: set plugin $plugin.ID description to $desc
020    $interval = random value from 50 to 70 - 1
021    al engine: set plugin $plugin.ID timer interval to $interval s

В этих строках производится обработка, в случае выставления системой любого из флагов инициализации. То есть сюда мы попадаем если AL Engine выставила один из флагов “init” или “reinit” а это возможно только в том случае, если была начата новая игра или загружена сохраненная.

017 Проверяем соответствие флагов. Тип данных у флагов <string> и вводятся они как текст.

018-019 Получаем из языкового файла текст, и устанавливаем его  как дескриптор данного AL plugin. Дескриптор будет отражаться в меню настройки AL в соответствующей данному plugin строке. В нашем случае это текст «Движение лайнеров по вселенной Х» (перевод ЕГ).

020-021 Получаем случайный интервал в пределах 50 – 70 секунд, и указываем его AL Engine как интервал вызова нашего AL plugin.

022    
023   else if $plugin.Event == 'isenabled'
024    $enabled = $plugin.Vars[1]
025    return $enabled

 Если при старте plugina был выставлен флаг “isenabled”, то это означает, что в  данный момент формируется меню настройки AL и система запрашивает у скрипта текущее состояние AL plugin, так как сама система не осуществляет за ним постоянного контроля.

023 проверка на соответствие флага.

024 Возвращаем нужное нам значение в переменную $enabled из массива $plugin.Vars.

025 Возвращаем это значение движку, который в свою очередь при формировании меню выставит выключатель в положение соответствующее этому значению.

026    
027   else if $plugin.Event == 'start'
028    $plugin.Vars[1] = [TRUE]
029    
030   else if $plugin.Event == 'stop'
031    $plugin.Vars[1] = [FALSE]

026 -031 Если игрок изменил значение выключателя в меню настройки AL, то после нажатия “EnterAL Engine запускает наш контроллер установив соответствующий флаг, а скрипт в свою очередь производит соответствующие изменения в [1] ячейке массива.

032    
033   else if $plugin.Event == 'timer'
034 @  = [THIS] ->call script '!al.tpliners.event.timer' :plugin  ID=$plugin.ID plugin data=$plugin.Vars
035   end
036   
037   return null

И обработка последнего из возможных флагов-событий, флаг ‘timer’. Получив этот флаг, контроллер нашего AL plugin безоговорочно стартует основной скрипт управления AL объектами !al.tpliners.event.timer передав ему в виде аргументов имя нашего AL plugin, оно также соответствует имени глобальной переменной содержащей пойнтер на рабочий массив данных, и сам пойнтер.

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

 

Скрипт таймер

Назначение этого скрипта, это непосредственно реализация самой идеи вашего AL plugin, создание и управление AL объектами. Именно этот скрипт создаст задуманные вами объекты, назначит им соответствующие команды, проверит живы ли они, и произведет воссоздание уничтоженных. Мы продолжим рассмотрение на основе того же AL plugin управляющего летающими по галактике лайнерами.

Основные задачи на нашего скрипта  !al.tpliners.event.timer, это не допустить своего собственного запуска этого если игрок отключил это AL plugin в меню настройки AL, не забывайте что AL Engine независимо от этого будет производить запуск этого скрипта с флагом ‘timer’. А если скрипт находиться в активном состоянии, то произвести проверку уже созданных лайнеров, отдать новые команды живым и воссоздать и отправить новые вместо убитых. Подробно рассматривать процесс воссоздания  и контроля мы не будем. Рассмотрим только принцип блокировки запуска в случае отключения этого AL plugin.

Script !al.tpliners.event.timer

Version: 1
for Script Engine Version: 25

Description

AL plugin tp liners timer event

Arguments

  • 1: plugin.ID , Var/String , 'plugin ID'
  • 2: plugin.Vars , Value , 'plugin data'

Source Text


001   
002   * read state data
003   $plugin.Enabled = $plugin.Vars[1]
004   
005   skip if $plugin.Enabled
006    goto label exit
007   
008   * check ships

...

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

...  
062   exit:
063   * store state data
064   
065   return null

 

Из предыдущего скрипта видно какие аргументы мы передаем текущему. Это строка с именем скрипта и пойнтер массива с флагами. Вся интересующая нас проверка осуществляется в первых шести строчках далее идет код процедур проверок и респауна лайнеров, его рассматривать мы не будем. А сома блокировка запуска очень проста:

003 Получаем значение флага состояния из массива.

005-006 Проверка состояния переменной и если флаг [TRUE] продолжаем выполнять скрипт, в противном случае переход на строку 062 и выход, до следующего запуска по ‘timer’ или изменения флага через меню AL.

            Теперь вы знаете как создать и правильно организовать работу AL Engine, для того чтобы узнать больше рассмотрите работу других AL  плагинов идущих с игрой. Мое мнение, что чем более насыщена жизнь в Х2-Вселенной разного рода интересными вещами тем интереснее играть.

 


Оглавление Сообщение об ошибках Ваше мнение о проекте E-Mail автору
Сайт создан в системе uCoz