Last updated: 06/10/2024, 02:17

Current Project: Rejuvenation of Hellkeeper.net

Tutorials index

An introduction to AI scripting

This tutorial will get you started with AI scripting by creating a simple .u2s script and explaining what a few of the .u2s commands do.

Basic scene

Preparation

Create the directory for your .u2s scripts (see the related tutorial if you have problems), we're calling this one "u2stutorial". Download the level used in this tutorial HERE. It's a simple room with 4 PathNodes, a PlayerStart, a Light and a light Marine. I've set the level's MapName to "u2stutorial" to correspond to the directory you've created.

Play the level. The Marine is walking around randomly (he's autonomous), because he doesn't have an AI script yet. In this condition the underlying AI code takes control of the pawn and he reacts to all surrounding stimuli (see/hear enemies etc.)

Create an empty text file and save it as "marine01.u2s" in your "../Scripts/u2stutorial" directory. This is the AI script that the marine will use. Make sure that your text editor doesn't try to append a .txt extension when you save the file!

Select the marine and open his properties. Open the AI tab and look for the "CommandFileName" slot. Enter "marine01" (no extension!) and save the map. You have now set the Marine's AI script.

A simple patrol

Add the following lines to the "marine01.u2s" file and save it:


sleep 2
gotoactor PathNode0
gotoactor PathNode1
sleep 2
gotoactor PathNode2
agentcall Event_U_Wave 1
gotoactor PathNode3
sleep

Play the level and see what happens. When you start the level the marine stands still for 2 seconds, then runs to PathNode0, PathNode1 (where he waits for another 2 seconds), then to PathNode2 (where he plays the animation "Event_U_Wave". Then he runs to PathNode3, where he waits indefinitely.

Let's take a look at the commands used in our example (parameters in () brackets are required, parameters in [] brackets are optional):
sleep [time] - tells an NPC to wait for x seconds. If you don't specify a time the NPC will wait forever, until an incoming event wakes him up.
gotoactor (actor) - makes an NPC go to the specified actor. You use the actor's object name, not its tag name (you can see the object name when you select an actor and open its properties)! gotoactor is a latent command, meaning that the script stops executing until the command has been finished (in this case the script won't continue until the specified destination has been reached).
agentcall (action name) (0/1) - plays an agent action, which you can treat as an animation for now (more on agents at the Golem University). 1 means that the agentcall is latent (meaning that the NPC won't execute the next command until he has finished his animation), 0 means that the command is not latent and the NPC immediately prcoesses the next .u2s command. You can see the difference if you update your script to "agentcall Event_U_Wave 0" and play the level again.

The marine will now start waving and continue running (the next gotoactor command following the agentcall).

Labels

You can create labels and jump to them, for example to create a looping sequence of actions.

Add two more lines to the beginning and end of your script and delete the final sleep statement, so that it looks like this:


:MarinePatrol
sleep 2
gotoactor PathNode0
gotoactor PathNode1
sleep 2
gotoactor PathNode2
agentcall Event_U_Wave 1
gotoactor PathNode3
gotolabel MarinePatrol
Play the level and see what happens. You define labels with the : character and jump to them with the "gotolabel" command.

You can also call labels, the script will jump to the specified label and then jump back to the line after the call statement when it encounters a return:


:WaitABit
sleep 5
call PatrolThisArea
sleep 3
gotolabel WaitABit

:PatrolThisArea
gotoactor PathNode0
gotoactor PathNode1
return
This makes the NPC wait 5 seconds, go to PathNode0 and PathNode1, wait 3 seconds and start all over.

Messages and debugging

To see a bit better what's going on you can print out messages. They will only appear on screen if you've enabled the debug message area, though.

Modify your script again so that it looks like this:


:MarinePatrol
message "sleeping 2 seconds"
sleep 2
message "going to pathnode 0, then PathNode1"
gotoactor PathNode0
gotoactor PathNode1
message "sleeping 2 seconds"
sleep 2
message "going to pathnode 2"
gotoactor PathNode2
message "waving!"
agentcall Event_U_Wave 1
gotoactor PathNode3
message "starting over"
gotolabel MarinePatrol
When you play the level the script will print Note that "gotoactor" and "sleep" are latent commands, you have to print the message of what the NPC is about to do before you tell him to do it.

An easier way to follow a script is using the game's debug mode. You can read more about it in the debugging tutorial. Delete all text messages from the script and add the line "debugmode 11" at the very beginning, before the :MarinePatrol label. Play the game and see what happens.

Some additional commands

Here's some additional handy (okay, random ;)) script commands (indicated by ->, do not add those to your actual script):

Modify your script again so that it looks like this:


:MarinePatrol
sleep 2
gotoactor PathNode0
-> turntoactor Light0
-> fire 2
-> firealt 2
gotoactor PathNode1
sleep 2
-> setmovespeed 0.5
gotoactor PathNode2
-> setmovespeed 1
agentcall Event_U_Wave 1
gotoactor PathNode3
gotolabel MarinePatrol
Explanation:
turntoactor (actor) - tells an NPC to turn towards a certain object.
fire (duration) - makes an NPC fire for X seconds.
firealt (duration) - makes the NPC use his alt-fire for X seconds.
setmovespeed - modifies the NPC's movement speed

Events

Events are an important tool for scripting AI behavior, here's a quick inroduction:

There's already a trigger in the level that sends the event "ChangeMarinePatrol". To be able to trigger an NPC the bTriggerNPCs flag (under "Trigger") has to be set to true. The marine won't react to the trigger yet because he hasn't been told to. We'll change that now.

I've simplified the existing script a bit for . Delete all lines and enter the following commands:


:MarinePatrol
ontrigger ChangeMarinePatrol gotolabel MarinePatrol2
gotoactor PathNode0
gotoactor PathNode1
sleep 2
gotolabel MarinePatrol

:MarinePatrol2
ontrigger ChangeMarinePatrol gotolabel MarinePatrol
gotoactor PathNode2
gotoactor PathNode3
sleep 2
gotolabel MarinePatrol2
Play the game and see what happens when you touch the trigger. The Marine loops through the MarinePatrol label until he recevies the ChangeMarinePatrol event from the level, at which point he loops the MarinePatrol2 part of the script.

Explanation:

ontrigger (event) gotolabel (label) - the script jumps to the label when the NPC receives the event. Subsequent ontrigger lines clear the old one, so you can use the same event to make the NPC do different things (this is how the above example works

Tutorial by Matthias Worch

© 2005-2024, by Hellkeeper.

Valid XHTML 1.1 & CSS 3