Scripting:Basic course

From STNE Wiki

(Difference between revisions)
Jump to: navigation, search
(Kapitel 2 - Variablen)
m
 
(33 intermediate revisions not shown)
Line 1: Line 1:
-
{{NeedTranslation}}
 
{{ScriptingMenu}}
{{ScriptingMenu}}
'''This is a beginners course for the STNE engine script. It is not complete and probably not 100% correct. I have basically taught myself to use the STNE engine through trail and error, bad translation, good examples, and the benevolence of others. My spelling sucks. I'm sorry. If you see a mistake please fix it.'''
'''This is a beginners course for the STNE engine script. It is not complete and probably not 100% correct. I have basically taught myself to use the STNE engine through trail and error, bad translation, good examples, and the benevolence of others. My spelling sucks. I'm sorry. If you see a mistake please fix it.'''
__TOC__
__TOC__
-
==Vorwort==
+
==Preface==
Much like the German version this course is aimed primarily at those who have never programmed and would like to start scripting in STNE. Please realize it is not easy and it will take a little while before you realize results. Be patient and keep at it! Like all good things it takes effort but it should be worth the time you put into it. I wish you the best of luck.
Much like the German version this course is aimed primarily at those who have never programmed and would like to start scripting in STNE. Please realize it is not easy and it will take a little while before you realize results. Be patient and keep at it! Like all good things it takes effort but it should be worth the time you put into it. I wish you the best of luck.
Line 44: Line 43:
==Chapter 2 - Variables==
==Chapter 2 - Variables==
===Basic types===
===Basic types===
-
Think of a variable as a reference that you can use again and again and again. They can be a word, a number, or true/false. These are all called [[Scripting:DataTypes|DataTypes]] and, of course, each has a special name:
+
Think of a variable as a reference that you can use again and again and again. They can be a word, a number, or true/false. These are all called [[Scripting:DataTypes|Data Types]] and, of course, each has a special name:
 +
* String  - a series of characters
 +
* Integer - a whole number
 +
* Boolean - decision (True/False)
-
'''Nein''', lediglich ein weiterer Fachbegriff der Programmierer. Variablen sind eine Art von Platzhalter, in denen man Informationen, wie zum Beispiel Strings, für eine spätere Verwendung abspeichern kann. Natürlich gibt es für verschiedene Informationen ganz spezielle und verschiedene Variablentypen, die man auch [[Scripting:Datentypen|Datentypen]] nennt.
+
===Variables===
 +
Imagine you have a gigantic project with hundreds of lines of code. Dozens upon dozens of times your code will output the lines:
 +
<Pre><nowiki>Captains log Stardate:</nowiki></pre>
 +
You could code:
 +
<Pre><nowiki>WriteLine('Captains log Stardate:');</nowiki></pre>
 +
every single time and maybe misspell it. Or you could use a variable.
 +
Before a variable can be used, or called, it must be created. You do this with the word "Var" followed by the name followed by "As" followed by the type of variable it is followed by "=" followed by the data to be stored.
-
Die wichtigsten [[Scripting:Datentypen|Datentypen]] sind:
+
Sound complicated?
-
* String  - Zeichenketten
+
Bear with us.
-
* Integer - Zahlen
+
-
* Boolean - Entscheidungen (<tt>Ja/Nein; Wahr/Falsch; True/False</tt>)
+
-
===Variablen setzen===
+
In keeping with the above example let us declare a String variable that contains the line: 'Captains log Stardate:'
-
Da das Arbeiten mit statischen Daten auf Dauer, vor allem bei längeren Scripten, ziemlich zeitaufwendig und unflexibel ist, verwendet man Variablen. Diese speichern Daten, geben sie auf Wunsch aus und lassen sich auch belibig oft verändern.
+
<Pre><nowiki>Var CL As String = 'Captains Log Stardate:';</nowiki></pre>
 +
the name can be anything you choose it to be. In this example we used the letters CL because they are an acronym for Captains Log but you could as easily use LC or X or foo. Choose something that makes sense to you because you will use it through your code.
 +
No two variables can have the same name though.
-
Um eine Variable zu erschaffen verwendet man den Befehl ''var''.  
+
Lets create a number, or integer, variable:
 +
<Pre><nowiki>Var SD As Integer = 234121;</nowiki></pre>
 +
Notice that because this is a number the type is Integer and because this is not a String we DO NOT put quotes around the assignment (what follows the equal sign).
 +
When you run this program, though, it doesn't seem to do much. That is because everything is happening behind the curtain and trust us you don't want to look back there! But if we add an output statement:
 +
<Pre><nowiki>WriteLine(CL & SD);</nowiki></pre>
 +
Things start to happen. Cool huh? Just in case your having trouble your code should look like this:
 +
<Pre><nowiki>Var CL As String = 'Captains Log Stardate:';
 +
Var SD As Integer = 234121;
 +
WriteLine(CL & SD);</nowiki></pre>
 +
Remember that variable assignments always have to come before variable calls. Your code is executed one line at a time and it needs to know what CL is before it can WriteLine CL. Also note the clever use of the & symbol. It stuck the integer and the string together!
 +
The output looks like:
 +
<Pre><nowiki>Captains Log Stardate:234121</nowiki></pre>
 +
See if you can find a way to get a space between the colon and the number...
 +
<Pre><nowiki>Captains Log Stardate: 234121</nowiki></pre>
 +
===Converting One Data Type to Another===
 +
In many programming languages including an older version of the STNE engine you often need to convert variables from one type to another.
 +
For instance if you had a variable:
 +
<Pre>Var number As Integer = 12345;</Pre>
 +
You couldn't use it in certain functions like
 +
<Pre>WriteLine(number);</pre>
 +
Because the parameters for WriteLine() would only accept Strings and the variable 'number' is an Integer.
 +
In that case you would use another function CStr() to convert it to a String:
 +
<Pre>CStr(number)</Pre>
 +
You could even place that inside the parameters of WriteLine():
 +
<Pre>WriteLine(CStr(number));</Pre>
-
Nach ''VAR'' kommt dann der Variablen Name, dieser darf Zahlen und Buchstaben enthalten. Zahlen allerdings nur mit einer Ausnahme, sie dürfen nicht an erster Stelle stehen. Optional danach kann ein ''AS'' stehen (as, engl., als) dieses gibt an was für einen Datentyp die Variable hat, zb. String also eine Zeichenkette. Hier ein Beispiel:
+
Likewise you could covert a String to it's integer value with CInt();
-
<pre>VAR i1 AS String</pre>
+
-
Um dieser Variable einen Inhalt zuzuordnen, schreibt man in der nächsten Zeile die Variable vor ein Gleichheitszeichen, dahinter kommt dann der Inhalt, den die Variable annehmen soll, in unserem nächsten Beispiel ein <i>Hallo!</i>.
+
-
<pre>Var test AS String
+
-
test = 'Hallo!'</pre>
+
-
man kann das ganze auch in eine Zeile packen, das sieht dann wie folgt aus:
+
-
<pre>VAR test AS String = 'Hallo!'</pre>
+
-
Auch hier müssen wir wieder die einfachen Anführungszeichen setzen, als Kennzeichen dafür, dass wir einen String als Inhalt benutzen. Wir können Variablen aber auch andere Datentypen wie Integer oder Bolean zuweisen. Dazu einfach string durch den jeweiligen Datetyp ersetzten.(Liste der Typen: [[Scripting:Typen|klick mich]])
+
-
Auch kann man die Variable "leeren" hierzu gibt man ihr einfach nichts mit, hier auch dazu ein Beispiel:
+
But lucky for us the language is much smarter now and this has become a problem of such little significance that we can not even think up a satisfactory example.
-
<pre>VAR test AS String = 'Hallo!'
+
-
test = ''</pre>
+
-
===Anwendungsbeispiele mit Variablen===
+
===Rules for Naming Variables===
-
VAR test AS String = 'Hallo!'
+
There are some rules for naming your variables
-
WriteLine( test & ' Wie gehts?');
+
* Do not duplicate names. Each script you make must only use a name once, and those names are case insensitive. This means that FOO and foo are actually the same.
-
Auch hier ist weider zu beachten das kein Leerzeichen eingefügt wird! Die Variable kann an jeder Stelle innerhalb der Klammern stehen, zu beachten ist nur, dass sie nicht innerhalb von Anführungszeichen steht sonst wird die Variable als String gewertet.
+
* Do not use spaces. Use capital letters to signify different words.
-
VAR test AS String = 'Hallo!'
+
* Do not use reserved names. Certain names are needed by the complier and by the STNE system and should be avoided. This names include dates, commands for system-defined functions, and features.
-
WriteLine(test);
+
* For clear coding consider starting your variable name with a three digits representing the variable type. For example:
-
Hier wird nun zum Beispiel nur eine Variable ausgegeben.
+
<pre>intDeutNeeded</pre>
 +
* Remember always attempt to make your code as easy to understand as possible. Someday you will come back to it and try to understand what you were attempting.
-
===Umwandlung von Variablen in andere Datentypen===
+
===Summary: Variables===
-
Wollen wir eine Integer-Variable, also eine Zahl, ausgeben, so bekommen wir ein Problem. Der Computer verarbeitet ein Integer intern anders als ein String. Ein String kann er ausgeben ein Integer nicht. Daher müssen alle Integervariablen (wie allen anderen auch) in Stringvariablen umgewandelt werden, bevor man diese ausgeben kann.
+
 
-
Die geschieht über den Befehl
+
* A variable takes the place of "hard coded" data.
-
<pre><nowiki>CStr();</nowiki></pre>
+
* To create a variable use 'VAR <b>Name</b> AS <b>Data type</b>;''
-
Beispiel:
+
* To assign data to a variable you use ''<b>Name</b> = <b>Content</b>;''
 +
* To output a variable use ''WriteLine(<b>Name</b>);'' This can be very important when debugging.
 +
* The ''&'' symbol connects variables withing a  function call''WriteLine();''
 +
 
 +
==Chapter 3 - Control Structures==
 +
Now that you know how to create and use variables it is time to tackle Control Structures. These are the decision making lines that will make your scripts very powerful.
 +
 
 +
===If - Else===
 +
This works exactly how it sounds. <B>IF</B> evaluates a statement and when it is true will execute the next few lines of code that are within curly braces "{" and "}". You can also include an <B>ELSE</B> statement that will execute when the <B>IF</B> evaluates to false.
 +
For example this code evaluates a variable and executes the code within the curly braces in response:
<pre><nowiki>
<pre><nowiki>
-
VAR zahl AS Integer;
+
Var tribbles As Boolean = True;
-
zahl = 5;
+
If (tribbles){
-
WriteLine(CStr(Zahl));
+
  WriteLine('Oh no! The food!');
 +
}
 +
Else{
 +
  WriteLine('The food is safe.');
 +
}
</nowiki></pre>
</nowiki></pre>
-
 
+
When the code runs it will evaluate tribbles. See it is true and then run the code within the curly braces and ignore the code after the ELSE statement. Try it out.
-
Umgekehrt müssen Stringvariablen in Integer umgewandelt werden, wenn mit diesen zum Beispiel gerechnet werden soll.
+
-
Dies geschießt über:
+
You can also use an IF statement to compare amounts. In that case you would use the equal symbol:
-
<pre><nowiki>CInt();</nowiki></pre>
+
-
Beispiel:
+
<pre><nowiki>
<pre><nowiki>
-
VAR einstring AS String;
+
Var EPSamount As Integer = 44;
-
VAR einezahl AS Integer;
+
If (EPSamount = 45){
-
einstring = '42';
+
  WriteLine('We have exactly ' & EPSamount & ' available');
-
einezahl = CInt(einstring);
+
}
 +
Else{
 +
  WriteLine('Im givin her all shes got, Cpatain!');
 +
}
</nowiki></pre>
</nowiki></pre>
 +
Since EPSamount does not equal 45 this the statement will evaluate to false. It then ignores the code after the IF statement and executes the code after the ELSE statement.
-
===Regeln bei der Bennenung von Variablen===
+
You can also use "<",">","<=",">=" for different types of comparisons. In that order and in English those are called "less then", "greater then", "less then or equal to", and "greater then or equal to". These can be a little confusing at first so remember the bigger side of the symbol is toward the larger number. "a<b" says that a is less then b. b is greater.
-
 
+
You can also you the words "AND" and "OR" to write more complex IF statements with multiple tests but each test will need to be inside it's own parentheses which can get very confusing very fast:
-
* Niemals reservierte Namen benutzen! Dazu Zählen u.a. alle Datumsangaben, wie <tt>Date</tt>, <tt>Minute</tt>, <tt>Day</tt> etc.; jegliche Befehle und vom Systemvorgegebenen Funktionsnamen und Eigenschaften wie: <tt>Flotte</tt>, <tt>BenutzeSchiff</tt>, <tt>Nahrung</tt>, <tt>FliegeZu</tt> etc.
+
-
* Man sollte der Übersicht wegen die Variablen immer (Richtlinie) mit drei Buchstaben beginnen lassen, welche beschreiben, welches Datenformat die Variable hat (z.B.: <tt>strVariablenName</tt> für ein String, <tt>IntVariablenName</tt> für ein Integer etc.)
+
-
* Man sollte immer die gleichen Namensrichtlinien einsetzen, damit man bei älteren Scripten noch den Durchblick behält
+
-
*
+
-
 
+
-
===Zusammenfassung: Variablen===
+
-
 
+
-
* Eine Variable ist ein Platzhalter für einen variablen Inhalt eines festgelegten Datentypen.
+
-
* Um eine Variable zu erstellen wird ''VAR <b>Name</b> AS <b>Datentyp</b>;'' verwendet.
+
-
* Um einer Variablen einen Inhalt zu zuweisen wird ''<b>Name</b> = <b>Inhalt</b>;'' verwendet.
+
-
* Um eine Variable auszugeben oder mit ihr zu arbeiten, wird der Name geschrieben zB: ''WriteLine(<b>Name</b>);''
+
-
* Es ist möglich mehrere Variablen mit Hilfe des ''&''-Zeichens innerhalb des Befehls ''WriteLine();'' regelrecht anzuhängen.
+
-
 
+
-
==Kapitel 3 - Kontrollstrukturen==
+
-
Da wir uns in Kapitel 2 mit Variablen beschäftigt haben, können wir uns nun dem eigentlichen Aufwand beim Programmieren zuwenden: den Kontrollstrukturen. Diese Wort klingt ersteinmal sehr hochtrabend, an und für sich ist es jedoch sehr einfach.
+
-
 
+
-
===If - then - Else===
+
-
Es werden 2 Variablen miteinander verglichen oder überprüft, ob eine Variable einem Wert entspricht und dann wird darauf reagiert.
+
<pre><nowiki>
<pre><nowiki>
-
VAR var1 AS Integer = 42;
+
If ((dilth>5)AND(deut>10)AND(ANTIM>10)){
-
if (var1 = 42)
+
   WriteLine('Ready for deep space exploration');
-
{
+
-
   WriteLine('var1 ist 42');
+
}
}
-
else
+
Else{
-
{
+
   WriteLine('Are you crazy? We wont make it past pluto!');
-
   WriteLine('var1 ist nicht 42');
+
}
}
</nowiki></pre>
</nowiki></pre>
-
Dies ist ersteinmal sehr einfach und wirkt auf den ersten Blick sinnlos, was es auch ist. Aber es zeigt auf einfache Art, wie man 2 Werte miteinander vergleicht, dies kann man zum Beispiel dafür nutzen, um zu prüfen wieviel Lageraum ein Schiff noch hat. Dazu aber irgendwann später mehr.
+
Remember the more clear your code is the easier it is for someone in the future, probably you, to understand it so you might re-write the above statement using more variables:
-
Bleiben wir bei dem Code und schauen ihn uns einmal genauer an:
+
<pre><nowiki>
-
In der ersten Zeile wird die Variable '''var1''' definiert, dies sollte aus Kapitel 2 bekannt sein.
+
Var dilth AS Boolean = (dilthAmount>5);
-
<pre><nowiki>If (var1 = 42)</nowiki></pre>
+
Var deut AS Boolean = (deutAmount>10);
-
Hier wird der Vergleich durgeführt, in diesem Fall wir geschaut ob der Wert von Zahl1 42 ist.
+
Var antiM As Boolean = (antiMAmount>10);
-
Man könnte an dieser Stelle genausogut prüfen ob der Wert größer oder kleiner ist, als ein anderer.
+
If ((dilth)AND(deut)AND(antiM)){
-
Hierfür nutzt man dann nicht "=" sondern "<",">","<=",">="
+
  WriteLine('Ready for deep space exploration');
-
Innerhalb der { } folgt dann der Code, welcher ausgeführt werden soll, wenn die Bedigung stimmt, also in diesem Fall, wenn '''var1 ''' gleich 42 ist.
+
}
 +
Else{
 +
  WriteLine('Are you crazy? We wont make it past pluto!');
 +
}
 +
</nowiki></pre>
 +
It is completely up to you!
-
Das folgende ''Else'' mit den Klammern gibt, welche Aktionen ausgeführt werden sollen, wenn die Bedingung nicht stimmt.
+
===Loops===
 +
The next important control structure to learn are loops. A loop works like an if statement, that is executing the lines of code within curly braces "{" "}" but a loop will not exit until the conditions that started become false.
-
Zu guter letzt gibt es noch ''Elseif'' dies ist dafür gedacht wenn man mehr als eine Alternative hat.
+
====While====
-
Beispiel
+
Consider the following code:
<pre><nowiki>
<pre><nowiki>
-
VAR var1 AS Integer = 42;
+
Var ore As integer= 0;
-
if (var1 < 42)
+
WriteLine('Do you need ore?');
-
{
+
while ((ore < 12)){
-
   WriteLine('var1 ist kleiner als 42');
+
   WriteLine('We have ' & ore &' ore. We need more ore!');
 +
  ore = ore + 2;
}
}
-
elseif (var1 > 42)
+
WriteLine('Thanks. We can start making Duranium.');
-
{
+
</nowiki></pre>
-
   WriteLine('var1 ist größer als 42');
+
When executing the WHILE repeats until ore reaches twelve and then it moves on. This type of code can cause problems though when you write a statement that will never evaluate false:
 +
<pre><nowiki>
 +
Var isKilingon As Boolean = True;
 +
while (isKilingon){
 +
   WriteLine('Today is a good day to die!');
}
}
-
else
+
WriteLine('Enough battle!');
-
{
+
</nowiki></pre>
-
   WriteLine('var1 ist weder größer noch kleiner als 42');
+
If run this code would print the line 'Today is a good day to die!' forever and never print the line 'Enough battle'. Luckily when this happens the STNE engine steps in and kills the script.
 +
 
 +
====Do====
 +
DO loops work just like WHILE loops except that regardless the evaluation a DO will execute at least once.
 +
<pre><nowiki>
 +
VAR friendlyShip AS Boolean = False;
 +
WriteLine('Ship on Federation sensors');
 +
Do(friendlyShip){
 +
   WriteLine('Hale them.');
}
}
 +
WriteLine('No response. Open fire!');
</nowiki></pre>
</nowiki></pre>
-
Dies ist nicht auf ein ''elseif'' beschränkt, es können beliebig viele sein.
+
When this script is run, regardless of the fact that the statement evaluated false it will run once. If something happened inside the statement that made it become true though it would run again.
-
===Schleifen===
+
====For====
-
Die soeben kennen gelernten Strukturen helfen uns Fallunterscheidungen zu machen. Aber was machen wir wenn wir eine ganze Liste (zum Beispiel Schiffe) haben und die abarbeiten wollen? Dafür gibt es ''Schleifen'', hier unterscheid man in drei Arten: Kopf-, Fuss- und Zählergesteuert.
+
A FOR loop works just like a WHILE loop except it has a built in integer variable which it increments after every loop. This makes it very good for incrementing. Consider our earlier example:
-
====while====
+
-
While Schleifen sind Kopfgesteuert, dass heißt, solange die Bedingung zutrifft, wird der Inhalt der Schleife ausgeführt.
+
-
Es gelten die selben Operatoren wie bei Abfragen mit if: =,<,>,>=,<=,<>
+
<pre><nowiki>
<pre><nowiki>
-
VAR i AS Integer;
+
Var ore As integer= 0;
-
i = 0;
+
WriteLine('Do you need ore?');
-
WriteLine('Ich zähle jetzt bis Zehn');
+
while ((ore < 12)){
-
while ( i <= 10)
+
   WriteLine('We have ' & ore &' ore. We need more ore!');
-
{
+
   ore = ore + 2;
-
   WriteLine(CStr(i));
+
-
   i = i + 1;
+
}
}
 +
WriteLine('Thanks. We can start making Duranium.');
</nowiki></pre>
</nowiki></pre>
-
Solange '''i''' kleiner oder gleich 10 ist, wird '''i''' ausgegeben und dann einen hochgezählt.
+
This could also be written using a FOR loop:
-
Bei Whileschleifen ist zu beachten, dass wenn die Bedingung zu Anfang bereits '''nicht''' erfüllt ist, dass sie dann nicht durchläuft. Soll sie mindestens einmal durchlaufen muss man Fussgesteuerte Schleifen wählen.
+
-
====Do====
+
-
Do-Schleifen sind Fussgesteuert. Sie funktionieren wie While-Schleifen nur das sie mindestens einmal durchlaufen.
+
<pre><nowiki>
<pre><nowiki>
-
VAR i AS Integer;
+
Var ore As integer;
-
i = 10;
+
WriteLine('Do you need ore?');
-
WriteLine('Ich zähle jetzt bis Null');
+
for(ore=0 To 12 Step 2){
-
Do
+
   WriteLine('We have ' & ore &' ore. We need more ore!');
-
{
+
-
   WriteLine(CStr(i));
+
-
  i = i -1;
+
}
}
-
While (i >= 0);
+
WriteLine('Thanks. We can start making Duranium.');
</nowiki></pre>
</nowiki></pre>
-
Gebe '''i''' solange aus und zähle einen runter, solange '''i''' größer gleich null ist.
+
See how the incrementation is taken care of in the parameters, or between the parentheses? It takes the integer variable ore from 0 to 12 by sets of 2.
-
Aus der Beschreibung wird deutlich wo der unterschied zwischen While- und Do-Schleifen liegt.
+
-
In beiden Schleifen wird deutlich das ich jedes mal die Variable '''i''' runter bzw. hochzählen muss, um dies zu umgehen gibt es die möglichkeit Zählergesteuerte Schleifen zu verwenden.
+
If you do not specify a step it will assume the step is 1.
-
====For====
+
==Chapter 4 - Functions==
-
For-Schleifen sind genau dies.  
+
===Introduction===
 +
The last object to learn about are functions. A function is a series of lines of code that can be called from main to run again and again. Consider that we have the following code.
<pre><nowiki>
<pre><nowiki>
-
VAR i AS Integer;
+
WriteLine('Get them out of there!');
-
For ( i = 0 To 10)
+
WriteLine('Attempting to beam up away-team');
-
{
+
</nowiki></pre>
-
  WriteLine(CStr(i));
+
But you want to run that ten times.
-
}</nowiki></pre>
+
You could write those two lines ten times or you could make a function. In that way a function can act similar to variables though as you will see they are much more powerful.
-
auf diese Weise kann man sich ein wenig Arbeit abnehmen, da die Schleife einem das Zählen abnimmt. So kann man auch Endlosschleifen vermeiden, die auftreten wenn man vergisst, die Schleifenvariable (in diesen Fällen immer '''i''') runter- bzw. hochzuzählen.
+
To create a function you use the following formula 'Function' followed by the name you give it, followed by the symbols "(){}"
-
 
+
Here is an example using the code above:
-
For-Schleifen bieten noch eine weitere Möglichkeit: Es kann angegeben werden in welchen Schritten die Schleife zählt.
+
<pre><nowiki>
<pre><nowiki>
-
VAR i AS Integer;
+
Function BeamUp(){
-
For ( i = 0 To 100 Step 10)
+
  WriteLine('Get them out of there!');
-
{
+
  WriteLine('Attempting to beam up away-team');
-
   WriteLine(CStr(i));
+
}
-
}</nowiki></pre>
+
</nowiki></pre>
-
Der Code ist der bis auf das ''Step'' identisch. Die Zahl die hinter Step steht kann sowohl positiv als auch negativ sein.
+
Now every time BeamUp() is called it looks through the entire script for the Function BeamUp() and will run those two lines of code. For example:
 +
<pre><nowiki>
 +
WriteLine('We are at the Borg ship.');
 +
BeamUp();
 +
WriteLine('We are at the Klingon colony.');
 +
BeamUp();
 +
Function BeamUp(){
 +
  WriteLine('Get them out of there!');
 +
  WriteLine('Attempting to beam up away-team!');
 +
}
 +
WriteLine('We are at the Syndicate station');
 +
BeamUp();
 +
</nowiki></pre>
 +
===Parameters===
 +
But it gets better. You can pass a function variables making it more versatile. To specify what types of variables a function can be passed you need to declare them between the parenthesis "()". These are called the Functions Parameters. You declare a function in the parameters the same way you do in regular code and you can declare as many variables of any type as you want so long as you separate them by comas. For example
 +
<pre><nowiki>
 +
Function BeamUp(number As Int32, crew As Boolean, teamName As String){
 +
   If(crew){
 +
    WriteLine('Beaming up ' & number & ' ' & teamName & '.');
 +
    WriteLine('Attempting to beam up away-team!');
 +
    Else{
 +
      WriteLine('There is nobody there');
 +
    }
 +
  }
 +
}
 +
</nowiki></pre>
 +
For some reason when the compiler checks for errors it replaces the word Integer with Int32. Don't worry. It you write either one your code will still work.
 +
Now when you make the function call you need to pass it values that match it's parameters.
 +
In the above example you might call it this way:
 +
<pre><nowiki>
 +
BeamUp(5, True, Medics);
 +
</nowiki></pre>
 +
<pre><nowiki>
 +
Function BeamUp(number As Int32, crew As Boolean, teamName As String){
 +
  If(crew){
 +
    WriteLine('Beaming up ' & number & ' ' & teamName & '.');
 +
    WriteLine('Attempting to beam up away-team!');
 +
    Else{
 +
      WriteLine('There is nobody there');
 +
    }
 +
  }
 +
}
 +
WriteLine('We are at the Borg ship.');
 +
BeamUp();
 +
WriteLine('We are at the Klingon colony.');
 +
BeamUp();
 +
WriteLine('We are at the Syndicate station');
 +
BeamUp();
 +
</nowiki></pre>
 +
Also for clarity consider keeping your Functions separate from your main code either all above or all bellow.
-
==Kapitel 4 - Der Shipmanager - Einführung==
+
Now that we now have a few basics, let us turn to the really interesting parts, the control of the game content through scripts.
-
Nachdem wir nun über ein paar Grundlagen verfügen, wollen wir uns den wirklich interessanten Dingen zuwenden, der Steuerung von Spielinhalten durch Scripte.
+
-
Um mit Schiffen zu interagieren gibt es eine Sammlung von Methoden, welche im Shipmanager zu finden sind.
+
To interact with ships there is a collection of methods, which can be found in CShipManager. To use them, we must first assign a ShipManager to either a ship or a fleet. This is done via assignment of a new CShipManager variable
-
Hierzu müssen wir dem Shipmanager als erstes Mitteilen, welches bzw. welche Flotte er verwenden soll.
+
<pre><nowiki>Var ShipManager As New CShipManager();</nowiki></pre>
-
Hierführ gibt es die Befehle:
+
To assign the safety officer, there are the commands:
-
<pre><nowiki>ShipManager.BenutzeSchiff(NCC-Nummer des Schiffes);</nowiki></pre>
+
<pre><nowiki>ShipManager.SelectShip(NCC-Number of Ship);</nowiki></pre>
-
bzw.
+
or,
-
<pre><nowiki>ShipManager.BenutzeFlotte(ID der Flotte);</nowiki></pre>
+
<pre><nowiki>ShipManager.SelectFleet(ID of Fleet);</nowiki></pre>
-
Damit weiß der ShipManager schonmal welches Schiff, bzw. welche Flotte die Aktionen ausführen soll.
+
This way the ShipManager knows which ship or fleet to interact with.
-
Mit dem Shipmanager können folgende Aktionen ausgeführt werden:
+
Syntax:
-
*An- und Abdocken
+
  CShipManager.TransferToShip(<i>ToShipID, Amount, EBeamResource.Resource</i>)
-
*Alarm Stufe ändern
+
You just need to replace the parameters with the respective values. Here's an example:
-
*Aus Flotten austreten
+
  ShipManager.SelectShip (1);
-
*Aus Orbit einfliegen austreten
+
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);
-
*Benennen(Name As String)
+
Of course, you can also beam from an entire fleet, if your replace ShipManager.SelectShip(1) by ShipManager.SelectFleet(1), Then the script transfers the amount from every ship in a fleet:
-
*Deuterium sammeln (Nur mit FP)
+
  ShipManager.BenutzteFlotte (1);
-
*Erz sammeln (Nur mit FP)
+
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);
-
*Fliegen
+
-
*Sensoren aktivieren / deaktivieren
+
-
*Reparieren
+
-
*Batterien entladen
+
-
*Schilde aktivieren/deaktiviere/aufladen
+
-
*Reservebatterie aufladen
+
-
*Traktorstrahl ein- / ausschalten
+
-
*Beamen
+
-
*Verstecken
+
-
*Replikator aktivieren/deaktivieren
+
-
*Waren über Bord werfen
+
-
*Warpkern aktiveren/deaktivieren
+
-
*Wrackextraktoren
+
-
Eine vollständige Auflistung aller Funktionen findet sich im [http://game.stne.net/ObjectExplorer.aspx?p=CShipManager Objekt-Explorer].
+
With the Ship Managers, you can do the following:
 +
* Docking and undocking
 +
* Alert level change
 +
* Escape from fleets
 +
* Enter or leave orbit
 +
* Rename (name As String)
 +
* Collect deuterium (only with FP)
 +
* Gather ore (only with FP)
 +
* Fly (FlyTo() AutoPilot, only with FP)
 +
* Fly (Using the Fly() method)
 +
* Tractor beam on / off
 +
* Beaming
 +
* Hide
 +
* Enable / Disable the Replicators
 +
* Jettison Goods
 +
* Enable / Disable the Warp Core
 +
* Wreck extraction
 +
* And more
-
Im folgenden wollen wir uns einige Funktionen genauer anschauen:
+
For a complete list of the CShipManager features, see [http://game.stne.net/ObjectExplorer.aspx?p=CShipManager Object Explorer].
-
===Beamen===
+
-
Syntaxe:
+
-
ShipManager.TransferiereZuSchiff(''Schiffid'', ''Menge'', EBeamRessource.''Ware'');
+
-
Hier musst du nun nurnoch den kursiven Text mit deinen Angaben ersetzten. Hier ein Beispiele:
+
-
ShipManager.BenutzteSchiff(1);
+
-
ShipManager.TransferiereZuSchiff(2, 20, EBeamRessource.Nahrung);
+
-
Natürlich kann man auch eine ganze Flotte beamen lassen, dazu ersetzt du ''ShipManager.BenutzteSchiff(1);'' durch ''ShipManager.BenutzteFlotte(1);'' Dann sieht das Script folgendermasen aus:
+
-
ShipManager.BenutzteFlotte(1);
+
-
ShipManager.TransferiereZuSchiff(2, 20, EBeamRessource.Nahrung);
+
-
===Fliegen===
+
Next, we will look at some specific features:
-
Bei der Syntaxe gibt es 2 Möglichkeiten, die eine für Spieler unter Level 8 oder mit [[Feature-Pack]], also mit Autopilot, und die andere für die Leute über Level 8 und ohne Feature-Pack, die Variante ohne Autopilot.
+
-
====Fliegen mit dem Autopiloten====
+
-
<font color="red">'''''Nur für Spieler mit Feature-Pack oder unter Kolonisationslevel 8 möglich!'''''</font>
+
-
Der Befehl:
+
===Beaming===
-
ShipManager.FliegeZu(''xxx|yyy'');
+
Syntax:
-
Auch hier Gilt es wieder das kursive durch die eigenen Angaben zu ersetzten. Wie in folgendem Beispiel:
+
  CShipManager.TransferToShip(ToShipID, Amount, EBeamResource.Resource)
-
ShipManager.BenutzteSchiff(1);
+
You just need to replace the parameters with the respective values. Here's an example:
-
ShipManager.FliegeZu('123|465');
+
  ShipManager.SelectShip (1);
-
oder mit dem Flottenbefehl:
+
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);
-
ShipManager.BenutzteFlotte(1);
+
Of course, you can also beam from an entire fleet, if your replace ShipManager.SelectShip(1) by ShipManager.SelectFleet(1), Then the script transfers the amount from every ship in a fleet:
-
ShipManager.FliegeZu('123|465');
+
  ShipManager.SelectFleet (1);
-
Mit deisem Befehl fliegt das Schiff zu einer belibigen Position, [[NPC|NPC-Gebiete]] ausgenommen, und umgeht dabei wie der Autopilot Energie-intensive Hindernisse, sowie solche die das Schiff oder die Crew Gefährden.
+
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);
-
====Fliegen ohne Autopilot====
+
===Flying===
-
Der Befehl hierzu sieht wie folgt aus:
+
There are two versions of flying, CShipManager.FlyTo() (For players with the [[Feature-Pack]]), and CShipManager.Fly() (Works for everyone). FlyTo() is an auto pilot, like the helm control with FP, while Fly() moves you a number of sectors in a straight line.
-
  ShipManager.Fliege(''Strecke'', EShipRichtung.''Richtung'');
+
 
-
Auch hier ersetzt du die kursiven Worte mit deinen Angaben, ein Beispiel folgt:
+
====Flying with the Autopilot====
-
ShipManager.BenutzteSchiff(1);
+
<font color="red">'''''Only for players with the feature pack!'''''</font>
-
ShipManager.Fliege(5, EShipRichtung.Hoch);
+
 
-
ShipManager.Fliege(8, EshipRichtung.Links);
+
 
-
oder wenn es eine ganze Flotte ist:
+
The command:
-
ShipManager.BenutzteFlotte(1);
+
  ShipManager.FlyTo (<i>'xxx | yyy'</i>);
-
ShipManager.Fliege(5, EShipRichtung.Hoch);
+
Again, it you need to replace the italicized parameter 'xxx | yyy' with something appropriate. Here is an example:
-
ShipManager.Fliege(8, EshipRichtung.Links);
+
  ShipManager.SelectShip(1);
 +
ShipManager.FlyTo('123|465');
 +
Or, with a fleet:
 +
ShipManager.SelectFleet(1);
 +
ShipManager.FlyTo('123|465');
 +
 +
With this command, the ship or fleet flew through space to the destination, using the auto pilot to bypass [[NPC | NPC Areas]], energy-intensive obstacles, and those which endanger the ship or the crew
 +
 
 +
====Flying without the Autopilot====
 +
The command for this is as follows:
 +
  ShipManager.Fly (''distance'',''EShipDirection.Direction'');
 +
Here is an example:
 +
  ShipManager.SelectShip (1);
 +
  ShipManager.Fly (5, EShipDirection.Up);
 +
  ShipManager.Fly (8, EShipDirection.Left);
 +
or if you wanted to move an entire fleet:
 +
  ShipManager.SelectFleet (1);
 +
  ShipManager.Fly (5, EShipDirection.Up);
 +
  ShipManager.Fly (8, EShipDirection.Left);
 +
 
 +
Please note, Fly() will <B>NOT</b> avoid dangerous areas, it will fly in a straight line though Nebulas etc.
===Schiffsystem nutzen===
===Schiffsystem nutzen===
kommt noch
kommt noch
-
===Alternative zum Schiffsmanager: Schiffsaktion===
+
=== An alternative to using the Ship Manager: Ship Action ===
-
Für Objekte des Typ's CMyFlotte und CMyShip kann über die Eigenschaft Aktion direkt auf die Funktionen des Schiffsmanagers zugegriffen werden.
+
The objects CMyShip (not CShip) And CMyFleet can access methods of the Ship Manager directly via the Action method of the object.
-
<pre><nowiki>VAR Schiff AS CMyShip = new CMyShip( 4711 )
+
<pre><nowiki>VAR Ship AS CMyShip = new CMyShip( 1 );
-
Schiff.Aktion.Abdocken()</nowiki></pre>
+
Ship.Action.Undock();</nowiki></pre>
-
<pre><nowiki>VAR Flotte AS CMyFlotte = new CMyFlotte( 4711 )
+
<pre><nowiki>VAR Fleet AS CMyFleet = new CMyFleet( 1 );
-
Flotte.Aktion.Abdocken()</nowiki></pre>
+
Fleet.Action.Undock();</nowiki></pre>
==Enumeration ist Alles==
==Enumeration ist Alles==
kommt noch
kommt noch
-
==Methoden==
+
== Methods ==
 +
 
 +
Anything that you would want to do more than one time can be grouped into scripting methods. A scripting method is essentially a function or a procedure (The difference between a function and a procedure being that a function returns a value. A procedure does not.)
-
Öfters wiederkehrende Aufgaben können in Methoden zusammengefasst werden:
 
<pre><nowiki>
<pre><nowiki>
-
Function ShowKoords(x As Integer, y As Integer)
+
// This would be considered a procedure, as it returns no value
 +
Function ShowCoords (x As Integer, y As Integer)
{
{
-
  WriteLine(CStr(x) + '|' + CStr(y));
+
  WriteLine (CStr(x) + '|' + CStr(y));
}
}
-
</nowiki></pre>
+
</nowiki> </pre>
-
Die Methode ShowKoords kann dann im Script folgendermaßen aufgerufen werden:
+
The method ShowCoords can then be called in the script as follows:
<pre><nowiki>
<pre><nowiki>
-
ShowKoords(3, 4);
+
ShowCoords (3, 4);
-
ShowKoords(ship.MapPosition.X,ship.MapPosition.Y);
+
ShowCoords (ship.MapPosition.X, ship.MapPosition.Y);
-
</nowiki></pre>
+
</nowiki> </pre>
-
Wenn berechnete Werte von der Methode zurückgegeben werden sollen:
+
If calculated values are to be returned by the method:
<pre><nowiki>
<pre><nowiki>
-
Function Distanz(x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer
+
// This is a function, as it returns a value
 +
Function distance (x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer
{
{
-
  Var distanz As Integer;
+
  Var As Integer distance;
    
    
-
  distanz = Math.Abs(x1 - x2) + Math.Abs(y1 - y2);
+
  distance = Math.abs (x1 - x2) + Math.abs (y1 - y2);
-
  Return distanz ;
+
  Return distance;
}
}
-
WriteLine(Distanz(1, 1, 5, 5));
+
WriteLine (distance (1, 1, 5, 5));
</nowiki></pre>
</nowiki></pre>
-
Einfache Typen werden immer 'ByVal' übergeben, d.h. die Werte werden als Kopie an die Methode übergeben und die entsprechenden Variablen im Script nicht verändert.
+
Simple types are always passed by value (the value assigned to the variable is pushed onto the stack before calling the method). Examples of a simple type are Integer, Double, Char. This means that you don't change their values in the calling method. Complex types (such as Classes, Strings, Dates, Objects) are passed by reference (as attempting to pass such by value is very memory intensive unnecessarily, so the address of the variable is pushed onto the stack instead), so if you change the value of a complex type from a called function, it changes the value in the calling function as well.
-
'ByRef' ist zwar in der Scriptengine vorgesehen und kann angegeben werden, ist aber derzeit ohne Funktion.
+
-
Objekte werden immer ByRef übergeben.
+
-
==Klassen==
+
For Classes or methods that need to be consistent and available from multiple scripts, There is the scripting pragma #Include. The syntax is as follows:
 +
<pre><nowiki>#Include ScriptName = 'The Name of the included script', FromUser = 'Server-UserID';</nowiki></pre>
-
In Klassen können Daten und Methoden in einem Objekt gekapselt werden:
+
So something like:
 +
<pre><nowiki>#Include ScriptName = 'My Coordinate Methods', FromUser = 'En1-123456';</nowiki></pre>
-
<pre><nowiki>
+
Keep in mind, that a variable or a method can only be declared once, so if you define something in the include, its name must be unique.
-
Class CKoords
+
 
 +
== Classes ==
 +
To encapsulate both data and functions within a single object, you can use classes. The benefits of classes are that they can reuse variable names (variables are scoped within the class), You can make your code more self documenting, and they are easily included with a minim of name space clashes (you're less likely to use the same for a variable or function within the same name space scope).
 +
 
 +
<pre> <nowiki>
 +
Class CCoords
{
{
-
  Var x As Integer;
+
  Var x As Integer;
-
  Var y As Integer;
+
  Var y Integer;
    
    
-
  Function New(x As Integer, y As Integer)
+
  New Function (x As Integer, y As Integer)
-
  {
+
  {
-
    This.x = x;
+
    This.x = x;
-
    This.y = y;
+
    This.y = y;
-
  }
+
  }
    
    
-
  Function ToString() As String
+
  ToString () As String
 +
  {
 +
    Return (CStr (x) + '|' + CStr (y);
 +
  }
 +
 
 +
  Function distance (coord As CCoords) As Integer
 +
  {
 +
    Return Math.Abs ??(x - coord.x) + Math.abs (y - coord.y);
 +
  }
 +
}
 +
 
 +
Var ko1 As New CCoords (3, 5);
 +
Var ko2 As CCoords;
 +
 
 +
ko2 = New CKoords(8, 9);
 +
WriteLine ('Distance from' ko1.ToString + () + 'for' + ko2.ToString () + ': ' + CStr (ko1.distance (ko2)));
 +
</nowiki> </pre>
 +
 
 +
Important: classes always need a new () method, otherwise a new object of class will be generated! Worse, you won't be able to have multiple instances of the class. This is fine if you are creating a static class, but this is rarely the case. If you don't need to send any parameters to initialize the object, you can create an empty New method:
 +
<pre> <nowiki>
 +
Class Coords2
 +
{
 +
  Function New()
   {
   {
-
     Return (CStr(x) + '|' + CStr(y);
+
     ; // NOP (No Operation) instruction, does nothing
   }
   }
-
 
+
...
-
   Function Distanz(koord As CKoords) As Integer
+
}
 +
</nowiki> </pre>
 +
 
 +
You can also call methods statically from any context by prefixing the class name:
 +
<pre> <nowiki>
 +
Class Coords3
 +
{
 +
   Function NotTrue() As Boolean
   {
   {
-
     Return Math.Abs(x - koord.x) + Math.Abs(y - koord.y);
+
     Return False;
   }
   }
}
}
-
Var ko1 As New CKoords(3, 5);
+
Var MyFalse As Boolean = Coords3.NotTrue;
-
Var ko2 As CKoords;
+
</nowiki> </pre>
 +
The above is also an example of a read only object property. You can get the value multiple times, but you can never change it. This is useful in some instances. Finally, The class can access a method within the class, but you have to prefix either the class name for a static value, or use the This pointer to access dynamic data:
-
ko2 = New CKoords(8, 9);
+
<pre><nowiki>
-
WriteLine('Distanz von ' + ko1.ToString() + ' nach ' + ko2.ToString() + ': ' + CStr(ko1.Distanz(ko2)));
+
Class CCoords
-
</nowiki></pre>
+
{
 +
  Var x As Integer;
 +
  Var y Integer;
 +
 
 +
  New Function (x As Integer, y As Integer)
 +
  {
 +
    This.x = x;
 +
    This.y = y;
 +
  }
 +
   
 +
  ToString () As String
 +
  {
 +
    Return (CStr (x) + '|' + CStr (y);
 +
  }
 +
 
 +
  Function distance (coord As CCoords) As Integer
 +
  {
 +
    Return Math.Abs ??(x - coord.x) + Math.abs (y - coord.y);
 +
  }
 +
  // Method added to Coords
 +
  Function GetPoint() As SPoint {
 +
    Return SPoint.FromString(This.ToString());
 +
  }
 +
}
 +
</nowiki> </pre>
-
Wichtig: Klassen brauchen immer eine Methode New(), sonst kann kein neues Objekt der Klasse generiert werden!
+
If you try and access the method GetPoint statically, you will generate a run time error. If the method GetPoint did not use the This pointer, the code would look for ToString in the script global name space, and generate a compile time error.
-
==Autoren==
+
==Authors==
-
(hier dürfen sich diejenigen verewigen die hier min. ein Kapitel geschrieben haben [sonst kommt noch einer daher nur weil er nen Rechtschreibfehler verbessert hat ;)])
+
{|
{|
!Nickname
!Nickname
-
!IG-id
+
!IG-ID
-
!Kapitel
+
!Chapter
|-
|-
|WiZz4Rd
|WiZz4Rd
-
|16475
+
|DE1-16475
-
|Kapitel 1, Kapitel 2, Kapitel 4
+
|Chapter 1, Chapter 2, Chapter 4
|-
|-
|Stryke
|Stryke
-
|28885
+
|DE1-28885
-
|Vorwort, Kapitel 3, Kapitel 4
+
|Preface, Chapter 3, Chapter 4
|-
|-
-
|[[Spieler:Xenon|Xenon]]
+
|Xenon
-
|10127
+
|DE1-10127
-
|Korrektur & Überarbeitung Kapitel 1
+
|Corrector & Chapter 1 revision
|-
|-
|Fling
|Fling
-
|54865
+
|DE1-54865
-
|Kapitel 7, Kapitel 8
+
|Chapter 7, Chapter 8
|}
|}
 +
==Translators==
 +
 +
{|
 +
!Nickname
 +
!IG-ID
 +
!Chapter
 +
|-
 +
|Cs.temp.mail
 +
|Unknown
 +
|Preface, Chapter 1, Chapter 2, Chapter 3, Chapter 4
 +
|-
 +
|Miltiades
 +
|EN1-56599
 +
|Chapter 4, Chapter 6, Chapter 7
 +
|-
 +
|Glest Durnham
 +
|EN1-6609
 +
|Corrector
 +
|}
-
[[Kategorie:Scripting-Hilfe|Anfängerkurs]]
+
[[Category:Scripting]]

Latest revision as of 09:10, 2 May 2020

Main | Syntax | Operators | Interfaces | FAQ | Contents | API Reference | Index

This is a beginners course for the STNE engine script. It is not complete and probably not 100% correct. I have basically taught myself to use the STNE engine through trail and error, bad translation, good examples, and the benevolence of others. My spelling sucks. I'm sorry. If you see a mistake please fix it.

Contents

Preface

Much like the German version this course is aimed primarily at those who have never programmed and would like to start scripting in STNE. Please realize it is not easy and it will take a little while before you realize results. Be patient and keep at it! Like all good things it takes effort but it should be worth the time you put into it. I wish you the best of luck.

Chapter 1 - Strings

In programming a String is a series of characters. The chapter title would be a String as would this text. The famous line "Hello World!" is also a String and it is this String you will be working with.

"Hello World!"

We don't really know where it started but when first embarking on learning a programming language the first program you tend to write will be "Hello World!" In the STNE engine this is very easy. First launch the script editor under: Database -> Script Editor -> Create a new script -> Custom script without input wizard Then you will click "Edit source code". In the text field provided type:

WriteLine('Hello World!');

Now click Save&Run. Did it work? If not double check your input. Are the capital letters capital? Are there opening and closing quote marks and parentheses? Does it end with a semicolon? When it works you should see the line:

Hello World!
Congratulations you are now programming. Try making a program that says:
Hello World!
Live long and prosper!

Your code should look like this:

WriteLine('Hello World!');
WriteLine('Live long and prosper!');

Note every line of code ends with a semicolon. But what if you want to write everything on one line:

Hello World! Live long and prosper!

This is done by use of the & symbol:

WriteLine('Hello World!'&' Live long and prosper!');

The & symbol allows you to combine two Strings. It literately sticks them right next to each other which is why ' Live long and prosper!' has the preceding space. See what happens when you remove it!

"But wait!" You say. "I could simple code:
WriteLine('Hello World! Live long and prosper!');
and never have to deal with the & symbol!"

True, and as a programmer you will have many choices of different ways to do things. But the '&' is important as you will find out in the next chapter.

Summary: Strings

  • A String is a sequence of several characters.
  • A String is output, or printed, using the command WriteLine();.
  • You may use the character & to combine one String with another within the parameters, or parentheses, of WriteLine();.

Chapter 2 - Variables

Basic types

Think of a variable as a reference that you can use again and again and again. They can be a word, a number, or true/false. These are all called Data Types and, of course, each has a special name:

  • String - a series of characters
  • Integer - a whole number
  • Boolean - decision (True/False)

Variables

Imagine you have a gigantic project with hundreds of lines of code. Dozens upon dozens of times your code will output the lines:

Captains log Stardate:

You could code:

WriteLine('Captains log Stardate:');

every single time and maybe misspell it. Or you could use a variable. Before a variable can be used, or called, it must be created. You do this with the word "Var" followed by the name followed by "As" followed by the type of variable it is followed by "=" followed by the data to be stored.

Sound complicated? Bear with us.

In keeping with the above example let us declare a String variable that contains the line: 'Captains log Stardate:'

Var CL As String = 'Captains Log Stardate:';

the name can be anything you choose it to be. In this example we used the letters CL because they are an acronym for Captains Log but you could as easily use LC or X or foo. Choose something that makes sense to you because you will use it through your code. No two variables can have the same name though.

Lets create a number, or integer, variable:

Var SD As Integer = 234121;

Notice that because this is a number the type is Integer and because this is not a String we DO NOT put quotes around the assignment (what follows the equal sign). When you run this program, though, it doesn't seem to do much. That is because everything is happening behind the curtain and trust us you don't want to look back there! But if we add an output statement:

WriteLine(CL & SD);

Things start to happen. Cool huh? Just in case your having trouble your code should look like this:

Var CL As String = 'Captains Log Stardate:';
Var SD As Integer = 234121;
WriteLine(CL & SD);

Remember that variable assignments always have to come before variable calls. Your code is executed one line at a time and it needs to know what CL is before it can WriteLine CL. Also note the clever use of the & symbol. It stuck the integer and the string together! The output looks like:

Captains Log Stardate:234121

See if you can find a way to get a space between the colon and the number...

Captains Log Stardate: 234121

Converting One Data Type to Another

In many programming languages including an older version of the STNE engine you often need to convert variables from one type to another. For instance if you had a variable:

Var number As Integer = 12345;

You couldn't use it in certain functions like

WriteLine(number);

Because the parameters for WriteLine() would only accept Strings and the variable 'number' is an Integer.

In that case you would use another function CStr() to convert it to a String:

CStr(number)

You could even place that inside the parameters of WriteLine():

WriteLine(CStr(number));

Likewise you could covert a String to it's integer value with CInt();

But lucky for us the language is much smarter now and this has become a problem of such little significance that we can not even think up a satisfactory example.

Rules for Naming Variables

There are some rules for naming your variables

  • Do not duplicate names. Each script you make must only use a name once, and those names are case insensitive. This means that FOO and foo are actually the same.
  • Do not use spaces. Use capital letters to signify different words.
  • Do not use reserved names. Certain names are needed by the complier and by the STNE system and should be avoided. This names include dates, commands for system-defined functions, and features.
  • For clear coding consider starting your variable name with a three digits representing the variable type. For example:
intDeutNeeded
  • Remember always attempt to make your code as easy to understand as possible. Someday you will come back to it and try to understand what you were attempting.

Summary: Variables

  • A variable takes the place of "hard coded" data.
  • To create a variable use 'VAR Name AS Data type;
  • To assign data to a variable you use Name = Content;
  • To output a variable use WriteLine(Name); This can be very important when debugging.
  • The & symbol connects variables withing a function callWriteLine();

Chapter 3 - Control Structures

Now that you know how to create and use variables it is time to tackle Control Structures. These are the decision making lines that will make your scripts very powerful.

If - Else

This works exactly how it sounds. IF evaluates a statement and when it is true will execute the next few lines of code that are within curly braces "{" and "}". You can also include an ELSE statement that will execute when the IF evaluates to false. For example this code evaluates a variable and executes the code within the curly braces in response:

Var tribbles As Boolean = True;
If (tribbles){
  WriteLine('Oh no! The food!');
}
Else{
  WriteLine('The food is safe.');
}

When the code runs it will evaluate tribbles. See it is true and then run the code within the curly braces and ignore the code after the ELSE statement. Try it out.

You can also use an IF statement to compare amounts. In that case you would use the equal symbol:

Var EPSamount As Integer = 44;
If (EPSamount = 45){
  WriteLine('We have exactly ' & EPSamount & ' available');
}
Else{
  WriteLine('Im givin her all shes got, Cpatain!');
}

Since EPSamount does not equal 45 this the statement will evaluate to false. It then ignores the code after the IF statement and executes the code after the ELSE statement.

You can also use "<",">","<=",">=" for different types of comparisons. In that order and in English those are called "less then", "greater then", "less then or equal to", and "greater then or equal to". These can be a little confusing at first so remember the bigger side of the symbol is toward the larger number. "a<b" says that a is less then b. b is greater. You can also you the words "AND" and "OR" to write more complex IF statements with multiple tests but each test will need to be inside it's own parentheses which can get very confusing very fast:

If ((dilth>5)AND(deut>10)AND(ANTIM>10)){
  WriteLine('Ready for deep space exploration');
}
Else{
  WriteLine('Are you crazy? We wont make it past pluto!');
}

Remember the more clear your code is the easier it is for someone in the future, probably you, to understand it so you might re-write the above statement using more variables:

Var dilth AS Boolean = (dilthAmount>5);
Var deut AS Boolean = (deutAmount>10);
Var antiM As Boolean = (antiMAmount>10);
If ((dilth)AND(deut)AND(antiM)){
  WriteLine('Ready for deep space exploration');
}
Else{
  WriteLine('Are you crazy? We wont make it past pluto!');
}

It is completely up to you!

Loops

The next important control structure to learn are loops. A loop works like an if statement, that is executing the lines of code within curly braces "{" "}" but a loop will not exit until the conditions that started become false.

While

Consider the following code:

Var ore As integer= 0;
WriteLine('Do you need ore?');
while ((ore < 12)){
  WriteLine('We have ' & ore &' ore. We need more ore!');
  ore = ore + 2;
}
WriteLine('Thanks. We can start making Duranium.');

When executing the WHILE repeats until ore reaches twelve and then it moves on. This type of code can cause problems though when you write a statement that will never evaluate false:

Var isKilingon As Boolean = True;
while (isKilingon){
  WriteLine('Today is a good day to die!');
}
WriteLine('Enough battle!');

If run this code would print the line 'Today is a good day to die!' forever and never print the line 'Enough battle'. Luckily when this happens the STNE engine steps in and kills the script.

Do

DO loops work just like WHILE loops except that regardless the evaluation a DO will execute at least once.

VAR friendlyShip AS Boolean = False;
WriteLine('Ship on Federation sensors');
Do(friendlyShip){
  WriteLine('Hale them.');
}
WriteLine('No response. Open fire!');

When this script is run, regardless of the fact that the statement evaluated false it will run once. If something happened inside the statement that made it become true though it would run again.

For

A FOR loop works just like a WHILE loop except it has a built in integer variable which it increments after every loop. This makes it very good for incrementing. Consider our earlier example:

Var ore As integer= 0;
WriteLine('Do you need ore?');
while ((ore < 12)){
  WriteLine('We have ' & ore &' ore. We need more ore!');
  ore = ore + 2;
}
WriteLine('Thanks. We can start making Duranium.');

This could also be written using a FOR loop:

Var ore As integer;
WriteLine('Do you need ore?');
for(ore=0 To 12 Step 2){
  WriteLine('We have ' & ore &' ore. We need more ore!');
}
WriteLine('Thanks. We can start making Duranium.');

See how the incrementation is taken care of in the parameters, or between the parentheses? It takes the integer variable ore from 0 to 12 by sets of 2.

If you do not specify a step it will assume the step is 1.

Chapter 4 - Functions

Introduction

The last object to learn about are functions. A function is a series of lines of code that can be called from main to run again and again. Consider that we have the following code.

WriteLine('Get them out of there!');
WriteLine('Attempting to beam up away-team');

But you want to run that ten times. You could write those two lines ten times or you could make a function. In that way a function can act similar to variables though as you will see they are much more powerful. To create a function you use the following formula 'Function' followed by the name you give it, followed by the symbols "(){}" Here is an example using the code above:

Function BeamUp(){
  WriteLine('Get them out of there!');
  WriteLine('Attempting to beam up away-team');
}

Now every time BeamUp() is called it looks through the entire script for the Function BeamUp() and will run those two lines of code. For example:

WriteLine('We are at the Borg ship.');
BeamUp();
WriteLine('We are at the Klingon colony.');
BeamUp();
Function BeamUp(){
  WriteLine('Get them out of there!');
  WriteLine('Attempting to beam up away-team!');
}
WriteLine('We are at the Syndicate station');
BeamUp();

Parameters

But it gets better. You can pass a function variables making it more versatile. To specify what types of variables a function can be passed you need to declare them between the parenthesis "()". These are called the Functions Parameters. You declare a function in the parameters the same way you do in regular code and you can declare as many variables of any type as you want so long as you separate them by comas. For example

Function BeamUp(number As Int32, crew As Boolean, teamName As String){
  If(crew){
    WriteLine('Beaming up ' & number & ' ' & teamName & '.');
    WriteLine('Attempting to beam up away-team!');
    Else{
      WriteLine('There is nobody there');
    }
  }
} 

For some reason when the compiler checks for errors it replaces the word Integer with Int32. Don't worry. It you write either one your code will still work. Now when you make the function call you need to pass it values that match it's parameters. In the above example you might call it this way:

BeamUp(5, True, Medics);
Function BeamUp(number As Int32, crew As Boolean, teamName As String){
  If(crew){
    WriteLine('Beaming up ' & number & ' ' & teamName & '.');
    WriteLine('Attempting to beam up away-team!');
    Else{
      WriteLine('There is nobody there');
    }
  }
}
WriteLine('We are at the Borg ship.');
BeamUp();
WriteLine('We are at the Klingon colony.');
BeamUp();
WriteLine('We are at the Syndicate station');
BeamUp();

Also for clarity consider keeping your Functions separate from your main code either all above or all bellow.

Now that we now have a few basics, let us turn to the really interesting parts, the control of the game content through scripts.

To interact with ships there is a collection of methods, which can be found in CShipManager. To use them, we must first assign a ShipManager to either a ship or a fleet. This is done via assignment of a new CShipManager variable

Var ShipManager As New CShipManager();

To assign the safety officer, there are the commands:

ShipManager.SelectShip(NCC-Number of Ship);

or,

ShipManager.SelectFleet(ID of Fleet);

This way the ShipManager knows which ship or fleet to interact with.

Syntax:

 CShipManager.TransferToShip(ToShipID, Amount, EBeamResource.Resource)

You just need to replace the parameters with the respective values. Here's an example:

 ShipManager.SelectShip (1);
 ShipManager.TransferToShip (2, 20, EBeamRessource.Food);

Of course, you can also beam from an entire fleet, if your replace ShipManager.SelectShip(1) by ShipManager.SelectFleet(1), Then the script transfers the amount from every ship in a fleet:

 ShipManager.BenutzteFlotte (1);
 ShipManager.TransferToShip (2, 20, EBeamRessource.Food);

With the Ship Managers, you can do the following:

  • Docking and undocking
  • Alert level change
  • Escape from fleets
  • Enter or leave orbit
  • Rename (name As String)
  • Collect deuterium (only with FP)
  • Gather ore (only with FP)
  • Fly (FlyTo() AutoPilot, only with FP)
  • Fly (Using the Fly() method)
  • Tractor beam on / off
  • Beaming
  • Hide
  • Enable / Disable the Replicators
  • Jettison Goods
  • Enable / Disable the Warp Core
  • Wreck extraction
  • And more

For a complete list of the CShipManager features, see Object Explorer.

Next, we will look at some specific features:

Beaming

Syntax:

 CShipManager.TransferToShip(ToShipID, Amount, EBeamResource.Resource)

You just need to replace the parameters with the respective values. Here's an example:

 ShipManager.SelectShip (1);
 ShipManager.TransferToShip (2, 20, EBeamRessource.Food);

Of course, you can also beam from an entire fleet, if your replace ShipManager.SelectShip(1) by ShipManager.SelectFleet(1), Then the script transfers the amount from every ship in a fleet:

 ShipManager.SelectFleet (1);
 ShipManager.TransferToShip (2, 20, EBeamRessource.Food);

Flying

There are two versions of flying, CShipManager.FlyTo() (For players with the Feature-Pack), and CShipManager.Fly() (Works for everyone). FlyTo() is an auto pilot, like the helm control with FP, while Fly() moves you a number of sectors in a straight line.

Flying with the Autopilot

Only for players with the feature pack!


The command:

 ShipManager.FlyTo ('xxx | yyy');

Again, it you need to replace the italicized parameter 'xxx | yyy' with something appropriate. Here is an example:

ShipManager.SelectShip(1);
ShipManager.FlyTo('123|465');

Or, with a fleet:

ShipManager.SelectFleet(1);
ShipManager.FlyTo('123|465');

With this command, the ship or fleet flew through space to the destination, using the auto pilot to bypass NPC Areas, energy-intensive obstacles, and those which endanger the ship or the crew

Flying without the Autopilot

The command for this is as follows:

 ShipManager.Fly (distance,EShipDirection.Direction);

Here is an example:

 ShipManager.SelectShip (1);
 ShipManager.Fly (5, EShipDirection.Up);
 ShipManager.Fly (8, EShipDirection.Left);

or if you wanted to move an entire fleet:

 ShipManager.SelectFleet (1);
 ShipManager.Fly (5, EShipDirection.Up);
 ShipManager.Fly (8, EShipDirection.Left);

Please note, Fly() will NOT avoid dangerous areas, it will fly in a straight line though Nebulas etc.

Schiffsystem nutzen

kommt noch

An alternative to using the Ship Manager: Ship Action

The objects CMyShip (not CShip) And CMyFleet can access methods of the Ship Manager directly via the Action method of the object.

VAR Ship AS CMyShip = new CMyShip( 1 );
Ship.Action.Undock();
VAR Fleet AS CMyFleet = new CMyFleet( 1 );
Fleet.Action.Undock();

Enumeration ist Alles

kommt noch

Methods

Anything that you would want to do more than one time can be grouped into scripting methods. A scripting method is essentially a function or a procedure (The difference between a function and a procedure being that a function returns a value. A procedure does not.)

// This would be considered a procedure, as it returns no value
Function ShowCoords (x As Integer, y As Integer)
{
   WriteLine (CStr(x) + '|' + CStr(y));
}
 

The method ShowCoords can then be called in the script as follows:

ShowCoords (3, 4);
ShowCoords (ship.MapPosition.X, ship.MapPosition.Y);
 

If calculated values are to be returned by the method:

// This is a function, as it returns a value
Function distance (x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer
{
   Var As Integer distance;
  
   distance = Math.abs (x1 - x2) + Math.abs (y1 - y2);
   Return distance;
}

WriteLine (distance (1, 1, 5, 5));

Simple types are always passed by value (the value assigned to the variable is pushed onto the stack before calling the method). Examples of a simple type are Integer, Double, Char. This means that you don't change their values in the calling method. Complex types (such as Classes, Strings, Dates, Objects) are passed by reference (as attempting to pass such by value is very memory intensive unnecessarily, so the address of the variable is pushed onto the stack instead), so if you change the value of a complex type from a called function, it changes the value in the calling function as well.

For Classes or methods that need to be consistent and available from multiple scripts, There is the scripting pragma #Include. The syntax is as follows:

#Include ScriptName = 'The Name of the included script', FromUser = 'Server-UserID';

So something like:

#Include ScriptName = 'My Coordinate Methods', FromUser = 'En1-123456';

Keep in mind, that a variable or a method can only be declared once, so if you define something in the include, its name must be unique.

Classes

To encapsulate both data and functions within a single object, you can use classes. The benefits of classes are that they can reuse variable names (variables are scoped within the class), You can make your code more self documenting, and they are easily included with a minim of name space clashes (you're less likely to use the same for a variable or function within the same name space scope).

 
Class CCoords
{
   Var x As Integer;
   Var y Integer;
  
   New Function (x As Integer, y As Integer)
   {
     This.x = x;
     This.y = y;
   }
  
   ToString () As String
   {
     Return (CStr (x) + '|' + CStr (y);
   }
  
   Function distance (coord As CCoords) As Integer
   {
     Return Math.Abs ??(x - coord.x) + Math.abs (y - coord.y);
   }
}

Var ko1 As New CCoords (3, 5);
Var ko2 As CCoords;

ko2 = New CKoords(8, 9);
WriteLine ('Distance from' ko1.ToString + () + 'for' + ko2.ToString () + ': ' + CStr (ko1.distance (ko2)));
 

Important: classes always need a new () method, otherwise a new object of class will be generated! Worse, you won't be able to have multiple instances of the class. This is fine if you are creating a static class, but this is rarely the case. If you don't need to send any parameters to initialize the object, you can create an empty New method:

 
Class Coords2 
{
  Function New()
  {
    ; // NOP (No Operation) instruction, does nothing
  }
 ...
}
 

You can also call methods statically from any context by prefixing the class name:

 
Class Coords3 
{
  Function NotTrue() As Boolean 
  {
    Return False;
  }
}

Var MyFalse As Boolean = Coords3.NotTrue;
 

The above is also an example of a read only object property. You can get the value multiple times, but you can never change it. This is useful in some instances. Finally, The class can access a method within the class, but you have to prefix either the class name for a static value, or use the This pointer to access dynamic data:

Class CCoords
{
   Var x As Integer;
   Var y Integer;
  
   New Function (x As Integer, y As Integer)
   {
     This.x = x;
     This.y = y;
   }
    
   ToString () As String
   {
     Return (CStr (x) + '|' + CStr (y);
   }
  
   Function distance (coord As CCoords) As Integer
   {
     Return Math.Abs ??(x - coord.x) + Math.abs (y - coord.y);
   }
   // Method added to Coords
   Function GetPoint() As SPoint {
     Return SPoint.FromString(This.ToString());
   }
}
 

If you try and access the method GetPoint statically, you will generate a run time error. If the method GetPoint did not use the This pointer, the code would look for ToString in the script global name space, and generate a compile time error.

Authors

Nickname IG-ID Chapter
WiZz4Rd DE1-16475 Chapter 1, Chapter 2, Chapter 4
Stryke DE1-28885 Preface, Chapter 3, Chapter 4
Xenon DE1-10127 Corrector & Chapter 1 revision
Fling DE1-54865 Chapter 7, Chapter 8

Translators

Nickname IG-ID Chapter
Cs.temp.mail Unknown Preface, Chapter 1, Chapter 2, Chapter 3, Chapter 4
Miltiades EN1-56599 Chapter 4, Chapter 6, Chapter 7
Glest Durnham EN1-6609 Corrector