Artemis Tutorials

Characters - Artemis Mission Scripting 101 - Part One

This is a three part tutorial written for Artemis 1.702

The Artemis Spaceship Bridge Simulator provides a fun challenge to the creative writing community. Most people are familiar with fan stories for science fiction series like Star Trek or Battlestar Galactica. Fan fiction enthusiasts of TV, movie and books "borrow" characters and settings to tell their own stories, some arguably better than the inspirations. The simulator opens a different chance for story telling. When you write a prose story you guide the reader through fixed events and character interactions that always read the same and have the same outcome. When you script an Artemis mission you write characters and events, but have no control over how the player will be introduced to them or in what order. You might have a story that makes sense when run from A to B to C, but your player crew might decide to fly around and run into C first and then A, and never get to B. While you're certainly welcome to write whatever story your imagination can conjure, the best adventures are the ones that let the player feel they are in charge, and not just following along.
Whether you want to write your own space saga or just a combat mission to test your crew's mettle, the mission is a blank page that always begins the same.

Artemis missions are written in XML, eXtensible Markup Language, the big brother of HTML, HyperText Markup Language, the basic building blocks of web pages and the interwebs.
While HTML is used to layout webpages for web browsers, XML is used to structure and store data in reliable and predictable ways.
Artemis has its own Markup Language, which we will refer to in good humor as AML, Artemis Markup Language. AML has gone through several revisions, along with significant updates to the game itself. Each update tends to break missions written for the previous version. This can be a little annoying, especially if you spent months writing epic multi chapter stories. This tutorial is written for Artemis 1.702.

For this tutorial we're going to create three mission scripts, each a simple example of an important building block that can be strung together for more ambitious missions.

All story telling is about characters, events and timing. Characters move through the events in a certain structure, one thing happening after another, sometimes the end is told first, sometime we end in the middle. With Artemis each mission has the chance of being told in any order.

This part of the tutorial will be about setting up characters. Strictly speaking Artemis doesn't have traditional characters, like Kirk, Picard or Starbuck. In the galaxy of Artemis the spaceships, space stations, nebulas, anomalies and other space stuff are the characters. Unless you're a fan of Farscape, Paradigm Shift, or you cried when the USS Enterprise self destructed over the Genesis Planet, this will be a different way to think about story telling. The Artemis itself is the protagonist, with the players making up each part of that characters motivation and back-story. The space stations are usually passive characters, but the aliens and space monsters are most definitely antagonists.

The game comes with several decent missions of its own, among them "Module 3 bases" a gamemaster reference by Thom Robertson and the excellent "Havoc in the Hamak System" by Mike Substelny. Hamak is especially wonderful because Mike has commented in detail how the mission works and what is happening as it plays through. I found this very helpful when I was first exploring mission scripting.

When creating a new mission you need to create a new folder in the /Program Files/Artemis/dat/Missions folder. The new folder name must start with MISS_, contain no spaces and should give a clear, but abbreviated, idea about the mission name. As an example the "Module 3 bases" folder is called "MISS_Module_3_bases". Inside the folder you only need one file, the XML mission that must be similarly named, but end with dot xml, as opposed to dot doc or dot txt.
There are many text editors that you can choose from, I personally prefer BBEdit, and the Artemis community has the fantastic Artemis Mission Editor.

Example:
Folder: MISS_AJAX_tutorial_1
XML File: MISS_AJAX_tutorial_1.xml
Download this tutorial mission as zip file.

We recommend that you don't get in the habit of editing the mission files while they are in the Mission folder itself, instead work on the files somewhere else and then copy them into the Mission folder for testing. This is just good workflow habit.

Artemis missions are structured as XML, so they need a reference container. In our case we open and close with a "mission" tag.

<mission version="1">

</mission>


Sometimes referred as open alligator and close alligator, anyone familiar with webpage markup will recognize the use of "greater than" and "less than" to format AML tags. AML tags are the building blocks of data used to work up our mission.
Now that we have a blank page we need to tell the simulator what will appear on that page when that mission first starts. This is where the appropriately named "start" tag comes into play.

<mission version="1">
<!--- COMMENT: this is where we specify what appears when the mission first starts -->
<start>

</start>
</mission>


You might notice I also snuck in a comment tag describing the start section of this mission. Comments will help you keep track of what you are doing and help others as well.

At this point we don't yet have a valid mission file for the simulator. We still need to tell it where our player ship will appear and be called.

<mission version="1">
<!--- COMMENT: this is where we specify what appears when the mission first starts -->
<start>
<!--- add the player ship named "SS AJAX" to the exact middle of the playfield -->
<create type ="player" x="50000" y="0" z="50000" name="SS AJAX"/>
</start>
</mission>


If we copy and pasted the code above into an empty text editor and saved it in the folder style described above we would have a simple, if empty, playfield to run around.

We've placed the player ship in the exact middle of the playfield. The playfield is a constant 100,000 units by 100,000 units. The playfield uses an x, y and z-axis to determine placement of objects. At the time of this writing Artemis 1.702 ignores the y-axis, and objects obey a basic 2D orientation on the same y-axis of 0.
Honestly, placing objects on the playfield with accuracy was the hardest part of mission scripting for me to get a handle on. I had to draw a reference square with the x on the top and z on the right side, and added arrows pointing left and down to remind myself how the units progressed. I made a JPG of the reference for your own use.
I also found this nice degree wheel. I have one printed out on my desk as well. Download for yourself.
Let's add a space station for the player to interact with!

<mission version="1">
<!--- COMMENT: this is where we specify what appears when the mission first starts -->
<start>
<!--- add the player ship named "SS AJAX" to the exact center -->
<create type ="player" x="50000" y="0" z="50000" name="SS AJAX"/>
<!--- add space station "OUTPOST ALPHA" to the center right -->
<create type ="station" raceKeys="friendly" hullKeys="base" x="25000" y="0" z="50000" name="OUTPOST ALPHA"/>
</start>
</mission>


Our Helm player could now fly to the space station and dock! Our Comm player can call ahead to prepare the station for docking and even order the station to manufacture a specific kind of ordinance! Our Science player could select the station and learn about it!
At this point we'll stop and look at the new "create" tag that we introduced. When we want new objects to appear on the playfield we must invoke the create tag. Unlike the "mission" and "start" tags there is no need to have an end tag that closes the statement. The "create" tag is self closing, as are most AML tags. The forward slash before the close alligator is critical, the XML must be valid or the mission will stop loading and present the dreaded "Failed or mismatch directory" warning. This is the only error message Artemis gives when there is a typo or syntax error in the mission file. Fortunatley, the mission will load and play all the way through to the first problem, so you can usually play test simple missions and find the issue that way.
We see that the "mission" tag has one property of "version". This information is actually ignored by the simulator and is really for the scriptwriter's own reference. The "start" tag has no properties, while the "create" tag has seven!
When we are creating an object for the playfield we need to tell the game what makes this object special. We tell the game what type of object it is, what relationship it has to the player, what 3D model to use, where exactly it appears for the first time and invoke a name. The name that is given is what the game will show where ever that object is referenced, and also how you'll refer to that object when scripting. (Keep in mind that long names can get obnoxious pretty quickly.)

While this mission is functional and more importantly valid, it's a little dull. We'll add three enemy ships for our players to confront.

<mission version="1">
<!--- COMMENT: this is where we specify what appears when the mission first starts -->
<start>
<!--- add the player ship named "SS AJAX" to the exact center -->
<create type ="player" x="50000" y="0" z="50000" name="SS AJAX"/>

<!--- add space station "OUTPOST ALPHA" to the center right -->
<create type ="station" raceKeys="friendly" hullKeys="base" x="25000" y="0" z="50000" name="OUTPOST ALPHA"/>

<!--- add three enemy ships to center left -->
<create type ="enemy" raceKeys="Kralien enemy" name="KR01" hullKeys="small" x="75000" y="0" z="49900" angle="0" fleetnumber="1"/>
<create type ="enemy" raceKeys="Kralien enemy" name="KR02" hullKeys="small" x="75000" y="0" z="50000" angle="90" fleetnumber="1"/>
<create type ="enemy" raceKeys="Kralien enemy" name="KR03" hullKeys="small" x="75000" y="0" z="50100" angle="180" fleetnumber="1"/>
</start>
</mission>


Viola! You now have a simple mission to defend OUTPOST ALPHA from the Kralien attackers.
We've also introduced two new properties for the "create" tag; angle and fleetnumber.
The angle property tells the game what direction the ship is facing when it is first created, and the fleet number lets us coordinate a number of enemy ships together. These ships are each pointing a different direction. The angles are 0 to 359, same as the Helm and Weapons directions. The first enemy, KR01, is facing up to the 0 angle. The second ship is facing right at the 90 angle, and the third ship is facing 180 pointing down. You can add an angle property to the players "create" tag if you want to specify what direction the player ship will be facing at start. We also spaced the enemy ships apart, with the middle one being center left. You'll usually want to give your objects a healthy distance.

When we run this mission the enemies will fly toward the player and fight until they or the player are destroyed. They will chase the player all over the playfield, albeit very slowly. The default motivation for enemy characters is to destroy the player. If we wanted to add a deeper motivation to one of these characters we could invoke the "add_ai" tag.

<create type ="enemy" raceKeys="Kralien enemy" name="KR02" hullKeys="small" x="75000" y="0" z="50000" angle="90" fleetnumber="1"/>
<clear_ai name="KR02"/>
<add_ai type="CHASE_STATION" name="KR02"/>


We actually need to invoke 2 tags to make this work as we expect. We use the "clear_ai" tag to, well, clear the ai stack, and then the "add_ai" to tell the character what we want it to do. Clearing the AI stack is important, since each object has a default behaviour that it will revert to if circumstances change. This can cause them to do unexpected things. In the example above we've told the enemy spaceship, KR01, to attack the nearest space station that is friendly to the player. Since there is only one station on the playfield, that enemy will head straight to OUTPOST ALPHA, ignore the player, and commence attacking until it is destroyed. If there was more than one friendly station on the playfield and we wanted to avoid confusion, we can specify the property of "targetName".

<create type ="enemy" raceKeys="Kralien enemy" name="KR02" hullKeys="small" x="75000" y="0" z="50000" angle="90" fleetnumber="1"/>
<clear_ai name="KR02"/>
<add_ai type="CHASE_STATION" name="KR02" targetName="OUTPOST ALPHA"/>


This makes for a very literal bad guy. Your Weapons officer could use them as target practice and this enemy will ignore you and continue to attack the station.
The good news is it's called an "AI stack" for good reason. We can stack AI commands on top of each other to create more interesting behavior.

<create type ="enemy" raceKeys="Kralien enemy" name="KR02" hullKeys="small" x="75000" y="0" z="50000" angle="90" fleetnumber="1"/>
<clear_ai name="KR02"/>
<add_ai type="CHASE_STATION" name="KR02" targetName="OUTPOST ALPHA"/>
<add_ai type="CHASE_PLAYER" name="KR02" value1="5000" value2="3000"/>


This is more interesting. The enemy is now motivated to destroy OUTPOST CHARLIE, however, if the player gets to close it will begin attacking the player. This still means that the player could stand off 5000 units, value1, and still use the enemy as target practice.

<create type ="enemy" raceKeys="Kralien enemy" name="KR02" hullKeys="small" x="75000" y="0" z="50000" angle="90" fleetnumber="1"/>
<clear_ai name="KR02"/>
<add_ai type="CHASE_STATION" name="KR02" targetName="OUTPOST ALPHA"/>
<add_ai type="CHASE_PLAYER" name="KR02" value1="5000" value2="3000"/>
<add_ai type="CHASE_ANGER" name="KR02"/>


Now we have a more realistic bad guy. The "chase anger" tells the enemy to attack whatever character has attacked it. This enemy will now appear on the playfield, head toward OUTPOST ALPHA, attack the player if they get to close and return fire if attacked.

Put it all together and we have a decent training mission for a new crew. Let's add an informative title and subtitle to our tutorial. Our new crew may not realize the jeopardy that they are in right away, so we'll add a pop up warning to alert them!

<!-- mission_data is the big wrapper for all the parts of a mission -->
<mission version="1.5">
<!--- COMMENT: this is where we specify what appears when the mission first starts -->
<start>
<!--- have a nice big mission title appear on the main screen -->
<big_message title="AJAX tutorial 1" subtitle1="written by Michael Sweeney"/>

<!--- have a warning pop up on the main screen -->
<warning_popup_message message="ALERT: Enemy ships detected!" consoles="M"/>

<!--- add the player ship named "AJAX" to the exact center -->
<create type ="player" x="50000" y="0" z="50000" name="SS AJAX"/>

<!--- add space station "OUTPOST ALPHA" to the center right -->
<create type ="station" raceKeys="friendly" hullKeys="base" x="25000" y="0" z="50000" name="OUTPOST ALPHA"/>

<!--- add three enemy ships to center left -->
<create type ="enemy" raceKeys="Kralien enemy" name="KR01" hullKeys="small" x="75000" y="0" z="49900" angle="90" fleetnumber="1"/>
<clear_ai name="KR01"/>
<add_ai type="CHASE_STATION" name="KR01" targetName="OUTPOST ALPHA"/>
<add_ai type="CHASE_PLAYER" name="KR01" value1="5000" value2="3000"/>
<add_ai type="CHASE_ANGER" name="KR01"/>

<create type ="enemy" raceKeys="Kralien enemy" name="KR02" hullKeys="small" x="75000" y="0" z="50000" angle="90" fleetnumber="1"/>
<clear_ai name="KR02"/>
<add_ai type="CHASE_STATION" name="KR02" targetName="OUTPOST ALPHA"/>
<add_ai type="CHASE_PLAYER" name="KR02" value1="5000" value2="3000"/>
<add_ai type="CHASE_ANGER" name="KR02"/>

<create type ="enemy" raceKeys="Kralien enemy" name="KR03" hullKeys="small" x="75000" y="0" z="50100" angle="90" fleetnumber="1"/>
<clear_ai name="KR03"/>
<add_ai type="CHASE_STATION" name="KR03" targetName="OUTPOST ALPHA"/>
<add_ai type="CHASE_PLAYER" name="KR03" value1="5000" value2="3000"/>
<add_ai type="CHASE_ANGER" name="KR03"/>

</start>
</mission>


Our playfield is a little barren at this point, so we might consider adding a few things to make it more interesting. We have quite a few objects to choose from. Obviously we could add more space stations and bad guys. We could also add friendly space ships, space whales, anolomies, mines, asteroids, nebulas, space monsters and black holes.

<!--- add a nebula to the top left -->
<create type ="nebulas" count="10" startX="75000" startY="0" startZ="25000" radius ="5000" startAngle="0" endAngle="360" randomRange="2000" randomSeed="1"/>

<!--- add a friendly spaceship to the bottom right -->
<create type ="neutral" raceKeys="friendly" hullKeys="cargo" x="25000" y="0" z="75000" name="TR80" angle="0"/>

<!--- add a mine field that seperates the bad guys from our player -->
<create type ="mines" count="30" startX="65000" startY="0" startZ="25000" endX="65000" endY="0" endZ="75000"/>

<!--- add an asteroid field that seperates the our player from the station -->
<create type ="asteroids" count="30" startX="35000" startY="0" startZ="25000" endX="35000" endY="0" endZ="75000"/>

<!--- add a space monster to the top right -->
<create type="monster" x="25000" y="0" z="25000" angle="0" name="MONSTER"/>

<!--- add a black hole to the bottom left -->
<create type="blackHole" x="75000" y="0" z="75000" name="BLACKHOLE"/>

<!--- add a pod of space whales near the station -->
<create type="whale" x="15000" y="0" z="55000" angle="0" name="SPACE WHALES" podnumber="1" />

<!--- add an anomaly near the player -->
<create type="anomaly" x="45000" y="0" z="55000" angle="0" name="ANOMALY"/>


This should give a good start to setting up the playfield and putting our basic characters into motion.
Download the tutorial mission folder.

Safe journey!

Comments or suggestions? Please respond to the ARTEMIS FORUM THREAD.

Posted: Monday, April 22, 2013

Past Articles - Artemis Tutorials:
Timing Artemis Mission Scripting 101 Part Three - Thursday, May 30, 2013
Events Artemis Mission Scripting 101 Part Two - Monday, April 29, 2013
Characters - Artemis Mission Scripting 101 - Part One - Monday, April 22, 2013
What is Artemis? - Friday, April 19, 2013

Categories: Artemis Tutorials | Artemis Missions | 3D Printer |