The Completes Idiot's Guide to the AL Engine

The place to discuss scripting and game modifications for X²: The Threat.

Moderators: Moderators for English X Forum, Scripting / Modding Moderators

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

The Completes Idiot's Guide to the AL Engine

Post by ticaki »

l3th4l wrote:i did my best to translate tic's post, feel free to correct me and/or edit for layout ;)
thx to l3th4l for translating!

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=3 
005    set global variable: name=$plugin.ID value=$plugin.data 
006    $plugin.data[1] = [TRUE] 
007    $temp =  array alloc: size=$maxships 
008    $plugin.data[2] = $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[1] = [TRUE] 
019   else if $plugin.event == 'stop' 
020    $plugin.data[1] = [FALSE] 
021   else if $plugin.event == 'isenabled' 
022    $on = $plugin.data[1] 
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[1] = [TRUE] 
019   else if $plugin.event == 'stop' 
020    $plugin.data[1] = [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[1] 
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)

Code: Select all

$plugin.enable = $plugin.data[1]
skip if $plugin.enable
  goto end // return null
7. Continue with 5.


Example

al.plugin.khaak -> init-Script
al.khaak.main -> AL-control-Script
al.khaak.event.timer -> Khaakspawn-Script

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
BalaGi, Kingdoms End, 28.03.2004
examples by ticaki and ArcaJeth[D6a]
translated by l3th4l
proofread by CBJ
Last edited by ticaki on Sun, 18. Jul 04, 22:56, edited 3 times in total.
Xenon_Slayer
EGOSOFT
EGOSOFT
Posts: 13124
Joined: Sat, 9. Nov 02, 11:45
x4

Post by Xenon_Slayer »

I am guessing you can:

Create Pirate Patroles with Pirate controled M6's. Just an Idea im thinking over. Big guide, thanks.
Come watch me on Twitch where I occasionally play several of the X games
User avatar
moggy2
Posts: 5505
Joined: Wed, 6. Nov 02, 20:31
x3ap

Post by moggy2 »

could you explain the timer a bit better? I'm not sure I followed when the script is called with <timer> event.

am I right in saying that the script is called every time the number of seconds in the timer variable has elapsed, with the event Timer=[TRUE].
l3th4l
Posts: 118
Joined: Sat, 14. Feb 04, 20:30
x4

Post by l3th4l »

as far as i understand it, the timer variable is set when the script is initialized. this variable 'n' is an integer which represents the scripts cycling time in seconds. the time event is automatically triggered every n seconds..

hope that make it clearer ;)
User avatar
giskard
Posts: 5230
Joined: Wed, 6. Nov 02, 20:31
xr

Post by giskard »

Thanks Tic :)

AL engine info is much appricated mate.
I'll link back to this thread for my own questions and add Balagis overview to the answers as well.

Giskard
This signature has been stolen by the well known Teladi Signature Thief X Siggy.
User avatar
moggy2
Posts: 5505
Joined: Wed, 6. Nov 02, 20:31
x3ap

Post by moggy2 »

l3th4l wrote:as far as i understand it, the timer variable is set when the script is initialized. this variable 'n' is an integer which represents the scripts cycling time in seconds. the time event is automatically triggered every n seconds..

hope that make it clearer ;)
That's what I thought. It may have been me, or the translation, but it didn't seem to specify exactly when the script would be called with the event <timer>. Makes a lot more sense now.
User avatar
Burianek
Posts: 2981
Joined: Mon, 29. Dec 03, 03:29
x3tc

Post by Burianek »

I've put some blank AL scripts along with some more rough instructions on the site in my signature.

right click on al-blank plugin instructions.zip and select save as....

If you're still struggling with this stuff, or even if you're an old pro and just want a preformatted template, just download them and change / fill in the blanks to get a correctly working AL script with a minimum of fuss.
Last edited by Burianek on Wed, 4. May 05, 01:11, edited 1 time in total.
"Nature's first green is gold" . . . stay golden.
strat
Posts: 103
Joined: Sat, 19. Jun 04, 13:54
x3

Post by strat »

Ticata

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

Ok, I know I'm a biginner. But the title say's Idiots guide.
Maybe I'm an Ij'jut or pished or both,

Probly both.

Strat...
Einstein rules relativity,
Well in theory at least.

Read on a public loo wall.
CBJ
EGOSOFT
EGOSOFT
Posts: 54099
Joined: Tue, 29. Apr 03, 00:56
x4

Post by CBJ »

This is a beginners guide to how to use scripts to access the AL engine, not a beginners guide to scripting in general.
strat
Posts: 103
Joined: Sat, 19. Jun 04, 13:54
x3

Post by strat »

No Probs buddy, still wishing I had more time to learn all this, Wife won't alloy me to become un-employed so I'm stuck with sixty hours plus work a week. Thanks to all

Strat...
Einstein rules relativity,
Well in theory at least.

Read on a public loo wall.
Neurosys
Posts: 12
Joined: Sat, 30. Jun 07, 12:23
x3

Post by Neurosys »

Are these four things all you can monitor? I was thinking more event based for example I am trying to trigger my script ANYTIME a noteriety change happens.. I guess I could put on a timer and just continually check it but I would prefer to be able to wait for the trigger.
Cycrow
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 22422
Joined: Sun, 14. Nov 04, 23:26
x4

Post by Cycrow »

its only those few evetns that are available

other triggers dont exist
User avatar
ninjitsumonk
Posts: 1874
Joined: Thu, 1. Mar 07, 09:21
x3

Post by ninjitsumonk »

Alternatively you could have a "backburner" that just constantly runs while the playership exists and gets all the notorieties then if there are any discrepencies with the original it does whatever and then returns to the loop, using the gosub command.
Archeo Avis wrote:
if you take out phrasing and root notes and just look at the notes, they are the same
So what you're saying is, if you ignore everything that's different and focus only on the one thing that's the same, they're same.

Good God.
Jonson27
Posts: 170
Joined: Thu, 3. Jun 04, 14:08
x2

Post by Jonson27 »

What if you wanted to have a kill signal for a pirate ship that is handled by an al plugin? I can see how the timer event can handle most other things, like decision making, but ... i'm not sure how a plugin would handle the kill event or other signals builtin to the scripting engine. Would the plugin for the ship just use the normal kill signal or it would check to see if the ship still exists (in the plugin) instead?

I'm talking about this if you're not sure what i mean:

Code: Select all

global script map: set: key=SIGNAL_KILLED, class=Ship, race=Pirate, script='al.ship.signal.killed.pirate', prio=100
Where would that instruction go? In the init event of the plugin?
Hello there!! (Jumping up and down)
User avatar
Chris Gi
Posts: 960
Joined: Wed, 20. Sep 06, 09:57
x3tc

Post by Chris Gi »

The 'global script map' is not suitable for something like this. And your AL plugin should test if a ship still exists anyway.

But if you want a special script bound to the kill signal of all ships handled by your AL plugin, you can always override the globally assigned script by means of the 'connect signal/command' instruction.
--------------------------------

[ external image ]

Return to “X²: The Threat - Scripts and Modding”