[DE]The Completes Idiot's Guide to the AL Engine/plz transl.

Hier ist der ideale Ort um über Scripts und Mods für X²: Die Bedrohung zu diskutieren.

Moderators: Scripting / Modding Moderators, Moderatoren für Deutsches X-Forum

ticaki
Posts: 4861
Joined: Wed, 6. Nov 02, 20:31
x3

[DE]The Completes Idiot's Guide to the AL Engine/plz transl.

Post by ticaki »

The Completes Idiot's Guide to the AL Engine
---------------------------------------------

Hier mal ne kurze und grobe Beschreibung:

- AL Plugins werden über "init" Skripte mit Namen "!al.plugin.*" oder
"al.plugin.*" ins Spiel eingebunden (Theoretisch liese sich das aber
auch über andere beliebige Skripte erledigen). Diese Skripte werden bei
einem neuen Spiel oder beim Laden eines Savegames ausgeführt.

- Ein AL Plugin wird durch das Command "al plugin: register script"
registriert. Das Plugin wird dabei durch einen Skriptnamen
identifiziert, der Skriptname ist hier also die ID des Plugins.

Code: Select all

001   al engine: register script='al.control.pirat.tl.fill.ph'
002   al engine: register script='al.control.pirat.all.race.m'
003   al engine: register script='al.control.pirat.xenons'
004   al engine: register script='al.control.pirat.all.race.ts'
005   al engine: register script='al.control.pirat.sector.ap'
006   return null
Erstmal das komplette AL-Controlscript

Code: Select all

Script al.control.pirat.sector.ap
Version: 0
for Script Engine Version: 25

Arguments
1: plugin.ID , Var/String , 'plugin ID' 
2: plugin.event , Var/String , 'plugin mode' 

Source Text

001   $plugin.data = get global variable: name=$plugin.ID
002   $maxships = 2
003   if not $plugin.data
004    $plugin.data =  array alloc: size=2
005    set global variable: name=$plugin.ID value=$plugin.data
006    $plugin.data[0] = 0
007    $temp =  array alloc: size=$maxships
008    $plugin.data[1] = $temp
009   end
010   
011   if $plugin.event == 'init' OR $plugin.event == 'reinit'
012   *$decr = sprintf: pageid=943 textid=1005, null, null, null, null, null
013    al engine: set plugin $plugin.ID description to 'my pirat script'
014    $interval = random value from 100 to 200 - 1
015    al engine: set plugin $plugin.ID timer interval to $interval s
016    return null
017   else if $plugin.event == 'start'
018    $plugin.data[0] = [TRUE]
019   else if $plugin.event == 'stop'
020    $plugin.data[0] = [FALSE]
021   else if $plugin.event == 'isenabled'
022    $on = $plugin.data[0]
023    return $on
024   else if $plugin.event == 'timer'
025 @  = [THIS] -> call script 'al.pirat.sector.ap' :  plugin.data=$plugin.data  maxships=$maxships  Target Sector=LooManckStrats Vermächtnis
026   end
027   return null
- Die AL Engine benutzt Events um mit den Plugins zu kommunizieren: <init> <reinit> <timer> <start> <stop> <isenabled>

Dafür wird einfach das registrierte Plugin-Skript mit Parametern aufgerufen:

<PluginID=PluginScriptName> <event>

Code: Select all

Script al.control.pirat.sector.ap
Version: 0
for Script Engine Version: 25

Arguments
1: plugin.ID , Var/String , 'plugin ID' 
2: plugin.event , Var/String , 'plugin mode' 

- Nach dem Ausführen der al.plugin.* werden die registrierten Plugins
einmal mit folgenden String-Parametern aufgerufen:

<PluginID=PluginScriptName> <init> bei neuem Spiel
<PluginID=PluginScriptName> <reinit> nach Save laden

Code: Select all

011   if $plugin.event == 'init' OR $plugin.event == 'reinit'

- Die AL Engine hält intern nur einen einzigen Statuswert pro Plugin.
Und das ist ein Timerinterval. Falls dieses Interval > 0 ist, wird nach
jedem Ablauf des Intervals das Plugin-Skript mit String-Parametern:

<PluginID=PluginScriptName> <timer>

aufgerufen. Das Timer-Interval kann durch das Command "al plugin: set
timer interval" gesetzt werden.

Code: Select all

014    $interval = random value from 100 to 200 - 1
015    al engine: set plugin $plugin.ID timer interval to $interval s
- Eine Beschreibung des Plugins kann durch "al plugin: set description"
angegeben werden. Erscheint dann im Manage AL Plugin Menü.

Code: Select all

012   *$decr = sprintf: pageid=943 textid=1005, null, null, null, null, null
013    al engine: set plugin $plugin.ID description to 'my pirat script'
- Beschreibung und Timerinterval wird i.d.R im <init> bzw. <reinit>
Event gesetzt.

- Die Events <start> und <stop> werden über das AL Menü ausgelöst.

Code: Select all

017   else if $plugin.event == 'start'
018    $plugin.data[0] = [TRUE]
019   else if $plugin.event == 'stop'
020    $plugin.data[0] = [FALSE]
Dort wird auch der <isenabled> Event benutzt, um festzustellen, ob das Plugin
gestoppt oder gestartet ist. Der <isenabled> Event muß TRUE (gestartet)
oder FALSE zurückgeben.

Code: Select all

021   else if $plugin.event == 'isenabled'
022    $on = $plugin.data[0]
023    return $on
- Der Rest ist durch das Plugin selbst zu erledigen. I.d.R. wird es so
sein, das pro Plugin eine globale Variable existiert, in der die
Statusinfos über ein Array gespeichert sind. Dieses Array kann z.b. so
aufgebaut sein:

0: Datenstruktur-Versionsinformation
1: Plugin State (enabled/disabled)
2: zusätzliche State Daten....
3: ...

Genaueres könnt ihr euch mal in den beigefügten AL Scripts ankucken.

Dadurch das die AL Engine nun das looping fürs Plugin übernimmt, kann
fast problemlos das Plugin "gepatcht" werden. Denn bei jedem neuen
TimerEvent wird die aktuellste Scriptversion verwendet. Das Plugin muß
dann natürlich sicherstellen, das es mit noch alten State-Daten umgehen
kann bzw. muß diese Updaten. Dafür kann man z.b. so eine
Datenstruktur-Versionsinformation im State-Array verwenden.



Ein normaler AL Plugin Arbeitsablauf sieht dann so aus:

1. AL Engine: al.plugin.test

2. al.plugin.test: register script=al.test

3. AL Engine: sende Event <init> (also rufe Skript al.test auf mit
Parametern: "al.test" "init"

4. al.test: Reaktion auf "init": setze Timerinterval und Beschreibung,
initialisiere State-Array und in globaler Variable (Name = PluginID =
PluginScriptName) festhalten.

5. AL Engine: wartet bis gesetztes Timerinterval abgelaufen ist und
sendet dann den Event <timer>.

6. al.test: erkennt <timer> Event und tut irgendwas

7. al erkennt nicht ob das script ausgeführt werden darf ;)

8. weiter mit 5)


BalaGi, Kingdoms End, 28.03.2004
Last edited by ticaki on Wed, 7. Jul 04, 12:56, edited 7 times in total.
Zur Zeit nicht aktiv
User avatar
giskard
Posts: 5230
Joined: Wed, 6. Nov 02, 20:31
xr

Post by giskard »

[EN reply]

This basically describes features similar to Global Variables only these variables are used by the AL engine and shared amongst all scripts.

The timer interval seems to be an important control for running AL scripts.
My translation may be off a bit though as i dont speak german.

The post seems to say the plugin scripts are executed in sequence and can be loaded at the start of the new game or when loading a saved game.

Remember my translation may be off :)
Tic said he plans to expand on this post so best wait for the that.

Giskard
This signature has been stolen by the well known Teladi Signature Thief X Siggy.
ticaki
Posts: 4861
Joined: Wed, 6. Nov 02, 20:31
x3

Post by ticaki »

[EN]
example code insert ;)
There are any questions? Is the Guide really wrote for noobs?

[DE]
Beispielcode eingefügt ;)
Irgend welche Fragen dazu? Ist die Anleitung Noob sicher?

Greets ticaki
Zur Zeit nicht aktiv
User avatar
lenny5000
Posts: 892
Joined: Mon, 29. Sep 03, 19:06
x3

Post by lenny5000 »

Ist die Anleitung Noob sicher?
Nein :)
Ich persönlich habe Probleme das ganze zu verstehen, weil du nicht sagst, was dein al-script eigentlich machen soll.
Das solltest du noch hinzufügen was das Teil machen soll :)
Greets
lenny5000
ArcaJeth
Posts: 2245
Joined: Mon, 10. Nov 03, 18:22
x3tc

Post by ArcaJeth »

[DE reply]

Also ich habs mit Hilfe des Threads hier und dem Liner-Script was bei RC1 dabei ist verstanden (glaube ich ;-) ). Es wäre vielleicht noch ganz nützlich kurz zu erklären wofür man AL-Plugins nutzen kann/sollte und was AL-Plugins von den normalen Scripts unterscheidet.

@lenny5000 die Codeschnipsel die Ticaki oben eingefügt hat tun ansich noch nichts, sie bewirken nur, dass das Script welches in Zeile 25 steht ('al.pirat.sector.ap') als AL-Plugin läuft.

Ich werde mich heute Abend mal an einem AL-Plugin versuchen um 1. zu sehen ob ichs wirklich verstanden habe und um 2. das Ergebnis hier zu Posten, evtl. hilft ein Beispiel mehr ja ;-)
User avatar
giskard
Posts: 5230
Joined: Wed, 6. Nov 02, 20:31
xr

Post by giskard »

ticaki wrote:[EN]
example code insert ;)
There are any questions? Is the Guide really wrote for noobs?

[DE]
Beispielcode eingefügt ;)
Irgend welche Fragen dazu? Ist die Anleitung Noob sicher?

Greets ticaki
Its a little above Noob level due to the language being used. However for those with a little scripting experience its not bad.

Bala thinks like a programmer and you can tell that from the text. However Noobs think like Noobs and Noob text needs to read like English/German for them. Introduce them to the programer speak in Engish/German (eg ordinary every day language).

Giskard
This signature has been stolen by the well known Teladi Signature Thief X Siggy.
ArcaJeth
Posts: 2245
Joined: Mon, 10. Nov 03, 18:22
x3tc

Post by ArcaJeth »

Also hier nun mein AL-Plugin :) ... es sorgt einfach nur dafür, dass alle 30-45min (Zeile 17 & 18 vom Mainscript) ein Khaak-Schiff im Sektor des Spielers erscheint. Es ist extra einfach gehalten da es hier nur als Beispiel dienen soll.

al.plugin.khaak -> init-Script
al.khaak.main -> AL-Controll-Script
al.khaak.event.timer -> Khaakspawn-Script (das Script welches bei jedem durchlauf gestartet wird)

Script "al.plugin.khaak"

Code: Select all

001   * Register the Script as AL-Plugin
002   al engine: register script='al.khaak.main'
003   return null
Script "al.khaak.main"

Code: Select all

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

001   $plugin.Vars = get global variable: name=$plugin.ID
002   
003   if not $plugin.Vars
004   * Define the Data-Array
005    $plugin.Vars =  array alloc: size=2
006    set global variable: name=$plugin.ID value=$plugin.Vars
007   *  Plugin Version
008    $plugin.Vars[0] = 0
009   *  Plugin Status
010    $plugin.Vars[1] = [TRUE]
011   end
012   
013   if $plugin.Event == 'init' OR $plugin.Event == 'reinit'
014   * If game is started or loaded
015    $description = 'Extra Khaakspawn'
016    al engine: set plugin $plugin.ID description to $description
017    $interval = random value from 1800 to 2700 - 1
018    al engine: set plugin $plugin.ID timer interval to $interval s
019    
020   else if $plugin.Event == 'isenabled'
021   * Return Pluginstatus
022    $enabled = $plugin.Vars[1]
023    return $enabled
024    
025   else if $plugin.Event == 'start'
026   * Set Status to TRUE (enabled)
027    $plugin.Vars[1] = [TRUE]
028    
029   else if $plugin.Event == 'stop'
030   * Set Status to FALSE (disabled)
031    $plugin.Vars[1] = [FALSE]
032    
033   else if $plugin.Event == 'timer'
034   * Start the Script every time the timer is released
035 @  = [THIS] -> call script 'al.khaak.event.timer' :  plugin ID=$plugin.ID  plugin data=$plugin.Vars
036   end
037   
038   return null
Script "al.khaak.event.timer"

Code: Select all

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

001   $plugin.enabled = $plugin.Vars[1]
002   
003   * If plugin is disabled goto label Exit
004   skip if $plugin.enabled
005    goto label Exit
006   
007   $sector = [PLAYERSHIP] -> get sector
008   $Ship.ObjClass = [PLAYERSHIP] -> get object class
009   
010   if $Ship.ObjClass == Heavy Fighter M3
011   * Khaak M4
012    $khaak.type = Unbekanntes Feindschiff
013    
014   else if $Ship.ObjClass == Cruiser M6
015   * Small KhaakCluster
016    $khaak.type = Unbekanntes Feindschiff
017    
018   else if $Ship.ObjClass == Destroyer M2 OR $Ship.ObjClass == Battle Ship M1
019   * Big KhaakCluster
020    $khaak.type = Unbekanntes Feindschiff
021   end
022   
023   $pos.x = random value from -30000 to 30001 - 1
024   $pos.y = random value from -30000 to 30001 - 1
025   $pos.z = random value from -30000 to 30001 - 1
026   
027   $khaak =  create ship: type=$khaak.type owner=Khaak addto=$sector x=$pos.x y=$pos.y z=$pos.z
028   $khaak -> add default items to ship
029   
030   Exit:
031   return null
l3th4l
Posts: 118
Joined: Sat, 14. Feb 04, 20:30
x4

Post by l3th4l »

i did my best to translate tic's post, feel free to correct me and/or edit for layout ;)


This guide is not meant for 'noobs' or beginners in scripting ;)


- AL plugins are integrated into the game by 'init' scripts which are
named '!al.plugin.*' or 'al.plugin.*'. they are executed every time
you start a new game or load a savegame.

- AL plugins are registered with the command 'al plugin: register
script'. the plugin is identified by a scriptname which also serves as
the ID of the plugin.

Code: Select all

001   al engine: register script='al.control.pirat.tl.fill.ph' 
002   al engine: register script='al.control.pirat.all.race.m' 
003   al engine: register script='al.control.pirat.xenons' 
004   al engine: register script='al.control.pirat.all.race.ts' 
005   al engine: register script='al.control.pirat.sector.ap' 
006   return null
First of all, this is the complete AL-controlscript:

Code: Select all

Script al.control.pirat.sector.ap 
Version: 0 
for Script Engine Version: 25 

Arguments 
1: plugin.ID , Var/String , 'plugin ID' 
2: plugin.event , Var/String , 'plugin mode' 

Source Text 

001   $plugin.data = get global variable: name=$plugin.ID 
002   $maxships = 2 
003   if not $plugin.data 
004    $plugin.data =  array alloc: size=2 
005    set global variable: name=$plugin.ID value=$plugin.data 
006    $plugin.data[0] = 0 
007    $temp =  array alloc: size=$maxships 
008    $plugin.data[1] = $temp 
009   end 
010    
011   if $plugin.event == 'init' OR $plugin.event == 'reinit' 
012   *$decr = sprintf: pageid=943 textid=1005, null, null, null, null, null 
013    al engine: set plugin $plugin.ID description to 'my pirat script' 
014    $interval = random value from 100 to 200 - 1 
015    al engine: set plugin $plugin.ID timer interval to $interval s 
016    return null 
017   else if $plugin.event == 'start' 
018    $plugin.data[0] = [TRUE] 
019   else if $plugin.event == 'stop' 
020    $plugin.data[0] = [FALSE] 
021   else if $plugin.event == 'isenabled' 
022    $on = $plugin.data[0] 
023    return $on 
024   else if $plugin.event == 'timer' 
025 @  = [THIS] -> call script 'al.pirat.sector.ap' :  plugin.data=$plugin.data  maxships=$maxships  Target Sector=LooManckStrats Vermächtnis 
026   end 
027   return null
- The AL engine uses events to communicate with the AL plugins:
<init> <reinit> <timer> <start> <stop> <isenabled>

This happens by calling the registered plugin-script with two
parameters: <PluginID=PluginScriptName> <event>

Code: Select all

Script al.control.pirat.sector.ap 
Version: 0 
for Script Engine Version: 25 

Arguments 
1: plugin.ID , Var/String , 'plugin ID' 
2: plugin.event , Var/String , 'plugin mode'
- After execution of the 'al.plugin.*' script, the registered plugins
are called once with the following string parameters:

<PluginID=PluginScriptName> <init> whenever you start a new game
<PluginID=PluginScriptName> <reinit> after loading a savegame

Code: Select all

011   if $plugin.event == 'init' OR $plugin.event == 'reinit'
- Internally the AL engine only has one state variable for each plugin
which is the timer interval. if this interval is > 0 the plugin-script
is called with the string parameters

<PluginID=PluginScriptName> <timer>

every time the interval expires. The timer interval can be set with
the command 'al plugin: set timer interval'

Code: Select all

014    $interval = random value from 100 to 200 - 1 
015    al engine: set plugin $plugin.ID timer interval to $interval s
- A description of the plugin can be set by the command 'al plugin:
set description'. It appears in the Manage AL Plugin menu.

Code: Select all

012   *$decr = sprintf: pageid=943 textid=1005, null, null, null, null, null 
013    al engine: set plugin $plugin.ID description to 'my pirat script'
- Usually the description and timerinterval is set during the <init>
or <reinit> event

- The events <start> and <stop> are triggered by the AL menu

Code: Select all

017   else if $plugin.event == 'start' 
018    $plugin.data[0] = [TRUE] 
019   else if $plugin.event == 'stop' 
020    $plugin.data[0] = [FALSE]
This is also where the <isenabled> event is used to determine whether
the plugin is running or not. The <isenabled> event must return TRUE
or FALSE.

Code: Select all

021   else if $plugin.event == 'isenabled' 
022    $on = $plugin.data[0] 
023    return $on
- The rest has to be done by the plugin. Usually there will be one
global variable in which the status information of the plugin is saved
in an array. Such an array could look like this:

0: datastructure-versioninformation
1: plugin state (enabled/disabled)
2: additional state data
3: ...

For an example you can look at the AL scipts that came with 1.4.

Because the AL engine now does the 'looping', the plugin can be
'patched' very easily. This is because after each TimerEvent the most
recent scriptversion will be used. Of course the plugin has to make
sure, it can still handle the old state-data and must update it, if
this is not the case. this is what the datastructure-versioninformation part of the state-array is used for.

A typical AL Plugin execution will look like this:

1. AL Engine: el.plugin.test
2. al.plugin.test: register script=al.test
3. AL Engine: trigger event <init> (calls script al.test with parameters: 'al.test' 'init'
4. al.test: reaction on 'init': set timerinterval and description; initialize state-array and save it in global variable (name=PluginID=PluginScriptName)
5. AL Engine: wait until timerinterval expires and then trigger event <timer>
6. al.test: executes code based on event <timer> (note: the AL engine
does not know, if a script is allowed to be executed. the scripter has
to check that for him/herself)
7. Continue with 5.

Return to “X²: Die Bedrohung - Scripts und Modding”