<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.en.stne.net/skins/common/feed.css?270"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wiki.en.stne.net/index.php?feed=atom&amp;target=Miltiades&amp;title=Special%3AContributions%2FMiltiades</id>
		<title>STNE Wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.en.stne.net/index.php?feed=atom&amp;target=Miltiades&amp;title=Special%3AContributions%2FMiltiades"/>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Special:Contributions/Miltiades"/>
		<updated>2026-05-14T00:14:18Z</updated>
		<subtitle>From STNE Wiki</subtitle>
		<generator>MediaWiki 1.16.0</generator>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:InfoBar_Links</id>
		<title>Scripting:InfoBar Links</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:InfoBar_Links"/>
				<updated>2012-05-22T06:18:24Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Understanding InfoBar Links&lt;br /&gt;
&lt;br /&gt;
&amp;lt;B&amp;gt;IMPORTANT NOTICE:&amp;lt;/B&amp;gt;&lt;br /&gt;
The CHtmlControl object, as of this time, is broke, and will display extra text most times that it is used (e.g you get &amp;amp;lt; class=&amp;quot;&amp;quot; title=&amp;quot;&amp;quot; id=&amp;quot;&amp;quot;&amp;amp;gt; in front of the desired output). For this reason, if at all possible use CHtmlDiv or CHtmlSpan objects instead. These objects can still be passed in and out as CHtmlControl, and there are no serious drawbacks to using specific types in most circumstances. In the case that you get a CHtmlControl object from the system, it looks like it terminates correctly, so you can use the assignment shown in this guide without any adverse affects.&lt;br /&gt;
&lt;br /&gt;
The STNE engine allows for extensions accessible for the 'InfoBar', an area at the top of the UI (user interface) primary pane. The intent it seems is to allow extensibility to the UI, and allow a certain level of customizations. These could include notes, coordinates, a list alliance members, etc. The InfoBar itself you have probably seen, it is the area where [You have a new message] appears. &lt;br /&gt;
&lt;br /&gt;
To understand how to create an InfoBar application, one must first understand how it actually manages to get to the UI. This is done by CallBack methods. A callback is similar to system signal handlers in concept. When you tell the script to 'hook' a callback, it is added to a list of code to process every time that callback happens (with the exception that unlike a system signal, it can be pre filtered). A script can only hook a specific callback once, so if you need to have 3 individual methods happen for a particular callback event, you add them to a single function and call them all from there (In a normal driver or signal handler, you would not call the handler from a class, and this is good methodology to follow even with scripts) The following is an example of callback handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function RegisterHooks() {&lt;br /&gt;
  ScriptContext.EnableExtension();&lt;br /&gt;
  ScriptContext.RegisterEvent(EGuiEventType.InfoBarAfterCreate, AddressOf CB_InfoBarAfterCreate);&lt;br /&gt;
  ScriptContext.ActivateEvents();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function CB_InfoBarAfterCreate(CBEvent As CGuiEventOnInfoBarAfterCreate) {&lt;br /&gt;
  // processing for event goes here, create the link, the output, etc.&lt;br /&gt;
  Var LinkItem As String = &amp;quot;my_infobar_app&amp;quot;;&lt;br /&gt;
  Var Div As CHtmlDiv;&lt;br /&gt;
  InfoBarLink(CBEvent, LinkItem);&lt;br /&gt;
  Div = InfoBarDiv(CBEvent, LinkItem);&lt;br /&gt;
  Div.Style.Add('display', 'none'); &lt;br /&gt;
  Div.Add(&amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RegisterHooks();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
RegisterHooks is a function called from the main body of the script, and the function itself handles adding the entry point onto the callback stack. Firstly, it sets up for being an extension via EnableExtensions. Next, it adds a handler to the callback stack, giving the code reference via AddressOf. Lastly, it lets the script engine know it's ready to handle events. Normally you will have any validation (checking data storage, initializing variables, etc) happening between EnableExtension and RegisterEvent. This function is called only at script initialization, which should be when you click on “Execute Script”, but experience tells me it gets called occasionally in other circumstances (the script seems to like to run from the main body after an STNE restart).&lt;br /&gt;
&lt;br /&gt;
Once you have the callback hooked, you need the InfoBar link. For an InfoBar application to work, it needs two more components, other than the output. The first is a clickable link item, which usually contains the name of the script. The other is an area upon which to place your actual output. While the output can be appended from a different callback method, this is not the usual case. Firstly, set up the link:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function InfoBarLink(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) {&lt;br /&gt;
  Var InfoBarAlignRight As Boolean = True;&lt;br /&gt;
  Var UrlCon As CHtmlControl;&lt;br /&gt;
  Var LinkText As String = &amp;quot;My InfoBar App&amp;quot;;&lt;br /&gt;
  // Create the app bar link&lt;br /&gt;
  Var Url As CJsAction = CUrlBuilder.JsToggleElement(LinkItem);&lt;br /&gt;
  UrlCon = CControlBuilder.BracketLink(Url, LinkText);&lt;br /&gt;
  Var UrlSmall As New CHtmlSmall();&lt;br /&gt;
  UrlSmall.Add(UrlCon)&lt;br /&gt;
  CBEvent.CreateItem(InfoBarAlignRight).Add(UrlSmall.GuiControl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively, you can use an HTML div to do the same job, as it can hold a CHtmlControl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function InfoBarLink(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) {&lt;br /&gt;
  Var InfoBarAlignRight As Boolean = True;&lt;br /&gt;
  Var UrlCon As New CHtmlDiv(); // Div instead of control, and instiated&lt;br /&gt;
  Var LinkText As String = &amp;quot;My InfoBar App&amp;quot;;&lt;br /&gt;
  // Create the app bar link&lt;br /&gt;
  Var Url As CJsAction = CUrlBuilder.JsToggleElement(LinkItem);&lt;br /&gt;
  UrlCon.Add(CControlBuilder.BracketLink(Url, LinkText)); // Added to div rather than assigned to a control&lt;br /&gt;
  Var UrlSmall As New CHtmlSmall();&lt;br /&gt;
  UrlSmall.Add(UrlCon)&lt;br /&gt;
  CBEvent.CreateItem(InfoBarAlignRight).Add(UrlSmall.GuiControl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This function simply sets up a toggle-able link on the InfoBar... It does not actually display anything other than the link, and clicking on it will do nothing, because no data is attached to it. The first line declares the function, and expects the first passed parameter to be of type  CGuiEventOnInfoBarAfterCreate, which is itself a child of the class CGuiEvent. CGuiEvent could be used instead, if this handler was to process multiple callbacks, but you loose accessibility to anything specific to the child (unless you cast it back to it's particular type). The declaration of InfoBarAlignRight is for clarity. If it was false, it would align on the left. LinkText is literally the text the link will have. JsToggleElement is how the UI adds the javascript code to toggle the output (a div tag) between visible and hidden. BracketLink adds [ and ] around the text. CHtmlSmall applies the small HTML tag to the link. The CreateItem is how the script adds the newly created link into the UI, on the InfoBar.&lt;br /&gt;
&lt;br /&gt;
Now that we have the link, we need to add the output area for the link. This is done by creating a layered div tag. Why layered? So the output stays precisely where you want it, and it actually hides when necessary. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function InfoBarDiv(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) As CHtmlDiv {&lt;br /&gt;
  Var BorderColor As String = &amp;quot;#16344E&amp;quot;;&lt;br /&gt;
  Var OuterDiv As New CHtmlDiv();&lt;br /&gt;
  Var Div As New CHtmlDiv();&lt;br /&gt;
  &lt;br /&gt;
  CBEvent.Page.Body.Controls.Insert(0, OuterDiv.GuiControl);&lt;br /&gt;
  OuterDiv.Style.Add('position', 'absolute');&lt;br /&gt;
  OuterDiv.Width = '99%';&lt;br /&gt;
  OuterDiv.Style.Add('z-index', '255'); &lt;br /&gt;
  &lt;br /&gt;
  OuterDiv.Add(Div);&lt;br /&gt;
  Div.Style.Add('position', 'absolute');&lt;br /&gt;
  Div.Style.Add('top', '0');&lt;br /&gt;
  Div.Style.Add('right', '0');&lt;br /&gt;
  Div.Style.Add('z-index', '255');&lt;br /&gt;
  Div.Style.Add('background-color', 'black');&lt;br /&gt;
  Div.Style.Add('border-style', 'solid');&lt;br /&gt;
  Div.Style.Add('border-color', BorderColor);&lt;br /&gt;
  Div.Style.Add('border-width', '1px');&lt;br /&gt;
  Div.ID = LinkItem; &lt;br /&gt;
  Return Div;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually the InfoBar creation and the div creation are in the same function or method, but for purposes of example I have split them into two functions. The first part is the setup and assignment. LinkItem is the name of the inner div, and it is usually similar to the link name. Keep in mind that if you create two scripts and name the div the same, they will both appear and hide when either script link is toggled, so you want the inner div name to be unique. The middle of the function sets up the inner div output area. The width is 1% short of maximum, because some browsers (notably Opera) tend to cut the right border off if it is 100%. The Z-Index ensures it's appears above normal output. The last part of the function sets up the inner div, with a black background and the standard STNE blue border 1 pixel wide. The alignment for the output is top right of the outer div, which is created just below the InfoBar. The output is adjusted to the smallest possible area that still displays the output. The following is the entire script:&lt;br /&gt;
&lt;br /&gt;
Now, you may ask yourself, why the z-index assignment? On the inner div, it is for completeness more than anything else, since there is only one inner div. If there were multiple divs, you would be telling the parser who lays over whom, or who to stack next to who. For the outer div, it's a little more particular, since any div with the same z index will not overlay another of the same index (it displays as well as it can next to or around), and will stack over/under other levels of z index.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#UseInterface Web, Gui;&lt;br /&gt;
&lt;br /&gt;
Function InfoBarLink(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) {&lt;br /&gt;
  Var InfoBarAlignRight As Boolean = True;&lt;br /&gt;
  Var UrlCon As CHtmlControl;&lt;br /&gt;
  Var LinkText As String = &amp;quot;My InfoBar App&amp;quot;;&lt;br /&gt;
  // Create the app bar link&lt;br /&gt;
  Var Url As CJsAction = CUrlBuilder.JsToggleElement(LinkItem);&lt;br /&gt;
  UrlCon = CControlBuilder.BracketLink(Url, LinkText);&lt;br /&gt;
  Var UrlSmall As New CHtmlSmall();&lt;br /&gt;
  UrlSmall.Add(UrlCon)&lt;br /&gt;
  CBEvent.CreateItem(InfoBarAlignRight).Add(UrlSmall.GuiControl);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function InfoBarDiv(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) As CHtmlDiv {&lt;br /&gt;
  Var BorderColor As String = &amp;quot;#16344E&amp;quot;;&lt;br /&gt;
  Var OuterDiv As New CHtmlDiv();&lt;br /&gt;
  Var Div As New CHtmlDiv();&lt;br /&gt;
  &lt;br /&gt;
  CBEvent.Page.Body.Controls.Insert(0, OuterDiv.GuiControl);&lt;br /&gt;
  OuterDiv.Style.Add('position', 'absolute');&lt;br /&gt;
  OuterDiv.Width = '99%';&lt;br /&gt;
  OuterDiv.Style.Add('z-index', '255'); &lt;br /&gt;
  &lt;br /&gt;
  OuterDiv.Add(Div);&lt;br /&gt;
  Div.Style.Add('position', 'absolute');&lt;br /&gt;
  Div.Style.Add('top', '0');&lt;br /&gt;
  Div.Style.Add('right', '0');&lt;br /&gt;
  Div.Style.Add('z-index', '255');&lt;br /&gt;
  Div.Style.Add('background-color', 'black');&lt;br /&gt;
  Div.Style.Add('border-style', 'solid');&lt;br /&gt;
  Div.Style.Add('border-color', BorderColor);&lt;br /&gt;
  Div.Style.Add('border-width', '1px');&lt;br /&gt;
  Div.ID = LinkItem; &lt;br /&gt;
  Return Div;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Function RegisterHooks() {&lt;br /&gt;
  ScriptContext.EnableExtension();&lt;br /&gt;
  ScriptContext.RegisterEvent(EGuiEventType.InfoBarAfterCreate, AddressOf CB_InfoBarAfterCreate);&lt;br /&gt;
  ScriptContext.ActivateEvents();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function CB_InfoBarAfterCreate(CBEvent As CGuiEventOnInfoBarAfterCreate) {&lt;br /&gt;
  // processing for event goes here, create the link, the output, etc.&lt;br /&gt;
  Var LinkItem As String = &amp;quot;my_infobar_app&amp;quot;;&lt;br /&gt;
  Var Div As CHtmlDiv;&lt;br /&gt;
  InfoBarLink(CBEvent, LinkItem);&lt;br /&gt;
  Div = InfoBarDiv(CBEvent, LinkItem);&lt;br /&gt;
  Div.Style.Add('display', 'none'); // See notes below&lt;br /&gt;
  Div.Add(&amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RegisterHooks();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Normally, at the Div.Add in CB_ InfoBarAfterCreate, you would add your output table or div instead of a text string. Also, you would toggle the output with a URL Parameter, with something like this in CB_ InfoBarAfterCreate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  Var ShowDiv As Boolean = False;&lt;br /&gt;
  // option processing here, usually returning the status of ShowDiv, like Showdiv = ProcessOptions()&lt;br /&gt;
  // … table/div output creation, like Div.Add(function());&lt;br /&gt;
  If (ShowDiv) {&lt;br /&gt;
    Div.Style.Add('display', 'block');&lt;br /&gt;
  } Else {&lt;br /&gt;
    Div.Style.Add('display', 'none');&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
But URL/Form parameter passing and processing is for another tutorial&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 06:19, 9 October 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Incubation_Chamber</id>
		<title>Incubation Chamber</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Incubation_Chamber"/>
				<updated>2011-11-24T11:32:56Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Itemsmenu}}&lt;br /&gt;
{| cellspacing=&amp;quot;0&amp;quot; style=&amp;quot;float:right;margin-left:3em&amp;quot;&lt;br /&gt;
! Incubation Chamber&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | &lt;br /&gt;
http://game.en.stne.net/i/items/1589.gif &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;Incubation Chamber&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-top:0px; border-bottom:0px&amp;quot; | '''When Used'''&lt;br /&gt;
|-&lt;br /&gt;
| class=&amp;quot;nl&amp;quot; style=&amp;quot;padding:0px&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* +1 Crew&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-top:0px; border-bottom:0px&amp;quot; | '''On Installation'''&lt;br /&gt;
|-&lt;br /&gt;
| class=&amp;quot;nl&amp;quot; style=&amp;quot;padding:0px&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; |&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;Item cannot be installed&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! '''Construction Costs'''&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | None&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; |'''Can be found in the &amp;lt;br&amp;gt;[[Debris Field]] of a [[The Syndicat| Syndicat]] ship'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Incubation Chamber'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;An incubation chamber is a kind of artificial womb. In the chamber embryos can grow up to their full size and have ability to survive without needing a surrogate mother. The Borg use similar maturation chamber for drones.&amp;lt;/i&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;b&amp;gt;In these chambers embryos can be grown into a new crew member. Amazingly, It only takes one day. However, at least one crew member must be present, which can operate the incubation chamber.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;Br&amp;gt;&lt;br /&gt;
+1 Crew after a day&lt;br /&gt;
&amp;lt;/b&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;B&amp;gt;Item-Type-ID:&amp;lt;/b&amp;gt; 1589&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Active for: &amp;lt;/b&amp;gt; 24h&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Cool down for: &amp;lt;/b&amp;gt; 24h&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;B&amp;gt;Charges:&amp;lt;/b&amp;gt; -1&amp;lt;br&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;B&amp;gt;Notes:&amp;lt;/b&amp;gt; On use, this item binds to the ship and produces 1 new crew member after 24 hours. It then cools down for 24 hours. so in essence, you get 1 crew member from it every 48 hours. &lt;br /&gt;
&lt;br /&gt;
[[Category:Items]]&lt;br /&gt;
[[Category:Syndicat item (with effect)]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Incubation_Chamber</id>
		<title>Incubation Chamber</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Incubation_Chamber"/>
				<updated>2011-11-23T11:17:43Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Menu}}&lt;br /&gt;
{| cellspacing=&amp;quot;0&amp;quot; style=&amp;quot;float:right;margin-left:3em&amp;quot;&lt;br /&gt;
! Incubation Chamber&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | &lt;br /&gt;
http://game.en.stne.net/i/items/1589.gif &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;Incubation Chamber&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-top:0px; border-bottom:0px&amp;quot; | '''When Used'''&lt;br /&gt;
|-&lt;br /&gt;
| class=&amp;quot;nl&amp;quot; style=&amp;quot;padding:0px&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* +1 Crew&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-top:0px; border-bottom:0px&amp;quot; | '''On Installation'''&lt;br /&gt;
|-&lt;br /&gt;
| class=&amp;quot;nl&amp;quot; style=&amp;quot;padding:0px&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;Item cannot be installed&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! '''Construction Costs'''&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
* none&lt;br /&gt;
Can be found in the [[Debris Field]] of a [[The Syndicat| Syndicat]] ship &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Incubation Chamber'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;An incubation chamber is a kind of artificial womb. In the chamber embryos can grow up to their full size and have ability to survive without needing a surrogate mother. The Borg use similar maturation chamber for drones.&amp;lt;/i&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;b&amp;gt;In these chambers embryos can be grown into a new crew member. Amazingly, It only takes one day. However, at least one crew member must be present, which can operate the incubation chamber.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;Br&amp;gt;&lt;br /&gt;
+1 Crew after a day&lt;br /&gt;
&amp;lt;/b&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;B&amp;gt;Item-ID-Type-ID:&amp;lt;/b&amp;gt; 1589&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Active for: &amp;lt;/b&amp;gt; 24h&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;B&amp;gt;Notes:&amp;lt;/b&amp;gt; On use, this item binds to the ship and produces 1 new crew member every 24 hours. What happens to the item once the ship is full is unknown.&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Incubation_Chamber</id>
		<title>Incubation Chamber</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Incubation_Chamber"/>
				<updated>2011-11-23T10:56:28Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;On use, this item binds to the ship and produces 1 new crew member every 24 hours. What happens to the item once the ship is full is unknown.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Item ID:&amp;lt;/b&amp;gt;271396&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Installable:&amp;lt;/b&amp;gt;No&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;B&amp;gt;Usable:&amp;lt;/b&amp;gt;Yes&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Incubation_Chamber</id>
		<title>Incubation Chamber</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Incubation_Chamber"/>
				<updated>2011-11-23T10:55:58Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;On use, this item binds to the ship and produces 1 new crew member every 24 hours. What happens to the item once the ship is full is unknown.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Item ID:&amp;lt;/b&amp;gt;271396&lt;br /&gt;
&amp;lt;b&amp;gt;Installable:&amp;lt;b&amp;gt;No&lt;br /&gt;
&amp;lt;B&amp;gt;Useable:&amp;lt;/b&amp;gt;Yes&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Incubation_Chamber</id>
		<title>Incubation Chamber</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Incubation_Chamber"/>
				<updated>2011-11-23T10:53:57Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;On use, this item binds to the ship and produces 1 new crew member every 24 hours. What happens to the item once the ship is full is unknown.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Item ID:&amp;lt;/b&amp;gt;271396&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Incubation_Chamber</id>
		<title>Incubation Chamber</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Incubation_Chamber"/>
				<updated>2011-11-23T10:51:18Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: Created page with &amp;quot;On use, this item binds to the ship and produces 1 new crew member every 24 hours. What happens to the item once the ship is full is unknown.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;On use, this item binds to the ship and produces 1 new crew member every 24 hours. What happens to the item once the ship is full is unknown.&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Basic_course</id>
		<title>Scripting:Basic course</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Basic_course"/>
				<updated>2011-11-12T06:00:37Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: /* Classes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedTranslation}}&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
'''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.'''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Vorwort==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Chapter 1 - Strings==&lt;br /&gt;
In programming a String is a series of characters. The chapter title would be a String as would this text. The famous line &amp;quot;Hello World!&amp;quot; is also a String and it is this String you will be working with.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Hello World!&amp;quot; ===&lt;br /&gt;
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 &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
In the STNE engine this is very easy.&lt;br /&gt;
First launch the script editor under:&lt;br /&gt;
Database -&amp;gt; Script Editor -&amp;gt; Create a new script -&amp;gt; Custom script without input wizard&lt;br /&gt;
Then you will click &amp;quot;Edit source code&amp;quot;.&lt;br /&gt;
In the text field provided type: &lt;br /&gt;
&amp;lt;pre&amp;gt;WriteLine('Hello World!');&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now click Save&amp;amp;Run.&lt;br /&gt;
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?&lt;br /&gt;
When it works you should see the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;Hello World!&amp;lt;/pre&amp;gt;&lt;br /&gt;
Congratulations you are now programming. Try making a program that says:&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World!&lt;br /&gt;
Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Your code should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!');&lt;br /&gt;
WriteLine('Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note every line of code ends with a semicolon.&lt;br /&gt;
But what if you want to write everything on one line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World! Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is done by use of the &amp;amp; symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!'&amp;amp;' Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;amp; 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!&lt;br /&gt;
&amp;quot;But wait!&amp;quot; You say. &amp;quot;I could simple code: &amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World! Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt; and never have to deal with the &amp;amp; symbol!&amp;quot;&lt;br /&gt;
True, and as a programmer you will have many choices of different ways to do things. But the '&amp;amp;' is important as you will find out in the next chapter.&lt;br /&gt;
&lt;br /&gt;
===Summary: Strings===&lt;br /&gt;
&lt;br /&gt;
* A String is a sequence of several characters.&lt;br /&gt;
* A String is output, or printed, using the command ''WriteLine();''.&lt;br /&gt;
* You may use the character &amp;amp; to combine one String with another within the parameters, or parentheses, of ''WriteLine();''.&lt;br /&gt;
&lt;br /&gt;
==Chapter 2 - Variables==&lt;br /&gt;
===Basic types===&lt;br /&gt;
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:&lt;br /&gt;
* String  - a series of characters&lt;br /&gt;
* Integer - a whole number&lt;br /&gt;
* Boolean - decision (True/False)&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Imagine you have a gigantic project with hundreds of lines of code. Dozens upon dozens of times your code will output the lines:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains log Stardate:&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
You could code:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Captains log Stardate:');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
every single time and maybe misspell it. Or you could use a variable.&lt;br /&gt;
Before a variable can be used, or called, it must be created. You do this with the word &amp;quot;Var&amp;quot; followed by the name followed by &amp;quot;As&amp;quot; followed by the type of variable it is followed by &amp;quot;=&amp;quot; followed by the data to be stored.&lt;br /&gt;
&lt;br /&gt;
Sound complicated?&lt;br /&gt;
Bear with us.&lt;br /&gt;
&lt;br /&gt;
In keeping with the above example let us declare a String variable that contains the line: 'Captains log Stardate:'&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
No two variables can have the same name though.&lt;br /&gt;
&lt;br /&gt;
Lets create a number, or integer, variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var SD As Integer = 234121;&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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).&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Things start to happen. Cool huh? Just in case your having trouble your code should look like this:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&lt;br /&gt;
Var SD As Integer = 234121;&lt;br /&gt;
WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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 &amp;amp; symbol. It stuck the integer and the string together!&lt;br /&gt;
The output looks like:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate:234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
See if you can find a way to get a space between the colon and the number...&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate: 234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Converting One Data Type to Another===&lt;br /&gt;
In many programming languages including an older version of the STNE engine you often need to convert variables from one type to another.&lt;br /&gt;
For instance if you had a variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;Var number As Integer = 12345;&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You couldn't use it in certain functions like &lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(number);&amp;lt;/pre&amp;gt;&lt;br /&gt;
Because the parameters for WriteLine() would only accept Strings and the variable 'number' is an Integer.&lt;br /&gt;
&lt;br /&gt;
In that case you would use another function CStr() to convert it to a String:&lt;br /&gt;
&amp;lt;Pre&amp;gt;CStr(number)&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You could even place that inside the parameters of WriteLine():&lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(CStr(number));&amp;lt;/Pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Likewise you could covert a String to it's integer value with CInt();&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Rules for Naming Variables===&lt;br /&gt;
There are some rules for naming your variables&lt;br /&gt;
* 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.&lt;br /&gt;
* Do not use spaces. Use capital letters to signify different words. &lt;br /&gt;
* 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.&lt;br /&gt;
* For clear coding consider starting your variable name with a three digits representing the variable type. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;intDeutNeeded&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
===Summary: Variables===&lt;br /&gt;
&lt;br /&gt;
* A variable takes the place of &amp;quot;hard coded&amp;quot; data.&lt;br /&gt;
* To create a variable use 'VAR &amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; AS &amp;lt;b&amp;gt;Datentype&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To assign data to a variable you use ''&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; = &amp;lt;b&amp;gt;Inhalt&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To output a variable use ''WriteLine(&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt;);'' This can be very important when debugging.&lt;br /&gt;
* The ''&amp;amp;'' symbol connects variables withing a  function call''WriteLine();''&lt;br /&gt;
&lt;br /&gt;
==Chapter 3 - Control Structures==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===If - Else===&lt;br /&gt;
This works exactly how it sounds. &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates a statement and when it is true will execute the next few lines of code that are within curly braces &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot;. You can also include an &amp;lt;B&amp;gt;ELSE&amp;lt;/B&amp;gt; statement that will execute when the &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates to false.&lt;br /&gt;
For example this code evaluates a variable and executes the code within the curly braces in response:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var tribbles As Boolean = True;&lt;br /&gt;
If (tribbles){&lt;br /&gt;
  WriteLine('Oh no! The food!');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('The food is safe.');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
 &lt;br /&gt;
You can also use an IF statement to compare amounts. In that case you would use the equal symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var EPSamount As Integer = 44;&lt;br /&gt;
If (EPSamount = 45){&lt;br /&gt;
  WriteLine('We have exactly ' &amp;amp; EPSamount &amp;amp; ' available');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Im givin her all shes got, Cpatain!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
You can also use &amp;quot;&amp;lt;&amp;quot;,&amp;quot;&amp;gt;&amp;quot;,&amp;quot;&amp;lt;=&amp;quot;,&amp;quot;&amp;gt;=&amp;quot; for different types of comparisons. In that order and in English those are called &amp;quot;less then&amp;quot;, &amp;quot;greater then&amp;quot;, &amp;quot;less then or equal to&amp;quot;, and &amp;quot;greater then or equal to&amp;quot;. These can be a little confusing at first so remember the bigger side of the symbol is toward the larger number. &amp;quot;a&amp;lt;b&amp;quot; says that a is less then b. b is greater.&lt;br /&gt;
You can also you the words &amp;quot;AND&amp;quot; and &amp;quot;OR&amp;quot; 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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
If ((dilth&amp;gt;5)AND(deut&amp;gt;10)AND(ANTIM&amp;gt;10)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var dilth AS Boolean = (dilthAmount&amp;gt;5);&lt;br /&gt;
Var deut AS Boolean = (deutAmount&amp;gt;10);&lt;br /&gt;
Var antiM As Boolean = (antiMAmount&amp;gt;10);&lt;br /&gt;
If ((dilth)AND(deut)AND(antiM)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is completely up to you!&lt;br /&gt;
&lt;br /&gt;
===Loops===&lt;br /&gt;
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 &amp;quot;{&amp;quot; &amp;quot;}&amp;quot; but a loop will not exit until the conditions that started become false.&lt;br /&gt;
&lt;br /&gt;
====While====&lt;br /&gt;
Consider the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var isKilingon As Boolean = True;&lt;br /&gt;
while (isKilingon){&lt;br /&gt;
  WriteLine('Today is a good day to die!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Enough battle!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Do====&lt;br /&gt;
DO loops work just like WHILE loops except that regardless the evaluation a DO will execute at least once. &lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
VAR friendlyShip AS Boolean = False;&lt;br /&gt;
WriteLine('Ship on Federation sensors');&lt;br /&gt;
Do(friendlyShip){&lt;br /&gt;
  WriteLine('Hale them.');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('No response. Open fire!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====For====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This could also be written using a FOR loop:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
for(ore=0 To 12 Step 2){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you do not specify a step it will assume the step is 1.&lt;br /&gt;
&lt;br /&gt;
==Chapter 4 - Functions==&lt;br /&gt;
===Introduction===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('Get them out of there!');&lt;br /&gt;
WriteLine('Attempting to beam up away-team');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
But you want to run that ten times.&lt;br /&gt;
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.&lt;br /&gt;
To create a function you use the following formula 'Function' followed by the name you give it, followed by the symbols &amp;quot;(){}&amp;quot;&lt;br /&gt;
Here is an example using the code above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Parameters===&lt;br /&gt;
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 &amp;quot;()&amp;quot;. 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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
Now when you make the function call you need to pass it values that match it's parameters.&lt;br /&gt;
In the above example you might call it this way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
BeamUp(5, True, Medics);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also for clarity consider keeping your Functions separate from your main code either all above or all bellow.&lt;br /&gt;
&lt;br /&gt;
Now that we now have a few basics, let us turn to the really interesting parts, the control of the game content through scripts.&lt;br /&gt;
&lt;br /&gt;
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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Var ShipManager As New CShipManager();&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To assign the safety officer, there are the commands:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectShip(NCC-Number of Ship);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
or,&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectFleet(ID of Fleet);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way the ShipManager knows which ship or fleet to interact with.&lt;br /&gt;
&lt;br /&gt;
Syntax:&lt;br /&gt;
  CShipManager.TransferToShip(&amp;lt;i&amp;gt;ToShipID, Amount, EBeamResource.Resource&amp;lt;/i&amp;gt;)&lt;br /&gt;
You just need to replace the parameters with the respective values. Here's an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
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:&lt;br /&gt;
  ShipManager.BenutzteFlotte (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
&lt;br /&gt;
With the Ship Managers, you can do the following:&lt;br /&gt;
* Docking and undocking&lt;br /&gt;
* Alert level change&lt;br /&gt;
* Escape from fleets&lt;br /&gt;
* Enter or leave orbit&lt;br /&gt;
* Rename (name As String)&lt;br /&gt;
* Collect deuterium (only with FP)&lt;br /&gt;
* Gather ore (only with FP)&lt;br /&gt;
* Fly (FlyTo() AutoPilot, only with FP)&lt;br /&gt;
* Fly (Using the Fly() method)&lt;br /&gt;
* Tractor beam on / off&lt;br /&gt;
* Beaming&lt;br /&gt;
* Hide&lt;br /&gt;
* Enable / Disable the Replicators&lt;br /&gt;
* Jettison Goods &lt;br /&gt;
* Enable / Disable the Warp Core &lt;br /&gt;
* Wreck extraction&lt;br /&gt;
* And more&lt;br /&gt;
&lt;br /&gt;
For a complete list of the CShipManager features, see [http://game.stne.net/ObjectExplorer.aspx?p=CShipManager Object Explorer].&lt;br /&gt;
&lt;br /&gt;
Next, we will look at some specific features:&lt;br /&gt;
&lt;br /&gt;
===Beaming===&lt;br /&gt;
Syntax:&lt;br /&gt;
  CShipManager.TransferToShip(ToShipID, Amount, EBeamResource.Resource)&lt;br /&gt;
You just need to replace the parameters with the respective values. Here's an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
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:&lt;br /&gt;
  ShipManager.SelectFleet (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
&lt;br /&gt;
===Flying===&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Flying with the Autopilot====&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;'''''Only for players with the feature pack!'''''&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The command:&lt;br /&gt;
  ShipManager.FlyTo (&amp;lt;i&amp;gt;'xxx | yyy'&amp;lt;/i&amp;gt;);&lt;br /&gt;
Again, it you need to replace the italicized parameter 'xxx | yyy' with something appropriate. Here is an example:&lt;br /&gt;
 ShipManager.SelectShip(1);&lt;br /&gt;
 ShipManager.FlyTo('123|465');&lt;br /&gt;
Or, with a fleet:&lt;br /&gt;
 ShipManager.SelectFleet(1);&lt;br /&gt;
 ShipManager.FlyTo('123|465');&lt;br /&gt;
 &lt;br /&gt;
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&lt;br /&gt;
&lt;br /&gt;
====Flying without the Autopilot====&lt;br /&gt;
The command for this is as follows:&lt;br /&gt;
  ShipManager.Fly (''distance'',''EShipDirection.Direction'');&lt;br /&gt;
Here is an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.Fly (5, EShipDirection.Up);&lt;br /&gt;
  ShipManager.Fly (8, EShipDirection.Left);&lt;br /&gt;
or if you wanted to move an entire fleet:&lt;br /&gt;
  ShipManager.SelectFleet (1);&lt;br /&gt;
  ShipManager.Fly (5, EShipDirection.Up);&lt;br /&gt;
  ShipManager.Fly (8, EShipDirection.Left);&lt;br /&gt;
&lt;br /&gt;
Please note, Fly() will &amp;lt;B&amp;gt;NOT&amp;lt;/b&amp;gt; avoid dangerous areas, it will fly in a straight line though Nebulas etc.&lt;br /&gt;
&lt;br /&gt;
===Schiffsystem nutzen===&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
=== An alternative to using the Ship Manager: Ship Action ===&lt;br /&gt;
&lt;br /&gt;
The objects CMyShip (not CShip) And CMyFleet can access methods of the Ship Manager directly via the Action method of the object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Ship AS CMyShip = new CMyShip( 1 );&lt;br /&gt;
Ship.Action.Undock();&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Fleet AS CMyFleet = new CMyFleet( 1 );&lt;br /&gt;
Fleet.Action.Undock();&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Enumeration ist Alles==&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
== Methods ==&lt;br /&gt;
&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
// This would be considered a procedure, as it returns no value&lt;br /&gt;
Function ShowCoords (x As Integer, y As Integer)&lt;br /&gt;
{&lt;br /&gt;
   WriteLine (CStr(x) + '|' + CStr(y));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
The method ShowCoords can then be called in the script as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
ShowCoords (3, 4);&lt;br /&gt;
ShowCoords (ship.MapPosition.X, ship.MapPosition.Y);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
If calculated values are to be returned by the method:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
// This is a function, as it returns a value&lt;br /&gt;
Function distance (x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer&lt;br /&gt;
{&lt;br /&gt;
   Var As Integer distance;&lt;br /&gt;
  &lt;br /&gt;
   distance = Math.abs (x1 - x2) + Math.abs (y1 - y2);&lt;br /&gt;
   Return distance;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine (distance (1, 1, 5, 5));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;#Include ScriptName = 'The Name of the included script', FromUser = 'Server-UserID';&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;#Include ScriptName = 'My Coordinate Methods', FromUser = 'En1-123456';&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Classes ==&lt;br /&gt;
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). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Class CCoords&lt;br /&gt;
{&lt;br /&gt;
   Var x As Integer;&lt;br /&gt;
   Var y Integer;&lt;br /&gt;
  &lt;br /&gt;
   New Function (x As Integer, y As Integer)&lt;br /&gt;
   {&lt;br /&gt;
     This.x = x;&lt;br /&gt;
     This.y = y;&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   ToString () As String&lt;br /&gt;
   {&lt;br /&gt;
     Return (CStr (x) + '|' + CStr (y);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   Function distance (coord As CCoords) As Integer&lt;br /&gt;
   {&lt;br /&gt;
     Return Math.Abs ??(x - coord.x) + Math.abs (y - coord.y);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var ko1 As New CCoords (3, 5);&lt;br /&gt;
Var ko2 As CCoords;&lt;br /&gt;
&lt;br /&gt;
ko2 = New CKoords(8, 9);&lt;br /&gt;
WriteLine ('Distance from' ko1.ToString + () + 'for' + ko2.ToString () + ': ' + CStr (ko1.distance (ko2)));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt; &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Class Coords2 &lt;br /&gt;
{&lt;br /&gt;
  Function New()&lt;br /&gt;
  {&lt;br /&gt;
    ; // NOP (No Operation) instruction, does nothing&lt;br /&gt;
  }&lt;br /&gt;
 ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also call methods statically from any context by prefixing the class name:&lt;br /&gt;
&amp;lt;pre&amp;gt; &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Class Coords3 &lt;br /&gt;
{&lt;br /&gt;
  Function NotTrue() As Boolean &lt;br /&gt;
  {&lt;br /&gt;
    Return False;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var MyFalse As Boolean = Coords3.NotTrue;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Class CCoords&lt;br /&gt;
{&lt;br /&gt;
   Var x As Integer;&lt;br /&gt;
   Var y Integer;&lt;br /&gt;
  &lt;br /&gt;
   New Function (x As Integer, y As Integer)&lt;br /&gt;
   {&lt;br /&gt;
     This.x = x;&lt;br /&gt;
     This.y = y;&lt;br /&gt;
   }&lt;br /&gt;
    &lt;br /&gt;
   ToString () As String&lt;br /&gt;
   {&lt;br /&gt;
     Return (CStr (x) + '|' + CStr (y);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   Function distance (coord As CCoords) As Integer&lt;br /&gt;
   {&lt;br /&gt;
     Return Math.Abs ??(x - coord.x) + Math.abs (y - coord.y);&lt;br /&gt;
   }&lt;br /&gt;
   // Method added to Coords&lt;br /&gt;
   Function GetPoint() As SPoint {&lt;br /&gt;
     Return SPoint.FromString(This.ToString());&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Autoren==&lt;br /&gt;
(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 ;)])&lt;br /&gt;
{|&lt;br /&gt;
!Nickname&lt;br /&gt;
!IG-id&lt;br /&gt;
!Kapitel&lt;br /&gt;
|-&lt;br /&gt;
|WiZz4Rd&lt;br /&gt;
|16475&lt;br /&gt;
|Kapitel 1, Kapitel 2, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|Stryke&lt;br /&gt;
|28885&lt;br /&gt;
|Vorwort, Kapitel 3, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|[[Spieler:Xenon|Xenon]]&lt;br /&gt;
|10127&lt;br /&gt;
|Korrektur &amp;amp; Überarbeitung Kapitel 1&lt;br /&gt;
|-&lt;br /&gt;
|Fling&lt;br /&gt;
|54865&lt;br /&gt;
|Kapitel 7, Kapitel 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Scripting-Hilfe|Anfängerkurs]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Basic_course</id>
		<title>Scripting:Basic course</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Basic_course"/>
				<updated>2011-11-12T05:26:16Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: /* Methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedTranslation}}&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
'''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.'''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Vorwort==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Chapter 1 - Strings==&lt;br /&gt;
In programming a String is a series of characters. The chapter title would be a String as would this text. The famous line &amp;quot;Hello World!&amp;quot; is also a String and it is this String you will be working with.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Hello World!&amp;quot; ===&lt;br /&gt;
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 &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
In the STNE engine this is very easy.&lt;br /&gt;
First launch the script editor under:&lt;br /&gt;
Database -&amp;gt; Script Editor -&amp;gt; Create a new script -&amp;gt; Custom script without input wizard&lt;br /&gt;
Then you will click &amp;quot;Edit source code&amp;quot;.&lt;br /&gt;
In the text field provided type: &lt;br /&gt;
&amp;lt;pre&amp;gt;WriteLine('Hello World!');&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now click Save&amp;amp;Run.&lt;br /&gt;
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?&lt;br /&gt;
When it works you should see the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;Hello World!&amp;lt;/pre&amp;gt;&lt;br /&gt;
Congratulations you are now programming. Try making a program that says:&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World!&lt;br /&gt;
Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Your code should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!');&lt;br /&gt;
WriteLine('Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note every line of code ends with a semicolon.&lt;br /&gt;
But what if you want to write everything on one line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World! Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is done by use of the &amp;amp; symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!'&amp;amp;' Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;amp; 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!&lt;br /&gt;
&amp;quot;But wait!&amp;quot; You say. &amp;quot;I could simple code: &amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World! Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt; and never have to deal with the &amp;amp; symbol!&amp;quot;&lt;br /&gt;
True, and as a programmer you will have many choices of different ways to do things. But the '&amp;amp;' is important as you will find out in the next chapter.&lt;br /&gt;
&lt;br /&gt;
===Summary: Strings===&lt;br /&gt;
&lt;br /&gt;
* A String is a sequence of several characters.&lt;br /&gt;
* A String is output, or printed, using the command ''WriteLine();''.&lt;br /&gt;
* You may use the character &amp;amp; to combine one String with another within the parameters, or parentheses, of ''WriteLine();''.&lt;br /&gt;
&lt;br /&gt;
==Chapter 2 - Variables==&lt;br /&gt;
===Basic types===&lt;br /&gt;
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:&lt;br /&gt;
* String  - a series of characters&lt;br /&gt;
* Integer - a whole number&lt;br /&gt;
* Boolean - decision (True/False)&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Imagine you have a gigantic project with hundreds of lines of code. Dozens upon dozens of times your code will output the lines:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains log Stardate:&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
You could code:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Captains log Stardate:');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
every single time and maybe misspell it. Or you could use a variable.&lt;br /&gt;
Before a variable can be used, or called, it must be created. You do this with the word &amp;quot;Var&amp;quot; followed by the name followed by &amp;quot;As&amp;quot; followed by the type of variable it is followed by &amp;quot;=&amp;quot; followed by the data to be stored.&lt;br /&gt;
&lt;br /&gt;
Sound complicated?&lt;br /&gt;
Bear with us.&lt;br /&gt;
&lt;br /&gt;
In keeping with the above example let us declare a String variable that contains the line: 'Captains log Stardate:'&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
No two variables can have the same name though.&lt;br /&gt;
&lt;br /&gt;
Lets create a number, or integer, variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var SD As Integer = 234121;&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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).&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Things start to happen. Cool huh? Just in case your having trouble your code should look like this:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&lt;br /&gt;
Var SD As Integer = 234121;&lt;br /&gt;
WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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 &amp;amp; symbol. It stuck the integer and the string together!&lt;br /&gt;
The output looks like:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate:234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
See if you can find a way to get a space between the colon and the number...&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate: 234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Converting One Data Type to Another===&lt;br /&gt;
In many programming languages including an older version of the STNE engine you often need to convert variables from one type to another.&lt;br /&gt;
For instance if you had a variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;Var number As Integer = 12345;&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You couldn't use it in certain functions like &lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(number);&amp;lt;/pre&amp;gt;&lt;br /&gt;
Because the parameters for WriteLine() would only accept Strings and the variable 'number' is an Integer.&lt;br /&gt;
&lt;br /&gt;
In that case you would use another function CStr() to convert it to a String:&lt;br /&gt;
&amp;lt;Pre&amp;gt;CStr(number)&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You could even place that inside the parameters of WriteLine():&lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(CStr(number));&amp;lt;/Pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Likewise you could covert a String to it's integer value with CInt();&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Rules for Naming Variables===&lt;br /&gt;
There are some rules for naming your variables&lt;br /&gt;
* 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.&lt;br /&gt;
* Do not use spaces. Use capital letters to signify different words. &lt;br /&gt;
* 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.&lt;br /&gt;
* For clear coding consider starting your variable name with a three digits representing the variable type. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;intDeutNeeded&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
===Summary: Variables===&lt;br /&gt;
&lt;br /&gt;
* A variable takes the place of &amp;quot;hard coded&amp;quot; data.&lt;br /&gt;
* To create a variable use 'VAR &amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; AS &amp;lt;b&amp;gt;Datentype&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To assign data to a variable you use ''&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; = &amp;lt;b&amp;gt;Inhalt&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To output a variable use ''WriteLine(&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt;);'' This can be very important when debugging.&lt;br /&gt;
* The ''&amp;amp;'' symbol connects variables withing a  function call''WriteLine();''&lt;br /&gt;
&lt;br /&gt;
==Chapter 3 - Control Structures==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===If - Else===&lt;br /&gt;
This works exactly how it sounds. &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates a statement and when it is true will execute the next few lines of code that are within curly braces &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot;. You can also include an &amp;lt;B&amp;gt;ELSE&amp;lt;/B&amp;gt; statement that will execute when the &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates to false.&lt;br /&gt;
For example this code evaluates a variable and executes the code within the curly braces in response:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var tribbles As Boolean = True;&lt;br /&gt;
If (tribbles){&lt;br /&gt;
  WriteLine('Oh no! The food!');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('The food is safe.');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
 &lt;br /&gt;
You can also use an IF statement to compare amounts. In that case you would use the equal symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var EPSamount As Integer = 44;&lt;br /&gt;
If (EPSamount = 45){&lt;br /&gt;
  WriteLine('We have exactly ' &amp;amp; EPSamount &amp;amp; ' available');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Im givin her all shes got, Cpatain!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
You can also use &amp;quot;&amp;lt;&amp;quot;,&amp;quot;&amp;gt;&amp;quot;,&amp;quot;&amp;lt;=&amp;quot;,&amp;quot;&amp;gt;=&amp;quot; for different types of comparisons. In that order and in English those are called &amp;quot;less then&amp;quot;, &amp;quot;greater then&amp;quot;, &amp;quot;less then or equal to&amp;quot;, and &amp;quot;greater then or equal to&amp;quot;. These can be a little confusing at first so remember the bigger side of the symbol is toward the larger number. &amp;quot;a&amp;lt;b&amp;quot; says that a is less then b. b is greater.&lt;br /&gt;
You can also you the words &amp;quot;AND&amp;quot; and &amp;quot;OR&amp;quot; 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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
If ((dilth&amp;gt;5)AND(deut&amp;gt;10)AND(ANTIM&amp;gt;10)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var dilth AS Boolean = (dilthAmount&amp;gt;5);&lt;br /&gt;
Var deut AS Boolean = (deutAmount&amp;gt;10);&lt;br /&gt;
Var antiM As Boolean = (antiMAmount&amp;gt;10);&lt;br /&gt;
If ((dilth)AND(deut)AND(antiM)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is completely up to you!&lt;br /&gt;
&lt;br /&gt;
===Loops===&lt;br /&gt;
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 &amp;quot;{&amp;quot; &amp;quot;}&amp;quot; but a loop will not exit until the conditions that started become false.&lt;br /&gt;
&lt;br /&gt;
====While====&lt;br /&gt;
Consider the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var isKilingon As Boolean = True;&lt;br /&gt;
while (isKilingon){&lt;br /&gt;
  WriteLine('Today is a good day to die!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Enough battle!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Do====&lt;br /&gt;
DO loops work just like WHILE loops except that regardless the evaluation a DO will execute at least once. &lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
VAR friendlyShip AS Boolean = False;&lt;br /&gt;
WriteLine('Ship on Federation sensors');&lt;br /&gt;
Do(friendlyShip){&lt;br /&gt;
  WriteLine('Hale them.');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('No response. Open fire!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====For====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This could also be written using a FOR loop:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
for(ore=0 To 12 Step 2){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you do not specify a step it will assume the step is 1.&lt;br /&gt;
&lt;br /&gt;
==Chapter 4 - Functions==&lt;br /&gt;
===Introduction===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('Get them out of there!');&lt;br /&gt;
WriteLine('Attempting to beam up away-team');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
But you want to run that ten times.&lt;br /&gt;
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.&lt;br /&gt;
To create a function you use the following formula 'Function' followed by the name you give it, followed by the symbols &amp;quot;(){}&amp;quot;&lt;br /&gt;
Here is an example using the code above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Parameters===&lt;br /&gt;
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 &amp;quot;()&amp;quot;. 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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
Now when you make the function call you need to pass it values that match it's parameters.&lt;br /&gt;
In the above example you might call it this way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
BeamUp(5, True, Medics);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also for clarity consider keeping your Functions separate from your main code either all above or all bellow.&lt;br /&gt;
&lt;br /&gt;
Now that we now have a few basics, let us turn to the really interesting parts, the control of the game content through scripts.&lt;br /&gt;
&lt;br /&gt;
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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Var ShipManager As New CShipManager();&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To assign the safety officer, there are the commands:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectShip(NCC-Number of Ship);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
or,&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectFleet(ID of Fleet);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way the ShipManager knows which ship or fleet to interact with.&lt;br /&gt;
&lt;br /&gt;
Syntax:&lt;br /&gt;
  CShipManager.TransferToShip(&amp;lt;i&amp;gt;ToShipID, Amount, EBeamResource.Resource&amp;lt;/i&amp;gt;)&lt;br /&gt;
You just need to replace the parameters with the respective values. Here's an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
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:&lt;br /&gt;
  ShipManager.BenutzteFlotte (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
&lt;br /&gt;
With the Ship Managers, you can do the following:&lt;br /&gt;
* Docking and undocking&lt;br /&gt;
* Alert level change&lt;br /&gt;
* Escape from fleets&lt;br /&gt;
* Enter or leave orbit&lt;br /&gt;
* Rename (name As String)&lt;br /&gt;
* Collect deuterium (only with FP)&lt;br /&gt;
* Gather ore (only with FP)&lt;br /&gt;
* Fly (FlyTo() AutoPilot, only with FP)&lt;br /&gt;
* Fly (Using the Fly() method)&lt;br /&gt;
* Tractor beam on / off&lt;br /&gt;
* Beaming&lt;br /&gt;
* Hide&lt;br /&gt;
* Enable / Disable the Replicators&lt;br /&gt;
* Jettison Goods &lt;br /&gt;
* Enable / Disable the Warp Core &lt;br /&gt;
* Wreck extraction&lt;br /&gt;
* And more&lt;br /&gt;
&lt;br /&gt;
For a complete list of the CShipManager features, see [http://game.stne.net/ObjectExplorer.aspx?p=CShipManager Object Explorer].&lt;br /&gt;
&lt;br /&gt;
Next, we will look at some specific features:&lt;br /&gt;
&lt;br /&gt;
===Beaming===&lt;br /&gt;
Syntax:&lt;br /&gt;
  CShipManager.TransferToShip(ToShipID, Amount, EBeamResource.Resource)&lt;br /&gt;
You just need to replace the parameters with the respective values. Here's an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
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:&lt;br /&gt;
  ShipManager.SelectFleet (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
&lt;br /&gt;
===Flying===&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Flying with the Autopilot====&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;'''''Only for players with the feature pack!'''''&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The command:&lt;br /&gt;
  ShipManager.FlyTo (&amp;lt;i&amp;gt;'xxx | yyy'&amp;lt;/i&amp;gt;);&lt;br /&gt;
Again, it you need to replace the italicized parameter 'xxx | yyy' with something appropriate. Here is an example:&lt;br /&gt;
 ShipManager.SelectShip(1);&lt;br /&gt;
 ShipManager.FlyTo('123|465');&lt;br /&gt;
Or, with a fleet:&lt;br /&gt;
 ShipManager.SelectFleet(1);&lt;br /&gt;
 ShipManager.FlyTo('123|465');&lt;br /&gt;
 &lt;br /&gt;
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&lt;br /&gt;
&lt;br /&gt;
====Flying without the Autopilot====&lt;br /&gt;
The command for this is as follows:&lt;br /&gt;
  ShipManager.Fly (''distance'',''EShipDirection.Direction'');&lt;br /&gt;
Here is an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.Fly (5, EShipDirection.Up);&lt;br /&gt;
  ShipManager.Fly (8, EShipDirection.Left);&lt;br /&gt;
or if you wanted to move an entire fleet:&lt;br /&gt;
  ShipManager.SelectFleet (1);&lt;br /&gt;
  ShipManager.Fly (5, EShipDirection.Up);&lt;br /&gt;
  ShipManager.Fly (8, EShipDirection.Left);&lt;br /&gt;
&lt;br /&gt;
Please note, Fly() will &amp;lt;B&amp;gt;NOT&amp;lt;/b&amp;gt; avoid dangerous areas, it will fly in a straight line though Nebulas etc.&lt;br /&gt;
&lt;br /&gt;
===Schiffsystem nutzen===&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
=== An alternative to using the Ship Manager: Ship Action ===&lt;br /&gt;
&lt;br /&gt;
The objects CMyShip (not CShip) And CMyFleet can access methods of the Ship Manager directly via the Action method of the object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Ship AS CMyShip = new CMyShip( 1 );&lt;br /&gt;
Ship.Action.Undock();&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Fleet AS CMyFleet = new CMyFleet( 1 );&lt;br /&gt;
Fleet.Action.Undock();&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Enumeration ist Alles==&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
== Methods ==&lt;br /&gt;
&lt;br /&gt;
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.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
// This would be considered a procedure, as it returns no value&lt;br /&gt;
Function ShowCoords (x As Integer, y As Integer)&lt;br /&gt;
{&lt;br /&gt;
   WriteLine (CStr(x) + '|' + CStr(y));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
The method ShowCoords can then be called in the script as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
ShowCoords (3, 4);&lt;br /&gt;
ShowCoords (ship.MapPosition.X, ship.MapPosition.Y);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
If calculated values are to be returned by the method:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
// This is a function, as it returns a value&lt;br /&gt;
Function distance (x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer&lt;br /&gt;
{&lt;br /&gt;
   Var As Integer distance;&lt;br /&gt;
  &lt;br /&gt;
   distance = Math.abs (x1 - x2) + Math.abs (y1 - y2);&lt;br /&gt;
   Return distance;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine (distance (1, 1, 5, 5));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;#Include ScriptName = 'The Name of the included script', FromUser = 'Server-UserID';&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;#Include ScriptName = 'My Coordinate Methods', FromUser = 'En1-123456';&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Klassen==&lt;br /&gt;
&lt;br /&gt;
In Klassen können Daten und Methoden in einem Objekt gekapselt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Class CKoords&lt;br /&gt;
{&lt;br /&gt;
  Var x As Integer;&lt;br /&gt;
  Var y As Integer;&lt;br /&gt;
  &lt;br /&gt;
  Function New(x As Integer, y As Integer)&lt;br /&gt;
  {&lt;br /&gt;
    This.x = x;&lt;br /&gt;
    This.y = y;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function ToString() As String&lt;br /&gt;
  {&lt;br /&gt;
    Return (CStr(x) + '|' + CStr(y);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function Distanz(koord As CKoords) As Integer&lt;br /&gt;
  {&lt;br /&gt;
    Return Math.Abs(x - koord.x) + Math.Abs(y - koord.y);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var ko1 As New CKoords(3, 5);&lt;br /&gt;
Var ko2 As CKoords;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ko2 = New CKoords(8, 9);&lt;br /&gt;
WriteLine('Distanz von ' + ko1.ToString() + ' nach ' + ko2.ToString() + ': ' + CStr(ko1.Distanz(ko2)));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig: Klassen brauchen immer eine Methode New(), sonst kann kein neues Objekt der Klasse generiert werden!&lt;br /&gt;
&lt;br /&gt;
==Autoren==&lt;br /&gt;
(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 ;)])&lt;br /&gt;
{|&lt;br /&gt;
!Nickname&lt;br /&gt;
!IG-id&lt;br /&gt;
!Kapitel&lt;br /&gt;
|-&lt;br /&gt;
|WiZz4Rd&lt;br /&gt;
|16475&lt;br /&gt;
|Kapitel 1, Kapitel 2, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|Stryke&lt;br /&gt;
|28885&lt;br /&gt;
|Vorwort, Kapitel 3, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|[[Spieler:Xenon|Xenon]]&lt;br /&gt;
|10127&lt;br /&gt;
|Korrektur &amp;amp; Überarbeitung Kapitel 1&lt;br /&gt;
|-&lt;br /&gt;
|Fling&lt;br /&gt;
|54865&lt;br /&gt;
|Kapitel 7, Kapitel 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Scripting-Hilfe|Anfängerkurs]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Basic_course</id>
		<title>Scripting:Basic course</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Basic_course"/>
				<updated>2011-11-12T04:55:40Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: /* Alternative to ShipManager: Ship.Action */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedTranslation}}&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
'''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.'''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Vorwort==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Chapter 1 - Strings==&lt;br /&gt;
In programming a String is a series of characters. The chapter title would be a String as would this text. The famous line &amp;quot;Hello World!&amp;quot; is also a String and it is this String you will be working with.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Hello World!&amp;quot; ===&lt;br /&gt;
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 &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
In the STNE engine this is very easy.&lt;br /&gt;
First launch the script editor under:&lt;br /&gt;
Database -&amp;gt; Script Editor -&amp;gt; Create a new script -&amp;gt; Custom script without input wizard&lt;br /&gt;
Then you will click &amp;quot;Edit source code&amp;quot;.&lt;br /&gt;
In the text field provided type: &lt;br /&gt;
&amp;lt;pre&amp;gt;WriteLine('Hello World!');&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now click Save&amp;amp;Run.&lt;br /&gt;
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?&lt;br /&gt;
When it works you should see the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;Hello World!&amp;lt;/pre&amp;gt;&lt;br /&gt;
Congratulations you are now programming. Try making a program that says:&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World!&lt;br /&gt;
Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Your code should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!');&lt;br /&gt;
WriteLine('Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note every line of code ends with a semicolon.&lt;br /&gt;
But what if you want to write everything on one line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World! Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is done by use of the &amp;amp; symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!'&amp;amp;' Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;amp; 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!&lt;br /&gt;
&amp;quot;But wait!&amp;quot; You say. &amp;quot;I could simple code: &amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World! Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt; and never have to deal with the &amp;amp; symbol!&amp;quot;&lt;br /&gt;
True, and as a programmer you will have many choices of different ways to do things. But the '&amp;amp;' is important as you will find out in the next chapter.&lt;br /&gt;
&lt;br /&gt;
===Summary: Strings===&lt;br /&gt;
&lt;br /&gt;
* A String is a sequence of several characters.&lt;br /&gt;
* A String is output, or printed, using the command ''WriteLine();''.&lt;br /&gt;
* You may use the character &amp;amp; to combine one String with another within the parameters, or parentheses, of ''WriteLine();''.&lt;br /&gt;
&lt;br /&gt;
==Chapter 2 - Variables==&lt;br /&gt;
===Basic types===&lt;br /&gt;
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:&lt;br /&gt;
* String  - a series of characters&lt;br /&gt;
* Integer - a whole number&lt;br /&gt;
* Boolean - decision (True/False)&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Imagine you have a gigantic project with hundreds of lines of code. Dozens upon dozens of times your code will output the lines:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains log Stardate:&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
You could code:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Captains log Stardate:');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
every single time and maybe misspell it. Or you could use a variable.&lt;br /&gt;
Before a variable can be used, or called, it must be created. You do this with the word &amp;quot;Var&amp;quot; followed by the name followed by &amp;quot;As&amp;quot; followed by the type of variable it is followed by &amp;quot;=&amp;quot; followed by the data to be stored.&lt;br /&gt;
&lt;br /&gt;
Sound complicated?&lt;br /&gt;
Bear with us.&lt;br /&gt;
&lt;br /&gt;
In keeping with the above example let us declare a String variable that contains the line: 'Captains log Stardate:'&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
No two variables can have the same name though.&lt;br /&gt;
&lt;br /&gt;
Lets create a number, or integer, variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var SD As Integer = 234121;&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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).&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Things start to happen. Cool huh? Just in case your having trouble your code should look like this:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&lt;br /&gt;
Var SD As Integer = 234121;&lt;br /&gt;
WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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 &amp;amp; symbol. It stuck the integer and the string together!&lt;br /&gt;
The output looks like:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate:234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
See if you can find a way to get a space between the colon and the number...&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate: 234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Converting One Data Type to Another===&lt;br /&gt;
In many programming languages including an older version of the STNE engine you often need to convert variables from one type to another.&lt;br /&gt;
For instance if you had a variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;Var number As Integer = 12345;&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You couldn't use it in certain functions like &lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(number);&amp;lt;/pre&amp;gt;&lt;br /&gt;
Because the parameters for WriteLine() would only accept Strings and the variable 'number' is an Integer.&lt;br /&gt;
&lt;br /&gt;
In that case you would use another function CStr() to convert it to a String:&lt;br /&gt;
&amp;lt;Pre&amp;gt;CStr(number)&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You could even place that inside the parameters of WriteLine():&lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(CStr(number));&amp;lt;/Pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Likewise you could covert a String to it's integer value with CInt();&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Rules for Naming Variables===&lt;br /&gt;
There are some rules for naming your variables&lt;br /&gt;
* 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.&lt;br /&gt;
* Do not use spaces. Use capital letters to signify different words. &lt;br /&gt;
* 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.&lt;br /&gt;
* For clear coding consider starting your variable name with a three digits representing the variable type. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;intDeutNeeded&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
===Summary: Variables===&lt;br /&gt;
&lt;br /&gt;
* A variable takes the place of &amp;quot;hard coded&amp;quot; data.&lt;br /&gt;
* To create a variable use 'VAR &amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; AS &amp;lt;b&amp;gt;Datentype&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To assign data to a variable you use ''&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; = &amp;lt;b&amp;gt;Inhalt&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To output a variable use ''WriteLine(&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt;);'' This can be very important when debugging.&lt;br /&gt;
* The ''&amp;amp;'' symbol connects variables withing a  function call''WriteLine();''&lt;br /&gt;
&lt;br /&gt;
==Chapter 3 - Control Structures==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===If - Else===&lt;br /&gt;
This works exactly how it sounds. &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates a statement and when it is true will execute the next few lines of code that are within curly braces &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot;. You can also include an &amp;lt;B&amp;gt;ELSE&amp;lt;/B&amp;gt; statement that will execute when the &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates to false.&lt;br /&gt;
For example this code evaluates a variable and executes the code within the curly braces in response:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var tribbles As Boolean = True;&lt;br /&gt;
If (tribbles){&lt;br /&gt;
  WriteLine('Oh no! The food!');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('The food is safe.');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
 &lt;br /&gt;
You can also use an IF statement to compare amounts. In that case you would use the equal symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var EPSamount As Integer = 44;&lt;br /&gt;
If (EPSamount = 45){&lt;br /&gt;
  WriteLine('We have exactly ' &amp;amp; EPSamount &amp;amp; ' available');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Im givin her all shes got, Cpatain!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
You can also use &amp;quot;&amp;lt;&amp;quot;,&amp;quot;&amp;gt;&amp;quot;,&amp;quot;&amp;lt;=&amp;quot;,&amp;quot;&amp;gt;=&amp;quot; for different types of comparisons. In that order and in English those are called &amp;quot;less then&amp;quot;, &amp;quot;greater then&amp;quot;, &amp;quot;less then or equal to&amp;quot;, and &amp;quot;greater then or equal to&amp;quot;. These can be a little confusing at first so remember the bigger side of the symbol is toward the larger number. &amp;quot;a&amp;lt;b&amp;quot; says that a is less then b. b is greater.&lt;br /&gt;
You can also you the words &amp;quot;AND&amp;quot; and &amp;quot;OR&amp;quot; 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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
If ((dilth&amp;gt;5)AND(deut&amp;gt;10)AND(ANTIM&amp;gt;10)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var dilth AS Boolean = (dilthAmount&amp;gt;5);&lt;br /&gt;
Var deut AS Boolean = (deutAmount&amp;gt;10);&lt;br /&gt;
Var antiM As Boolean = (antiMAmount&amp;gt;10);&lt;br /&gt;
If ((dilth)AND(deut)AND(antiM)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is completely up to you!&lt;br /&gt;
&lt;br /&gt;
===Loops===&lt;br /&gt;
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 &amp;quot;{&amp;quot; &amp;quot;}&amp;quot; but a loop will not exit until the conditions that started become false.&lt;br /&gt;
&lt;br /&gt;
====While====&lt;br /&gt;
Consider the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var isKilingon As Boolean = True;&lt;br /&gt;
while (isKilingon){&lt;br /&gt;
  WriteLine('Today is a good day to die!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Enough battle!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Do====&lt;br /&gt;
DO loops work just like WHILE loops except that regardless the evaluation a DO will execute at least once. &lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
VAR friendlyShip AS Boolean = False;&lt;br /&gt;
WriteLine('Ship on Federation sensors');&lt;br /&gt;
Do(friendlyShip){&lt;br /&gt;
  WriteLine('Hale them.');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('No response. Open fire!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====For====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This could also be written using a FOR loop:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
for(ore=0 To 12 Step 2){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you do not specify a step it will assume the step is 1.&lt;br /&gt;
&lt;br /&gt;
==Chapter 4 - Functions==&lt;br /&gt;
===Introduction===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('Get them out of there!');&lt;br /&gt;
WriteLine('Attempting to beam up away-team');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
But you want to run that ten times.&lt;br /&gt;
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.&lt;br /&gt;
To create a function you use the following formula 'Function' followed by the name you give it, followed by the symbols &amp;quot;(){}&amp;quot;&lt;br /&gt;
Here is an example using the code above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Parameters===&lt;br /&gt;
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 &amp;quot;()&amp;quot;. 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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
Now when you make the function call you need to pass it values that match it's parameters.&lt;br /&gt;
In the above example you might call it this way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
BeamUp(5, True, Medics);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also for clarity consider keeping your Functions separate from your main code either all above or all bellow.&lt;br /&gt;
&lt;br /&gt;
Now that we now have a few basics, let us turn to the really interesting parts, the control of the game content through scripts.&lt;br /&gt;
&lt;br /&gt;
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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Var ShipManager As New CShipManager();&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To assign the safety officer, there are the commands:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectShip(NCC-Number of Ship);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
or,&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectFleet(ID of Fleet);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way the ShipManager knows which ship or fleet to interact with.&lt;br /&gt;
&lt;br /&gt;
Syntax:&lt;br /&gt;
  CShipManager.TransferToShip(&amp;lt;i&amp;gt;ToShipID, Amount, EBeamResource.Resource&amp;lt;/i&amp;gt;)&lt;br /&gt;
You just need to replace the parameters with the respective values. Here's an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
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:&lt;br /&gt;
  ShipManager.BenutzteFlotte (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
&lt;br /&gt;
With the Ship Managers, you can do the following:&lt;br /&gt;
* Docking and undocking&lt;br /&gt;
* Alert level change&lt;br /&gt;
* Escape from fleets&lt;br /&gt;
* Enter or leave orbit&lt;br /&gt;
* Rename (name As String)&lt;br /&gt;
* Collect deuterium (only with FP)&lt;br /&gt;
* Gather ore (only with FP)&lt;br /&gt;
* Fly (FlyTo() AutoPilot, only with FP)&lt;br /&gt;
* Fly (Using the Fly() method)&lt;br /&gt;
* Tractor beam on / off&lt;br /&gt;
* Beaming&lt;br /&gt;
* Hide&lt;br /&gt;
* Enable / Disable the Replicators&lt;br /&gt;
* Jettison Goods &lt;br /&gt;
* Enable / Disable the Warp Core &lt;br /&gt;
* Wreck extraction&lt;br /&gt;
* And more&lt;br /&gt;
&lt;br /&gt;
For a complete list of the CShipManager features, see [http://game.stne.net/ObjectExplorer.aspx?p=CShipManager Object Explorer].&lt;br /&gt;
&lt;br /&gt;
Next, we will look at some specific features:&lt;br /&gt;
&lt;br /&gt;
===Beaming===&lt;br /&gt;
Syntax:&lt;br /&gt;
  CShipManager.TransferToShip(ToShipID, Amount, EBeamResource.Resource)&lt;br /&gt;
You just need to replace the parameters with the respective values. Here's an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
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:&lt;br /&gt;
  ShipManager.SelectFleet (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
&lt;br /&gt;
===Flying===&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Flying with the Autopilot====&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;'''''Only for players with the feature pack!'''''&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The command:&lt;br /&gt;
  ShipManager.FlyTo (&amp;lt;i&amp;gt;'xxx | yyy'&amp;lt;/i&amp;gt;);&lt;br /&gt;
Again, it you need to replace the italicized parameter 'xxx | yyy' with something appropriate. Here is an example:&lt;br /&gt;
 ShipManager.SelectShip(1);&lt;br /&gt;
 ShipManager.FlyTo('123|465');&lt;br /&gt;
Or, with a fleet:&lt;br /&gt;
 ShipManager.SelectFleet(1);&lt;br /&gt;
 ShipManager.FlyTo('123|465');&lt;br /&gt;
 &lt;br /&gt;
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&lt;br /&gt;
&lt;br /&gt;
====Flying without the Autopilot====&lt;br /&gt;
The command for this is as follows:&lt;br /&gt;
  ShipManager.Fly (''distance'',''EShipDirection.Direction'');&lt;br /&gt;
Here is an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.Fly (5, EShipDirection.Up);&lt;br /&gt;
  ShipManager.Fly (8, EShipDirection.Left);&lt;br /&gt;
or if you wanted to move an entire fleet:&lt;br /&gt;
  ShipManager.SelectFleet (1);&lt;br /&gt;
  ShipManager.Fly (5, EShipDirection.Up);&lt;br /&gt;
  ShipManager.Fly (8, EShipDirection.Left);&lt;br /&gt;
&lt;br /&gt;
Please note, Fly() will &amp;lt;B&amp;gt;NOT&amp;lt;/b&amp;gt; avoid dangerous areas, it will fly in a straight line though Nebulas etc.&lt;br /&gt;
&lt;br /&gt;
===Schiffsystem nutzen===&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
=== An alternative to using the Ship Manager: Ship Action ===&lt;br /&gt;
&lt;br /&gt;
The objects CMyShip (not CShip) And CMyFleet can access methods of the Ship Manager directly via the Action method of the object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Ship AS CMyShip = new CMyShip( 1 );&lt;br /&gt;
Ship.Action.Undock();&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Fleet AS CMyFleet = new CMyFleet( 1 );&lt;br /&gt;
Fleet.Action.Undock();&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Enumeration ist Alles==&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
==Methoden==&lt;br /&gt;
&lt;br /&gt;
Öfters wiederkehrende Aufgaben können in Methoden zusammengefasst werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function ShowKoords(x As Integer, y As Integer)&lt;br /&gt;
{&lt;br /&gt;
  WriteLine(CStr(x) + '|' + CStr(y));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Methode ShowKoords kann dann im Script folgendermaßen aufgerufen werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
ShowKoords(3, 4);&lt;br /&gt;
ShowKoords(ship.MapPosition.X,ship.MapPosition.Y);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn berechnete Werte von der Methode zurückgegeben werden sollen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function Distanz(x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer&lt;br /&gt;
{&lt;br /&gt;
  Var distanz As Integer;&lt;br /&gt;
  &lt;br /&gt;
  distanz = Math.Abs(x1 - x2) + Math.Abs(y1 - y2);&lt;br /&gt;
  Return distanz ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine(Distanz(1, 1, 5, 5));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
'ByRef' ist zwar in der Scriptengine vorgesehen und kann angegeben werden, ist aber derzeit ohne Funktion.&lt;br /&gt;
Objekte werden immer ByRef übergeben.&lt;br /&gt;
&lt;br /&gt;
==Klassen==&lt;br /&gt;
&lt;br /&gt;
In Klassen können Daten und Methoden in einem Objekt gekapselt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Class CKoords&lt;br /&gt;
{&lt;br /&gt;
  Var x As Integer;&lt;br /&gt;
  Var y As Integer;&lt;br /&gt;
  &lt;br /&gt;
  Function New(x As Integer, y As Integer)&lt;br /&gt;
  {&lt;br /&gt;
    This.x = x;&lt;br /&gt;
    This.y = y;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function ToString() As String&lt;br /&gt;
  {&lt;br /&gt;
    Return (CStr(x) + '|' + CStr(y);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function Distanz(koord As CKoords) As Integer&lt;br /&gt;
  {&lt;br /&gt;
    Return Math.Abs(x - koord.x) + Math.Abs(y - koord.y);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var ko1 As New CKoords(3, 5);&lt;br /&gt;
Var ko2 As CKoords;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ko2 = New CKoords(8, 9);&lt;br /&gt;
WriteLine('Distanz von ' + ko1.ToString() + ' nach ' + ko2.ToString() + ': ' + CStr(ko1.Distanz(ko2)));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig: Klassen brauchen immer eine Methode New(), sonst kann kein neues Objekt der Klasse generiert werden!&lt;br /&gt;
&lt;br /&gt;
==Autoren==&lt;br /&gt;
(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 ;)])&lt;br /&gt;
{|&lt;br /&gt;
!Nickname&lt;br /&gt;
!IG-id&lt;br /&gt;
!Kapitel&lt;br /&gt;
|-&lt;br /&gt;
|WiZz4Rd&lt;br /&gt;
|16475&lt;br /&gt;
|Kapitel 1, Kapitel 2, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|Stryke&lt;br /&gt;
|28885&lt;br /&gt;
|Vorwort, Kapitel 3, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|[[Spieler:Xenon|Xenon]]&lt;br /&gt;
|10127&lt;br /&gt;
|Korrektur &amp;amp; Überarbeitung Kapitel 1&lt;br /&gt;
|-&lt;br /&gt;
|Fling&lt;br /&gt;
|54865&lt;br /&gt;
|Kapitel 7, Kapitel 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Scripting-Hilfe|Anfängerkurs]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Basic_course</id>
		<title>Scripting:Basic course</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Basic_course"/>
				<updated>2011-11-11T18:37:36Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: /* Parameters */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedTranslation}}&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
'''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.'''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Vorwort==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Chapter 1 - Strings==&lt;br /&gt;
In programming a String is a series of characters. The chapter title would be a String as would this text. The famous line &amp;quot;Hello World!&amp;quot; is also a String and it is this String you will be working with.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Hello World!&amp;quot; ===&lt;br /&gt;
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 &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
In the STNE engine this is very easy.&lt;br /&gt;
First launch the script editor under:&lt;br /&gt;
Database -&amp;gt; Script Editor -&amp;gt; Create a new script -&amp;gt; Custom script without input wizard&lt;br /&gt;
Then you will click &amp;quot;Edit source code&amp;quot;.&lt;br /&gt;
In the text field provided type: &lt;br /&gt;
&amp;lt;pre&amp;gt;WriteLine('Hello World!');&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now click Save&amp;amp;Run.&lt;br /&gt;
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?&lt;br /&gt;
When it works you should see the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;Hello World!&amp;lt;/pre&amp;gt;&lt;br /&gt;
Congratulations you are now programming. Try making a program that says:&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World!&lt;br /&gt;
Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Your code should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!');&lt;br /&gt;
WriteLine('Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note every line of code ends with a semicolon.&lt;br /&gt;
But what if you want to write everything on one line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World! Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is done by use of the &amp;amp; symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!'&amp;amp;' Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;amp; 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!&lt;br /&gt;
&amp;quot;But wait!&amp;quot; You say. &amp;quot;I could simple code: &amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World! Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt; and never have to deal with the &amp;amp; symbol!&amp;quot;&lt;br /&gt;
True, and as a programmer you will have many choices of different ways to do things. But the '&amp;amp;' is important as you will find out in the next chapter.&lt;br /&gt;
&lt;br /&gt;
===Summary: Strings===&lt;br /&gt;
&lt;br /&gt;
* A String is a sequence of several characters.&lt;br /&gt;
* A String is output, or printed, using the command ''WriteLine();''.&lt;br /&gt;
* You may use the character &amp;amp; to combine one String with another within the parameters, or parentheses, of ''WriteLine();''.&lt;br /&gt;
&lt;br /&gt;
==Chapter 2 - Variables==&lt;br /&gt;
===Basic types===&lt;br /&gt;
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:&lt;br /&gt;
* String  - a series of characters&lt;br /&gt;
* Integer - a whole number&lt;br /&gt;
* Boolean - decision (True/False)&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Imagine you have a gigantic project with hundreds of lines of code. Dozens upon dozens of times your code will output the lines:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains log Stardate:&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
You could code:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Captains log Stardate:');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
every single time and maybe misspell it. Or you could use a variable.&lt;br /&gt;
Before a variable can be used, or called, it must be created. You do this with the word &amp;quot;Var&amp;quot; followed by the name followed by &amp;quot;As&amp;quot; followed by the type of variable it is followed by &amp;quot;=&amp;quot; followed by the data to be stored.&lt;br /&gt;
&lt;br /&gt;
Sound complicated?&lt;br /&gt;
Bear with us.&lt;br /&gt;
&lt;br /&gt;
In keeping with the above example let us declare a String variable that contains the line: 'Captains log Stardate:'&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
No two variables can have the same name though.&lt;br /&gt;
&lt;br /&gt;
Lets create a number, or integer, variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var SD As Integer = 234121;&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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).&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Things start to happen. Cool huh? Just in case your having trouble your code should look like this:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&lt;br /&gt;
Var SD As Integer = 234121;&lt;br /&gt;
WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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 &amp;amp; symbol. It stuck the integer and the string together!&lt;br /&gt;
The output looks like:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate:234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
See if you can find a way to get a space between the colon and the number...&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate: 234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Converting One Data Type to Another===&lt;br /&gt;
In many programming languages including an older version of the STNE engine you often need to convert variables from one type to another.&lt;br /&gt;
For instance if you had a variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;Var number As Integer = 12345;&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You couldn't use it in certain functions like &lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(number);&amp;lt;/pre&amp;gt;&lt;br /&gt;
Because the parameters for WriteLine() would only accept Strings and the variable 'number' is an Integer.&lt;br /&gt;
&lt;br /&gt;
In that case you would use another function CStr() to convert it to a String:&lt;br /&gt;
&amp;lt;Pre&amp;gt;CStr(number)&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You could even place that inside the parameters of WriteLine():&lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(CStr(number));&amp;lt;/Pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Likewise you could covert a String to it's integer value with CInt();&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Rules for Naming Variables===&lt;br /&gt;
There are some rules for naming your variables&lt;br /&gt;
* 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.&lt;br /&gt;
* Do not use spaces. Use capital letters to signify different words. &lt;br /&gt;
* 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.&lt;br /&gt;
* For clear coding consider starting your variable name with a three digits representing the variable type. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;intDeutNeeded&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
===Summary: Variables===&lt;br /&gt;
&lt;br /&gt;
* A variable takes the place of &amp;quot;hard coded&amp;quot; data.&lt;br /&gt;
* To create a variable use 'VAR &amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; AS &amp;lt;b&amp;gt;Datentype&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To assign data to a variable you use ''&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; = &amp;lt;b&amp;gt;Inhalt&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To output a variable use ''WriteLine(&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt;);'' This can be very important when debugging.&lt;br /&gt;
* The ''&amp;amp;'' symbol connects variables withing a  function call''WriteLine();''&lt;br /&gt;
&lt;br /&gt;
==Chapter 3 - Control Structures==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===If - Else===&lt;br /&gt;
This works exactly how it sounds. &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates a statement and when it is true will execute the next few lines of code that are within curly braces &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot;. You can also include an &amp;lt;B&amp;gt;ELSE&amp;lt;/B&amp;gt; statement that will execute when the &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates to false.&lt;br /&gt;
For example this code evaluates a variable and executes the code within the curly braces in response:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var tribbles As Boolean = True;&lt;br /&gt;
If (tribbles){&lt;br /&gt;
  WriteLine('Oh no! The food!');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('The food is safe.');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
 &lt;br /&gt;
You can also use an IF statement to compare amounts. In that case you would use the equal symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var EPSamount As Integer = 44;&lt;br /&gt;
If (EPSamount = 45){&lt;br /&gt;
  WriteLine('We have exactly ' &amp;amp; EPSamount &amp;amp; ' available');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Im givin her all shes got, Cpatain!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
You can also use &amp;quot;&amp;lt;&amp;quot;,&amp;quot;&amp;gt;&amp;quot;,&amp;quot;&amp;lt;=&amp;quot;,&amp;quot;&amp;gt;=&amp;quot; for different types of comparisons. In that order and in English those are called &amp;quot;less then&amp;quot;, &amp;quot;greater then&amp;quot;, &amp;quot;less then or equal to&amp;quot;, and &amp;quot;greater then or equal to&amp;quot;. These can be a little confusing at first so remember the bigger side of the symbol is toward the larger number. &amp;quot;a&amp;lt;b&amp;quot; says that a is less then b. b is greater.&lt;br /&gt;
You can also you the words &amp;quot;AND&amp;quot; and &amp;quot;OR&amp;quot; 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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
If ((dilth&amp;gt;5)AND(deut&amp;gt;10)AND(ANTIM&amp;gt;10)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var dilth AS Boolean = (dilthAmount&amp;gt;5);&lt;br /&gt;
Var deut AS Boolean = (deutAmount&amp;gt;10);&lt;br /&gt;
Var antiM As Boolean = (antiMAmount&amp;gt;10);&lt;br /&gt;
If ((dilth)AND(deut)AND(antiM)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is completely up to you!&lt;br /&gt;
&lt;br /&gt;
===Loops===&lt;br /&gt;
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 &amp;quot;{&amp;quot; &amp;quot;}&amp;quot; but a loop will not exit until the conditions that started become false.&lt;br /&gt;
&lt;br /&gt;
====While====&lt;br /&gt;
Consider the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var isKilingon As Boolean = True;&lt;br /&gt;
while (isKilingon){&lt;br /&gt;
  WriteLine('Today is a good day to die!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Enough battle!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Do====&lt;br /&gt;
DO loops work just like WHILE loops except that regardless the evaluation a DO will execute at least once. &lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
VAR friendlyShip AS Boolean = False;&lt;br /&gt;
WriteLine('Ship on Federation sensors');&lt;br /&gt;
Do(friendlyShip){&lt;br /&gt;
  WriteLine('Hale them.');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('No response. Open fire!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====For====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This could also be written using a FOR loop:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
for(ore=0 To 12 Step 2){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you do not specify a step it will assume the step is 1.&lt;br /&gt;
&lt;br /&gt;
==Chapter 4 - Functions==&lt;br /&gt;
===Introduction===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('Get them out of there!');&lt;br /&gt;
WriteLine('Attempting to beam up away-team');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
But you want to run that ten times.&lt;br /&gt;
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.&lt;br /&gt;
To create a function you use the following formula 'Function' followed by the name you give it, followed by the symbols &amp;quot;(){}&amp;quot;&lt;br /&gt;
Here is an example using the code above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Parameters===&lt;br /&gt;
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 &amp;quot;()&amp;quot;. 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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
Now when you make the function call you need to pass it values that match it's parameters.&lt;br /&gt;
In the above example you might call it this way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
BeamUp(5, True, Medics);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also for clarity consider keeping your Functions separate from your main code either all above or all bellow.&lt;br /&gt;
&lt;br /&gt;
Now that we now have a few basics, let us turn to the really interesting parts, the control of the game content through scripts.&lt;br /&gt;
&lt;br /&gt;
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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Var ShipManager As New CShipManager();&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To assign the safety officer, there are the commands:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectShip(NCC-Number of Ship);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
or,&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectFleet(ID of Fleet);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way the ShipManager knows which ship or fleet to interact with.&lt;br /&gt;
&lt;br /&gt;
Syntax:&lt;br /&gt;
  CShipManager.TransferToShip(&amp;lt;i&amp;gt;ToShipID, Amount, EBeamResource.Resource&amp;lt;/i&amp;gt;)&lt;br /&gt;
You just need to replace the parameters with the respective values. Here's an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
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:&lt;br /&gt;
  ShipManager.BenutzteFlotte (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
&lt;br /&gt;
With the Ship Managers, you can do the following:&lt;br /&gt;
* Docking and undocking&lt;br /&gt;
* Alert level change&lt;br /&gt;
* Escape from fleets&lt;br /&gt;
* Enter or leave orbit&lt;br /&gt;
* Rename (name As String)&lt;br /&gt;
* Collect deuterium (only with FP)&lt;br /&gt;
* Gather ore (only with FP)&lt;br /&gt;
* Fly (FlyTo() AutoPilot, only with FP)&lt;br /&gt;
* Fly (Using the Fly() method)&lt;br /&gt;
* Tractor beam on / off&lt;br /&gt;
* Beaming&lt;br /&gt;
* Hide&lt;br /&gt;
* Enable / Disable the Replicators&lt;br /&gt;
* Jettison Goods &lt;br /&gt;
* Enable / Disable the Warp Core &lt;br /&gt;
* Wreck extraction&lt;br /&gt;
* And more&lt;br /&gt;
&lt;br /&gt;
For a complete list of the CShipManager features, see [http://game.stne.net/ObjectExplorer.aspx?p=CShipManager Object Explorer].&lt;br /&gt;
&lt;br /&gt;
Next, we will look at some specific features:&lt;br /&gt;
&lt;br /&gt;
===Beaming===&lt;br /&gt;
Syntax:&lt;br /&gt;
  CShipManager.TransferToShip(ToShipID, Amount, EBeamResource.Resource)&lt;br /&gt;
You just need to replace the parameters with the respective values. Here's an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
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:&lt;br /&gt;
  ShipManager.SelectFleet (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
&lt;br /&gt;
===Flying===&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Flying with the Autopilot====&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;'''''Only for players with the feature pack!'''''&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The command:&lt;br /&gt;
  ShipManager.FlyTo (&amp;lt;i&amp;gt;'xxx | yyy'&amp;lt;/i&amp;gt;);&lt;br /&gt;
Again, it you need to replace the italicized parameter 'xxx | yyy' with something appropriate. Here is an example:&lt;br /&gt;
 ShipManager.SelectShip(1);&lt;br /&gt;
 ShipManager.FlyTo('123|465');&lt;br /&gt;
Or, with a fleet:&lt;br /&gt;
 ShipManager.SelectFleet(1);&lt;br /&gt;
 ShipManager.FlyTo('123|465');&lt;br /&gt;
 &lt;br /&gt;
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&lt;br /&gt;
&lt;br /&gt;
====Flying without the Autopilot====&lt;br /&gt;
The command for this is as follows:&lt;br /&gt;
  ShipManager.Fly (''distance'',''EShipDirection.Direction'');&lt;br /&gt;
Here is an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.Fly (5, EShipDirection.Up);&lt;br /&gt;
  ShipManager.Fly (8, EShipDirection.Left);&lt;br /&gt;
or if you wanted to move an entire fleet:&lt;br /&gt;
  ShipManager.SelectFleet (1);&lt;br /&gt;
  ShipManager.Fly (5, EShipDirection.Up);&lt;br /&gt;
  ShipManager.Fly (8, EShipDirection.Left);&lt;br /&gt;
&lt;br /&gt;
Please note, Fly() will &amp;lt;B&amp;gt;NOT&amp;lt;/b&amp;gt; avoid dangerous areas, it will fly in a straight line though Nebulas etc.&lt;br /&gt;
&lt;br /&gt;
===Schiffsystem nutzen===&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
===Alternative zum Schiffsmanager: Schiffsaktion===&lt;br /&gt;
&lt;br /&gt;
Für Objekte des Typ's CMyFlotte und CMyShip kann über die Eigenschaft Aktion direkt auf die Funktionen des Schiffsmanagers zugegriffen werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Schiff AS CMyShip = new CMyShip( 4711 )&lt;br /&gt;
Schiff.Aktion.Abdocken()&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Flotte AS CMyFlotte = new CMyFlotte( 4711 )&lt;br /&gt;
Flotte.Aktion.Abdocken()&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Enumeration ist Alles==&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
==Methoden==&lt;br /&gt;
&lt;br /&gt;
Öfters wiederkehrende Aufgaben können in Methoden zusammengefasst werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function ShowKoords(x As Integer, y As Integer)&lt;br /&gt;
{&lt;br /&gt;
  WriteLine(CStr(x) + '|' + CStr(y));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Methode ShowKoords kann dann im Script folgendermaßen aufgerufen werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
ShowKoords(3, 4);&lt;br /&gt;
ShowKoords(ship.MapPosition.X,ship.MapPosition.Y);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn berechnete Werte von der Methode zurückgegeben werden sollen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function Distanz(x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer&lt;br /&gt;
{&lt;br /&gt;
  Var distanz As Integer;&lt;br /&gt;
  &lt;br /&gt;
  distanz = Math.Abs(x1 - x2) + Math.Abs(y1 - y2);&lt;br /&gt;
  Return distanz ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine(Distanz(1, 1, 5, 5));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
'ByRef' ist zwar in der Scriptengine vorgesehen und kann angegeben werden, ist aber derzeit ohne Funktion.&lt;br /&gt;
Objekte werden immer ByRef übergeben.&lt;br /&gt;
&lt;br /&gt;
==Klassen==&lt;br /&gt;
&lt;br /&gt;
In Klassen können Daten und Methoden in einem Objekt gekapselt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Class CKoords&lt;br /&gt;
{&lt;br /&gt;
  Var x As Integer;&lt;br /&gt;
  Var y As Integer;&lt;br /&gt;
  &lt;br /&gt;
  Function New(x As Integer, y As Integer)&lt;br /&gt;
  {&lt;br /&gt;
    This.x = x;&lt;br /&gt;
    This.y = y;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function ToString() As String&lt;br /&gt;
  {&lt;br /&gt;
    Return (CStr(x) + '|' + CStr(y);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function Distanz(koord As CKoords) As Integer&lt;br /&gt;
  {&lt;br /&gt;
    Return Math.Abs(x - koord.x) + Math.Abs(y - koord.y);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var ko1 As New CKoords(3, 5);&lt;br /&gt;
Var ko2 As CKoords;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ko2 = New CKoords(8, 9);&lt;br /&gt;
WriteLine('Distanz von ' + ko1.ToString() + ' nach ' + ko2.ToString() + ': ' + CStr(ko1.Distanz(ko2)));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig: Klassen brauchen immer eine Methode New(), sonst kann kein neues Objekt der Klasse generiert werden!&lt;br /&gt;
&lt;br /&gt;
==Autoren==&lt;br /&gt;
(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 ;)])&lt;br /&gt;
{|&lt;br /&gt;
!Nickname&lt;br /&gt;
!IG-id&lt;br /&gt;
!Kapitel&lt;br /&gt;
|-&lt;br /&gt;
|WiZz4Rd&lt;br /&gt;
|16475&lt;br /&gt;
|Kapitel 1, Kapitel 2, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|Stryke&lt;br /&gt;
|28885&lt;br /&gt;
|Vorwort, Kapitel 3, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|[[Spieler:Xenon|Xenon]]&lt;br /&gt;
|10127&lt;br /&gt;
|Korrektur &amp;amp; Überarbeitung Kapitel 1&lt;br /&gt;
|-&lt;br /&gt;
|Fling&lt;br /&gt;
|54865&lt;br /&gt;
|Kapitel 7, Kapitel 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Scripting-Hilfe|Anfängerkurs]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Basic_course</id>
		<title>Scripting:Basic course</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Basic_course"/>
				<updated>2011-11-11T18:29:37Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: /* Flying */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedTranslation}}&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
'''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.'''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Vorwort==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Chapter 1 - Strings==&lt;br /&gt;
In programming a String is a series of characters. The chapter title would be a String as would this text. The famous line &amp;quot;Hello World!&amp;quot; is also a String and it is this String you will be working with.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Hello World!&amp;quot; ===&lt;br /&gt;
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 &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
In the STNE engine this is very easy.&lt;br /&gt;
First launch the script editor under:&lt;br /&gt;
Database -&amp;gt; Script Editor -&amp;gt; Create a new script -&amp;gt; Custom script without input wizard&lt;br /&gt;
Then you will click &amp;quot;Edit source code&amp;quot;.&lt;br /&gt;
In the text field provided type: &lt;br /&gt;
&amp;lt;pre&amp;gt;WriteLine('Hello World!');&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now click Save&amp;amp;Run.&lt;br /&gt;
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?&lt;br /&gt;
When it works you should see the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;Hello World!&amp;lt;/pre&amp;gt;&lt;br /&gt;
Congratulations you are now programming. Try making a program that says:&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World!&lt;br /&gt;
Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Your code should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!');&lt;br /&gt;
WriteLine('Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note every line of code ends with a semicolon.&lt;br /&gt;
But what if you want to write everything on one line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World! Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is done by use of the &amp;amp; symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!'&amp;amp;' Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;amp; 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!&lt;br /&gt;
&amp;quot;But wait!&amp;quot; You say. &amp;quot;I could simple code: &amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World! Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt; and never have to deal with the &amp;amp; symbol!&amp;quot;&lt;br /&gt;
True, and as a programmer you will have many choices of different ways to do things. But the '&amp;amp;' is important as you will find out in the next chapter.&lt;br /&gt;
&lt;br /&gt;
===Summary: Strings===&lt;br /&gt;
&lt;br /&gt;
* A String is a sequence of several characters.&lt;br /&gt;
* A String is output, or printed, using the command ''WriteLine();''.&lt;br /&gt;
* You may use the character &amp;amp; to combine one String with another within the parameters, or parentheses, of ''WriteLine();''.&lt;br /&gt;
&lt;br /&gt;
==Chapter 2 - Variables==&lt;br /&gt;
===Basic types===&lt;br /&gt;
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:&lt;br /&gt;
* String  - a series of characters&lt;br /&gt;
* Integer - a whole number&lt;br /&gt;
* Boolean - decision (True/False)&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Imagine you have a gigantic project with hundreds of lines of code. Dozens upon dozens of times your code will output the lines:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains log Stardate:&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
You could code:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Captains log Stardate:');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
every single time and maybe misspell it. Or you could use a variable.&lt;br /&gt;
Before a variable can be used, or called, it must be created. You do this with the word &amp;quot;Var&amp;quot; followed by the name followed by &amp;quot;As&amp;quot; followed by the type of variable it is followed by &amp;quot;=&amp;quot; followed by the data to be stored.&lt;br /&gt;
&lt;br /&gt;
Sound complicated?&lt;br /&gt;
Bear with us.&lt;br /&gt;
&lt;br /&gt;
In keeping with the above example let us declare a String variable that contains the line: 'Captains log Stardate:'&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
No two variables can have the same name though.&lt;br /&gt;
&lt;br /&gt;
Lets create a number, or integer, variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var SD As Integer = 234121;&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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).&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Things start to happen. Cool huh? Just in case your having trouble your code should look like this:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&lt;br /&gt;
Var SD As Integer = 234121;&lt;br /&gt;
WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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 &amp;amp; symbol. It stuck the integer and the string together!&lt;br /&gt;
The output looks like:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate:234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
See if you can find a way to get a space between the colon and the number...&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate: 234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Converting One Data Type to Another===&lt;br /&gt;
In many programming languages including an older version of the STNE engine you often need to convert variables from one type to another.&lt;br /&gt;
For instance if you had a variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;Var number As Integer = 12345;&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You couldn't use it in certain functions like &lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(number);&amp;lt;/pre&amp;gt;&lt;br /&gt;
Because the parameters for WriteLine() would only accept Strings and the variable 'number' is an Integer.&lt;br /&gt;
&lt;br /&gt;
In that case you would use another function CStr() to convert it to a String:&lt;br /&gt;
&amp;lt;Pre&amp;gt;CStr(number)&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You could even place that inside the parameters of WriteLine():&lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(CStr(number));&amp;lt;/Pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Likewise you could covert a String to it's integer value with CInt();&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Rules for Naming Variables===&lt;br /&gt;
There are some rules for naming your variables&lt;br /&gt;
* 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.&lt;br /&gt;
* Do not use spaces. Use capital letters to signify different words. &lt;br /&gt;
* 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.&lt;br /&gt;
* For clear coding consider starting your variable name with a three digits representing the variable type. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;intDeutNeeded&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
===Summary: Variables===&lt;br /&gt;
&lt;br /&gt;
* A variable takes the place of &amp;quot;hard coded&amp;quot; data.&lt;br /&gt;
* To create a variable use 'VAR &amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; AS &amp;lt;b&amp;gt;Datentype&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To assign data to a variable you use ''&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; = &amp;lt;b&amp;gt;Inhalt&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To output a variable use ''WriteLine(&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt;);'' This can be very important when debugging.&lt;br /&gt;
* The ''&amp;amp;'' symbol connects variables withing a  function call''WriteLine();''&lt;br /&gt;
&lt;br /&gt;
==Chapter 3 - Control Structures==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===If - Else===&lt;br /&gt;
This works exactly how it sounds. &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates a statement and when it is true will execute the next few lines of code that are within curly braces &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot;. You can also include an &amp;lt;B&amp;gt;ELSE&amp;lt;/B&amp;gt; statement that will execute when the &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates to false.&lt;br /&gt;
For example this code evaluates a variable and executes the code within the curly braces in response:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var tribbles As Boolean = True;&lt;br /&gt;
If (tribbles){&lt;br /&gt;
  WriteLine('Oh no! The food!');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('The food is safe.');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
 &lt;br /&gt;
You can also use an IF statement to compare amounts. In that case you would use the equal symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var EPSamount As Integer = 44;&lt;br /&gt;
If (EPSamount = 45){&lt;br /&gt;
  WriteLine('We have exactly ' &amp;amp; EPSamount &amp;amp; ' available');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Im givin her all shes got, Cpatain!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
You can also use &amp;quot;&amp;lt;&amp;quot;,&amp;quot;&amp;gt;&amp;quot;,&amp;quot;&amp;lt;=&amp;quot;,&amp;quot;&amp;gt;=&amp;quot; for different types of comparisons. In that order and in English those are called &amp;quot;less then&amp;quot;, &amp;quot;greater then&amp;quot;, &amp;quot;less then or equal to&amp;quot;, and &amp;quot;greater then or equal to&amp;quot;. These can be a little confusing at first so remember the bigger side of the symbol is toward the larger number. &amp;quot;a&amp;lt;b&amp;quot; says that a is less then b. b is greater.&lt;br /&gt;
You can also you the words &amp;quot;AND&amp;quot; and &amp;quot;OR&amp;quot; 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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
If ((dilth&amp;gt;5)AND(deut&amp;gt;10)AND(ANTIM&amp;gt;10)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var dilth AS Boolean = (dilthAmount&amp;gt;5);&lt;br /&gt;
Var deut AS Boolean = (deutAmount&amp;gt;10);&lt;br /&gt;
Var antiM As Boolean = (antiMAmount&amp;gt;10);&lt;br /&gt;
If ((dilth)AND(deut)AND(antiM)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is completely up to you!&lt;br /&gt;
&lt;br /&gt;
===Loops===&lt;br /&gt;
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 &amp;quot;{&amp;quot; &amp;quot;}&amp;quot; but a loop will not exit until the conditions that started become false.&lt;br /&gt;
&lt;br /&gt;
====While====&lt;br /&gt;
Consider the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var isKilingon As Boolean = True;&lt;br /&gt;
while (isKilingon){&lt;br /&gt;
  WriteLine('Today is a good day to die!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Enough battle!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Do====&lt;br /&gt;
DO loops work just like WHILE loops except that regardless the evaluation a DO will execute at least once. &lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
VAR friendlyShip AS Boolean = False;&lt;br /&gt;
WriteLine('Ship on Federation sensors');&lt;br /&gt;
Do(friendlyShip){&lt;br /&gt;
  WriteLine('Hale them.');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('No response. Open fire!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====For====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This could also be written using a FOR loop:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
for(ore=0 To 12 Step 2){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you do not specify a step it will assume the step is 1.&lt;br /&gt;
&lt;br /&gt;
==Chapter 4 - Functions==&lt;br /&gt;
===Introduction===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('Get them out of there!');&lt;br /&gt;
WriteLine('Attempting to beam up away-team');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
But you want to run that ten times.&lt;br /&gt;
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.&lt;br /&gt;
To create a function you use the following formula 'Function' followed by the name you give it, followed by the symbols &amp;quot;(){}&amp;quot;&lt;br /&gt;
Here is an example using the code above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Parameters===&lt;br /&gt;
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 &amp;quot;()&amp;quot;. 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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
Now when you make the function call you need to pass it values that match it's parameters.&lt;br /&gt;
In the above example you might call it this way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
BeamUp(5, True, Medics);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also for clarity consider keeping your Functions separate from your main code either all above or all bellow.&lt;br /&gt;
&lt;br /&gt;
Now that we now have a few basics, let us turn to the really interesting parts, the control of the game content through scripts.&lt;br /&gt;
&lt;br /&gt;
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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Var ShipManager As New CShipManager();&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To assign the safety officer, there are the commands:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectShip(NCC-Number of Ship);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
or,&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectFleet(ID of Fleet);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way the ShipManager knows which ship or fleet to interact with.&lt;br /&gt;
&lt;br /&gt;
With the Ship Managers, you can do the following:&lt;br /&gt;
* Docking and undocking&lt;br /&gt;
* Alert level change&lt;br /&gt;
* Escape from fleets&lt;br /&gt;
* Enter or leave orbit&lt;br /&gt;
* Rename (name As String)&lt;br /&gt;
* Collect deuterium (only with FP)&lt;br /&gt;
* Gather ore (only with FP)&lt;br /&gt;
* Fly (AutoPilot, only with FP)&lt;br /&gt;
* Fly (Using the FlyTo() method)&lt;br /&gt;
* Tractor beam on / off&lt;br /&gt;
* Beaming&lt;br /&gt;
* Hide&lt;br /&gt;
* Enable / Disable the Replicators&lt;br /&gt;
* Jettison Goods &lt;br /&gt;
* Enable / Disable the Warp Core &lt;br /&gt;
* Wreck extraction&lt;br /&gt;
* And more&lt;br /&gt;
&lt;br /&gt;
For a complete list of the features found in [http://game.stne.net/ObjectExplorer.aspx?p=CShipManager Object Explorer].&lt;br /&gt;
&lt;br /&gt;
Next, we will look at some specific features:&lt;br /&gt;
&lt;br /&gt;
===Beaming===&lt;br /&gt;
Syntax:&lt;br /&gt;
  CShipManager.TransferToShip(ToShipID, Amount, EBeamResource.Resource)&lt;br /&gt;
You just need to replace the parameters with the respective values. Here's an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
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:&lt;br /&gt;
  ShipManager.SelectFleet (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
&lt;br /&gt;
===Flying===&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Flying with the Autopilot====&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;'''''Only for players with the feature pack!'''''&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The command:&lt;br /&gt;
  ShipManager.FlyTo (&amp;lt;i&amp;gt;'xxx | yyy'&amp;lt;/i&amp;gt;);&lt;br /&gt;
Again, it you need to replace the italicized parameter 'xxx | yyy' with something appropriate. Here is an example:&lt;br /&gt;
 ShipManager.SelectShip(1);&lt;br /&gt;
 ShipManager.FlyTo('123|465');&lt;br /&gt;
Or, with a fleet:&lt;br /&gt;
 ShipManager.SelectFleet(1);&lt;br /&gt;
 ShipManager.FlyTo('123|465');&lt;br /&gt;
 &lt;br /&gt;
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&lt;br /&gt;
&lt;br /&gt;
====Flying without the Autopilot====&lt;br /&gt;
The command for this is as follows:&lt;br /&gt;
  ShipManager.Fly (''distance'',''EShipDirection.Direction'');&lt;br /&gt;
Here is an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.Fly (5, EShipDirection.Up);&lt;br /&gt;
  ShipManager.Fly (8, EShipDirection.Left);&lt;br /&gt;
or if you wanted to move an entire fleet:&lt;br /&gt;
  ShipManager.SelectFleet (1);&lt;br /&gt;
  ShipManager.Fly (5, EShipDirection.Up);&lt;br /&gt;
  ShipManager.Fly (8, EShipDirection.Left);&lt;br /&gt;
&lt;br /&gt;
Please note, Fly() will &amp;lt;B&amp;gt;NOT&amp;lt;/b&amp;gt; avoid dangerous areas, it will fly in a straight line though Nebulas etc.&lt;br /&gt;
&lt;br /&gt;
===Schiffsystem nutzen===&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
===Alternative zum Schiffsmanager: Schiffsaktion===&lt;br /&gt;
&lt;br /&gt;
Für Objekte des Typ's CMyFlotte und CMyShip kann über die Eigenschaft Aktion direkt auf die Funktionen des Schiffsmanagers zugegriffen werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Schiff AS CMyShip = new CMyShip( 4711 )&lt;br /&gt;
Schiff.Aktion.Abdocken()&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Flotte AS CMyFlotte = new CMyFlotte( 4711 )&lt;br /&gt;
Flotte.Aktion.Abdocken()&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Enumeration ist Alles==&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
==Methoden==&lt;br /&gt;
&lt;br /&gt;
Öfters wiederkehrende Aufgaben können in Methoden zusammengefasst werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function ShowKoords(x As Integer, y As Integer)&lt;br /&gt;
{&lt;br /&gt;
  WriteLine(CStr(x) + '|' + CStr(y));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Methode ShowKoords kann dann im Script folgendermaßen aufgerufen werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
ShowKoords(3, 4);&lt;br /&gt;
ShowKoords(ship.MapPosition.X,ship.MapPosition.Y);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn berechnete Werte von der Methode zurückgegeben werden sollen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function Distanz(x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer&lt;br /&gt;
{&lt;br /&gt;
  Var distanz As Integer;&lt;br /&gt;
  &lt;br /&gt;
  distanz = Math.Abs(x1 - x2) + Math.Abs(y1 - y2);&lt;br /&gt;
  Return distanz ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine(Distanz(1, 1, 5, 5));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
'ByRef' ist zwar in der Scriptengine vorgesehen und kann angegeben werden, ist aber derzeit ohne Funktion.&lt;br /&gt;
Objekte werden immer ByRef übergeben.&lt;br /&gt;
&lt;br /&gt;
==Klassen==&lt;br /&gt;
&lt;br /&gt;
In Klassen können Daten und Methoden in einem Objekt gekapselt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Class CKoords&lt;br /&gt;
{&lt;br /&gt;
  Var x As Integer;&lt;br /&gt;
  Var y As Integer;&lt;br /&gt;
  &lt;br /&gt;
  Function New(x As Integer, y As Integer)&lt;br /&gt;
  {&lt;br /&gt;
    This.x = x;&lt;br /&gt;
    This.y = y;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function ToString() As String&lt;br /&gt;
  {&lt;br /&gt;
    Return (CStr(x) + '|' + CStr(y);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function Distanz(koord As CKoords) As Integer&lt;br /&gt;
  {&lt;br /&gt;
    Return Math.Abs(x - koord.x) + Math.Abs(y - koord.y);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var ko1 As New CKoords(3, 5);&lt;br /&gt;
Var ko2 As CKoords;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ko2 = New CKoords(8, 9);&lt;br /&gt;
WriteLine('Distanz von ' + ko1.ToString() + ' nach ' + ko2.ToString() + ': ' + CStr(ko1.Distanz(ko2)));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig: Klassen brauchen immer eine Methode New(), sonst kann kein neues Objekt der Klasse generiert werden!&lt;br /&gt;
&lt;br /&gt;
==Autoren==&lt;br /&gt;
(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 ;)])&lt;br /&gt;
{|&lt;br /&gt;
!Nickname&lt;br /&gt;
!IG-id&lt;br /&gt;
!Kapitel&lt;br /&gt;
|-&lt;br /&gt;
|WiZz4Rd&lt;br /&gt;
|16475&lt;br /&gt;
|Kapitel 1, Kapitel 2, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|Stryke&lt;br /&gt;
|28885&lt;br /&gt;
|Vorwort, Kapitel 3, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|[[Spieler:Xenon|Xenon]]&lt;br /&gt;
|10127&lt;br /&gt;
|Korrektur &amp;amp; Überarbeitung Kapitel 1&lt;br /&gt;
|-&lt;br /&gt;
|Fling&lt;br /&gt;
|54865&lt;br /&gt;
|Kapitel 7, Kapitel 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Scripting-Hilfe|Anfängerkurs]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Basic_course</id>
		<title>Scripting:Basic course</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Basic_course"/>
				<updated>2011-11-11T18:00:08Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: /* Beaming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedTranslation}}&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
'''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.'''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Vorwort==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Chapter 1 - Strings==&lt;br /&gt;
In programming a String is a series of characters. The chapter title would be a String as would this text. The famous line &amp;quot;Hello World!&amp;quot; is also a String and it is this String you will be working with.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Hello World!&amp;quot; ===&lt;br /&gt;
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 &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
In the STNE engine this is very easy.&lt;br /&gt;
First launch the script editor under:&lt;br /&gt;
Database -&amp;gt; Script Editor -&amp;gt; Create a new script -&amp;gt; Custom script without input wizard&lt;br /&gt;
Then you will click &amp;quot;Edit source code&amp;quot;.&lt;br /&gt;
In the text field provided type: &lt;br /&gt;
&amp;lt;pre&amp;gt;WriteLine('Hello World!');&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now click Save&amp;amp;Run.&lt;br /&gt;
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?&lt;br /&gt;
When it works you should see the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;Hello World!&amp;lt;/pre&amp;gt;&lt;br /&gt;
Congratulations you are now programming. Try making a program that says:&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World!&lt;br /&gt;
Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Your code should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!');&lt;br /&gt;
WriteLine('Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note every line of code ends with a semicolon.&lt;br /&gt;
But what if you want to write everything on one line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World! Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is done by use of the &amp;amp; symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!'&amp;amp;' Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;amp; 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!&lt;br /&gt;
&amp;quot;But wait!&amp;quot; You say. &amp;quot;I could simple code: &amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World! Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt; and never have to deal with the &amp;amp; symbol!&amp;quot;&lt;br /&gt;
True, and as a programmer you will have many choices of different ways to do things. But the '&amp;amp;' is important as you will find out in the next chapter.&lt;br /&gt;
&lt;br /&gt;
===Summary: Strings===&lt;br /&gt;
&lt;br /&gt;
* A String is a sequence of several characters.&lt;br /&gt;
* A String is output, or printed, using the command ''WriteLine();''.&lt;br /&gt;
* You may use the character &amp;amp; to combine one String with another within the parameters, or parentheses, of ''WriteLine();''.&lt;br /&gt;
&lt;br /&gt;
==Chapter 2 - Variables==&lt;br /&gt;
===Basic types===&lt;br /&gt;
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:&lt;br /&gt;
* String  - a series of characters&lt;br /&gt;
* Integer - a whole number&lt;br /&gt;
* Boolean - decision (True/False)&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Imagine you have a gigantic project with hundreds of lines of code. Dozens upon dozens of times your code will output the lines:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains log Stardate:&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
You could code:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Captains log Stardate:');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
every single time and maybe misspell it. Or you could use a variable.&lt;br /&gt;
Before a variable can be used, or called, it must be created. You do this with the word &amp;quot;Var&amp;quot; followed by the name followed by &amp;quot;As&amp;quot; followed by the type of variable it is followed by &amp;quot;=&amp;quot; followed by the data to be stored.&lt;br /&gt;
&lt;br /&gt;
Sound complicated?&lt;br /&gt;
Bear with us.&lt;br /&gt;
&lt;br /&gt;
In keeping with the above example let us declare a String variable that contains the line: 'Captains log Stardate:'&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
No two variables can have the same name though.&lt;br /&gt;
&lt;br /&gt;
Lets create a number, or integer, variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var SD As Integer = 234121;&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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).&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Things start to happen. Cool huh? Just in case your having trouble your code should look like this:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&lt;br /&gt;
Var SD As Integer = 234121;&lt;br /&gt;
WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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 &amp;amp; symbol. It stuck the integer and the string together!&lt;br /&gt;
The output looks like:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate:234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
See if you can find a way to get a space between the colon and the number...&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate: 234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Converting One Data Type to Another===&lt;br /&gt;
In many programming languages including an older version of the STNE engine you often need to convert variables from one type to another.&lt;br /&gt;
For instance if you had a variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;Var number As Integer = 12345;&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You couldn't use it in certain functions like &lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(number);&amp;lt;/pre&amp;gt;&lt;br /&gt;
Because the parameters for WriteLine() would only accept Strings and the variable 'number' is an Integer.&lt;br /&gt;
&lt;br /&gt;
In that case you would use another function CStr() to convert it to a String:&lt;br /&gt;
&amp;lt;Pre&amp;gt;CStr(number)&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You could even place that inside the parameters of WriteLine():&lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(CStr(number));&amp;lt;/Pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Likewise you could covert a String to it's integer value with CInt();&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Rules for Naming Variables===&lt;br /&gt;
There are some rules for naming your variables&lt;br /&gt;
* 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.&lt;br /&gt;
* Do not use spaces. Use capital letters to signify different words. &lt;br /&gt;
* 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.&lt;br /&gt;
* For clear coding consider starting your variable name with a three digits representing the variable type. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;intDeutNeeded&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
===Summary: Variables===&lt;br /&gt;
&lt;br /&gt;
* A variable takes the place of &amp;quot;hard coded&amp;quot; data.&lt;br /&gt;
* To create a variable use 'VAR &amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; AS &amp;lt;b&amp;gt;Datentype&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To assign data to a variable you use ''&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; = &amp;lt;b&amp;gt;Inhalt&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To output a variable use ''WriteLine(&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt;);'' This can be very important when debugging.&lt;br /&gt;
* The ''&amp;amp;'' symbol connects variables withing a  function call''WriteLine();''&lt;br /&gt;
&lt;br /&gt;
==Chapter 3 - Control Structures==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===If - Else===&lt;br /&gt;
This works exactly how it sounds. &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates a statement and when it is true will execute the next few lines of code that are within curly braces &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot;. You can also include an &amp;lt;B&amp;gt;ELSE&amp;lt;/B&amp;gt; statement that will execute when the &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates to false.&lt;br /&gt;
For example this code evaluates a variable and executes the code within the curly braces in response:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var tribbles As Boolean = True;&lt;br /&gt;
If (tribbles){&lt;br /&gt;
  WriteLine('Oh no! The food!');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('The food is safe.');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
 &lt;br /&gt;
You can also use an IF statement to compare amounts. In that case you would use the equal symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var EPSamount As Integer = 44;&lt;br /&gt;
If (EPSamount = 45){&lt;br /&gt;
  WriteLine('We have exactly ' &amp;amp; EPSamount &amp;amp; ' available');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Im givin her all shes got, Cpatain!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
You can also use &amp;quot;&amp;lt;&amp;quot;,&amp;quot;&amp;gt;&amp;quot;,&amp;quot;&amp;lt;=&amp;quot;,&amp;quot;&amp;gt;=&amp;quot; for different types of comparisons. In that order and in English those are called &amp;quot;less then&amp;quot;, &amp;quot;greater then&amp;quot;, &amp;quot;less then or equal to&amp;quot;, and &amp;quot;greater then or equal to&amp;quot;. These can be a little confusing at first so remember the bigger side of the symbol is toward the larger number. &amp;quot;a&amp;lt;b&amp;quot; says that a is less then b. b is greater.&lt;br /&gt;
You can also you the words &amp;quot;AND&amp;quot; and &amp;quot;OR&amp;quot; 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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
If ((dilth&amp;gt;5)AND(deut&amp;gt;10)AND(ANTIM&amp;gt;10)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var dilth AS Boolean = (dilthAmount&amp;gt;5);&lt;br /&gt;
Var deut AS Boolean = (deutAmount&amp;gt;10);&lt;br /&gt;
Var antiM As Boolean = (antiMAmount&amp;gt;10);&lt;br /&gt;
If ((dilth)AND(deut)AND(antiM)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is completely up to you!&lt;br /&gt;
&lt;br /&gt;
===Loops===&lt;br /&gt;
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 &amp;quot;{&amp;quot; &amp;quot;}&amp;quot; but a loop will not exit until the conditions that started become false.&lt;br /&gt;
&lt;br /&gt;
====While====&lt;br /&gt;
Consider the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var isKilingon As Boolean = True;&lt;br /&gt;
while (isKilingon){&lt;br /&gt;
  WriteLine('Today is a good day to die!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Enough battle!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Do====&lt;br /&gt;
DO loops work just like WHILE loops except that regardless the evaluation a DO will execute at least once. &lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
VAR friendlyShip AS Boolean = False;&lt;br /&gt;
WriteLine('Ship on Federation sensors');&lt;br /&gt;
Do(friendlyShip){&lt;br /&gt;
  WriteLine('Hale them.');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('No response. Open fire!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====For====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This could also be written using a FOR loop:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
for(ore=0 To 12 Step 2){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you do not specify a step it will assume the step is 1.&lt;br /&gt;
&lt;br /&gt;
==Chapter 4 - Functions==&lt;br /&gt;
===Introduction===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('Get them out of there!');&lt;br /&gt;
WriteLine('Attempting to beam up away-team');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
But you want to run that ten times.&lt;br /&gt;
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.&lt;br /&gt;
To create a function you use the following formula 'Function' followed by the name you give it, followed by the symbols &amp;quot;(){}&amp;quot;&lt;br /&gt;
Here is an example using the code above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Parameters===&lt;br /&gt;
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 &amp;quot;()&amp;quot;. 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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
Now when you make the function call you need to pass it values that match it's parameters.&lt;br /&gt;
In the above example you might call it this way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
BeamUp(5, True, Medics);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also for clarity consider keeping your Functions separate from your main code either all above or all bellow.&lt;br /&gt;
&lt;br /&gt;
Now that we now have a few basics, let us turn to the really interesting parts, the control of the game content through scripts.&lt;br /&gt;
&lt;br /&gt;
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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Var ShipManager As New CShipManager();&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To assign the safety officer, there are the commands:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectShip(NCC-Number of Ship);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
or,&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectFleet(ID of Fleet);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way the ShipManager knows which ship or fleet to interact with.&lt;br /&gt;
&lt;br /&gt;
With the Ship Managers, you can do the following:&lt;br /&gt;
* Docking and undocking&lt;br /&gt;
* Alert level change&lt;br /&gt;
* Escape from fleets&lt;br /&gt;
* Enter or leave orbit&lt;br /&gt;
* Rename (name As String)&lt;br /&gt;
* Collect deuterium (only with FP)&lt;br /&gt;
* Gather ore (only with FP)&lt;br /&gt;
* Fly (AutoPilot, only with FP)&lt;br /&gt;
* Fly (Using the FlyTo() method)&lt;br /&gt;
* Tractor beam on / off&lt;br /&gt;
* Beaming&lt;br /&gt;
* Hide&lt;br /&gt;
* Enable / Disable the Replicators&lt;br /&gt;
* Jettison Goods &lt;br /&gt;
* Enable / Disable the Warp Core &lt;br /&gt;
* Wreck extraction&lt;br /&gt;
* And more&lt;br /&gt;
&lt;br /&gt;
For a complete list of the features found in [http://game.stne.net/ObjectExplorer.aspx?p=CShipManager Object Explorer].&lt;br /&gt;
&lt;br /&gt;
Next, we will look at some specific features:&lt;br /&gt;
&lt;br /&gt;
===Beaming===&lt;br /&gt;
Syntax:&lt;br /&gt;
  CShipManager.TransferToShip(ToShipID, Amount, EBeamResource.Resource)&lt;br /&gt;
You just need to replace the parameters with the respective values. Here's an example:&lt;br /&gt;
  ShipManager.SelectShip (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
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:&lt;br /&gt;
  ShipManager.SelectFleet (1);&lt;br /&gt;
  ShipManager.TransferToShip (2, 20, EBeamRessource.Food);&lt;br /&gt;
&lt;br /&gt;
===Fliegen===&lt;br /&gt;
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.&lt;br /&gt;
====Fliegen mit dem Autopiloten====&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;'''''Nur für Spieler mit Feature-Pack oder unter Kolonisationslevel 8 möglich!'''''&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Befehl:&lt;br /&gt;
 ShipManager.FliegeZu(''xxx|yyy'');&lt;br /&gt;
Auch hier Gilt es wieder das kursive durch die eigenen Angaben zu ersetzten. Wie in folgendem Beispiel:&lt;br /&gt;
 ShipManager.BenutzteSchiff(1);&lt;br /&gt;
 ShipManager.FliegeZu('123|465');&lt;br /&gt;
oder mit dem Flottenbefehl:&lt;br /&gt;
 ShipManager.BenutzteFlotte(1);&lt;br /&gt;
 ShipManager.FliegeZu('123|465');&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Fliegen ohne Autopilot====&lt;br /&gt;
Der Befehl hierzu sieht wie folgt aus:&lt;br /&gt;
 ShipManager.Fliege(''Strecke'', EShipRichtung.''Richtung'');&lt;br /&gt;
Auch hier ersetzt du die kursiven Worte mit deinen Angaben, ein Beispiel folgt:&lt;br /&gt;
 ShipManager.BenutzteSchiff(1);&lt;br /&gt;
 ShipManager.Fliege(5, EShipRichtung.Hoch);&lt;br /&gt;
 ShipManager.Fliege(8, EshipRichtung.Links);&lt;br /&gt;
oder wenn es eine ganze Flotte ist:&lt;br /&gt;
 ShipManager.BenutzteFlotte(1);&lt;br /&gt;
 ShipManager.Fliege(5, EShipRichtung.Hoch);&lt;br /&gt;
 ShipManager.Fliege(8, EshipRichtung.Links);&lt;br /&gt;
&lt;br /&gt;
===Schiffsystem nutzen===&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
===Alternative zum Schiffsmanager: Schiffsaktion===&lt;br /&gt;
&lt;br /&gt;
Für Objekte des Typ's CMyFlotte und CMyShip kann über die Eigenschaft Aktion direkt auf die Funktionen des Schiffsmanagers zugegriffen werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Schiff AS CMyShip = new CMyShip( 4711 )&lt;br /&gt;
Schiff.Aktion.Abdocken()&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Flotte AS CMyFlotte = new CMyFlotte( 4711 )&lt;br /&gt;
Flotte.Aktion.Abdocken()&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Enumeration ist Alles==&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
==Methoden==&lt;br /&gt;
&lt;br /&gt;
Öfters wiederkehrende Aufgaben können in Methoden zusammengefasst werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function ShowKoords(x As Integer, y As Integer)&lt;br /&gt;
{&lt;br /&gt;
  WriteLine(CStr(x) + '|' + CStr(y));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Methode ShowKoords kann dann im Script folgendermaßen aufgerufen werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
ShowKoords(3, 4);&lt;br /&gt;
ShowKoords(ship.MapPosition.X,ship.MapPosition.Y);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn berechnete Werte von der Methode zurückgegeben werden sollen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function Distanz(x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer&lt;br /&gt;
{&lt;br /&gt;
  Var distanz As Integer;&lt;br /&gt;
  &lt;br /&gt;
  distanz = Math.Abs(x1 - x2) + Math.Abs(y1 - y2);&lt;br /&gt;
  Return distanz ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine(Distanz(1, 1, 5, 5));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
'ByRef' ist zwar in der Scriptengine vorgesehen und kann angegeben werden, ist aber derzeit ohne Funktion.&lt;br /&gt;
Objekte werden immer ByRef übergeben.&lt;br /&gt;
&lt;br /&gt;
==Klassen==&lt;br /&gt;
&lt;br /&gt;
In Klassen können Daten und Methoden in einem Objekt gekapselt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Class CKoords&lt;br /&gt;
{&lt;br /&gt;
  Var x As Integer;&lt;br /&gt;
  Var y As Integer;&lt;br /&gt;
  &lt;br /&gt;
  Function New(x As Integer, y As Integer)&lt;br /&gt;
  {&lt;br /&gt;
    This.x = x;&lt;br /&gt;
    This.y = y;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function ToString() As String&lt;br /&gt;
  {&lt;br /&gt;
    Return (CStr(x) + '|' + CStr(y);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function Distanz(koord As CKoords) As Integer&lt;br /&gt;
  {&lt;br /&gt;
    Return Math.Abs(x - koord.x) + Math.Abs(y - koord.y);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var ko1 As New CKoords(3, 5);&lt;br /&gt;
Var ko2 As CKoords;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ko2 = New CKoords(8, 9);&lt;br /&gt;
WriteLine('Distanz von ' + ko1.ToString() + ' nach ' + ko2.ToString() + ': ' + CStr(ko1.Distanz(ko2)));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig: Klassen brauchen immer eine Methode New(), sonst kann kein neues Objekt der Klasse generiert werden!&lt;br /&gt;
&lt;br /&gt;
==Autoren==&lt;br /&gt;
(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 ;)])&lt;br /&gt;
{|&lt;br /&gt;
!Nickname&lt;br /&gt;
!IG-id&lt;br /&gt;
!Kapitel&lt;br /&gt;
|-&lt;br /&gt;
|WiZz4Rd&lt;br /&gt;
|16475&lt;br /&gt;
|Kapitel 1, Kapitel 2, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|Stryke&lt;br /&gt;
|28885&lt;br /&gt;
|Vorwort, Kapitel 3, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|[[Spieler:Xenon|Xenon]]&lt;br /&gt;
|10127&lt;br /&gt;
|Korrektur &amp;amp; Überarbeitung Kapitel 1&lt;br /&gt;
|-&lt;br /&gt;
|Fling&lt;br /&gt;
|54865&lt;br /&gt;
|Kapitel 7, Kapitel 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Scripting-Hilfe|Anfängerkurs]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Basic_course</id>
		<title>Scripting:Basic course</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Basic_course"/>
				<updated>2011-11-11T17:38:03Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: /* Parameters */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedTranslation}}&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
'''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.'''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Vorwort==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Chapter 1 - Strings==&lt;br /&gt;
In programming a String is a series of characters. The chapter title would be a String as would this text. The famous line &amp;quot;Hello World!&amp;quot; is also a String and it is this String you will be working with.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Hello World!&amp;quot; ===&lt;br /&gt;
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 &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
In the STNE engine this is very easy.&lt;br /&gt;
First launch the script editor under:&lt;br /&gt;
Database -&amp;gt; Script Editor -&amp;gt; Create a new script -&amp;gt; Custom script without input wizard&lt;br /&gt;
Then you will click &amp;quot;Edit source code&amp;quot;.&lt;br /&gt;
In the text field provided type: &lt;br /&gt;
&amp;lt;pre&amp;gt;WriteLine('Hello World!');&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now click Save&amp;amp;Run.&lt;br /&gt;
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?&lt;br /&gt;
When it works you should see the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;Hello World!&amp;lt;/pre&amp;gt;&lt;br /&gt;
Congratulations you are now programming. Try making a program that says:&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World!&lt;br /&gt;
Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Your code should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!');&lt;br /&gt;
WriteLine('Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note every line of code ends with a semicolon.&lt;br /&gt;
But what if you want to write everything on one line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World! Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is done by use of the &amp;amp; symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!'&amp;amp;' Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;amp; 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!&lt;br /&gt;
&amp;quot;But wait!&amp;quot; You say. &amp;quot;I could simple code: &amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World! Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt; and never have to deal with the &amp;amp; symbol!&amp;quot;&lt;br /&gt;
True, and as a programmer you will have many choices of different ways to do things. But the '&amp;amp;' is important as you will find out in the next chapter.&lt;br /&gt;
&lt;br /&gt;
===Summary: Strings===&lt;br /&gt;
&lt;br /&gt;
* A String is a sequence of several characters.&lt;br /&gt;
* A String is output, or printed, using the command ''WriteLine();''.&lt;br /&gt;
* You may use the character &amp;amp; to combine one String with another within the parameters, or parentheses, of ''WriteLine();''.&lt;br /&gt;
&lt;br /&gt;
==Chapter 2 - Variables==&lt;br /&gt;
===Basic types===&lt;br /&gt;
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:&lt;br /&gt;
* String  - a series of characters&lt;br /&gt;
* Integer - a whole number&lt;br /&gt;
* Boolean - decision (True/False)&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Imagine you have a gigantic project with hundreds of lines of code. Dozens upon dozens of times your code will output the lines:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains log Stardate:&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
You could code:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Captains log Stardate:');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
every single time and maybe misspell it. Or you could use a variable.&lt;br /&gt;
Before a variable can be used, or called, it must be created. You do this with the word &amp;quot;Var&amp;quot; followed by the name followed by &amp;quot;As&amp;quot; followed by the type of variable it is followed by &amp;quot;=&amp;quot; followed by the data to be stored.&lt;br /&gt;
&lt;br /&gt;
Sound complicated?&lt;br /&gt;
Bear with us.&lt;br /&gt;
&lt;br /&gt;
In keeping with the above example let us declare a String variable that contains the line: 'Captains log Stardate:'&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
No two variables can have the same name though.&lt;br /&gt;
&lt;br /&gt;
Lets create a number, or integer, variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var SD As Integer = 234121;&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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).&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Things start to happen. Cool huh? Just in case your having trouble your code should look like this:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&lt;br /&gt;
Var SD As Integer = 234121;&lt;br /&gt;
WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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 &amp;amp; symbol. It stuck the integer and the string together!&lt;br /&gt;
The output looks like:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate:234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
See if you can find a way to get a space between the colon and the number...&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate: 234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Converting One Data Type to Another===&lt;br /&gt;
In many programming languages including an older version of the STNE engine you often need to convert variables from one type to another.&lt;br /&gt;
For instance if you had a variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;Var number As Integer = 12345;&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You couldn't use it in certain functions like &lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(number);&amp;lt;/pre&amp;gt;&lt;br /&gt;
Because the parameters for WriteLine() would only accept Strings and the variable 'number' is an Integer.&lt;br /&gt;
&lt;br /&gt;
In that case you would use another function CStr() to convert it to a String:&lt;br /&gt;
&amp;lt;Pre&amp;gt;CStr(number)&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You could even place that inside the parameters of WriteLine():&lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(CStr(number));&amp;lt;/Pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Likewise you could covert a String to it's integer value with CInt();&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Rules for Naming Variables===&lt;br /&gt;
There are some rules for naming your variables&lt;br /&gt;
* 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.&lt;br /&gt;
* Do not use spaces. Use capital letters to signify different words. &lt;br /&gt;
* 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.&lt;br /&gt;
* For clear coding consider starting your variable name with a three digits representing the variable type. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;intDeutNeeded&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
===Summary: Variables===&lt;br /&gt;
&lt;br /&gt;
* A variable takes the place of &amp;quot;hard coded&amp;quot; data.&lt;br /&gt;
* To create a variable use 'VAR &amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; AS &amp;lt;b&amp;gt;Datentype&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To assign data to a variable you use ''&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; = &amp;lt;b&amp;gt;Inhalt&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To output a variable use ''WriteLine(&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt;);'' This can be very important when debugging.&lt;br /&gt;
* The ''&amp;amp;'' symbol connects variables withing a  function call''WriteLine();''&lt;br /&gt;
&lt;br /&gt;
==Chapter 3 - Control Structures==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===If - Else===&lt;br /&gt;
This works exactly how it sounds. &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates a statement and when it is true will execute the next few lines of code that are within curly braces &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot;. You can also include an &amp;lt;B&amp;gt;ELSE&amp;lt;/B&amp;gt; statement that will execute when the &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates to false.&lt;br /&gt;
For example this code evaluates a variable and executes the code within the curly braces in response:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var tribbles As Boolean = True;&lt;br /&gt;
If (tribbles){&lt;br /&gt;
  WriteLine('Oh no! The food!');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('The food is safe.');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
 &lt;br /&gt;
You can also use an IF statement to compare amounts. In that case you would use the equal symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var EPSamount As Integer = 44;&lt;br /&gt;
If (EPSamount = 45){&lt;br /&gt;
  WriteLine('We have exactly ' &amp;amp; EPSamount &amp;amp; ' available');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Im givin her all shes got, Cpatain!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
You can also use &amp;quot;&amp;lt;&amp;quot;,&amp;quot;&amp;gt;&amp;quot;,&amp;quot;&amp;lt;=&amp;quot;,&amp;quot;&amp;gt;=&amp;quot; for different types of comparisons. In that order and in English those are called &amp;quot;less then&amp;quot;, &amp;quot;greater then&amp;quot;, &amp;quot;less then or equal to&amp;quot;, and &amp;quot;greater then or equal to&amp;quot;. These can be a little confusing at first so remember the bigger side of the symbol is toward the larger number. &amp;quot;a&amp;lt;b&amp;quot; says that a is less then b. b is greater.&lt;br /&gt;
You can also you the words &amp;quot;AND&amp;quot; and &amp;quot;OR&amp;quot; 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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
If ((dilth&amp;gt;5)AND(deut&amp;gt;10)AND(ANTIM&amp;gt;10)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var dilth AS Boolean = (dilthAmount&amp;gt;5);&lt;br /&gt;
Var deut AS Boolean = (deutAmount&amp;gt;10);&lt;br /&gt;
Var antiM As Boolean = (antiMAmount&amp;gt;10);&lt;br /&gt;
If ((dilth)AND(deut)AND(antiM)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is completely up to you!&lt;br /&gt;
&lt;br /&gt;
===Loops===&lt;br /&gt;
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 &amp;quot;{&amp;quot; &amp;quot;}&amp;quot; but a loop will not exit until the conditions that started become false.&lt;br /&gt;
&lt;br /&gt;
====While====&lt;br /&gt;
Consider the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var isKilingon As Boolean = True;&lt;br /&gt;
while (isKilingon){&lt;br /&gt;
  WriteLine('Today is a good day to die!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Enough battle!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Do====&lt;br /&gt;
DO loops work just like WHILE loops except that regardless the evaluation a DO will execute at least once. &lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
VAR friendlyShip AS Boolean = False;&lt;br /&gt;
WriteLine('Ship on Federation sensors');&lt;br /&gt;
Do(friendlyShip){&lt;br /&gt;
  WriteLine('Hale them.');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('No response. Open fire!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====For====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This could also be written using a FOR loop:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
for(ore=0 To 12 Step 2){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you do not specify a step it will assume the step is 1.&lt;br /&gt;
&lt;br /&gt;
==Chapter 4 - Functions==&lt;br /&gt;
===Introduction===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('Get them out of there!');&lt;br /&gt;
WriteLine('Attempting to beam up away-team');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
But you want to run that ten times.&lt;br /&gt;
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.&lt;br /&gt;
To create a function you use the following formula 'Function' followed by the name you give it, followed by the symbols &amp;quot;(){}&amp;quot;&lt;br /&gt;
Here is an example using the code above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Parameters===&lt;br /&gt;
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 &amp;quot;()&amp;quot;. 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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
Now when you make the function call you need to pass it values that match it's parameters.&lt;br /&gt;
In the above example you might call it this way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
BeamUp(5, True, Medics);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also for clarity consider keeping your Functions separate from your main code either all above or all bellow.&lt;br /&gt;
&lt;br /&gt;
Now that we now have a few basics, let us turn to the really interesting parts, the control of the game content through scripts.&lt;br /&gt;
&lt;br /&gt;
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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Var ShipManager As New CShipManager();&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To assign the safety officer, there are the commands:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectShip(NCC-Number of Ship);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
or,&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectFleet(ID of Fleet);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way the ShipManager knows which ship or fleet to interact with.&lt;br /&gt;
&lt;br /&gt;
With the Ship Managers, you can do the following:&lt;br /&gt;
* Docking and undocking&lt;br /&gt;
* Alert level change&lt;br /&gt;
* Escape from fleets&lt;br /&gt;
* Enter or leave orbit&lt;br /&gt;
* Rename (name As String)&lt;br /&gt;
* Collect deuterium (only with FP)&lt;br /&gt;
* Gather ore (only with FP)&lt;br /&gt;
* Fly (AutoPilot, only with FP)&lt;br /&gt;
* Fly (Using the FlyTo() method)&lt;br /&gt;
* Tractor beam on / off&lt;br /&gt;
* Beaming&lt;br /&gt;
* Hide&lt;br /&gt;
* Enable / Disable the Replicators&lt;br /&gt;
* Jettison Goods &lt;br /&gt;
* Enable / Disable the Warp Core &lt;br /&gt;
* Wreck extraction&lt;br /&gt;
* And more&lt;br /&gt;
&lt;br /&gt;
For a complete list of the features found in [http://game.stne.net/ObjectExplorer.aspx?p=CShipManager Object Explorer].&lt;br /&gt;
&lt;br /&gt;
Next, we will look at some specific features:&lt;br /&gt;
&lt;br /&gt;
===Beamen===&lt;br /&gt;
Syntaxe:&lt;br /&gt;
 ShipManager.TransferiereZuSchiff(''Schiffid'', ''Menge'', EBeamRessource.''Ware'');&lt;br /&gt;
Hier musst du nun nurnoch den kursiven Text mit deinen Angaben ersetzten. Hier ein Beispiele:&lt;br /&gt;
 ShipManager.BenutzteSchiff(1);&lt;br /&gt;
 ShipManager.TransferiereZuSchiff(2, 20, EBeamRessource.Nahrung);&lt;br /&gt;
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:&lt;br /&gt;
 ShipManager.BenutzteFlotte(1);&lt;br /&gt;
 ShipManager.TransferiereZuSchiff(2, 20, EBeamRessource.Nahrung);&lt;br /&gt;
&lt;br /&gt;
===Fliegen===&lt;br /&gt;
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.&lt;br /&gt;
====Fliegen mit dem Autopiloten====&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;'''''Nur für Spieler mit Feature-Pack oder unter Kolonisationslevel 8 möglich!'''''&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Befehl:&lt;br /&gt;
 ShipManager.FliegeZu(''xxx|yyy'');&lt;br /&gt;
Auch hier Gilt es wieder das kursive durch die eigenen Angaben zu ersetzten. Wie in folgendem Beispiel:&lt;br /&gt;
 ShipManager.BenutzteSchiff(1);&lt;br /&gt;
 ShipManager.FliegeZu('123|465');&lt;br /&gt;
oder mit dem Flottenbefehl:&lt;br /&gt;
 ShipManager.BenutzteFlotte(1);&lt;br /&gt;
 ShipManager.FliegeZu('123|465');&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Fliegen ohne Autopilot====&lt;br /&gt;
Der Befehl hierzu sieht wie folgt aus:&lt;br /&gt;
 ShipManager.Fliege(''Strecke'', EShipRichtung.''Richtung'');&lt;br /&gt;
Auch hier ersetzt du die kursiven Worte mit deinen Angaben, ein Beispiel folgt:&lt;br /&gt;
 ShipManager.BenutzteSchiff(1);&lt;br /&gt;
 ShipManager.Fliege(5, EShipRichtung.Hoch);&lt;br /&gt;
 ShipManager.Fliege(8, EshipRichtung.Links);&lt;br /&gt;
oder wenn es eine ganze Flotte ist:&lt;br /&gt;
 ShipManager.BenutzteFlotte(1);&lt;br /&gt;
 ShipManager.Fliege(5, EShipRichtung.Hoch);&lt;br /&gt;
 ShipManager.Fliege(8, EshipRichtung.Links);&lt;br /&gt;
&lt;br /&gt;
===Schiffsystem nutzen===&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
===Alternative zum Schiffsmanager: Schiffsaktion===&lt;br /&gt;
&lt;br /&gt;
Für Objekte des Typ's CMyFlotte und CMyShip kann über die Eigenschaft Aktion direkt auf die Funktionen des Schiffsmanagers zugegriffen werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Schiff AS CMyShip = new CMyShip( 4711 )&lt;br /&gt;
Schiff.Aktion.Abdocken()&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Flotte AS CMyFlotte = new CMyFlotte( 4711 )&lt;br /&gt;
Flotte.Aktion.Abdocken()&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Enumeration ist Alles==&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
==Methoden==&lt;br /&gt;
&lt;br /&gt;
Öfters wiederkehrende Aufgaben können in Methoden zusammengefasst werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function ShowKoords(x As Integer, y As Integer)&lt;br /&gt;
{&lt;br /&gt;
  WriteLine(CStr(x) + '|' + CStr(y));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Methode ShowKoords kann dann im Script folgendermaßen aufgerufen werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
ShowKoords(3, 4);&lt;br /&gt;
ShowKoords(ship.MapPosition.X,ship.MapPosition.Y);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn berechnete Werte von der Methode zurückgegeben werden sollen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function Distanz(x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer&lt;br /&gt;
{&lt;br /&gt;
  Var distanz As Integer;&lt;br /&gt;
  &lt;br /&gt;
  distanz = Math.Abs(x1 - x2) + Math.Abs(y1 - y2);&lt;br /&gt;
  Return distanz ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine(Distanz(1, 1, 5, 5));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
'ByRef' ist zwar in der Scriptengine vorgesehen und kann angegeben werden, ist aber derzeit ohne Funktion.&lt;br /&gt;
Objekte werden immer ByRef übergeben.&lt;br /&gt;
&lt;br /&gt;
==Klassen==&lt;br /&gt;
&lt;br /&gt;
In Klassen können Daten und Methoden in einem Objekt gekapselt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Class CKoords&lt;br /&gt;
{&lt;br /&gt;
  Var x As Integer;&lt;br /&gt;
  Var y As Integer;&lt;br /&gt;
  &lt;br /&gt;
  Function New(x As Integer, y As Integer)&lt;br /&gt;
  {&lt;br /&gt;
    This.x = x;&lt;br /&gt;
    This.y = y;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function ToString() As String&lt;br /&gt;
  {&lt;br /&gt;
    Return (CStr(x) + '|' + CStr(y);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function Distanz(koord As CKoords) As Integer&lt;br /&gt;
  {&lt;br /&gt;
    Return Math.Abs(x - koord.x) + Math.Abs(y - koord.y);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var ko1 As New CKoords(3, 5);&lt;br /&gt;
Var ko2 As CKoords;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ko2 = New CKoords(8, 9);&lt;br /&gt;
WriteLine('Distanz von ' + ko1.ToString() + ' nach ' + ko2.ToString() + ': ' + CStr(ko1.Distanz(ko2)));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig: Klassen brauchen immer eine Methode New(), sonst kann kein neues Objekt der Klasse generiert werden!&lt;br /&gt;
&lt;br /&gt;
==Autoren==&lt;br /&gt;
(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 ;)])&lt;br /&gt;
{|&lt;br /&gt;
!Nickname&lt;br /&gt;
!IG-id&lt;br /&gt;
!Kapitel&lt;br /&gt;
|-&lt;br /&gt;
|WiZz4Rd&lt;br /&gt;
|16475&lt;br /&gt;
|Kapitel 1, Kapitel 2, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|Stryke&lt;br /&gt;
|28885&lt;br /&gt;
|Vorwort, Kapitel 3, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|[[Spieler:Xenon|Xenon]]&lt;br /&gt;
|10127&lt;br /&gt;
|Korrektur &amp;amp; Überarbeitung Kapitel 1&lt;br /&gt;
|-&lt;br /&gt;
|Fling&lt;br /&gt;
|54865&lt;br /&gt;
|Kapitel 7, Kapitel 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Scripting-Hilfe|Anfängerkurs]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Basic_course</id>
		<title>Scripting:Basic course</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Basic_course"/>
				<updated>2011-11-11T17:19:57Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedTranslation}}&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
'''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.'''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Vorwort==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Chapter 1 - Strings==&lt;br /&gt;
In programming a String is a series of characters. The chapter title would be a String as would this text. The famous line &amp;quot;Hello World!&amp;quot; is also a String and it is this String you will be working with.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Hello World!&amp;quot; ===&lt;br /&gt;
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 &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
In the STNE engine this is very easy.&lt;br /&gt;
First launch the script editor under:&lt;br /&gt;
Database -&amp;gt; Script Editor -&amp;gt; Create a new script -&amp;gt; Custom script without input wizard&lt;br /&gt;
Then you will click &amp;quot;Edit source code&amp;quot;.&lt;br /&gt;
In the text field provided type: &lt;br /&gt;
&amp;lt;pre&amp;gt;WriteLine('Hello World!');&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now click Save&amp;amp;Run.&lt;br /&gt;
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?&lt;br /&gt;
When it works you should see the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;Hello World!&amp;lt;/pre&amp;gt;&lt;br /&gt;
Congratulations you are now programming. Try making a program that says:&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World!&lt;br /&gt;
Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Your code should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!');&lt;br /&gt;
WriteLine('Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note every line of code ends with a semicolon.&lt;br /&gt;
But what if you want to write everything on one line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World! Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is done by use of the &amp;amp; symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!'&amp;amp;' Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;amp; 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!&lt;br /&gt;
&amp;quot;But wait!&amp;quot; You say. &amp;quot;I could simple code: &amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World! Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt; and never have to deal with the &amp;amp; symbol!&amp;quot;&lt;br /&gt;
True, and as a programmer you will have many choices of different ways to do things. But the '&amp;amp;' is important as you will find out in the next chapter.&lt;br /&gt;
&lt;br /&gt;
===Summary: Strings===&lt;br /&gt;
&lt;br /&gt;
* A String is a sequence of several characters.&lt;br /&gt;
* A String is output, or printed, using the command ''WriteLine();''.&lt;br /&gt;
* You may use the character &amp;amp; to combine one String with another within the parameters, or parentheses, of ''WriteLine();''.&lt;br /&gt;
&lt;br /&gt;
==Chapter 2 - Variables==&lt;br /&gt;
===Basic types===&lt;br /&gt;
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:&lt;br /&gt;
* String  - a series of characters&lt;br /&gt;
* Integer - a whole number&lt;br /&gt;
* Boolean - decision (True/False)&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Imagine you have a gigantic project with hundreds of lines of code. Dozens upon dozens of times your code will output the lines:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains log Stardate:&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
You could code:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Captains log Stardate:');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
every single time and maybe misspell it. Or you could use a variable.&lt;br /&gt;
Before a variable can be used, or called, it must be created. You do this with the word &amp;quot;Var&amp;quot; followed by the name followed by &amp;quot;As&amp;quot; followed by the type of variable it is followed by &amp;quot;=&amp;quot; followed by the data to be stored.&lt;br /&gt;
&lt;br /&gt;
Sound complicated?&lt;br /&gt;
Bear with us.&lt;br /&gt;
&lt;br /&gt;
In keeping with the above example let us declare a String variable that contains the line: 'Captains log Stardate:'&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
No two variables can have the same name though.&lt;br /&gt;
&lt;br /&gt;
Lets create a number, or integer, variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var SD As Integer = 234121;&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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).&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Things start to happen. Cool huh? Just in case your having trouble your code should look like this:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&lt;br /&gt;
Var SD As Integer = 234121;&lt;br /&gt;
WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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 &amp;amp; symbol. It stuck the integer and the string together!&lt;br /&gt;
The output looks like:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate:234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
See if you can find a way to get a space between the colon and the number...&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate: 234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Converting One Data Type to Another===&lt;br /&gt;
In many programming languages including an older version of the STNE engine you often need to convert variables from one type to another.&lt;br /&gt;
For instance if you had a variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;Var number As Integer = 12345;&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You couldn't use it in certain functions like &lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(number);&amp;lt;/pre&amp;gt;&lt;br /&gt;
Because the parameters for WriteLine() would only accept Strings and the variable 'number' is an Integer.&lt;br /&gt;
&lt;br /&gt;
In that case you would use another function CStr() to convert it to a String:&lt;br /&gt;
&amp;lt;Pre&amp;gt;CStr(number)&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You could even place that inside the parameters of WriteLine():&lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(CStr(number));&amp;lt;/Pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Likewise you could covert a String to it's integer value with CInt();&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Rules for Naming Variables===&lt;br /&gt;
There are some rules for naming your variables&lt;br /&gt;
* 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.&lt;br /&gt;
* Do not use spaces. Use capital letters to signify different words. &lt;br /&gt;
* 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.&lt;br /&gt;
* For clear coding consider starting your variable name with a three digits representing the variable type. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;intDeutNeeded&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
===Summary: Variables===&lt;br /&gt;
&lt;br /&gt;
* A variable takes the place of &amp;quot;hard coded&amp;quot; data.&lt;br /&gt;
* To create a variable use 'VAR &amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; AS &amp;lt;b&amp;gt;Datentype&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To assign data to a variable you use ''&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; = &amp;lt;b&amp;gt;Inhalt&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To output a variable use ''WriteLine(&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt;);'' This can be very important when debugging.&lt;br /&gt;
* The ''&amp;amp;'' symbol connects variables withing a  function call''WriteLine();''&lt;br /&gt;
&lt;br /&gt;
==Chapter 3 - Control Structures==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===If - Else===&lt;br /&gt;
This works exactly how it sounds. &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates a statement and when it is true will execute the next few lines of code that are within curly braces &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot;. You can also include an &amp;lt;B&amp;gt;ELSE&amp;lt;/B&amp;gt; statement that will execute when the &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates to false.&lt;br /&gt;
For example this code evaluates a variable and executes the code within the curly braces in response:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var tribbles As Boolean = True;&lt;br /&gt;
If (tribbles){&lt;br /&gt;
  WriteLine('Oh no! The food!');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('The food is safe.');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
 &lt;br /&gt;
You can also use an IF statement to compare amounts. In that case you would use the equal symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var EPSamount As Integer = 44;&lt;br /&gt;
If (EPSamount = 45){&lt;br /&gt;
  WriteLine('We have exactly ' &amp;amp; EPSamount &amp;amp; ' available');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Im givin her all shes got, Cpatain!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
You can also use &amp;quot;&amp;lt;&amp;quot;,&amp;quot;&amp;gt;&amp;quot;,&amp;quot;&amp;lt;=&amp;quot;,&amp;quot;&amp;gt;=&amp;quot; for different types of comparisons. In that order and in English those are called &amp;quot;less then&amp;quot;, &amp;quot;greater then&amp;quot;, &amp;quot;less then or equal to&amp;quot;, and &amp;quot;greater then or equal to&amp;quot;. These can be a little confusing at first so remember the bigger side of the symbol is toward the larger number. &amp;quot;a&amp;lt;b&amp;quot; says that a is less then b. b is greater.&lt;br /&gt;
You can also you the words &amp;quot;AND&amp;quot; and &amp;quot;OR&amp;quot; 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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
If ((dilth&amp;gt;5)AND(deut&amp;gt;10)AND(ANTIM&amp;gt;10)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var dilth AS Boolean = (dilthAmount&amp;gt;5);&lt;br /&gt;
Var deut AS Boolean = (deutAmount&amp;gt;10);&lt;br /&gt;
Var antiM As Boolean = (antiMAmount&amp;gt;10);&lt;br /&gt;
If ((dilth)AND(deut)AND(antiM)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is completely up to you!&lt;br /&gt;
&lt;br /&gt;
===Loops===&lt;br /&gt;
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 &amp;quot;{&amp;quot; &amp;quot;}&amp;quot; but a loop will not exit until the conditions that started become false.&lt;br /&gt;
&lt;br /&gt;
====While====&lt;br /&gt;
Consider the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var isKilingon As Boolean = True;&lt;br /&gt;
while (isKilingon){&lt;br /&gt;
  WriteLine('Today is a good day to die!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Enough battle!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Do====&lt;br /&gt;
DO loops work just like WHILE loops except that regardless the evaluation a DO will execute at least once. &lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
VAR friendlyShip AS Boolean = False;&lt;br /&gt;
WriteLine('Ship on Federation sensors');&lt;br /&gt;
Do(friendlyShip){&lt;br /&gt;
  WriteLine('Hale them.');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('No response. Open fire!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====For====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This could also be written using a FOR loop:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
for(ore=0 To 12 Step 2){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you do not specify a step it will assume the step is 1.&lt;br /&gt;
&lt;br /&gt;
==Chapter 4 - Functions==&lt;br /&gt;
===Introduction===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('Get them out of there!');&lt;br /&gt;
WriteLine('Attempting to beam up away-team');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
But you want to run that ten times.&lt;br /&gt;
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.&lt;br /&gt;
To create a function you use the following formula 'Function' followed by the name you give it, followed by the symbols &amp;quot;(){}&amp;quot;&lt;br /&gt;
Here is an example using the code above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Parameters===&lt;br /&gt;
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 &amp;quot;()&amp;quot;. 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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
Now when you make the function call you need to pass it values that match it's parameters.&lt;br /&gt;
In the above example you might call it this way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
BeamUp(5, True, Medics);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also for clarity consider keeping your Functions separate from your main code either all above or all bellow.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that we now have a few basics, let us turn to the really interesting things, the control of game content through scripts.&lt;br /&gt;
&lt;br /&gt;
To interact with ships there is a collection of methods, which can be found in the Ship managers  CShipManager. For this we must first assign a Ship manager to either a ship or a fleet.&lt;br /&gt;
&lt;br /&gt;
To assign the safety officer, there are the commands:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectShip(NCC-Number of Ship);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
or,&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectFleet(ID of Fleet);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit weiß der ShipManager schonmal welches Schiff, bzw. welche Flotte die Aktionen ausführen soll.&lt;br /&gt;
&lt;br /&gt;
Mit dem Shipmanager können folgende Aktionen ausgeführt werden:&lt;br /&gt;
*An- und Abdocken&lt;br /&gt;
*Alarm Stufe ändern&lt;br /&gt;
*Aus Flotten austreten&lt;br /&gt;
*Aus Orbit einfliegen austreten &lt;br /&gt;
*Benennen(Name As String)&lt;br /&gt;
*Deuterium sammeln (Nur mit FP)&lt;br /&gt;
*Erz sammeln (Nur mit FP)&lt;br /&gt;
*Fliegen&lt;br /&gt;
*Sensoren aktivieren / deaktivieren&lt;br /&gt;
*Reparieren&lt;br /&gt;
*Batterien entladen&lt;br /&gt;
*Schilde aktivieren/deaktiviere/aufladen&lt;br /&gt;
*Reservebatterie aufladen&lt;br /&gt;
*Traktorstrahl ein- / ausschalten&lt;br /&gt;
*Beamen&lt;br /&gt;
*Verstecken&lt;br /&gt;
*Replikator aktivieren/deaktivieren&lt;br /&gt;
*Waren über Bord werfen&lt;br /&gt;
*Warpkern aktiveren/deaktivieren&lt;br /&gt;
*Wrackextraktoren&lt;br /&gt;
&lt;br /&gt;
Eine vollständige Auflistung aller Funktionen findet sich im [http://game.stne.net/ObjectExplorer.aspx?p=CShipManager Objekt-Explorer].&lt;br /&gt;
&lt;br /&gt;
Im folgenden wollen wir uns einige Funktionen genauer anschauen:&lt;br /&gt;
===Beamen===&lt;br /&gt;
Syntaxe:&lt;br /&gt;
 ShipManager.TransferiereZuSchiff(''Schiffid'', ''Menge'', EBeamRessource.''Ware'');&lt;br /&gt;
Hier musst du nun nurnoch den kursiven Text mit deinen Angaben ersetzten. Hier ein Beispiele:&lt;br /&gt;
 ShipManager.BenutzteSchiff(1);&lt;br /&gt;
 ShipManager.TransferiereZuSchiff(2, 20, EBeamRessource.Nahrung);&lt;br /&gt;
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:&lt;br /&gt;
 ShipManager.BenutzteFlotte(1);&lt;br /&gt;
 ShipManager.TransferiereZuSchiff(2, 20, EBeamRessource.Nahrung);&lt;br /&gt;
&lt;br /&gt;
===Fliegen===&lt;br /&gt;
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.&lt;br /&gt;
====Fliegen mit dem Autopiloten====&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;'''''Nur für Spieler mit Feature-Pack oder unter Kolonisationslevel 8 möglich!'''''&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Befehl:&lt;br /&gt;
 ShipManager.FliegeZu(''xxx|yyy'');&lt;br /&gt;
Auch hier Gilt es wieder das kursive durch die eigenen Angaben zu ersetzten. Wie in folgendem Beispiel:&lt;br /&gt;
 ShipManager.BenutzteSchiff(1);&lt;br /&gt;
 ShipManager.FliegeZu('123|465');&lt;br /&gt;
oder mit dem Flottenbefehl:&lt;br /&gt;
 ShipManager.BenutzteFlotte(1);&lt;br /&gt;
 ShipManager.FliegeZu('123|465');&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Fliegen ohne Autopilot====&lt;br /&gt;
Der Befehl hierzu sieht wie folgt aus:&lt;br /&gt;
 ShipManager.Fliege(''Strecke'', EShipRichtung.''Richtung'');&lt;br /&gt;
Auch hier ersetzt du die kursiven Worte mit deinen Angaben, ein Beispiel folgt:&lt;br /&gt;
 ShipManager.BenutzteSchiff(1);&lt;br /&gt;
 ShipManager.Fliege(5, EShipRichtung.Hoch);&lt;br /&gt;
 ShipManager.Fliege(8, EshipRichtung.Links);&lt;br /&gt;
oder wenn es eine ganze Flotte ist:&lt;br /&gt;
 ShipManager.BenutzteFlotte(1);&lt;br /&gt;
 ShipManager.Fliege(5, EShipRichtung.Hoch);&lt;br /&gt;
 ShipManager.Fliege(8, EshipRichtung.Links);&lt;br /&gt;
&lt;br /&gt;
===Schiffsystem nutzen===&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
===Alternative zum Schiffsmanager: Schiffsaktion===&lt;br /&gt;
&lt;br /&gt;
Für Objekte des Typ's CMyFlotte und CMyShip kann über die Eigenschaft Aktion direkt auf die Funktionen des Schiffsmanagers zugegriffen werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Schiff AS CMyShip = new CMyShip( 4711 )&lt;br /&gt;
Schiff.Aktion.Abdocken()&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Flotte AS CMyFlotte = new CMyFlotte( 4711 )&lt;br /&gt;
Flotte.Aktion.Abdocken()&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Enumeration ist Alles==&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
==Methoden==&lt;br /&gt;
&lt;br /&gt;
Öfters wiederkehrende Aufgaben können in Methoden zusammengefasst werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function ShowKoords(x As Integer, y As Integer)&lt;br /&gt;
{&lt;br /&gt;
  WriteLine(CStr(x) + '|' + CStr(y));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Methode ShowKoords kann dann im Script folgendermaßen aufgerufen werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
ShowKoords(3, 4);&lt;br /&gt;
ShowKoords(ship.MapPosition.X,ship.MapPosition.Y);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn berechnete Werte von der Methode zurückgegeben werden sollen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function Distanz(x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer&lt;br /&gt;
{&lt;br /&gt;
  Var distanz As Integer;&lt;br /&gt;
  &lt;br /&gt;
  distanz = Math.Abs(x1 - x2) + Math.Abs(y1 - y2);&lt;br /&gt;
  Return distanz ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine(Distanz(1, 1, 5, 5));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
'ByRef' ist zwar in der Scriptengine vorgesehen und kann angegeben werden, ist aber derzeit ohne Funktion.&lt;br /&gt;
Objekte werden immer ByRef übergeben.&lt;br /&gt;
&lt;br /&gt;
==Klassen==&lt;br /&gt;
&lt;br /&gt;
In Klassen können Daten und Methoden in einem Objekt gekapselt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Class CKoords&lt;br /&gt;
{&lt;br /&gt;
  Var x As Integer;&lt;br /&gt;
  Var y As Integer;&lt;br /&gt;
  &lt;br /&gt;
  Function New(x As Integer, y As Integer)&lt;br /&gt;
  {&lt;br /&gt;
    This.x = x;&lt;br /&gt;
    This.y = y;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function ToString() As String&lt;br /&gt;
  {&lt;br /&gt;
    Return (CStr(x) + '|' + CStr(y);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function Distanz(koord As CKoords) As Integer&lt;br /&gt;
  {&lt;br /&gt;
    Return Math.Abs(x - koord.x) + Math.Abs(y - koord.y);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var ko1 As New CKoords(3, 5);&lt;br /&gt;
Var ko2 As CKoords;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ko2 = New CKoords(8, 9);&lt;br /&gt;
WriteLine('Distanz von ' + ko1.ToString() + ' nach ' + ko2.ToString() + ': ' + CStr(ko1.Distanz(ko2)));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig: Klassen brauchen immer eine Methode New(), sonst kann kein neues Objekt der Klasse generiert werden!&lt;br /&gt;
&lt;br /&gt;
==Autoren==&lt;br /&gt;
(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 ;)])&lt;br /&gt;
{|&lt;br /&gt;
!Nickname&lt;br /&gt;
!IG-id&lt;br /&gt;
!Kapitel&lt;br /&gt;
|-&lt;br /&gt;
|WiZz4Rd&lt;br /&gt;
|16475&lt;br /&gt;
|Kapitel 1, Kapitel 2, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|Stryke&lt;br /&gt;
|28885&lt;br /&gt;
|Vorwort, Kapitel 3, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|[[Spieler:Xenon|Xenon]]&lt;br /&gt;
|10127&lt;br /&gt;
|Korrektur &amp;amp; Überarbeitung Kapitel 1&lt;br /&gt;
|-&lt;br /&gt;
|Fling&lt;br /&gt;
|54865&lt;br /&gt;
|Kapitel 7, Kapitel 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Scripting-Hilfe|Anfängerkurs]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Basic_course</id>
		<title>Scripting:Basic course</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Basic_course"/>
				<updated>2011-11-11T17:10:57Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedTranslation}}&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
'''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.'''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Vorwort==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Chapter 1 - Strings==&lt;br /&gt;
In programming a String is a series of characters. The chapter title would be a String as would this text. The famous line &amp;quot;Hello World!&amp;quot; is also a String and it is this String you will be working with.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Hello World!&amp;quot; ===&lt;br /&gt;
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 &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
In the STNE engine this is very easy.&lt;br /&gt;
First launch the script editor under:&lt;br /&gt;
Database -&amp;gt; Script Editor -&amp;gt; Create a new script -&amp;gt; Custom script without input wizard&lt;br /&gt;
Then you will click &amp;quot;Edit source code&amp;quot;.&lt;br /&gt;
In the text field provided type: &lt;br /&gt;
&amp;lt;pre&amp;gt;WriteLine('Hello World!');&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now click Save&amp;amp;Run.&lt;br /&gt;
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?&lt;br /&gt;
When it works you should see the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;Hello World!&amp;lt;/pre&amp;gt;&lt;br /&gt;
Congratulations you are now programming. Try making a program that says:&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World!&lt;br /&gt;
Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Your code should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!');&lt;br /&gt;
WriteLine('Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note every line of code ends with a semicolon.&lt;br /&gt;
But what if you want to write everything on one line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World! Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is done by use of the &amp;amp; symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!'&amp;amp;' Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;amp; 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!&lt;br /&gt;
&amp;quot;But wait!&amp;quot; You say. &amp;quot;I could simple code: &amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World! Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt; and never have to deal with the &amp;amp; symbol!&amp;quot;&lt;br /&gt;
True, and as a programmer you will have many choices of different ways to do things. But the '&amp;amp;' is important as you will find out in the next chapter.&lt;br /&gt;
&lt;br /&gt;
===Summary: Strings===&lt;br /&gt;
&lt;br /&gt;
* A String is a sequence of several characters.&lt;br /&gt;
* A String is output, or printed, using the command ''WriteLine();''.&lt;br /&gt;
* You may use the character &amp;amp; to combine one String with another within the parameters, or parentheses, of ''WriteLine();''.&lt;br /&gt;
&lt;br /&gt;
==Chapter 2 - Variables==&lt;br /&gt;
===Basic types===&lt;br /&gt;
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:&lt;br /&gt;
* String  - a series of characters&lt;br /&gt;
* Integer - a whole number&lt;br /&gt;
* Boolean - decision (True/False)&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Imagine you have a gigantic project with hundreds of lines of code. Dozens upon dozens of times your code will output the lines:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains log Stardate:&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
You could code:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Captains log Stardate:');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
every single time and maybe misspell it. Or you could use a variable.&lt;br /&gt;
Before a variable can be used, or called, it must be created. You do this with the word &amp;quot;Var&amp;quot; followed by the name followed by &amp;quot;As&amp;quot; followed by the type of variable it is followed by &amp;quot;=&amp;quot; followed by the data to be stored.&lt;br /&gt;
&lt;br /&gt;
Sound complicated?&lt;br /&gt;
Bear with us.&lt;br /&gt;
&lt;br /&gt;
In keeping with the above example let us declare a String variable that contains the line: 'Captains log Stardate:'&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
No two variables can have the same name though.&lt;br /&gt;
&lt;br /&gt;
Lets create a number, or integer, variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var SD As Integer = 234121;&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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).&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Things start to happen. Cool huh? Just in case your having trouble your code should look like this:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&lt;br /&gt;
Var SD As Integer = 234121;&lt;br /&gt;
WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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 &amp;amp; symbol. It stuck the integer and the string together!&lt;br /&gt;
The output looks like:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate:234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
See if you can find a way to get a space between the colon and the number...&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate: 234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Converting One Data Type to Another===&lt;br /&gt;
In many programming languages including an older version of the STNE engine you often need to convert variables from one type to another.&lt;br /&gt;
For instance if you had a variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;Var number As Integer = 12345;&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You couldn't use it in certain functions like &lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(number);&amp;lt;/pre&amp;gt;&lt;br /&gt;
Because the parameters for WriteLine() would only accept Strings and the variable 'number' is an Integer.&lt;br /&gt;
&lt;br /&gt;
In that case you would use another function CStr() to convert it to a String:&lt;br /&gt;
&amp;lt;Pre&amp;gt;CStr(number)&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You could even place that inside the parameters of WriteLine():&lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(CStr(number));&amp;lt;/Pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Likewise you could covert a String to it's integer value with CInt();&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Rules for Naming Variables===&lt;br /&gt;
There are some rules for naming your variables&lt;br /&gt;
* 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.&lt;br /&gt;
* Do not use spaces. Use capital letters to signify different words. &lt;br /&gt;
* 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.&lt;br /&gt;
* For clear coding consider starting your variable name with a three digits representing the variable type. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;intDeutNeeded&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
===Summary: Variables===&lt;br /&gt;
&lt;br /&gt;
* A variable takes the place of &amp;quot;hard coded&amp;quot; data.&lt;br /&gt;
* To create a variable use 'VAR &amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; AS &amp;lt;b&amp;gt;Datentype&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To assign data to a variable you use ''&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; = &amp;lt;b&amp;gt;Inhalt&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To output a variable use ''WriteLine(&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt;);'' This can be very important when debugging.&lt;br /&gt;
* The ''&amp;amp;'' symbol connects variables withing a  function call''WriteLine();''&lt;br /&gt;
&lt;br /&gt;
==Chapter 3 - Control Structures==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===If - Else===&lt;br /&gt;
This works exactly how it sounds. &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates a statement and when it is true will execute the next few lines of code that are within curly braces &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot;. You can also include an &amp;lt;B&amp;gt;ELSE&amp;lt;/B&amp;gt; statement that will execute when the &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates to false.&lt;br /&gt;
For example this code evaluates a variable and executes the code within the curly braces in response:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var tribbles As Boolean = True;&lt;br /&gt;
If (tribbles){&lt;br /&gt;
  WriteLine('Oh no! The food!');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('The food is safe.');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
 &lt;br /&gt;
You can also use an IF statement to compare amounts. In that case you would use the equal symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var EPSamount As Integer = 44;&lt;br /&gt;
If (EPSamount = 45){&lt;br /&gt;
  WriteLine('We have exactly ' &amp;amp; EPSamount &amp;amp; ' available');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Im givin her all shes got, Cpatain!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
You can also use &amp;quot;&amp;lt;&amp;quot;,&amp;quot;&amp;gt;&amp;quot;,&amp;quot;&amp;lt;=&amp;quot;,&amp;quot;&amp;gt;=&amp;quot; for different types of comparisons. In that order and in English those are called &amp;quot;less then&amp;quot;, &amp;quot;greater then&amp;quot;, &amp;quot;less then or equal to&amp;quot;, and &amp;quot;greater then or equal to&amp;quot;. These can be a little confusing at first so remember the bigger side of the symbol is toward the larger number. &amp;quot;a&amp;lt;b&amp;quot; says that a is less then b. b is greater.&lt;br /&gt;
You can also you the words &amp;quot;AND&amp;quot; and &amp;quot;OR&amp;quot; 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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
If ((dilth&amp;gt;5)AND(deut&amp;gt;10)AND(ANTIM&amp;gt;10)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var dilth AS Boolean = (dilthAmount&amp;gt;5);&lt;br /&gt;
Var deut AS Boolean = (deutAmount&amp;gt;10);&lt;br /&gt;
Var antiM As Boolean = (antiMAmount&amp;gt;10);&lt;br /&gt;
If ((dilth)AND(deut)AND(antiM)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is completely up to you!&lt;br /&gt;
&lt;br /&gt;
===Loops===&lt;br /&gt;
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 &amp;quot;{&amp;quot; &amp;quot;}&amp;quot; but a loop will not exit until the conditions that started become false.&lt;br /&gt;
&lt;br /&gt;
====While====&lt;br /&gt;
Consider the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var isKilingon As Boolean = True;&lt;br /&gt;
while (isKilingon){&lt;br /&gt;
  WriteLine('Today is a good day to die!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Enough battle!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Do====&lt;br /&gt;
DO loops work just like WHILE loops except that regardless the evaluation a DO will execute at least once. &lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
VAR friendlyShip AS Boolean = False;&lt;br /&gt;
WriteLine('Ship on Federation sensors');&lt;br /&gt;
Do(friendlyShip){&lt;br /&gt;
  WriteLine('Hale them.');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('No response. Open fire!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====For====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This could also be written using a FOR loop:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
for(ore=0 To 12 Step 2){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you do not specify a step it will assume the step is 1.&lt;br /&gt;
&lt;br /&gt;
==Chapter 4 - Functions==&lt;br /&gt;
===Introduction===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('Get them out of there!');&lt;br /&gt;
WriteLine('Attempting to beam up away-team');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
But you want to run that ten times.&lt;br /&gt;
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.&lt;br /&gt;
To create a function you use the following formula 'Function' followed by the name you give it, followed by the symbols &amp;quot;(){}&amp;quot;&lt;br /&gt;
Here is an example using the code above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Parameters===&lt;br /&gt;
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 &amp;quot;()&amp;quot;. 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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
Now when you make the function call you need to pass it values that match it's parameters.&lt;br /&gt;
In the above example you might call it this way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
BeamUp(5, True, Medics);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also for clarity consider keeping your Functions separate from your main code either all above or all bellow.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nachdem wir nun über ein paar Grundlagen verfügen, wollen wir uns den wirklich interessanten Dingen zuwenden, der Steuerung von Spielinhalten durch Scripte.&lt;br /&gt;
&lt;br /&gt;
Um mit Schiffen zu interagieren gibt es eine Sammlung von Methoden, welche im Shipmanager zu finden sind.&lt;br /&gt;
Hierzu müssen wir dem Shipmanager als erstes Mitteilen, welches bzw. welche Flotte er verwenden soll.&lt;br /&gt;
&lt;br /&gt;
Hierführ gibt es die Befehle:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectShip(NCC-Nummer of Ship);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
or,&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectFleet(ID of Fleet);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit weiß der ShipManager schonmal welches Schiff, bzw. welche Flotte die Aktionen ausführen soll.&lt;br /&gt;
&lt;br /&gt;
Mit dem Shipmanager können folgende Aktionen ausgeführt werden:&lt;br /&gt;
*An- und Abdocken&lt;br /&gt;
*Alarm Stufe ändern&lt;br /&gt;
*Aus Flotten austreten&lt;br /&gt;
*Aus Orbit einfliegen austreten &lt;br /&gt;
*Benennen(Name As String)&lt;br /&gt;
*Deuterium sammeln (Nur mit FP)&lt;br /&gt;
*Erz sammeln (Nur mit FP)&lt;br /&gt;
*Fliegen&lt;br /&gt;
*Sensoren aktivieren / deaktivieren&lt;br /&gt;
*Reparieren&lt;br /&gt;
*Batterien entladen&lt;br /&gt;
*Schilde aktivieren/deaktiviere/aufladen&lt;br /&gt;
*Reservebatterie aufladen&lt;br /&gt;
*Traktorstrahl ein- / ausschalten&lt;br /&gt;
*Beamen&lt;br /&gt;
*Verstecken&lt;br /&gt;
*Replikator aktivieren/deaktivieren&lt;br /&gt;
*Waren über Bord werfen&lt;br /&gt;
*Warpkern aktiveren/deaktivieren&lt;br /&gt;
*Wrackextraktoren&lt;br /&gt;
&lt;br /&gt;
Eine vollständige Auflistung aller Funktionen findet sich im [http://game.stne.net/ObjectExplorer.aspx?p=CShipManager Objekt-Explorer].&lt;br /&gt;
&lt;br /&gt;
Im folgenden wollen wir uns einige Funktionen genauer anschauen:&lt;br /&gt;
===Beamen===&lt;br /&gt;
Syntaxe:&lt;br /&gt;
 ShipManager.TransferiereZuSchiff(''Schiffid'', ''Menge'', EBeamRessource.''Ware'');&lt;br /&gt;
Hier musst du nun nurnoch den kursiven Text mit deinen Angaben ersetzten. Hier ein Beispiele:&lt;br /&gt;
 ShipManager.BenutzteSchiff(1);&lt;br /&gt;
 ShipManager.TransferiereZuSchiff(2, 20, EBeamRessource.Nahrung);&lt;br /&gt;
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:&lt;br /&gt;
 ShipManager.BenutzteFlotte(1);&lt;br /&gt;
 ShipManager.TransferiereZuSchiff(2, 20, EBeamRessource.Nahrung);&lt;br /&gt;
&lt;br /&gt;
===Fliegen===&lt;br /&gt;
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.&lt;br /&gt;
====Fliegen mit dem Autopiloten====&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;'''''Nur für Spieler mit Feature-Pack oder unter Kolonisationslevel 8 möglich!'''''&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Befehl:&lt;br /&gt;
 ShipManager.FliegeZu(''xxx|yyy'');&lt;br /&gt;
Auch hier Gilt es wieder das kursive durch die eigenen Angaben zu ersetzten. Wie in folgendem Beispiel:&lt;br /&gt;
 ShipManager.BenutzteSchiff(1);&lt;br /&gt;
 ShipManager.FliegeZu('123|465');&lt;br /&gt;
oder mit dem Flottenbefehl:&lt;br /&gt;
 ShipManager.BenutzteFlotte(1);&lt;br /&gt;
 ShipManager.FliegeZu('123|465');&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Fliegen ohne Autopilot====&lt;br /&gt;
Der Befehl hierzu sieht wie folgt aus:&lt;br /&gt;
 ShipManager.Fliege(''Strecke'', EShipRichtung.''Richtung'');&lt;br /&gt;
Auch hier ersetzt du die kursiven Worte mit deinen Angaben, ein Beispiel folgt:&lt;br /&gt;
 ShipManager.BenutzteSchiff(1);&lt;br /&gt;
 ShipManager.Fliege(5, EShipRichtung.Hoch);&lt;br /&gt;
 ShipManager.Fliege(8, EshipRichtung.Links);&lt;br /&gt;
oder wenn es eine ganze Flotte ist:&lt;br /&gt;
 ShipManager.BenutzteFlotte(1);&lt;br /&gt;
 ShipManager.Fliege(5, EShipRichtung.Hoch);&lt;br /&gt;
 ShipManager.Fliege(8, EshipRichtung.Links);&lt;br /&gt;
&lt;br /&gt;
===Schiffsystem nutzen===&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
===Alternative zum Schiffsmanager: Schiffsaktion===&lt;br /&gt;
&lt;br /&gt;
Für Objekte des Typ's CMyFlotte und CMyShip kann über die Eigenschaft Aktion direkt auf die Funktionen des Schiffsmanagers zugegriffen werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Schiff AS CMyShip = new CMyShip( 4711 )&lt;br /&gt;
Schiff.Aktion.Abdocken()&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Flotte AS CMyFlotte = new CMyFlotte( 4711 )&lt;br /&gt;
Flotte.Aktion.Abdocken()&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Enumeration ist Alles==&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
==Methoden==&lt;br /&gt;
&lt;br /&gt;
Öfters wiederkehrende Aufgaben können in Methoden zusammengefasst werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function ShowKoords(x As Integer, y As Integer)&lt;br /&gt;
{&lt;br /&gt;
  WriteLine(CStr(x) + '|' + CStr(y));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Methode ShowKoords kann dann im Script folgendermaßen aufgerufen werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
ShowKoords(3, 4);&lt;br /&gt;
ShowKoords(ship.MapPosition.X,ship.MapPosition.Y);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn berechnete Werte von der Methode zurückgegeben werden sollen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function Distanz(x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer&lt;br /&gt;
{&lt;br /&gt;
  Var distanz As Integer;&lt;br /&gt;
  &lt;br /&gt;
  distanz = Math.Abs(x1 - x2) + Math.Abs(y1 - y2);&lt;br /&gt;
  Return distanz ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine(Distanz(1, 1, 5, 5));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
'ByRef' ist zwar in der Scriptengine vorgesehen und kann angegeben werden, ist aber derzeit ohne Funktion.&lt;br /&gt;
Objekte werden immer ByRef übergeben.&lt;br /&gt;
&lt;br /&gt;
==Klassen==&lt;br /&gt;
&lt;br /&gt;
In Klassen können Daten und Methoden in einem Objekt gekapselt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Class CKoords&lt;br /&gt;
{&lt;br /&gt;
  Var x As Integer;&lt;br /&gt;
  Var y As Integer;&lt;br /&gt;
  &lt;br /&gt;
  Function New(x As Integer, y As Integer)&lt;br /&gt;
  {&lt;br /&gt;
    This.x = x;&lt;br /&gt;
    This.y = y;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function ToString() As String&lt;br /&gt;
  {&lt;br /&gt;
    Return (CStr(x) + '|' + CStr(y);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function Distanz(koord As CKoords) As Integer&lt;br /&gt;
  {&lt;br /&gt;
    Return Math.Abs(x - koord.x) + Math.Abs(y - koord.y);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var ko1 As New CKoords(3, 5);&lt;br /&gt;
Var ko2 As CKoords;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ko2 = New CKoords(8, 9);&lt;br /&gt;
WriteLine('Distanz von ' + ko1.ToString() + ' nach ' + ko2.ToString() + ': ' + CStr(ko1.Distanz(ko2)));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig: Klassen brauchen immer eine Methode New(), sonst kann kein neues Objekt der Klasse generiert werden!&lt;br /&gt;
&lt;br /&gt;
==Autoren==&lt;br /&gt;
(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 ;)])&lt;br /&gt;
{|&lt;br /&gt;
!Nickname&lt;br /&gt;
!IG-id&lt;br /&gt;
!Kapitel&lt;br /&gt;
|-&lt;br /&gt;
|WiZz4Rd&lt;br /&gt;
|16475&lt;br /&gt;
|Kapitel 1, Kapitel 2, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|Stryke&lt;br /&gt;
|28885&lt;br /&gt;
|Vorwort, Kapitel 3, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|[[Spieler:Xenon|Xenon]]&lt;br /&gt;
|10127&lt;br /&gt;
|Korrektur &amp;amp; Überarbeitung Kapitel 1&lt;br /&gt;
|-&lt;br /&gt;
|Fling&lt;br /&gt;
|54865&lt;br /&gt;
|Kapitel 7, Kapitel 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Scripting-Hilfe|Anfängerkurs]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Basic_course</id>
		<title>Scripting:Basic course</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Basic_course"/>
				<updated>2011-11-11T17:10:14Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedTranslation}}&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
'''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.'''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Vorwort==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Chapter 1 - Strings==&lt;br /&gt;
In programming a String is a series of characters. The chapter title would be a String as would this text. The famous line &amp;quot;Hello World!&amp;quot; is also a String and it is this String you will be working with.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Hello World!&amp;quot; ===&lt;br /&gt;
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 &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
In the STNE engine this is very easy.&lt;br /&gt;
First launch the script editor under:&lt;br /&gt;
Database -&amp;gt; Script Editor -&amp;gt; Create a new script -&amp;gt; Custom script without input wizard&lt;br /&gt;
Then you will click &amp;quot;Edit source code&amp;quot;.&lt;br /&gt;
In the text field provided type: &lt;br /&gt;
&amp;lt;pre&amp;gt;WriteLine('Hello World!');&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now click Save&amp;amp;Run.&lt;br /&gt;
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?&lt;br /&gt;
When it works you should see the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;Hello World!&amp;lt;/pre&amp;gt;&lt;br /&gt;
Congratulations you are now programming. Try making a program that says:&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World!&lt;br /&gt;
Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Your code should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!');&lt;br /&gt;
WriteLine('Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note every line of code ends with a semicolon.&lt;br /&gt;
But what if you want to write everything on one line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;Hello World! Live long and prosper!&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is done by use of the &amp;amp; symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World!'&amp;amp;' Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;amp; 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!&lt;br /&gt;
&amp;quot;But wait!&amp;quot; You say. &amp;quot;I could simple code: &amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Hello World! Live long and prosper!');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt; and never have to deal with the &amp;amp; symbol!&amp;quot;&lt;br /&gt;
True, and as a programmer you will have many choices of different ways to do things. But the '&amp;amp;' is important as you will find out in the next chapter.&lt;br /&gt;
&lt;br /&gt;
===Summary: Strings===&lt;br /&gt;
&lt;br /&gt;
* A String is a sequence of several characters.&lt;br /&gt;
* A String is output, or printed, using the command ''WriteLine();''.&lt;br /&gt;
* You may use the character &amp;amp; to combine one String with another within the parameters, or parentheses, of ''WriteLine();''.&lt;br /&gt;
&lt;br /&gt;
==Chapter 2 - Variables==&lt;br /&gt;
===Basic types===&lt;br /&gt;
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:&lt;br /&gt;
* String  - a series of characters&lt;br /&gt;
* Integer - a whole number&lt;br /&gt;
* Boolean - decision (True/False)&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Imagine you have a gigantic project with hundreds of lines of code. Dozens upon dozens of times your code will output the lines:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains log Stardate:&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
You could code:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine('Captains log Stardate:');&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
every single time and maybe misspell it. Or you could use a variable.&lt;br /&gt;
Before a variable can be used, or called, it must be created. You do this with the word &amp;quot;Var&amp;quot; followed by the name followed by &amp;quot;As&amp;quot; followed by the type of variable it is followed by &amp;quot;=&amp;quot; followed by the data to be stored.&lt;br /&gt;
&lt;br /&gt;
Sound complicated?&lt;br /&gt;
Bear with us.&lt;br /&gt;
&lt;br /&gt;
In keeping with the above example let us declare a String variable that contains the line: 'Captains log Stardate:'&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
No two variables can have the same name though.&lt;br /&gt;
&lt;br /&gt;
Lets create a number, or integer, variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var SD As Integer = 234121;&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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).&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Things start to happen. Cool huh? Just in case your having trouble your code should look like this:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Var CL As String = 'Captains Log Stardate:';&lt;br /&gt;
Var SD As Integer = 234121;&lt;br /&gt;
WriteLine(CL &amp;amp; SD);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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 &amp;amp; symbol. It stuck the integer and the string together!&lt;br /&gt;
The output looks like:&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate:234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
See if you can find a way to get a space between the colon and the number...&lt;br /&gt;
&amp;lt;Pre&amp;gt;&amp;lt;nowiki&amp;gt;Captains Log Stardate: 234121&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Converting One Data Type to Another===&lt;br /&gt;
In many programming languages including an older version of the STNE engine you often need to convert variables from one type to another.&lt;br /&gt;
For instance if you had a variable:&lt;br /&gt;
&amp;lt;Pre&amp;gt;Var number As Integer = 12345;&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You couldn't use it in certain functions like &lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(number);&amp;lt;/pre&amp;gt;&lt;br /&gt;
Because the parameters for WriteLine() would only accept Strings and the variable 'number' is an Integer.&lt;br /&gt;
&lt;br /&gt;
In that case you would use another function CStr() to convert it to a String:&lt;br /&gt;
&amp;lt;Pre&amp;gt;CStr(number)&amp;lt;/Pre&amp;gt;&lt;br /&gt;
You could even place that inside the parameters of WriteLine():&lt;br /&gt;
&amp;lt;Pre&amp;gt;WriteLine(CStr(number));&amp;lt;/Pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Likewise you could covert a String to it's integer value with CInt();&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Rules for Naming Variables===&lt;br /&gt;
There are some rules for naming your variables&lt;br /&gt;
* 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.&lt;br /&gt;
* Do not use spaces. Use capital letters to signify different words. &lt;br /&gt;
* 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.&lt;br /&gt;
* For clear coding consider starting your variable name with a three digits representing the variable type. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;intDeutNeeded&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
===Summary: Variables===&lt;br /&gt;
&lt;br /&gt;
* A variable takes the place of &amp;quot;hard coded&amp;quot; data.&lt;br /&gt;
* To create a variable use 'VAR &amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; AS &amp;lt;b&amp;gt;Datentype&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To assign data to a variable you use ''&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt; = &amp;lt;b&amp;gt;Inhalt&amp;lt;/b&amp;gt;;''&lt;br /&gt;
* To output a variable use ''WriteLine(&amp;lt;b&amp;gt;Name&amp;lt;/b&amp;gt;);'' This can be very important when debugging.&lt;br /&gt;
* The ''&amp;amp;'' symbol connects variables withing a  function call''WriteLine();''&lt;br /&gt;
&lt;br /&gt;
==Chapter 3 - Control Structures==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===If - Else===&lt;br /&gt;
This works exactly how it sounds. &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates a statement and when it is true will execute the next few lines of code that are within curly braces &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot;. You can also include an &amp;lt;B&amp;gt;ELSE&amp;lt;/B&amp;gt; statement that will execute when the &amp;lt;B&amp;gt;IF&amp;lt;/B&amp;gt; evaluates to false.&lt;br /&gt;
For example this code evaluates a variable and executes the code within the curly braces in response:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var tribbles As Boolean = True;&lt;br /&gt;
If (tribbles){&lt;br /&gt;
  WriteLine('Oh no! The food!');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('The food is safe.');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
 &lt;br /&gt;
You can also use an IF statement to compare amounts. In that case you would use the equal symbol:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var EPSamount As Integer = 44;&lt;br /&gt;
If (EPSamount = 45){&lt;br /&gt;
  WriteLine('We have exactly ' &amp;amp; EPSamount &amp;amp; ' available');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Im givin her all shes got, Cpatain!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
You can also use &amp;quot;&amp;lt;&amp;quot;,&amp;quot;&amp;gt;&amp;quot;,&amp;quot;&amp;lt;=&amp;quot;,&amp;quot;&amp;gt;=&amp;quot; for different types of comparisons. In that order and in English those are called &amp;quot;less then&amp;quot;, &amp;quot;greater then&amp;quot;, &amp;quot;less then or equal to&amp;quot;, and &amp;quot;greater then or equal to&amp;quot;. These can be a little confusing at first so remember the bigger side of the symbol is toward the larger number. &amp;quot;a&amp;lt;b&amp;quot; says that a is less then b. b is greater.&lt;br /&gt;
You can also you the words &amp;quot;AND&amp;quot; and &amp;quot;OR&amp;quot; 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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
If ((dilth&amp;gt;5)AND(deut&amp;gt;10)AND(ANTIM&amp;gt;10)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var dilth AS Boolean = (dilthAmount&amp;gt;5);&lt;br /&gt;
Var deut AS Boolean = (deutAmount&amp;gt;10);&lt;br /&gt;
Var antiM As Boolean = (antiMAmount&amp;gt;10);&lt;br /&gt;
If ((dilth)AND(deut)AND(antiM)){&lt;br /&gt;
  WriteLine('Ready for deep space exploration');&lt;br /&gt;
}&lt;br /&gt;
Else{&lt;br /&gt;
  WriteLine('Are you crazy? We wont make it past pluto!');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is completely up to you!&lt;br /&gt;
&lt;br /&gt;
===Loops===&lt;br /&gt;
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 &amp;quot;{&amp;quot; &amp;quot;}&amp;quot; but a loop will not exit until the conditions that started become false.&lt;br /&gt;
&lt;br /&gt;
====While====&lt;br /&gt;
Consider the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var isKilingon As Boolean = True;&lt;br /&gt;
while (isKilingon){&lt;br /&gt;
  WriteLine('Today is a good day to die!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Enough battle!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Do====&lt;br /&gt;
DO loops work just like WHILE loops except that regardless the evaluation a DO will execute at least once. &lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
VAR friendlyShip AS Boolean = False;&lt;br /&gt;
WriteLine('Ship on Federation sensors');&lt;br /&gt;
Do(friendlyShip){&lt;br /&gt;
  WriteLine('Hale them.');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('No response. Open fire!');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====For====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer= 0;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
while ((ore &amp;lt; 12)){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
  ore = ore + 2;&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
This could also be written using a FOR loop:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Var ore As integer;&lt;br /&gt;
WriteLine('Do you need ore?');&lt;br /&gt;
for(ore=0 To 12 Step 2){&lt;br /&gt;
  WriteLine('We have ' &amp;amp; ore &amp;amp;' ore. We need more ore!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('Thanks. We can start making Duranium.');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you do not specify a step it will assume the step is 1.&lt;br /&gt;
&lt;br /&gt;
==Chapter 4 - Functions==&lt;br /&gt;
===Introduction===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('Get them out of there!');&lt;br /&gt;
WriteLine('Attempting to beam up away-team');&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
But you want to run that ten times.&lt;br /&gt;
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.&lt;br /&gt;
To create a function you use the following formula 'Function' followed by the name you give it, followed by the symbols &amp;quot;(){}&amp;quot;&lt;br /&gt;
Here is an example using the code above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
Function BeamUp(){&lt;br /&gt;
  WriteLine('Get them out of there!');&lt;br /&gt;
  WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Parameters===&lt;br /&gt;
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 &amp;quot;()&amp;quot;. 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&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
Now when you make the function call you need to pass it values that match it's parameters.&lt;br /&gt;
In the above example you might call it this way:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
BeamUp(5, True, Medics);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function BeamUp(number As Int32, crew As Boolean, teamName As String){&lt;br /&gt;
  If(crew){&lt;br /&gt;
    WriteLine('Beaming up ' &amp;amp; number &amp;amp; ' ' &amp;amp; teamName &amp;amp; '.');&lt;br /&gt;
    WriteLine('Attempting to beam up away-team!');&lt;br /&gt;
    Else{&lt;br /&gt;
      WriteLine('There is nobody there');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
WriteLine('We are at the Borg ship.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Klingon colony.');&lt;br /&gt;
BeamUp();&lt;br /&gt;
WriteLine('We are at the Syndicate station');&lt;br /&gt;
BeamUp();&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also for clarity consider keeping your Functions separate from your main code either all above or all bellow.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nachdem wir nun über ein paar Grundlagen verfügen, wollen wir uns den wirklich interessanten Dingen zuwenden, der Steuerung von Spielinhalten durch Scripte.&lt;br /&gt;
&lt;br /&gt;
Um mit Schiffen zu interagieren gibt es eine Sammlung von Methoden, welche im Shipmanager zu finden sind.&lt;br /&gt;
Hierzu müssen wir dem Shipmanager als erstes Mitteilen, welches bzw. welche Flotte er verwenden soll.&lt;br /&gt;
&lt;br /&gt;
Hierführ gibt es die Befehle:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.SelectShip(NCC-Nummer of Ship);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
or,&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;ShipManager.UseFleet(ID of Fleet);&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit weiß der ShipManager schonmal welches Schiff, bzw. welche Flotte die Aktionen ausführen soll.&lt;br /&gt;
&lt;br /&gt;
Mit dem Shipmanager können folgende Aktionen ausgeführt werden:&lt;br /&gt;
*An- und Abdocken&lt;br /&gt;
*Alarm Stufe ändern&lt;br /&gt;
*Aus Flotten austreten&lt;br /&gt;
*Aus Orbit einfliegen austreten &lt;br /&gt;
*Benennen(Name As String)&lt;br /&gt;
*Deuterium sammeln (Nur mit FP)&lt;br /&gt;
*Erz sammeln (Nur mit FP)&lt;br /&gt;
*Fliegen&lt;br /&gt;
*Sensoren aktivieren / deaktivieren&lt;br /&gt;
*Reparieren&lt;br /&gt;
*Batterien entladen&lt;br /&gt;
*Schilde aktivieren/deaktiviere/aufladen&lt;br /&gt;
*Reservebatterie aufladen&lt;br /&gt;
*Traktorstrahl ein- / ausschalten&lt;br /&gt;
*Beamen&lt;br /&gt;
*Verstecken&lt;br /&gt;
*Replikator aktivieren/deaktivieren&lt;br /&gt;
*Waren über Bord werfen&lt;br /&gt;
*Warpkern aktiveren/deaktivieren&lt;br /&gt;
*Wrackextraktoren&lt;br /&gt;
&lt;br /&gt;
Eine vollständige Auflistung aller Funktionen findet sich im [http://game.stne.net/ObjectExplorer.aspx?p=CShipManager Objekt-Explorer].&lt;br /&gt;
&lt;br /&gt;
Im folgenden wollen wir uns einige Funktionen genauer anschauen:&lt;br /&gt;
===Beamen===&lt;br /&gt;
Syntaxe:&lt;br /&gt;
 ShipManager.TransferiereZuSchiff(''Schiffid'', ''Menge'', EBeamRessource.''Ware'');&lt;br /&gt;
Hier musst du nun nurnoch den kursiven Text mit deinen Angaben ersetzten. Hier ein Beispiele:&lt;br /&gt;
 ShipManager.BenutzteSchiff(1);&lt;br /&gt;
 ShipManager.TransferiereZuSchiff(2, 20, EBeamRessource.Nahrung);&lt;br /&gt;
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:&lt;br /&gt;
 ShipManager.BenutzteFlotte(1);&lt;br /&gt;
 ShipManager.TransferiereZuSchiff(2, 20, EBeamRessource.Nahrung);&lt;br /&gt;
&lt;br /&gt;
===Fliegen===&lt;br /&gt;
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.&lt;br /&gt;
====Fliegen mit dem Autopiloten====&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;'''''Nur für Spieler mit Feature-Pack oder unter Kolonisationslevel 8 möglich!'''''&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Befehl:&lt;br /&gt;
 ShipManager.FliegeZu(''xxx|yyy'');&lt;br /&gt;
Auch hier Gilt es wieder das kursive durch die eigenen Angaben zu ersetzten. Wie in folgendem Beispiel:&lt;br /&gt;
 ShipManager.BenutzteSchiff(1);&lt;br /&gt;
 ShipManager.FliegeZu('123|465');&lt;br /&gt;
oder mit dem Flottenbefehl:&lt;br /&gt;
 ShipManager.BenutzteFlotte(1);&lt;br /&gt;
 ShipManager.FliegeZu('123|465');&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====Fliegen ohne Autopilot====&lt;br /&gt;
Der Befehl hierzu sieht wie folgt aus:&lt;br /&gt;
 ShipManager.Fliege(''Strecke'', EShipRichtung.''Richtung'');&lt;br /&gt;
Auch hier ersetzt du die kursiven Worte mit deinen Angaben, ein Beispiel folgt:&lt;br /&gt;
 ShipManager.BenutzteSchiff(1);&lt;br /&gt;
 ShipManager.Fliege(5, EShipRichtung.Hoch);&lt;br /&gt;
 ShipManager.Fliege(8, EshipRichtung.Links);&lt;br /&gt;
oder wenn es eine ganze Flotte ist:&lt;br /&gt;
 ShipManager.BenutzteFlotte(1);&lt;br /&gt;
 ShipManager.Fliege(5, EShipRichtung.Hoch);&lt;br /&gt;
 ShipManager.Fliege(8, EshipRichtung.Links);&lt;br /&gt;
&lt;br /&gt;
===Schiffsystem nutzen===&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
===Alternative zum Schiffsmanager: Schiffsaktion===&lt;br /&gt;
&lt;br /&gt;
Für Objekte des Typ's CMyFlotte und CMyShip kann über die Eigenschaft Aktion direkt auf die Funktionen des Schiffsmanagers zugegriffen werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Schiff AS CMyShip = new CMyShip( 4711 )&lt;br /&gt;
Schiff.Aktion.Abdocken()&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;VAR Flotte AS CMyFlotte = new CMyFlotte( 4711 )&lt;br /&gt;
Flotte.Aktion.Abdocken()&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Enumeration ist Alles==&lt;br /&gt;
kommt noch&lt;br /&gt;
&lt;br /&gt;
==Methoden==&lt;br /&gt;
&lt;br /&gt;
Öfters wiederkehrende Aufgaben können in Methoden zusammengefasst werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function ShowKoords(x As Integer, y As Integer)&lt;br /&gt;
{&lt;br /&gt;
  WriteLine(CStr(x) + '|' + CStr(y));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Die Methode ShowKoords kann dann im Script folgendermaßen aufgerufen werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
ShowKoords(3, 4);&lt;br /&gt;
ShowKoords(ship.MapPosition.X,ship.MapPosition.Y);&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn berechnete Werte von der Methode zurückgegeben werden sollen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Function Distanz(x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer&lt;br /&gt;
{&lt;br /&gt;
  Var distanz As Integer;&lt;br /&gt;
  &lt;br /&gt;
  distanz = Math.Abs(x1 - x2) + Math.Abs(y1 - y2);&lt;br /&gt;
  Return distanz ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine(Distanz(1, 1, 5, 5));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
'ByRef' ist zwar in der Scriptengine vorgesehen und kann angegeben werden, ist aber derzeit ohne Funktion.&lt;br /&gt;
Objekte werden immer ByRef übergeben.&lt;br /&gt;
&lt;br /&gt;
==Klassen==&lt;br /&gt;
&lt;br /&gt;
In Klassen können Daten und Methoden in einem Objekt gekapselt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Class CKoords&lt;br /&gt;
{&lt;br /&gt;
  Var x As Integer;&lt;br /&gt;
  Var y As Integer;&lt;br /&gt;
  &lt;br /&gt;
  Function New(x As Integer, y As Integer)&lt;br /&gt;
  {&lt;br /&gt;
    This.x = x;&lt;br /&gt;
    This.y = y;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function ToString() As String&lt;br /&gt;
  {&lt;br /&gt;
    Return (CStr(x) + '|' + CStr(y);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  Function Distanz(koord As CKoords) As Integer&lt;br /&gt;
  {&lt;br /&gt;
    Return Math.Abs(x - koord.x) + Math.Abs(y - koord.y);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var ko1 As New CKoords(3, 5);&lt;br /&gt;
Var ko2 As CKoords;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ko2 = New CKoords(8, 9);&lt;br /&gt;
WriteLine('Distanz von ' + ko1.ToString() + ' nach ' + ko2.ToString() + ': ' + CStr(ko1.Distanz(ko2)));&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig: Klassen brauchen immer eine Methode New(), sonst kann kein neues Objekt der Klasse generiert werden!&lt;br /&gt;
&lt;br /&gt;
==Autoren==&lt;br /&gt;
(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 ;)])&lt;br /&gt;
{|&lt;br /&gt;
!Nickname&lt;br /&gt;
!IG-id&lt;br /&gt;
!Kapitel&lt;br /&gt;
|-&lt;br /&gt;
|WiZz4Rd&lt;br /&gt;
|16475&lt;br /&gt;
|Kapitel 1, Kapitel 2, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|Stryke&lt;br /&gt;
|28885&lt;br /&gt;
|Vorwort, Kapitel 3, Kapitel 4&lt;br /&gt;
|-&lt;br /&gt;
|[[Spieler:Xenon|Xenon]]&lt;br /&gt;
|10127&lt;br /&gt;
|Korrektur &amp;amp; Überarbeitung Kapitel 1&lt;br /&gt;
|-&lt;br /&gt;
|Fling&lt;br /&gt;
|54865&lt;br /&gt;
|Kapitel 7, Kapitel 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Scripting-Hilfe|Anfängerkurs]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:STNE_SRS</id>
		<title>Scripting:STNE SRS</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:STNE_SRS"/>
				<updated>2011-11-11T17:02:49Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Getting short range sensor data&lt;br /&gt;
&lt;br /&gt;
The CMyShip has a method to retrieve data on ships in the current sector. It's accessed through the SRS method of CMyShip. Each object is a ship in the sector, whether or nor it's yours. Because the object is based on a list, you can easily retrieve the number of ships in the sector by using the Count property of the list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Assume your probe and another probe is in the sector, this would return 2&lt;br /&gt;
Var Ship As CMyShip = new CMyShip(123456);&lt;br /&gt;
WriteLine (Ship.SRS.Count); // output the number of ships in the sector&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Recently, LRSShipSlots was added. As of the time of this writing, it returns SRS slots count of the sector.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Assume your probe and another probe is in the sector, this would return 1.0&lt;br /&gt;
Var Ship As CMyShip = new CMyShip(123456);&lt;br /&gt;
WriteLine (Ship.LRSShipSlots); // output the slot count of the ships in the sector&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wanted to filter out your ships, you would need to iterate through the list of ships in SRS and not add them to an accumulator. This is accomplished by checking the CMyShip.UserID against your userid. The caveat is, it won't capture copiloted ships, that needs to be handled differently.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Uid As Integer = 67890; // your uid&lt;br /&gt;
Var Sid As Integer = 123456; // the ship to use for SRS data&lt;br /&gt;
Var ShipCount As Integer = 0;&lt;br /&gt;
Var ShipSlots As Double = 0.0;&lt;br /&gt;
Var StringSlots As String; // used to run time convert slots to a string formatting&lt;br /&gt;
Var SRSShip As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
Var Message As CStringBuilder = New CStringBuilder(); // Avoid ineffecient string concatenations of '&amp;amp;'&lt;br /&gt;
Var Ship As CMyShip = New CMyShip(Sid);&lt;br /&gt;
Var iter As IEnumerator = Ship.SRS.GetEnumerator; // don't store SRS, just get the iterator directly&lt;br /&gt;
While (iter.MoveNext) {&lt;br /&gt;
  SRSShip = iter.Current; // cast back to a CShip object&lt;br /&gt;
  If (SRSShip.UserID &amp;lt;&amp;gt; Uid) { // This does not work for copiloted ships, just your own&lt;br /&gt;
    ShipCount = ShipCount + 1;&lt;br /&gt;
    ShipSlots = ShipSlots + SRSShip.Definition.Slots;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StringSlots = ShipSlots;&lt;br /&gt;
Message.Append(&amp;quot;Number of ships is &amp;quot;);&lt;br /&gt;
Message.Append(ShipCount);&lt;br /&gt;
Message.Append(&amp;quot;, for &amp;quot;);&lt;br /&gt;
Message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;);&lt;br /&gt;
Message.Append(&amp;quot; slots.&amp;quot;);&lt;br /&gt;
WriteLine (Message.ToString);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assuming the same two probes are in the sector, the output would be “Number of ships is 1, for .5 slots.” As I stated above, this code would only show ships that were not owned by you. In order to filter out copiloted ships as well, you need to go one step further and make a list of all the ships you have control of. Luckily there's an iterator you can use to build a list of ship IDs that you control.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Function to create and return a CIntegerList of ships under your control&lt;br /&gt;
Function MyShipList() As CIntegerList {&lt;br /&gt;
  Var List As CIntegerList = New CIntegerList();&lt;br /&gt;
  Var Ship As CMyShip;&lt;br /&gt;
  Var iter As CShipEnumerator = New CShipEnumerator();&lt;br /&gt;
  While (iter.Next()) {&lt;br /&gt;
    Ship = iter.CurrentShip;&lt;br /&gt;
    List.Add(Ship.ShipID);&lt;br /&gt;
  }&lt;br /&gt;
  Return List;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var Sid As Integer = 123456; // the ship to use the SRS data from&lt;br /&gt;
Var ShipCount As Integer = 0;&lt;br /&gt;
Var ShipSlots As Double = 0.0;&lt;br /&gt;
Var StringSlots As String;&lt;br /&gt;
Var SRSShip As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
Var Message As CStringBuilder = New CStringBuilder(); // Avoid ineffecient string concatenations of '&amp;amp;'&lt;br /&gt;
Var Ship As CMyShip = New CMyShip(Sid);&lt;br /&gt;
Var Ships As CIntegerList = MyShipList(); // retrieve the ship list (nccs only)&lt;br /&gt;
Var iter As IEnumerator = Ship.SRS.GetEnumerator; // get the iterator directly again&lt;br /&gt;
While (iter.MoveNext) {&lt;br /&gt;
  SRSShip = iter.Current; // recast to a CShip&lt;br /&gt;
  // use the list builtin method to check if a value exists within the list&lt;br /&gt;
  If (NOT Ships.Contains(SRSShip.ShipID)) { &lt;br /&gt;
    ShipCount = ShipCount + 1;&lt;br /&gt;
    ShipSlots = ShipSlots + SRSShip.Definition.Slots;&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StringSlots = ShipSlots;&lt;br /&gt;
Message.Append(&amp;quot;Number of ships is &amp;quot;);&lt;br /&gt;
Message.Append(ShipCount);&lt;br /&gt;
Message.Append(&amp;quot;, for &amp;quot;);&lt;br /&gt;
Message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;);&lt;br /&gt;
Message.Append(&amp;quot; slots.&amp;quot;);&lt;br /&gt;
WriteLine (Message.ToString);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the addition of the MyShipList function. It iterates though the CShipEnumerator, which contains all the ships under your control, and adds them to a list that can then be cross referenced. The rest of the code, except for the owner check, is the same as before.&lt;br /&gt;
&lt;br /&gt;
Keep in mind your colonies also have the SRS object, so it could be applied to your colonies just as easily. It's a matter of changing The variable Ship from CMyShip to CMyColony. Of course you should also change the variable names to reflect that the object is a colony not a ship.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function MyShipList() As CIntegerList {&lt;br /&gt;
  Var List As CIntegerList = New CIntegerList();&lt;br /&gt;
  Var Ship As CMyShip;&lt;br /&gt;
  Var iter As CShipEnumerator = New CShipEnumerator();&lt;br /&gt;
  While (iter.Next()) {&lt;br /&gt;
    Ship = iter.CurrentShip;&lt;br /&gt;
    List.Add(Ship.ShipID);&lt;br /&gt;
  }&lt;br /&gt;
  Return List;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var Cid As Integer = 01234; // Was Sid&lt;br /&gt;
Var ShipCount As Integer = 0;&lt;br /&gt;
Var ShipSlots As Double = 0.0;&lt;br /&gt;
Var StringSlots As String;&lt;br /&gt;
Var SRSShip As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
Var Message As CStringBuilder = New CStringBuilder(); // Avoid ineffecient string concatenations of '&amp;amp;'&lt;br /&gt;
Var Colony As CMyColony = New CMyColony(Cid); // Was Ship&lt;br /&gt;
Var Ships As CIntegerList = MyShipList();&lt;br /&gt;
Var iter As IEnumerator = Colony.SRS.GetEnumerator;&lt;br /&gt;
While (iter.MoveNext) {&lt;br /&gt;
  SRSShip = iter.Current;&lt;br /&gt;
  If (NOT Ships.Contains(SRSShip.ShipID)) { &lt;br /&gt;
    ShipCount = ShipCount + 1;&lt;br /&gt;
    ShipSlots = ShipSlots + SRSShip.Definition.Slots;&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StringSlots = ShipSlots;&lt;br /&gt;
Message.Append(&amp;quot;Number of ships is &amp;quot;);&lt;br /&gt;
Message.Append(ShipCount);&lt;br /&gt;
Message.Append(&amp;quot;, for &amp;quot;);&lt;br /&gt;
Message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;);&lt;br /&gt;
Message.Append(&amp;quot; slots.&amp;quot;);&lt;br /&gt;
WriteLine (Message.ToString);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By now you're ready to wrap your code into a class. For the most part, it should be accessed statically. You'll want to alter the function that filters in order to allow for either a ship or a colony. If you move the loops for SRS into its own method, and use functions for ship and colony that just handle the differences between the two, this becomes a clean and fairly easy task&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Class to return the slots and count data as a single object, thereby requiring less specific functions&lt;br /&gt;
Class SRSSummary {&lt;br /&gt;
  Var Slots As Double;&lt;br /&gt;
  Var Count As Integer;&lt;br /&gt;
  // I could have left this out,, it isn't used in the example. Included for completeness&lt;br /&gt;
  Function New (sid As Integer) { &lt;br /&gt;
    ;&lt;br /&gt;
  }&lt;br /&gt;
  // Create and initialize the class&lt;br /&gt;
  Function New (c As Integer, s As Double) {&lt;br /&gt;
    Slots = s;&lt;br /&gt;
    Count = c;&lt;br /&gt;
  }&lt;br /&gt;
  // Beans style Get/Set methods for data access&lt;br /&gt;
  Function GetShipSlots() As Double {&lt;br /&gt;
    Return Slots;&lt;br /&gt;
  }&lt;br /&gt;
  Function SetShipSlots(s As Double) {&lt;br /&gt;
    Slots = s;&lt;br /&gt;
  }&lt;br /&gt;
  Function GetShipCount() As Integer {&lt;br /&gt;
    Return Count;&lt;br /&gt;
  }&lt;br /&gt;
  Function SetShipCount(c As Integer) {&lt;br /&gt;
    Count = c;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// The class that provides the desired data&lt;br /&gt;
// Note the lack of a new function. Without it, this class is only accessible statically&lt;br /&gt;
Class SRSData {&lt;br /&gt;
  // Make a CIntegerList of NCCs under your control&lt;br /&gt;
  Function MyShipList() As CIntegerList {&lt;br /&gt;
    Var List As CIntegerList = New CIntegerList();&lt;br /&gt;
    Var Ship As CMyShip;&lt;br /&gt;
    Var iter As CShipEnumerator = New CShipEnumerator();&lt;br /&gt;
    While (iter.Next()) {&lt;br /&gt;
      Ship = iter.CurrentShip;&lt;br /&gt;
      List.Add(Ship.ShipID);&lt;br /&gt;
    }&lt;br /&gt;
    Return List;&lt;br /&gt;
  }&lt;br /&gt;
  // Filter (CMyShip|CMyColony).SRS so only ships you don't control show up&lt;br /&gt;
  Function SRSSearch(srs As CShipList) As SRSSummary {&lt;br /&gt;
    Var shipcount As Integer = 0;&lt;br /&gt;
    Var shipslots As Double = 0.0;&lt;br /&gt;
    Var srsship As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
    Var summary As SRSSummary;&lt;br /&gt;
    Var ships As CIntegerList = SRSData.MyShipList();&lt;br /&gt;
    Var iter As IEnumerator = srs.GetEnumerator;&lt;br /&gt;
    While (iter.MoveNext) {&lt;br /&gt;
      srsship = iter.Current;&lt;br /&gt;
      If (NOT ships.Contains(srsship.ShipID)) { &lt;br /&gt;
        shipcount = shipcount + 1;&lt;br /&gt;
        shipslots = shipslots + srsship.Definition.Slots;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    Return New SRSSummary(shipcount, shipslots);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // I just can't bring myself to use a method named LRS to retrieve SRS data&lt;br /&gt;
  // Either the name will change to match the data, or the value will change to match the name.&lt;br /&gt;
  // This method returns the total of ships and slots within (CMyShip|CMyColony).SRS &lt;br /&gt;
  Function SRSAll(srs As CShipList) As SRSSummary {&lt;br /&gt;
    Var shipcount As Integer = 0;&lt;br /&gt;
    Var shipslots As Double = 0.0;&lt;br /&gt;
    Var srsship As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
    Var summary As SRSSummary;&lt;br /&gt;
    Var iter As IEnumerator = srs.GetEnumerator;&lt;br /&gt;
    While (iter.MoveNext) {&lt;br /&gt;
      srsship = iter.Current;&lt;br /&gt;
      shipcount = shipcount + 1;&lt;br /&gt;
      shipslots = shipslots + srsship.Definition.Slots;&lt;br /&gt;
    }&lt;br /&gt;
    Return New SRSSummary(srs.Count, shipslots);&lt;br /&gt;
  }&lt;br /&gt;
  // Return the filtered version of SRS for a ship  &lt;br /&gt;
  Function GetFilteredShipSRSSummary(shipID As Integer) As SRSSummary {&lt;br /&gt;
    Var ship As CMyShip = New CMyShip(shipID)&lt;br /&gt;
    Return SRSData.SRSSearch(Ship.SRS);&lt;br /&gt;
  }&lt;br /&gt;
  // Return the filtered version of SRS for a colony&lt;br /&gt;
  Function GetFilteredColonySRSSummary(colonyID As Integer) As SRSSummary {&lt;br /&gt;
    Var Colony As CMyColony = New CMyColony(colonyID);&lt;br /&gt;
    Return SRSData.SRSSearch(Colony.SRS);&lt;br /&gt;
  }&lt;br /&gt;
  // Return the total version of SRS for a ship  &lt;br /&gt;
  Function GetShipSRSSummary(shipID As Integer) As SRSSummary {&lt;br /&gt;
    Var ship As CMyShip = New CMyShip(shipid);&lt;br /&gt;
    Return SRSData.SRSAll(Ship.SRS);&lt;br /&gt;
  }&lt;br /&gt;
  // Return the total version of SRS for a colony&lt;br /&gt;
  Function GetColonySRSSummary(colonyID As Integer) As SRSSummary {&lt;br /&gt;
    Var colony As CMyColony = New CMyColony(colonyID);&lt;br /&gt;
    Return SRSData.SRSAll(colony.SRS);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// A fast output method. I could have done this within a table, but it adds unnecessary complexity for the example&lt;br /&gt;
Function ReportSRS (name As String, filtered As SRSSummary, total As SRSSummary) {&lt;br /&gt;
  Var StringSlots As String;&lt;br /&gt;
  Var message as New CStringBuilder();&lt;br /&gt;
  message.Append(&amp;quot;SRS summary for &amp;quot;);&lt;br /&gt;
  message.Append(name);&lt;br /&gt;
  message.Append(&amp;quot;: &amp;quot;);&lt;br /&gt;
  message.Append(filtered.GetShipCount());&lt;br /&gt;
  message.Append (&amp;quot;/&amp;quot;);&lt;br /&gt;
  message.Append(total.GetShipCount());&lt;br /&gt;
  message.Append(&amp;quot; ships for &amp;quot;);&lt;br /&gt;
  StringSlots = filtered.GetShipSlots();&lt;br /&gt;
  message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;));&lt;br /&gt;
  message.Append(&amp;quot;/&amp;quot;);&lt;br /&gt;
  StringSlots = total.GetShipSlots();&lt;br /&gt;
  message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;));&lt;br /&gt;
  message.Append(&amp;quot; slots.&amp;quot;);&lt;br /&gt;
  ScriptContext.WriteAppLog(message.ToString());&lt;br /&gt;
}  &lt;br /&gt;
  &lt;br /&gt;
// The Script Main() function.&lt;br /&gt;
Function Main() {&lt;br /&gt;
  Var summarytotal As SRSSummary; // SRS total counts&lt;br /&gt;
  Var summaryother As SRSSummary; // SRS filtered counts&lt;br /&gt;
  Var shipid As Integer = 123456; // The ship ncc to use&lt;br /&gt;
  var colid As Integer = 01234; // The colony ID to use&lt;br /&gt;
  Var ship As New CmyShip(shipID); // call the create for the objects&lt;br /&gt;
  Var colony As New CmyColony(colid); // ship and colony&lt;br /&gt;
  summarytotal = SRSData.GetShipSRSSummary(shipid); // Get the totals for the ship&lt;br /&gt;
  summaryother = SRSData.GetFilteredShipSRSSummary(shipid); // and the filtered values&lt;br /&gt;
  ReportSRS(ship.Name, summaryother, summarytotal); // show the data&lt;br /&gt;
  summarytotal = SRSData.GetColonySRSSummary(colid); // Totals for the colony object&lt;br /&gt;
  summaryother = SRSData.GetFilteredColonySRSSummary(colid); // and the filtered values&lt;br /&gt;
  ReportSRS(colony.Name, summaryother, summarytotal); // Show them as well&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Call the main function&lt;br /&gt;
Main();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see from the code above, the SRS data from both the colonies and the ships are handled by the same method statically. This is true for both the filtered and non filtered version of the routine. Also, notice that rather than rewrite a function for each type of data, I just created a small class with beans style get/set methods to return the data. It adds a little more CPU and memory usage to do it this way, but the memory usage is easily offset by the code reuse. (you halved the amount of code by only writing 4 very minimal methods and 2 small methods instead of 4 small methods). Essentially you end up using a small amount of extra CPU for maintainable clean code. While this tutorial retrieves just the ship slots and count, from here it would be easy to extend the class to return any available data within a CShip object.&lt;br /&gt;
&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 06:07, 6 November 2011 (CET)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:STNE_SRS</id>
		<title>Scripting:STNE SRS</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:STNE_SRS"/>
				<updated>2011-11-11T17:01:34Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Getting short range sensor data&lt;br /&gt;
&lt;br /&gt;
The CMyShip has a method to retrieve data on ships in the current sector. It's accessed through the SRS method of CMyShip. Each object is a ship in the sector, whether or nor it's yours. Because the object is based on a list, you can easily retrieve the number of ships in the sector by using the Count property of the list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Assume your probe and another probe is in the sector, this would return 2&lt;br /&gt;
Var Ship As CMyShip = new CMyShip(123456);&lt;br /&gt;
WriteLine (Ship.SRS.Count); // output the number of ships in the sector&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Recently, the method SRSShipSlots was obsoleted, and LRSShipSlots was added. These two methods are not comparable. The former returns the count, the latter (as of the time of this writing) returns SRS slots count of the sector.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Assume your probe and another probe is in the sector, this would return 1.0&lt;br /&gt;
Var Ship As CMyShip = new CMyShip(123456);&lt;br /&gt;
WriteLine (Ship.LRSShipSlots); // output the slot count of the ships in the sector&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wanted to filter out your ships, you would need to iterate through the list of ships in SRS and not add them to an accumulator. This is accomplished by checking the CMyShip.UserID against your userid. The caveat is, it won't capture copiloted ships, that needs to be handled differently.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Uid As Integer = 67890; // your uid&lt;br /&gt;
Var Sid As Integer = 123456; // the ship to use for SRS data&lt;br /&gt;
Var ShipCount As Integer = 0;&lt;br /&gt;
Var ShipSlots As Double = 0.0;&lt;br /&gt;
Var StringSlots As String; // used to run time convert slots to a string formatting&lt;br /&gt;
Var SRSShip As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
Var Message As CStringBuilder = New CStringBuilder(); // Avoid ineffecient string concatenations of '&amp;amp;'&lt;br /&gt;
Var Ship As CMyShip = New CMyShip(Sid);&lt;br /&gt;
Var iter As IEnumerator = Ship.SRS.GetEnumerator; // don't store SRS, just get the iterator directly&lt;br /&gt;
While (iter.MoveNext) {&lt;br /&gt;
  SRSShip = iter.Current; // cast back to a CShip object&lt;br /&gt;
  If (SRSShip.UserID &amp;lt;&amp;gt; Uid) { // This does not work for copiloted ships, just your own&lt;br /&gt;
    ShipCount = ShipCount + 1;&lt;br /&gt;
    ShipSlots = ShipSlots + SRSShip.Definition.Slots;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StringSlots = ShipSlots;&lt;br /&gt;
Message.Append(&amp;quot;Number of ships is &amp;quot;);&lt;br /&gt;
Message.Append(ShipCount);&lt;br /&gt;
Message.Append(&amp;quot;, for &amp;quot;);&lt;br /&gt;
Message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;);&lt;br /&gt;
Message.Append(&amp;quot; slots.&amp;quot;);&lt;br /&gt;
WriteLine (Message.ToString);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assuming the same two probes are in the sector, the output would be “Number of ships is 1, for .5 slots.” As I stated above, this code would only show ships that were not owned by you. In order to filter out copiloted ships as well, you need to go one step further and make a list of all the ships you have control of. Luckily there's an iterator you can use to build a list of ship IDs that you control.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Function to create and return a CIntegerList of ships under your control&lt;br /&gt;
Function MyShipList() As CIntegerList {&lt;br /&gt;
  Var List As CIntegerList = New CIntegerList();&lt;br /&gt;
  Var Ship As CMyShip;&lt;br /&gt;
  Var iter As CShipEnumerator = New CShipEnumerator();&lt;br /&gt;
  While (iter.Next()) {&lt;br /&gt;
    Ship = iter.CurrentShip;&lt;br /&gt;
    List.Add(Ship.ShipID);&lt;br /&gt;
  }&lt;br /&gt;
  Return List;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var Sid As Integer = 123456; // the ship to use the SRS data from&lt;br /&gt;
Var ShipCount As Integer = 0;&lt;br /&gt;
Var ShipSlots As Double = 0.0;&lt;br /&gt;
Var StringSlots As String;&lt;br /&gt;
Var SRSShip As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
Var Message As CStringBuilder = New CStringBuilder(); // Avoid ineffecient string concatenations of '&amp;amp;'&lt;br /&gt;
Var Ship As CMyShip = New CMyShip(Sid);&lt;br /&gt;
Var Ships As CIntegerList = MyShipList(); // retrieve the ship list (nccs only)&lt;br /&gt;
Var iter As IEnumerator = Ship.SRS.GetEnumerator; // get the iterator directly again&lt;br /&gt;
While (iter.MoveNext) {&lt;br /&gt;
  SRSShip = iter.Current; // recast to a CShip&lt;br /&gt;
  // use the list builtin method to check if a value exists within the list&lt;br /&gt;
  If (NOT Ships.Contains(SRSShip.ShipID)) { &lt;br /&gt;
    ShipCount = ShipCount + 1;&lt;br /&gt;
    ShipSlots = ShipSlots + SRSShip.Definition.Slots;&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StringSlots = ShipSlots;&lt;br /&gt;
Message.Append(&amp;quot;Number of ships is &amp;quot;);&lt;br /&gt;
Message.Append(ShipCount);&lt;br /&gt;
Message.Append(&amp;quot;, for &amp;quot;);&lt;br /&gt;
Message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;);&lt;br /&gt;
Message.Append(&amp;quot; slots.&amp;quot;);&lt;br /&gt;
WriteLine (Message.ToString);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the addition of the MyShipList function. It iterates though the CShipEnumerator, which contains all the ships under your control, and adds them to a list that can then be cross referenced. The rest of the code, except for the owner check, is the same as before.&lt;br /&gt;
&lt;br /&gt;
Keep in mind your colonies also have the SRS object, so it could be applied to your colonies just as easily. It's a matter of changing The variable Ship from CMyShip to CMyColony. Of course you should also change the variable names to reflect that the object is a colony not a ship.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function MyShipList() As CIntegerList {&lt;br /&gt;
  Var List As CIntegerList = New CIntegerList();&lt;br /&gt;
  Var Ship As CMyShip;&lt;br /&gt;
  Var iter As CShipEnumerator = New CShipEnumerator();&lt;br /&gt;
  While (iter.Next()) {&lt;br /&gt;
    Ship = iter.CurrentShip;&lt;br /&gt;
    List.Add(Ship.ShipID);&lt;br /&gt;
  }&lt;br /&gt;
  Return List;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var Cid As Integer = 01234; // Was Sid&lt;br /&gt;
Var ShipCount As Integer = 0;&lt;br /&gt;
Var ShipSlots As Double = 0.0;&lt;br /&gt;
Var StringSlots As String;&lt;br /&gt;
Var SRSShip As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
Var Message As CStringBuilder = New CStringBuilder(); // Avoid ineffecient string concatenations of '&amp;amp;'&lt;br /&gt;
Var Colony As CMyColony = New CMyColony(Cid); // Was Ship&lt;br /&gt;
Var Ships As CIntegerList = MyShipList();&lt;br /&gt;
Var iter As IEnumerator = Colony.SRS.GetEnumerator;&lt;br /&gt;
While (iter.MoveNext) {&lt;br /&gt;
  SRSShip = iter.Current;&lt;br /&gt;
  If (NOT Ships.Contains(SRSShip.ShipID)) { &lt;br /&gt;
    ShipCount = ShipCount + 1;&lt;br /&gt;
    ShipSlots = ShipSlots + SRSShip.Definition.Slots;&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StringSlots = ShipSlots;&lt;br /&gt;
Message.Append(&amp;quot;Number of ships is &amp;quot;);&lt;br /&gt;
Message.Append(ShipCount);&lt;br /&gt;
Message.Append(&amp;quot;, for &amp;quot;);&lt;br /&gt;
Message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;);&lt;br /&gt;
Message.Append(&amp;quot; slots.&amp;quot;);&lt;br /&gt;
WriteLine (Message.ToString);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By now you're ready to wrap your code into a class. For the most part, it should be accessed statically. You'll want to alter the function that filters in order to allow for either a ship or a colony. If you move the loops for SRS into its own method, and use functions for ship and colony that just handle the differences between the two, this becomes a clean and fairly easy task&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Class to return the slots and count data as a single object, thereby requiring less specific functions&lt;br /&gt;
Class SRSSummary {&lt;br /&gt;
  Var Slots As Double;&lt;br /&gt;
  Var Count As Integer;&lt;br /&gt;
  // I could have left this out,, it isn't used in the example. Included for completeness&lt;br /&gt;
  Function New (sid As Integer) { &lt;br /&gt;
    ;&lt;br /&gt;
  }&lt;br /&gt;
  // Create and initialize the class&lt;br /&gt;
  Function New (c As Integer, s As Double) {&lt;br /&gt;
    Slots = s;&lt;br /&gt;
    Count = c;&lt;br /&gt;
  }&lt;br /&gt;
  // Beans style Get/Set methods for data access&lt;br /&gt;
  Function GetShipSlots() As Double {&lt;br /&gt;
    Return Slots;&lt;br /&gt;
  }&lt;br /&gt;
  Function SetShipSlots(s As Double) {&lt;br /&gt;
    Slots = s;&lt;br /&gt;
  }&lt;br /&gt;
  Function GetShipCount() As Integer {&lt;br /&gt;
    Return Count;&lt;br /&gt;
  }&lt;br /&gt;
  Function SetShipCount(c As Integer) {&lt;br /&gt;
    Count = c;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// The class that provides the desired data&lt;br /&gt;
// Note the lack of a new function. Without it, this class is only accessible statically&lt;br /&gt;
Class SRSData {&lt;br /&gt;
  // Make a CIntegerList of NCCs under your control&lt;br /&gt;
  Function MyShipList() As CIntegerList {&lt;br /&gt;
    Var List As CIntegerList = New CIntegerList();&lt;br /&gt;
    Var Ship As CMyShip;&lt;br /&gt;
    Var iter As CShipEnumerator = New CShipEnumerator();&lt;br /&gt;
    While (iter.Next()) {&lt;br /&gt;
      Ship = iter.CurrentShip;&lt;br /&gt;
      List.Add(Ship.ShipID);&lt;br /&gt;
    }&lt;br /&gt;
    Return List;&lt;br /&gt;
  }&lt;br /&gt;
  // Filter (CMyShip|CMyColony).SRS so only ships you don't control show up&lt;br /&gt;
  Function SRSSearch(srs As CShipList) As SRSSummary {&lt;br /&gt;
    Var shipcount As Integer = 0;&lt;br /&gt;
    Var shipslots As Double = 0.0;&lt;br /&gt;
    Var srsship As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
    Var summary As SRSSummary;&lt;br /&gt;
    Var ships As CIntegerList = SRSData.MyShipList();&lt;br /&gt;
    Var iter As IEnumerator = srs.GetEnumerator;&lt;br /&gt;
    While (iter.MoveNext) {&lt;br /&gt;
      srsship = iter.Current;&lt;br /&gt;
      If (NOT ships.Contains(srsship.ShipID)) { &lt;br /&gt;
        shipcount = shipcount + 1;&lt;br /&gt;
        shipslots = shipslots + srsship.Definition.Slots;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    Return New SRSSummary(shipcount, shipslots);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // I just can't bring myself to use a method named LRS to retrieve SRS data&lt;br /&gt;
  // Either the name will change to match the data, or the value will change to match the name.&lt;br /&gt;
  // This method returns the total of ships and slots within (CMyShip|CMyColony).SRS &lt;br /&gt;
  Function SRSAll(srs As CShipList) As SRSSummary {&lt;br /&gt;
    Var shipcount As Integer = 0;&lt;br /&gt;
    Var shipslots As Double = 0.0;&lt;br /&gt;
    Var srsship As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
    Var summary As SRSSummary;&lt;br /&gt;
    Var iter As IEnumerator = srs.GetEnumerator;&lt;br /&gt;
    While (iter.MoveNext) {&lt;br /&gt;
      srsship = iter.Current;&lt;br /&gt;
      shipcount = shipcount + 1;&lt;br /&gt;
      shipslots = shipslots + srsship.Definition.Slots;&lt;br /&gt;
    }&lt;br /&gt;
    Return New SRSSummary(srs.Count, shipslots);&lt;br /&gt;
  }&lt;br /&gt;
  // Return the filtered version of SRS for a ship  &lt;br /&gt;
  Function GetFilteredShipSRSSummary(shipID As Integer) As SRSSummary {&lt;br /&gt;
    Var ship As CMyShip = New CMyShip(shipID)&lt;br /&gt;
    Return SRSData.SRSSearch(Ship.SRS);&lt;br /&gt;
  }&lt;br /&gt;
  // Return the filtered version of SRS for a colony&lt;br /&gt;
  Function GetFilteredColonySRSSummary(colonyID As Integer) As SRSSummary {&lt;br /&gt;
    Var Colony As CMyColony = New CMyColony(colonyID);&lt;br /&gt;
    Return SRSData.SRSSearch(Colony.SRS);&lt;br /&gt;
  }&lt;br /&gt;
  // Return the total version of SRS for a ship  &lt;br /&gt;
  Function GetShipSRSSummary(shipID As Integer) As SRSSummary {&lt;br /&gt;
    Var ship As CMyShip = New CMyShip(shipid);&lt;br /&gt;
    Return SRSData.SRSAll(Ship.SRS);&lt;br /&gt;
  }&lt;br /&gt;
  // Return the total version of SRS for a colony&lt;br /&gt;
  Function GetColonySRSSummary(colonyID As Integer) As SRSSummary {&lt;br /&gt;
    Var colony As CMyColony = New CMyColony(colonyID);&lt;br /&gt;
    Return SRSData.SRSAll(colony.SRS);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// A fast output method. I could have done this within a table, but it adds unnecessary complexity for the example&lt;br /&gt;
Function ReportSRS (name As String, filtered As SRSSummary, total As SRSSummary) {&lt;br /&gt;
  Var StringSlots As String;&lt;br /&gt;
  Var message as New CStringBuilder();&lt;br /&gt;
  message.Append(&amp;quot;SRS summary for &amp;quot;);&lt;br /&gt;
  message.Append(name);&lt;br /&gt;
  message.Append(&amp;quot;: &amp;quot;);&lt;br /&gt;
  message.Append(filtered.GetShipCount());&lt;br /&gt;
  message.Append (&amp;quot;/&amp;quot;);&lt;br /&gt;
  message.Append(total.GetShipCount());&lt;br /&gt;
  message.Append(&amp;quot; ships for &amp;quot;);&lt;br /&gt;
  StringSlots = filtered.GetShipSlots();&lt;br /&gt;
  message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;));&lt;br /&gt;
  message.Append(&amp;quot;/&amp;quot;);&lt;br /&gt;
  StringSlots = total.GetShipSlots();&lt;br /&gt;
  message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;));&lt;br /&gt;
  message.Append(&amp;quot; slots.&amp;quot;);&lt;br /&gt;
  ScriptContext.WriteAppLog(message.ToString());&lt;br /&gt;
}  &lt;br /&gt;
  &lt;br /&gt;
// The Script Main() function.&lt;br /&gt;
Function Main() {&lt;br /&gt;
  Var summarytotal As SRSSummary; // SRS total counts&lt;br /&gt;
  Var summaryother As SRSSummary; // SRS filtered counts&lt;br /&gt;
  Var shipid As Integer = 123456; // The ship ncc to use&lt;br /&gt;
  var colid As Integer = 01234; // The colony ID to use&lt;br /&gt;
  Var ship As New CmyShip(shipID); // call the create for the objects&lt;br /&gt;
  Var colony As New CmyColony(colid); // ship and colony&lt;br /&gt;
  summarytotal = SRSData.GetShipSRSSummary(shipid); // Get the totals for the ship&lt;br /&gt;
  summaryother = SRSData.GetFilteredShipSRSSummary(shipid); // and the filtered values&lt;br /&gt;
  ReportSRS(ship.Name, summaryother, summarytotal); // show the data&lt;br /&gt;
  summarytotal = SRSData.GetColonySRSSummary(colid); // Totals for the colony object&lt;br /&gt;
  summaryother = SRSData.GetFilteredColonySRSSummary(colid); // and the filtered values&lt;br /&gt;
  ReportSRS(colony.Name, summaryother, summarytotal); // Show them as well&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Call the main function&lt;br /&gt;
Main();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see from the code above, the SRS data from both the colonies and the ships are handled by the same method statically. This is true for both the filtered and non filtered version of the routine. Also, notice that rather than rewrite a function for each type of data, I just created a small class with beans style get/set methods to return the data. It adds a little more CPU and memory usage to do it this way, but the memory usage is easily offset by the code reuse. (you halved the amount of code by only writing 4 very minimal methods and 2 small methods instead of 4 small methods). Essentially you end up using a small amount of extra CPU for maintainable clean code. While this tutorial retrieves just the ship slots and count, from here it would be easy to extend the class to return any available data within a CShip object.&lt;br /&gt;
&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 06:07, 6 November 2011 (CET)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Operators</id>
		<title>Scripting:Operators</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Operators"/>
				<updated>2011-11-07T17:04:45Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: /* Arithmetic operators */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scripting]]&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
&lt;br /&gt;
== Table ==&lt;br /&gt;
In this section, a and b represent either literal values, object references or expressions evaluating to the appropriate type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== String operators ===&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
! Operator name !! Syntax&lt;br /&gt;
|-&lt;br /&gt;
| Concatenation || a &amp;amp; b&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Comparison operators ===&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
! Operator name !! Syntax&lt;br /&gt;
|-&lt;br /&gt;
| Equals                   || a = b&lt;br /&gt;
|-&lt;br /&gt;
| References equal         || a Is b&lt;br /&gt;
|-&lt;br /&gt;
| Not equal to             || a &amp;lt;&amp;gt; b&lt;br /&gt;
|-&lt;br /&gt;
| Greater than             || a &amp;gt; b&lt;br /&gt;
|-&lt;br /&gt;
| Less than                || a &amp;lt; b&lt;br /&gt;
|-&lt;br /&gt;
| Greater than or equal to || a &amp;gt;= b&lt;br /&gt;
|-&lt;br /&gt;
| Less than or equal to    || a &amp;lt;= b&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Arithmetic operators ===&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
! Operator name !! Syntax&lt;br /&gt;
|-&lt;br /&gt;
| Assignment    || a = b&lt;br /&gt;
|-&lt;br /&gt;
| Addition       || a + b&lt;br /&gt;
|-&lt;br /&gt;
| Subtraction    || a - b&lt;br /&gt;
|-&lt;br /&gt;
| Multiplication || a * b&lt;br /&gt;
|-&lt;br /&gt;
| Division       || a / b&lt;br /&gt;
|-&lt;br /&gt;
| Post Increment      || a++&lt;br /&gt;
|-&lt;br /&gt;
| Pre Increment      || ++a&lt;br /&gt;
|-&lt;br /&gt;
| Post Decrement      || a--&lt;br /&gt;
|-&lt;br /&gt;
| Pre Decrement      || --a&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Logical operators ===&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
! Operator name !! Syntax&lt;br /&gt;
|-&lt;br /&gt;
| Logical NOT    || NOT a&lt;br /&gt;
|-&lt;br /&gt;
| Logical AND    || a AND b&lt;br /&gt;
|-&lt;br /&gt;
| Logical OR     || a OR b&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other operators ===&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
! Operator name !! Syntax&lt;br /&gt;
|-&lt;br /&gt;
| Function call      || a()&lt;br /&gt;
|-&lt;br /&gt;
| Function reference || AddressOf a&lt;br /&gt;
|-&lt;br /&gt;
| Member (b of a)    || a.b&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Precedence ==&lt;br /&gt;
&lt;br /&gt;
The exact operator precedence is unknown. However, the following order of precedence seems to apply:&lt;br /&gt;
&lt;br /&gt;
* Member, Function call&lt;br /&gt;
* Increment, Decrement&lt;br /&gt;
* Multiplication&lt;br /&gt;
* Addition, Subtraction&lt;br /&gt;
* Comparison&lt;br /&gt;
* Logical NOT&lt;br /&gt;
* Logical OR, Logical AND&lt;br /&gt;
* Assignment&lt;br /&gt;
&lt;br /&gt;
Operators with the same precedence seem to be applied from left to right. Keep in mind that the logical AND and OR are lazy. That is, if the left argument already dictates the outcome, the right argument is not evaluated. This is mainly important for arguments with side effects, such as function calls or the increment/decrement operators. It can also prevent referencing a NULL reference.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Assignment operator v.s. equals operator ===&lt;br /&gt;
&lt;br /&gt;
The {{code | assignment}} operator and the {{code | equals}} operator use the same symbol. It depends on the context which operator is used. The {{code | assignment}} operator is used when a line of code follows the syntax {{code | Identifier {{=}} Value;}}. In all other cases, the {{code | equals}} operator is used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Increment and decrement operators ===&lt;br /&gt;
&lt;br /&gt;
There are two versions of the increment and decrement operators, namely the suffix and the prefix versions. The suffix versions increment or decrements the value hold by the identifier and then returns the old value. The prefix versions increment or decrement the value and return the result.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
 Var i As Integer = 5;&lt;br /&gt;
 WriteLine(i++); // Writes 5&lt;br /&gt;
 WriteLine(i);   // Writes 6&lt;br /&gt;
 WriteLine(i--)  // Writes 6&lt;br /&gt;
 WriteLine(i);   // Writes 5&lt;br /&gt;
 &lt;br /&gt;
 i = 5;&lt;br /&gt;
 WriteLine(++i); // Writes 6&lt;br /&gt;
 WriteLine(i);   // Writes 6&lt;br /&gt;
 WriteLine(--i); // Writes 5&lt;br /&gt;
 WriteLine(i);   // Writes 5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== References equal ===&lt;br /&gt;
&lt;br /&gt;
The {{code | References equal}} operator returns true if both identifiers hold the same reference (or: point to the same object).&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
  Var i As String = &amp;quot;a&amp;quot;;&lt;br /&gt;
  Var j As String = &amp;quot;a&amp;quot;;&lt;br /&gt;
  WriteLine(i Is j); // false&lt;br /&gt;
 &lt;br /&gt;
  i = j;&lt;br /&gt;
  WriteLine(i Is j); // true&lt;br /&gt;
&lt;br /&gt;
For types defined as Struct in the Object Explorer, this operator will never return true. When assigning one struct variable to another, the value is copied instead of the reference.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AddressOf ===&lt;br /&gt;
&lt;br /&gt;
The {{code | AddressOf}} operator actually returns a CDelegate instance.&lt;br /&gt;
&lt;br /&gt;
An example:&lt;br /&gt;
 Var Delegate As CDelegate = AddressOf MyFunction;&lt;br /&gt;
 &lt;br /&gt;
 Function MyFunction() {&lt;br /&gt;
   WriteLine(&amp;quot;Hello universe!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 Delegate.Invoke();  // Writes &amp;quot;Hello universe!&amp;quot;;&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:FAQ</id>
		<title>Scripting:FAQ</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:FAQ"/>
				<updated>2011-11-07T16:57:24Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: /* How are the current Script engine classes defined, and how can one define one's own classes? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ScriptingMenu}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==What scripting language is used to execute the scripts?==&lt;br /&gt;
&lt;br /&gt;
* An independent interpreter was written for [[STNE]].  It is not available elsewhere.  The syntax is likewise its own, though comparable to other languages - primary Javascript, PHP, and Visual Basic. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Are the used available objects of the Script engine also of the actual STNE engine?==&lt;br /&gt;
&lt;br /&gt;
* No. [[STNE]] internally uses completely different objects within a completely different structure. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==How are the current Script engine classes defined, and how can one define one's own classes?==&lt;br /&gt;
&lt;br /&gt;
* At present it is not possible to define one's own classes.  Available classes are firmly embodied within the [[STNE]] source text, and represent internally a genuine ''.NET'' object.&lt;br /&gt;
[Edit] While the available classes statment is still true, you can now define your own classes. The caveat is, they are simple classes, so there is no inheritance (so no overloading) or pragmas (private/protected/friend)&lt;br /&gt;
&lt;br /&gt;
==Would it be possible to use objects and classes which are not intended for the Script engine?==&lt;br /&gt;
&lt;br /&gt;
* No.  During the use of each object it is determined whether the object type is certified.  This is also performed during a Script's execution. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==How ensured that one does not use stranger of objects within the Script engine, e.g. stranger of ships steers?==&lt;br /&gt;
&lt;br /&gt;
* Each object examines independently whether the owner of object agrees with the current player context and/or whether these accesses on it may have. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==What if I cause a continuous loop within the source text - will it then hang the whole server?==&lt;br /&gt;
&lt;br /&gt;
* In principle one can only hang one of four CCU cores.  Each Script which does not terminated after 10 seconds of use is stopped. If it is repeatedly recognized that a Script exceeds the time limit on a CCU, the Script is then deactivated and/or the ability of implementing Scripts is withdrawn from that player's account. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==How many variables may I define, and how large is the maximum memory consumption?==&lt;br /&gt;
&lt;br /&gt;
* You may define as many variables as you require.  With each object production, memory consumption is roughly estimated. If more than approximately 10 MB of memory will be used, then the Script is terminated.  If the Script is estimated to exceed 50 MB of memory, then the ability of implementing Scripts will be automatically withdrawn from that player's account.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Why aren't Scripts implemented immediately, and how are they adjusted?==&lt;br /&gt;
&lt;br /&gt;
* All Scripts are implemented internally one behind the other sequentially.  Scripts which can be implemented, are placed in a waiting queue, and implemented only when all previous Scripts have been implemented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==What is the maximum allowable size of a Script?==&lt;br /&gt;
&lt;br /&gt;
* A Script may be as large as 100 KB.  This corresponds to approximately 2,500 lines of source text.  This size should be more than sufficient. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==My Script exceeds the limits. Is there a possibility to implement it anyway?==&lt;br /&gt;
&lt;br /&gt;
* You may submit such Scripts for consideration as an exception.  However, these are only approved if the Script represents a considerable enrichment to the Community.  There must be a reasonable cause for such permission.  Moreover, the Script source text will be examined.  Turn it over to a Game Admin. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Can I store variables somewhere permanently, e.g. in a file?==&lt;br /&gt;
&lt;br /&gt;
* Yes, over the object ''CDataNodeStorage''.&lt;br /&gt;
* See also the applicable thread in the forum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:STNE_SRS</id>
		<title>Scripting:STNE SRS</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:STNE_SRS"/>
				<updated>2011-11-06T05:07:06Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: Created page with &amp;quot;Getting short range sensor data  The CMyShip has a method to retrieve data on ships in the current sector. It's accessed through the SRS method of CMyShip. Each object is a ship ...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Getting short range sensor data&lt;br /&gt;
&lt;br /&gt;
The CMyShip has a method to retrieve data on ships in the current sector. It's accessed through the SRS method of CMyShip. Each object is a ship in the sector, whether or nor it's yours. Because the object is based on a list, you can easily retrieve the number of ships in the sector by using the Count property of the list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Assume your probe and another probe is in the sector, this would return 2&lt;br /&gt;
Var Ship As CMyShip = new CMyShip(123456);&lt;br /&gt;
WriteLine (Ship.SRS.Count); // output the number of ships in the sector&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Recently, the method SRSShipCount was obsoleted, and LRSShipSlots was added. These two methods are not comparable. The former returns the count, the latter (as of the time of this writing) returns SRS slots count of the sector.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Assume your probe and another probe is in the sector, this would return 1.0&lt;br /&gt;
Var Ship As CMyShip = new CMyShip(123456);&lt;br /&gt;
WriteLine (Ship.LRSShipSlots); // output the slot count of the ships in the sector&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wanted to filter out your ships, you would need to iterate through the list of ships in SRS and not add them to an accumulator. This is accomplished by checking the CMyShip.UserID against your userid. The caveat is, it won't capture copiloted ships, that needs to be handled differently.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Uid As Integer = 67890; // your uid&lt;br /&gt;
Var Sid As Integer = 123456; // the ship to use for SRS data&lt;br /&gt;
Var ShipCount As Integer = 0;&lt;br /&gt;
Var ShipSlots As Double = 0.0;&lt;br /&gt;
Var StringSlots As String; // used to run time convert slots to a string formatting&lt;br /&gt;
Var SRSShip As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
Var Message As CStringBuilder = New CStringBuilder(); // Avoid ineffecient string concatenations of '&amp;amp;'&lt;br /&gt;
Var Ship As CMyShip = New CMyShip(Sid);&lt;br /&gt;
Var iter As IEnumerator = Ship.SRS.GetEnumerator; // don't store SRS, just get the iterator directly&lt;br /&gt;
While (iter.MoveNext) {&lt;br /&gt;
  SRSShip = iter.Current; // cast back to a CShip object&lt;br /&gt;
  If (SRSShip.UserID &amp;lt;&amp;gt; Uid) { // This does not work for copiloted ships, just your own&lt;br /&gt;
    ShipCount = ShipCount + 1;&lt;br /&gt;
    ShipSlots = ShipSlots + SRSShip.Definition.Slots;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StringSlots = ShipSlots;&lt;br /&gt;
Message.Append(&amp;quot;Number of ships is &amp;quot;);&lt;br /&gt;
Message.Append(ShipCount);&lt;br /&gt;
Message.Append(&amp;quot;, for &amp;quot;);&lt;br /&gt;
Message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;);&lt;br /&gt;
Message.Append(&amp;quot; slots.&amp;quot;);&lt;br /&gt;
WriteLine (Message.ToString);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Assuming the same two probes are in the sector, the output would be “Number of ships is 1, for .5 slots.” As I stated above, this code would only show ships that were not owned by you. In order to filter out copiloted ships as well, you need to go one step further and make a list of all the ships you have control of. Luckily there's an iterator you can use to build a list of ship IDs that you control.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Function to create and return a CIntegerList of ships under your control&lt;br /&gt;
Function MyShipList() As CIntegerList {&lt;br /&gt;
  Var List As CIntegerList = New CIntegerList();&lt;br /&gt;
  Var Ship As CMyShip;&lt;br /&gt;
  Var iter As CShipEnumerator = New CShipEnumerator();&lt;br /&gt;
  While (iter.Next()) {&lt;br /&gt;
    Ship = iter.CurrentShip;&lt;br /&gt;
    List.Add(Ship.ShipID);&lt;br /&gt;
  }&lt;br /&gt;
  Return List;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var Sid As Integer = 123456; // the ship to use the SRS data from&lt;br /&gt;
Var ShipCount As Integer = 0;&lt;br /&gt;
Var ShipSlots As Double = 0.0;&lt;br /&gt;
Var StringSlots As String;&lt;br /&gt;
Var SRSShip As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
Var Message As CStringBuilder = New CStringBuilder(); // Avoid ineffecient string concatenations of '&amp;amp;'&lt;br /&gt;
Var Ship As CMyShip = New CMyShip(Sid);&lt;br /&gt;
Var Ships As CIntegerList = MyShipList(); // retrieve the ship list (nccs only)&lt;br /&gt;
Var iter As IEnumerator = Ship.SRS.GetEnumerator; // get the iterator directly again&lt;br /&gt;
While (iter.MoveNext) {&lt;br /&gt;
  SRSShip = iter.Current; // recast to a CShip&lt;br /&gt;
  // use the list builtin method to check if a value exists within the list&lt;br /&gt;
  If (NOT Ships.Contains(SRSShip.ShipID)) { &lt;br /&gt;
    ShipCount = ShipCount + 1;&lt;br /&gt;
    ShipSlots = ShipSlots + SRSShip.Definition.Slots;&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StringSlots = ShipSlots;&lt;br /&gt;
Message.Append(&amp;quot;Number of ships is &amp;quot;);&lt;br /&gt;
Message.Append(ShipCount);&lt;br /&gt;
Message.Append(&amp;quot;, for &amp;quot;);&lt;br /&gt;
Message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;);&lt;br /&gt;
Message.Append(&amp;quot; slots.&amp;quot;);&lt;br /&gt;
WriteLine (Message.ToString);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the addition of the MyShipList function. It iterates though the CShipEnumerator, which contains all the ships under your control, and adds them to a list that can then be cross referenced. The rest of the code, except for the owner check, is the same as before.&lt;br /&gt;
&lt;br /&gt;
Keep in mind your colonies also have the SRS object, so it could be applied to your colonies just as easily. It's a matter of changing The variable Ship from CMyShip to CMyColony. Of course you should also change the variable names to reflect that the object is a colony not a ship.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function MyShipList() As CIntegerList {&lt;br /&gt;
  Var List As CIntegerList = New CIntegerList();&lt;br /&gt;
  Var Ship As CMyShip;&lt;br /&gt;
  Var iter As CShipEnumerator = New CShipEnumerator();&lt;br /&gt;
  While (iter.Next()) {&lt;br /&gt;
    Ship = iter.CurrentShip;&lt;br /&gt;
    List.Add(Ship.ShipID);&lt;br /&gt;
  }&lt;br /&gt;
  Return List;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Var Cid As Integer = 01234; // Was Sid&lt;br /&gt;
Var ShipCount As Integer = 0;&lt;br /&gt;
Var ShipSlots As Double = 0.0;&lt;br /&gt;
Var StringSlots As String;&lt;br /&gt;
Var SRSShip As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
Var Message As CStringBuilder = New CStringBuilder(); // Avoid ineffecient string concatenations of '&amp;amp;'&lt;br /&gt;
Var Colony As CMyColony = New CMyColony(Cid); // Was Ship&lt;br /&gt;
Var Ships As CIntegerList = MyShipList();&lt;br /&gt;
Var iter As IEnumerator = Colony.SRS.GetEnumerator;&lt;br /&gt;
While (iter.MoveNext) {&lt;br /&gt;
  SRSShip = iter.Current;&lt;br /&gt;
  If (NOT Ships.Contains(SRSShip.ShipID)) { &lt;br /&gt;
    ShipCount = ShipCount + 1;&lt;br /&gt;
    ShipSlots = ShipSlots + SRSShip.Definition.Slots;&lt;br /&gt;
  } &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StringSlots = ShipSlots;&lt;br /&gt;
Message.Append(&amp;quot;Number of ships is &amp;quot;);&lt;br /&gt;
Message.Append(ShipCount);&lt;br /&gt;
Message.Append(&amp;quot;, for &amp;quot;);&lt;br /&gt;
Message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;);&lt;br /&gt;
Message.Append(&amp;quot; slots.&amp;quot;);&lt;br /&gt;
WriteLine (Message.ToString);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By now you're ready to wrap your code into a class. For the most part, it should be accessed statically. You'll want to alter the function that filters in order to allow for either a ship or a colony. If you move the loops for SRS into its own method, and use functions for ship and colony that just handle the differences between the two, this becomes a clean and fairly easy task&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Class to return the slots and count data as a single object, thereby requiring less specific functions&lt;br /&gt;
Class SRSSummary {&lt;br /&gt;
  Var Slots As Double;&lt;br /&gt;
  Var Count As Integer;&lt;br /&gt;
  // I could have left this out,, it isn't used in the example. Included for completeness&lt;br /&gt;
  Function New (sid As Integer) { &lt;br /&gt;
    ;&lt;br /&gt;
  }&lt;br /&gt;
  // Create and initialize the class&lt;br /&gt;
  Function New (c As Integer, s As Double) {&lt;br /&gt;
    Slots = s;&lt;br /&gt;
    Count = c;&lt;br /&gt;
  }&lt;br /&gt;
  // Beans style Get/Set methods for data access&lt;br /&gt;
  Function GetShipSlots() As Double {&lt;br /&gt;
    Return Slots;&lt;br /&gt;
  }&lt;br /&gt;
  Function SetShipSlots(s As Double) {&lt;br /&gt;
    Slots = s;&lt;br /&gt;
  }&lt;br /&gt;
  Function GetShipCount() As Integer {&lt;br /&gt;
    Return Count;&lt;br /&gt;
  }&lt;br /&gt;
  Function SetShipCount(c As Integer) {&lt;br /&gt;
    Count = c;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// The class that provides the desired data&lt;br /&gt;
// Note the lack of a new function. Without it, this class is only accessible statically&lt;br /&gt;
Class SRSData {&lt;br /&gt;
  // Make a CIntegerList of NCCs under your control&lt;br /&gt;
  Function MyShipList() As CIntegerList {&lt;br /&gt;
    Var List As CIntegerList = New CIntegerList();&lt;br /&gt;
    Var Ship As CMyShip;&lt;br /&gt;
    Var iter As CShipEnumerator = New CShipEnumerator();&lt;br /&gt;
    While (iter.Next()) {&lt;br /&gt;
      Ship = iter.CurrentShip;&lt;br /&gt;
      List.Add(Ship.ShipID);&lt;br /&gt;
    }&lt;br /&gt;
    Return List;&lt;br /&gt;
  }&lt;br /&gt;
  // Filter (CMyShip|CMyColony).SRS so only ships you don't control show up&lt;br /&gt;
  Function SRSSearch(srs As CShipList) As SRSSummary {&lt;br /&gt;
    Var shipcount As Integer = 0;&lt;br /&gt;
    Var shipslots As Double = 0.0;&lt;br /&gt;
    Var srsship As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
    Var summary As SRSSummary;&lt;br /&gt;
    Var ships As CIntegerList = SRSData.MyShipList();&lt;br /&gt;
    Var iter As IEnumerator = srs.GetEnumerator;&lt;br /&gt;
    While (iter.MoveNext) {&lt;br /&gt;
      srsship = iter.Current;&lt;br /&gt;
      If (NOT ships.Contains(srsship.ShipID)) { &lt;br /&gt;
        shipcount = shipcount + 1;&lt;br /&gt;
        shipslots = shipslots + srsship.Definition.Slots;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    Return New SRSSummary(shipcount, shipslots);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // I just can't bring myself to use a method named LRS to retrieve SRS data&lt;br /&gt;
  // Either the name will change to match the data, or the value will change to match the name.&lt;br /&gt;
  // This method returns the total of ships and slots within (CMyShip|CMyColony).SRS &lt;br /&gt;
  Function SRSAll(srs As CShipList) As SRSSummary {&lt;br /&gt;
    Var shipcount As Integer = 0;&lt;br /&gt;
    Var shipslots As Double = 0.0;&lt;br /&gt;
    Var srsship As CShip; // Note, this is a CShip, not a CMyShip&lt;br /&gt;
    Var summary As SRSSummary;&lt;br /&gt;
    Var iter As IEnumerator = srs.GetEnumerator;&lt;br /&gt;
    While (iter.MoveNext) {&lt;br /&gt;
      srsship = iter.Current;&lt;br /&gt;
      shipcount = shipcount + 1;&lt;br /&gt;
      shipslots = shipslots + srsship.Definition.Slots;&lt;br /&gt;
    }&lt;br /&gt;
    Return New SRSSummary(srs.Count, shipslots);&lt;br /&gt;
  }&lt;br /&gt;
  // Return the filtered version of SRS for a ship  &lt;br /&gt;
  Function GetFilteredShipSRSSummary(shipID As Integer) As SRSSummary {&lt;br /&gt;
    Var ship As CMyShip = New CMyShip(shipID)&lt;br /&gt;
    Return SRSData.SRSSearch(Ship.SRS);&lt;br /&gt;
  }&lt;br /&gt;
  // Return the filtered version of SRS for a colony&lt;br /&gt;
  Function GetFilteredColonySRSSummary(colonyID As Integer) As SRSSummary {&lt;br /&gt;
    Var Colony As CMyColony = New CMyColony(colonyID);&lt;br /&gt;
    Return SRSData.SRSSearch(Colony.SRS);&lt;br /&gt;
  }&lt;br /&gt;
  // Return the total version of SRS for a ship  &lt;br /&gt;
  Function GetShipSRSSummary(shipID As Integer) As SRSSummary {&lt;br /&gt;
    Var ship As CMyShip = New CMyShip(shipid);&lt;br /&gt;
    Return SRSData.SRSAll(Ship.SRS);&lt;br /&gt;
  }&lt;br /&gt;
  // Return the total version of SRS for a colony&lt;br /&gt;
  Function GetColonySRSSummary(colonyID As Integer) As SRSSummary {&lt;br /&gt;
    Var colony As CMyColony = New CMyColony(colonyID);&lt;br /&gt;
    Return SRSData.SRSAll(colony.SRS);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// A fast output method. I could have done this within a table, but it adds unnecessary complexity for the example&lt;br /&gt;
Function ReportSRS (name As String, filtered As SRSSummary, total As SRSSummary) {&lt;br /&gt;
  Var StringSlots As String;&lt;br /&gt;
  Var message as New CStringBuilder();&lt;br /&gt;
  message.Append(&amp;quot;SRS summary for &amp;quot;);&lt;br /&gt;
  message.Append(name);&lt;br /&gt;
  message.Append(&amp;quot;: &amp;quot;);&lt;br /&gt;
  message.Append(filtered.GetShipCount());&lt;br /&gt;
  message.Append (&amp;quot;/&amp;quot;);&lt;br /&gt;
  message.Append(total.GetShipCount());&lt;br /&gt;
  message.Append(&amp;quot; ships for &amp;quot;);&lt;br /&gt;
  StringSlots = filtered.GetShipSlots();&lt;br /&gt;
  message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;));&lt;br /&gt;
  message.Append(&amp;quot;/&amp;quot;);&lt;br /&gt;
  StringSlots = total.GetShipSlots();&lt;br /&gt;
  message.Append(StringSlots.Replace(&amp;quot;,&amp;quot;, &amp;quot;.&amp;quot;));&lt;br /&gt;
  message.Append(&amp;quot; slots.&amp;quot;);&lt;br /&gt;
  ScriptContext.WriteAppLog(message.ToString());&lt;br /&gt;
}  &lt;br /&gt;
  &lt;br /&gt;
// The Script Main() function.&lt;br /&gt;
Function Main() {&lt;br /&gt;
  Var summarytotal As SRSSummary; // SRS total counts&lt;br /&gt;
  Var summaryother As SRSSummary; // SRS filtered counts&lt;br /&gt;
  Var shipid As Integer = 123456; // The ship ncc to use&lt;br /&gt;
  var colid As Integer = 01234; // The colony ID to use&lt;br /&gt;
  Var ship As New CmyShip(shipID); // call the create for the objects&lt;br /&gt;
  Var colony As New CmyColony(colid); // ship and colony&lt;br /&gt;
  summarytotal = SRSData.GetShipSRSSummary(shipid); // Get the totals for the ship&lt;br /&gt;
  summaryother = SRSData.GetFilteredShipSRSSummary(shipid); // and the filtered values&lt;br /&gt;
  ReportSRS(ship.Name, summaryother, summarytotal); // show the data&lt;br /&gt;
  summarytotal = SRSData.GetColonySRSSummary(colid); // Totals for the colony object&lt;br /&gt;
  summaryother = SRSData.GetFilteredColonySRSSummary(colid); // and the filtered values&lt;br /&gt;
  ReportSRS(colony.Name, summaryother, summarytotal); // Show them as well&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Call the main function&lt;br /&gt;
Main();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see from the code above, the SRS data from both the colonies and the ships are handled by the same method statically. This is true for both the filtered and non filtered version of the routine. Also, notice that rather than rewrite a function for each type of data, I just created a small class with beans style get/set methods to return the data. It adds a little more CPU and memory usage to do it this way, but the memory usage is easily offset by the code reuse. (you halved the amount of code by only writing 4 very minimal methods and 2 small methods instead of 4 small methods). Essentially you end up using a small amount of extra CPU for maintainable clean code. While this tutorial retrieves just the ship slots and count, from here it would be easy to extend the class to return any available data within a CShip object.&lt;br /&gt;
&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 06:07, 6 November 2011 (CET)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Main_page</id>
		<title>Scripting:Main page</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Main_page"/>
				<updated>2011-11-06T04:26:37Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: /* Topics: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scripting]]&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
{{CreateScriptingArticle}}&lt;br /&gt;
&lt;br /&gt;
This section of the Wiki is intended to document the scripting engine found in the game. Most scripting related pages in STNE can be found from the main menu trough Database -&amp;gt; Scripting.&lt;br /&gt;
&lt;br /&gt;
=== Topics: ===&lt;br /&gt;
* [[Scripting:Syntax|Syntax]]&lt;br /&gt;
* [[Scripting:Operators|Operators]]&lt;br /&gt;
* [[Scripting:Interfaces|Interfaces]]&lt;br /&gt;
&lt;br /&gt;
* [[Scripting:Basic course|Basic course]] (mostly translated)&lt;br /&gt;
* [[Scripting:Script_editor|The external script editor]]&lt;br /&gt;
* [[Scripting:InvokeItem|A tutorial on scripting the portal InvokeItem()]]&lt;br /&gt;
* [[Scripting:InfoBar Links|A tutorial on scripting for an InfoBar link]]&lt;br /&gt;
* [[Scripting:Data Storage|A tutorial on understanding STNE non volatile storage]]&lt;br /&gt;
* [[Scripting:STNE Classes|A tutorial on understanding STNE classes]]&lt;br /&gt;
* [[Scripting:STNE SRS|A tutorial on getting short range sensor data]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:STNE_Classes</id>
		<title>Scripting:STNE Classes</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:STNE_Classes"/>
				<updated>2011-10-22T08:17:30Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Classes in STNE&lt;br /&gt;
&lt;br /&gt;
Firstly, you need to understand that the script compiler is not a binary compiler. It is a front end lexical analyzer (lex an) for Visual Basic and .Net. The reason you need to understand this is because it means that operator syntax comes from VB, so there are some differences that you might not expect. It also means that you can use a VB reference for some of the operators (such as logical not, and null pointer reference). Since the lex an reprocesses into VB (Keep in mind this comes from experience with the engine, not from direct knowledge) this can be quite helpful, and confusing at the same time.&lt;br /&gt;
&lt;br /&gt;
Classes in STNE are similar to classes in a fully classful language, with a few major exceptions:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The classes are not inheritable&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The use of the This pointer is required to access class methods from within the class&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Declarations are used as static references to the class&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;There is no scoping of variables or methods (private/protected/public)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Operator overloading has not been tested by myself, but I doubt it's included.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Since classes are not inheritable, there is no method or variable overloading&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also some caveats you should be aware of that pertain to the lexical analyzer. &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Additional ending braces (}) can cause the lex an to issue no warnings during compile, yet not producing usable code&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Prototyping is not supported (to the best of my knowledge)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Since prototyping is not supported, implicit casting is used with variables, with the default type being String (This includes declarations of variables). &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Function or method mismatches can cause a null pointer exception during compile, without giving a reference point as to where (eg no line number of the occurrence)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Line terminators (eg ';') are not necessary. A new line compliments the ; if the code is written on one line. (Not recommended, but usable)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While there are many other anomalies, the basic lex an is sound enough to do some rather fancy coding. Seeing how this feature is left out of many online games, the engine is laudable. Even better, while there is more work necessary to make is robust, it is actually maintained along with STNE changes.&lt;br /&gt;
&lt;br /&gt;
So, why bother to write a classfull script? &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Data objects can be reused and even stored in memory in lists&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Rather than suck server memory dry (which will abort your script), you can instantiate the class and then free the memory when complete&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;You can avoid memory sucking multi-dimensional arrays&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;You can write more complete self documenting code that is easier to maintain&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To create a static class, all you need to is declare it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  …&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Once it is declared, any method declared is also available. This of course doesn't work well with variables... They need memory allocation. You can create a 'property' of the class by simply returning a static value as thus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that when we called Pi from Circumference, we used the accessor MyMath. Since this is going to be used statically, you do not want to use a This pointer, as that requires you to instantiate the class. The majority of the functionality you will want from a class is handled by the static methods, but you have to remember that while you can call a static method from an instantiation, the inverse is not true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return This.Pi * radius * radius; // Or MyMath.Pi * Math.Pow(radius, 2.0);&lt;br /&gt;
}&lt;br /&gt;
// This will fail miserably. Since the class cannot be instantiated in this form&lt;br /&gt;
Var cir As Double = MyMath.Circumference(3.0);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to create an instantiated class, you need to have two components. The new method in the class, and the assignment in the code. The new method can be empty, but it has to exist to instantiate the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Var Radius As Double&lt;br /&gt;
  Function New() {&lt;br /&gt;
    ; // Null instruction, essentially a placeholder&lt;br /&gt;
  }&lt;br /&gt;
  Function New(r As Double) {&lt;br /&gt;
    Radius = r;&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to access a method within the class, you need to use a reference pointer (Either statically via the class name, or dynamically via the This pointer). The lex an will only look for functions that are global to the script if you don't specifically reference the class. In most cases, this is not an issue (annoying yes, an issue, not really) unless you name a global function the same as a class method. Name your global functions differently than your class functions, it will help you in the long run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Output (message As String) {&lt;br /&gt;
     WriteLine (“MyMath: “ &amp;amp; message);&lt;br /&gt;
  }&lt;br /&gt;
  Function ShowCircumference() {&lt;br /&gt;
    MyMath.Output(This.Circumference);&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, notice the lack of the function parameter list in the call to This.Circumference within ShowCircumference(). If there are no parameters necessary (eg a procedure), the parameter list can be left off (As if you were accessing a variable in the class).&lt;br /&gt;
&lt;br /&gt;
In order to free the memory used by an instantiation, you have to either leave the scope of the delcartion (return from a function), or assign the reference to a null pointer. The next time the garbage collector runs, it will free the memory. The garbage is a mechanism that free resources and performs other various maintenance operations automatically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function C (cir As Double) As Double {&lt;br /&gt;
  Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
  Return mmath.Circumference(cir);&lt;br /&gt;
} // Pointer is now unassigned, the garbage collector will reclaim the memory&lt;br /&gt;
&lt;br /&gt;
Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
…&lt;br /&gt;
mmath = Nothing; // Let the garbage collector reclaim the memory&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To use another class within you classes, you just need to instantiate the other class and manipulate it like you would with any other function. To allow access to the methods of that class, you simply wrap the other functions methods within your own.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyPoint {&lt;br /&gt;
  Var Point As SPoint;&lt;br /&gt;
  Function New(newx As Integer, newy As Integer) {&lt;br /&gt;
    Point = New Spoint(newx, newy);&lt;br /&gt;
  }&lt;br /&gt;
  Function New(newpoint As SPoint) {&lt;br /&gt;
    Point = newpoint;&lt;br /&gt;
  }&lt;br /&gt;
   Function X () As Integer {&lt;br /&gt;
    Return Point.X;&lt;br /&gt;
  }&lt;br /&gt;
   Function Y () As Integer {&lt;br /&gt;
    Return Point.Y;&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Classes in STNE can be extremely useful for self documenting code and for maintaining a small memory footprint for your script. Although STNE script classes are more simplistic that a full classful language, this does not detract much from the the usefulness of them. &lt;br /&gt;
&lt;br /&gt;
Code used for this exercise:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Var Radius As Double&lt;br /&gt;
  Function New() {&lt;br /&gt;
    ;&lt;br /&gt;
  }&lt;br /&gt;
  Function New(r As Double) {&lt;br /&gt;
    Radius = r;&lt;br /&gt;
  }&lt;br /&gt;
  Function Radius(c As Double) As Double {&lt;br /&gt;
    Return Math.Sqrt(c / MyMath.Pi);&lt;br /&gt;
  }&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or MyMath.Pi * Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
  Function Circumference() As Double {&lt;br /&gt;
    Return MyMath.Circumference(Radius);&lt;br /&gt;
  }&lt;br /&gt;
  Function Output (message As String) {&lt;br /&gt;
     WriteLine (&amp;quot;MyMath: &amp;quot; &amp;amp; message);&lt;br /&gt;
  }&lt;br /&gt;
  Function ShowCircumference() {&lt;br /&gt;
    MyMath.Output(&amp;quot;C=&amp;quot; &amp;amp; This.Circumference);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Class MyPoint {&lt;br /&gt;
  Var Point As SPoint;&lt;br /&gt;
  New(newx As Integer, newy As Integer) {&lt;br /&gt;
    Point = New Spoint(newx, newy);&lt;br /&gt;
  }&lt;br /&gt;
  New(newpoint As SPoint) {&lt;br /&gt;
    Point = newpoint;&lt;br /&gt;
  }&lt;br /&gt;
   Function X () As Integer {&lt;br /&gt;
    Return Point.X;&lt;br /&gt;
  }&lt;br /&gt;
   Function Y () As Integer {&lt;br /&gt;
    Return Point.Y;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine(MyMath.Circumference(3));&lt;br /&gt;
Var m As MyMath = New MyMath(3);&lt;br /&gt;
WriteLine(m.Circumference());&lt;br /&gt;
&lt;br /&gt;
MyMath.Output(MyMath.Circumference(3));&lt;br /&gt;
&lt;br /&gt;
MyMath.ShowCircumference (3);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 21:19, 18 October 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:STNE_Classes</id>
		<title>Scripting:STNE Classes</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:STNE_Classes"/>
				<updated>2011-10-22T08:15:17Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Classes in STNE&lt;br /&gt;
&lt;br /&gt;
Firstly, you need to understand that the script compiler is not a binary compiler. It is a front end lexical analyzer (lex an) for Visual Basic and .Net. The reason you need to understand this is because it means that operator syntax comes from VB, so there are some differences that you might not expect. It also means that you can use a VB reference for some of the operators (such as logical not, and null pointer reference). Since the lex an reprocesses into VB (Keep in mind this comes from experience with the engine, not from direct knowledge) this can be quite helpful, and confusing at the same time.&lt;br /&gt;
&lt;br /&gt;
Classes in STNE are similar to classes in a fully classful language, with a few major exceptions:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The classes are not inheritable&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The use of the This pointer is required to access class methods from within the class&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Declarations are used as static references to the class&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;There is no scoping of variables or methods (private/protected/public)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Operator overloading has not been tested by myself, but I doubt it's included.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Since classes are not inheritable, there is no method or variable overloading&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also some caveats you should be aware of that pertain to the lexical analyzer. &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Additional ending braces (}) can cause the lex an to issue no warnings during compile, yet not producing usable code&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Prototyping is not supported (to the best of my knowledge)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Since prototyping is not supported, implicit casting is used with varibales, with the default type being String (This includes declarations of varibales). &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Function or method mismatches can cause a null pointer exception during compile, without giving a reference point as to where (eg no line number of the occurrence)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Line terminators (eg ';') are not necessary. A new line compliments the ; if the code is written on one line. (Not recommended, but usable)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While there are many other anomalies, the basic lex an is sound enough to do some rather fancy coding. Seeing how this feature is left out of many online games, the engine is laudable. Even better, while there is more work necessary to make is robust, it is actually maintained along with STNE changes.&lt;br /&gt;
&lt;br /&gt;
So, why bother to write a classfull script? &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Data objects can be reused and even stored in memory in lists&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Rather than suck server memory dry (which will abort your script), you can instantiate the class and then free the memory when complete&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;You can avoid memory sucking multi-dimensional arrays&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;You can write more complete self documenting code that is easier to maintain&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To create a static class, all you need to is declare it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  …&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Once it is declared, any method declared is also available. This of course doesn't work well with variables... They need memory allocation. You can create a 'property' of the class by simply returning a static value as thus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that when we called Pi from Circumference, we used the accessor MyMath. Since this is going to be used statically, you do not want to use a This pointer, as that requires you to instantiate the class. The majority of the functionality you will want from a class is handled by the static methods, but you have to remember that while you can call a static method from an instantiation, the inverse is not true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return This.Pi * radius * radius; // Or MyMath.Pi * Math.Pow(radius, 2.0);&lt;br /&gt;
}&lt;br /&gt;
// This will fail miserably. Since the class cannot be instantiated in this form&lt;br /&gt;
Var cir As Double = MyMath.Circumference(3.0);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to create an instantiated class, you need to have two components. The new method in the class, and the assignment in the code. The new method can be empty, but it has to exist to instantiate the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Var Radius As Double&lt;br /&gt;
  Function New() {&lt;br /&gt;
    ; // Null instruction, essentially a placeholder&lt;br /&gt;
  }&lt;br /&gt;
  Function New(r As Double) {&lt;br /&gt;
    Radius = r;&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to access a method within the class, you need to use a reference pointer (Either statically via the class name, or dynamically via the This pointer). The lex an will only look for functions that are global to the script if you don't specifically reference the class. In most cases, this is not an issue (annoying yes, an issue, not really) unless you name a global function the same as a class method. Name your global functions differently than your class functions, it will help you in the long run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Output (message As String) {&lt;br /&gt;
     WriteLine (“MyMath: “ &amp;amp; message);&lt;br /&gt;
  }&lt;br /&gt;
  Function ShowCircumference() {&lt;br /&gt;
    MyMath.Output(This.Circumference);&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, notice the lack of the function parameter list in the call to This.Circumference within ShowCircumference(). If there are no parameters necessary (eg a procedure), the parameter list can be left off (As if you were accessing a variable in the class).&lt;br /&gt;
&lt;br /&gt;
In order to free the memory used by an instantiation, you have to either leave the scope of the delcartion (return from a function), or assign the reference to a null pointer. The next time the garbage collector runs, it will free the memory. The garbage is a mechanism that free resources and performs other various maintenance operations automatically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function C (cir As Double) As Double {&lt;br /&gt;
  Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
  Return mmath.Circumference(cir);&lt;br /&gt;
} // Pointer is now unassigned, the garbage collector will reclaim the memory&lt;br /&gt;
&lt;br /&gt;
Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
…&lt;br /&gt;
mmath = Nothing; // Let the garbage collector reclaim the memory&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To use another class within you classes, you just need to instantiate the other class and manipulate it like you would with any other function. To allow access to the methods of that class, you simply wrap the other functions methods within your own.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyPoint {&lt;br /&gt;
  Var Point As SPoint;&lt;br /&gt;
  Function New(newx As Integer, newy As Integer) {&lt;br /&gt;
    Point = New Spoint(newx, newy);&lt;br /&gt;
  }&lt;br /&gt;
  Function New(newpoint As SPoint) {&lt;br /&gt;
    Point = newpoint;&lt;br /&gt;
  }&lt;br /&gt;
   Function X () As Integer {&lt;br /&gt;
    Return Point.X;&lt;br /&gt;
  }&lt;br /&gt;
   Function Y () As Integer {&lt;br /&gt;
    Return Point.Y;&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Classes in STNE can be extremely useful for self documenting code and for maintaining a small memory footprint for your script. Although STNE script classes are more simplistic that a full classful language, this does not detract much from the the usefulness of them. &lt;br /&gt;
&lt;br /&gt;
Code used for this exercise:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Var Radius As Double&lt;br /&gt;
  Function New() {&lt;br /&gt;
    ;&lt;br /&gt;
  }&lt;br /&gt;
  Function New(r As Double) {&lt;br /&gt;
    Radius = r;&lt;br /&gt;
  }&lt;br /&gt;
  Function Radius(c As Double) As Double {&lt;br /&gt;
    Return Math.Sqrt(c / MyMath.Pi);&lt;br /&gt;
  }&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or MyMath.Pi * Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
  Function Circumference() As Double {&lt;br /&gt;
    Return MyMath.Circumference(Radius);&lt;br /&gt;
  }&lt;br /&gt;
  Function Output (message As String) {&lt;br /&gt;
     WriteLine (&amp;quot;MyMath: &amp;quot; &amp;amp; message);&lt;br /&gt;
  }&lt;br /&gt;
  Function ShowCircumference() {&lt;br /&gt;
    MyMath.Output(&amp;quot;C=&amp;quot; &amp;amp; This.Circumference);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Class MyPoint {&lt;br /&gt;
  Var Point As SPoint;&lt;br /&gt;
  New(newx As Integer, newy As Integer) {&lt;br /&gt;
    Point = New Spoint(newx, newy);&lt;br /&gt;
  }&lt;br /&gt;
  New(newpoint As SPoint) {&lt;br /&gt;
    Point = newpoint;&lt;br /&gt;
  }&lt;br /&gt;
   Function X () As Integer {&lt;br /&gt;
    Return Point.X;&lt;br /&gt;
  }&lt;br /&gt;
   Function Y () As Integer {&lt;br /&gt;
    Return Point.Y;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine(MyMath.Circumference(3));&lt;br /&gt;
Var m As MyMath = New MyMath(3);&lt;br /&gt;
WriteLine(m.Circumference());&lt;br /&gt;
&lt;br /&gt;
MyMath.Output(MyMath.Circumference(3));&lt;br /&gt;
&lt;br /&gt;
MyMath.ShowCircumference (3);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 21:19, 18 October 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:STNE_Classes</id>
		<title>Scripting:STNE Classes</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:STNE_Classes"/>
				<updated>2011-10-18T19:22:26Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Classes in STNE&lt;br /&gt;
&lt;br /&gt;
Firstly, you need to understand that the script compiler is not a binary compiler. It is a front end lexical analyzer (lex an) for Visual Basic and .Net. The reason you need to understand this is because it means that operator syntax comes from VB, so there are some differences that you might not expect. It also means that you can use a VB reference for some of the operators (such as logical not, and null pointer reference). Since the lex an reprocesses into VB (Keep in mind this comes from experience with the engine, not from direct knowledge) this can be quite helpful, and confusing at the same time.&lt;br /&gt;
&lt;br /&gt;
Classes in STNE are similar to classes in a fully classful language, with a few major exceptions:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The classes are not inheritable&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The use of the This pointer is required to access class methods from within the class&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Declarations are used as static references to the class&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;There is no scoping of variables or methods (private/protected/public)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Operator overloading has not been tested by myself, but I doubt it's included.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Since classes are not inheritable, there is no method or variable overloading&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also some caveats you should be aware of that pertain to the lexical analyzer. &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Additional ending braces (}) can cause the lex an to issue no warnings during compile, yet not producing usable code&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Prototyping is not supported (to the best of my knowledge)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Since prototyping is not supported, implicit casting is used with varibales, with the default type being String (This includes declarations of varibales). &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Function or method mismatches can cause a null pointer exception during compile, without giving a reference point as to where (eg no line number of the occurrence)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Line terminators (eg ';') are not necessary. A new line compliments the ; if the code is written on one line. (Not recommended, but usable)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While there are many other anomalies, the basic lex an is sound enough to do some rather fancy coding. Seeing how this feature is left out of many online games, the engine is laudable. Even better, while there is more work necessary to make is robust, it is actually maintained along with STNE changes.&lt;br /&gt;
&lt;br /&gt;
So, why bother to write a classfull script? &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Data objects can be reused and even stored in memory in lists&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Rather than suck server memory dry (which will abort your script), you can instantiate the class and then free the memory when complete&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;You can avoid memory sucking multi-dimensional arrays&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;You can write more complete self documenting code that is easier to maintain&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To create a static class, all you need to is declare it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  …&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Once it is declared, any method declared is also available. This of course doesn't work well with variables... They need memory allocation. You can create a 'property' of the class by simply returning a static value as thus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that when we called Pi from Circumference, we used the accessor MyMath. Since this is going to be used statically, you do not want to use a This pointer, as that requires you to instantiate the class. The majority of the functionality you will want from a class is handled by the static methods, but you have to remember that while you can call a static method from an instantiation, the inverse is not true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return This.Pi * radius * radius; // Or MyMath.Pi * Math.Pow(radius, 2.0);&lt;br /&gt;
}&lt;br /&gt;
// This will fail miserably. Since the class cannot be instantiated in this form&lt;br /&gt;
Var cir As Double = MyMath.Circumference(3.0);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to create an instantiated class, you need to have two components. The new method in the class, and the assignment in the code. The new method can be empty, but it has to exist to instantiate the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Var Radius As Double&lt;br /&gt;
  Function New() {&lt;br /&gt;
    ; // Null instruction, essentially a placeholder&lt;br /&gt;
  }&lt;br /&gt;
  Function New(r As Double) {&lt;br /&gt;
    Radius = r;&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to access a method within the class, you need to use a reference pointer (Either statically via the class name, or dynamically via the This pointer). The lex an will only look for functions that are global to the script if you don't specifically reference the class. In most cases, this is not an issue (annoying yes, an issue, not really) unless you name a global function the same as a class method. Name your global functions differently than your class functions, it will help you in the long run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Output (message As String) {&lt;br /&gt;
     WriteLine (“MyMath: “ &amp;amp; message);&lt;br /&gt;
  }&lt;br /&gt;
  Function ShowCircumference() {&lt;br /&gt;
    MyMath.Output(This.Circumference);&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, notice the lack of the function parameter list in the call to This.Circumference within ShowCircumference(). If there are no parameters necessary (eg a procedure), the parameter list can be left off (As if you were accessing a variable in the class).&lt;br /&gt;
&lt;br /&gt;
In order to free the memory used by an instantiation, you have to either leave the scope of the delcartion (return from a function), or assign the reference to a null pointer. The next time the garbage collector runs, it will free the memory. The garbage is a mechanism that free resources and performs other various maintenance operations automatically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function C (cir As Double) As Double {&lt;br /&gt;
  Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
  Return mmath.Circumference(cir);&lt;br /&gt;
} // Pointer is now unassigned, the garbage collector will reclaim the memory&lt;br /&gt;
&lt;br /&gt;
Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
…&lt;br /&gt;
mmath = Nothing; // Let the garbage collector reclaim the memory&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To use another class within you classes, you just need to instantiate the other class and manipulate it like you would with any other function. To allow access to the methods of that class, you simply wrap the other functions methods within your own.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyPoint {&lt;br /&gt;
  Var Point As SPoint;&lt;br /&gt;
  Function New(newx As Integer, newy As Integer) {&lt;br /&gt;
    Point = New Spoint(newx, newy);&lt;br /&gt;
  }&lt;br /&gt;
  Function New(newpoint As SPoint) {&lt;br /&gt;
    Point = newpoint;&lt;br /&gt;
  }&lt;br /&gt;
   Function X () As Integer {&lt;br /&gt;
    Return Point.X;&lt;br /&gt;
  }&lt;br /&gt;
   Function Y () As Integer {&lt;br /&gt;
    Return Point.Y;&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Classes in STNE can be extremely useful for self documenting code and for maintaining a small memory footprint for your script. Although STNE script classes are more simplistic that a full classful language, this does not detract much from the the usefulness of them. &lt;br /&gt;
&lt;br /&gt;
Code used for this exercise:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Var Radius As Double&lt;br /&gt;
  Function New() {&lt;br /&gt;
    ;&lt;br /&gt;
  }&lt;br /&gt;
  Function New(r As Double) {&lt;br /&gt;
    Radius = r;&lt;br /&gt;
  }&lt;br /&gt;
  Function Radius(c As Double) As Double {&lt;br /&gt;
    Return Math.Sqrt(c / MyMath.Pi);&lt;br /&gt;
  }&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or MyMath.Pi * Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
  Function Circumference() As Double {&lt;br /&gt;
    Return MyMath.Circumference(Radius);&lt;br /&gt;
  }&lt;br /&gt;
  Function Output (message As String) {&lt;br /&gt;
     WriteLine (&amp;quot;MyMath: &amp;quot; &amp;amp; message);&lt;br /&gt;
  }&lt;br /&gt;
  Function ShowCircumference() {&lt;br /&gt;
    MyMath.Output(&amp;quot;C=&amp;quot; &amp;amp; This.Circumference);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Class MyPoint {&lt;br /&gt;
  Var Point As SPoint;&lt;br /&gt;
  New(newx As Integer, newy As Integer) {&lt;br /&gt;
    Point = New Spoint(newx, newy);&lt;br /&gt;
  }&lt;br /&gt;
  New(newpoint As SPoint) {&lt;br /&gt;
    Point = newpoint;&lt;br /&gt;
  }&lt;br /&gt;
   Function X () As Integer {&lt;br /&gt;
    Return Point.X;&lt;br /&gt;
  }&lt;br /&gt;
   Function Y () As Integer {&lt;br /&gt;
    Return Point.Y;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine(MyMath.Circumference(3));&lt;br /&gt;
Var m As MyMath = New MyMath(3);&lt;br /&gt;
WriteLine(m.Circumference());&lt;br /&gt;
&lt;br /&gt;
MyMath.Output(MyMath.Circumference(3));&lt;br /&gt;
&lt;br /&gt;
MyMath.ShowCircumference (3);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 21:19, 18 October 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:STNE_Classes</id>
		<title>Scripting:STNE Classes</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:STNE_Classes"/>
				<updated>2011-10-18T19:20:32Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Classes in STNE&lt;br /&gt;
&lt;br /&gt;
Firstly, you need to understand that the script compiler is not a binary compiler. It is a front end lexical analyzer (lex an) for Visual Basic and .Net. The reason you need to understand this is because it means that operator syntax comes from VB, so there are some differences that you might not expect. It also means that you can use a VB reference for some of the operators (such as logical not, and null pointer reference). Since the lex an reprocesses into VB (Keep in mind this comes from experience with the engine, not from direct knowledge) this can be quite helpful, and confusing at the same time.&lt;br /&gt;
&lt;br /&gt;
Classes in STNE are similar to classes in a fully classful language, with a few major exceptions:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The classes are not inheritable&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The use of the This pointer is required to access class methods from within the class&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Declarations are used as static references to the class&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;There is no scoping of variables or methods (private/protected/public)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Operator overloading has not been tested by myself, but I doubt it's included.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Since classes are not inheritable, there is no method or variable overloading&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also some caveats you should be aware of that pertain to the lexical analyzer. &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Additional ending braces (}) can cause the lex an to issue no warnings during compile, yet not producing usable code&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Prototyping is not supported (to the best of my knowledge)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Since prototyping is not supported, implicit casting is used with varibales, with the default type being String (This includes declarations of varibales). &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Function or method mismatches can cause a null pointer exception during compile, without giving a reference point as to where (eg no line number of the occurrence)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;Line terminators (eg ';') are not necessary. A new line compliments the ; if the code is written on one line. (Not recommended, but usable)&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While there are many other anomalies, the basic lex an is sound enough to do some rather fancy coding. Seeing how this feature is left out of many online games, the engine is laudable. Even better, while there is more work necessary to make is robust, it is actually maintained along with STNE changes.&lt;br /&gt;
&lt;br /&gt;
So, why bother to write a classfull script? &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Data objects can be reused and even stored in memory in lists&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Rather than suck server memory dry (which will abort your script), you can instantiate the class and then free the memory when complete&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;You can avoid memory sucking multi-dimensional arrays&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;You can write more complete self documenting code that is easier to maintain&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To create a static class, all you need to is declare it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  …&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Once it is declared, any method declared is also available. This of course doesn't work well with variables... They need memory allocation. You can create a 'property' of the class by simply returning a static value as thus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that when we called Pi from Circumference, we used the accessor MyMath. Since this is going to be used statically, you do not want to use a This pointer, as that requires you to instantiate the class. The majority of the functionality you will want from a class is handled by the static methods, but you have to remember that while you can call a static method from an instantiation, the inverse is not true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return This.Pi * radius * radius; // Or MyMath.Pi * Math.Pow(radius, 2.0);&lt;br /&gt;
}&lt;br /&gt;
// This will fail miserably. Since the class cannot be instantiated in this form&lt;br /&gt;
Var cir As Double = MyMath.Circumference(3.0);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to create an instantiated class, you need to have two components. The new method in the class, and the assignment in the code. The new method can be empty, but it has to exist to instantiate the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Var Radius As Double&lt;br /&gt;
  Function New() {&lt;br /&gt;
    ; // Null instruction, essentially a placeholder&lt;br /&gt;
  }&lt;br /&gt;
  Function New(r As Double) {&lt;br /&gt;
    Radius = r;&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to access a method within the class, you need to use a reference pointer (Either statically via the class name, or dynamically via the This pointer). The lex an will only look for functions that are global to the script if you don't specifically reference the class. In most cases, this is not an issue (annoying yes, an issue, not really) unless you name a global function the same as a class method. Name your global functions differently than your class functions, it will help you in the long run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Output (message As String) {&lt;br /&gt;
     WriteLine (“MyMath: “ &amp;amp; message);&lt;br /&gt;
  }&lt;br /&gt;
  Function ShowCircumference() {&lt;br /&gt;
    MyMath.Output(This.Circumference);&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, notice the lack of the function parameter list in the call to This.Circumference within ShowCircumference(). If there are no parameters necessary (eg a procedure), the parameter list can be left off (As if you were accessing a variable in the class).&lt;br /&gt;
&lt;br /&gt;
In order to free the memory used by an instantiation, you have to either leave the scope of the delcartion (return from a function), or assign the reference to a null pointer. The next time the garbage collector runs, it will free the memory. The garbage is a mechanism that free resources and performs other various maintenance operations automatically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function C (cir As Double) As Double {&lt;br /&gt;
  Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
  Return mmath.Circumference(cir);&lt;br /&gt;
} // Pointer is now unassigned, the garbage collector will reclaim the memory&lt;br /&gt;
&lt;br /&gt;
Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
…&lt;br /&gt;
mmath = Nothing; // Let the garbage collector reclaim the memory&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To use another class within you classes, you just need to instantiate the other class and manipulate it like you would with any other function. To allow access to the methods of that class, you simply wrap the other functions methods within your own.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyPoint {&lt;br /&gt;
  Var Point As SPoint;&lt;br /&gt;
  Function New(newx As Integer, newy As Integer) {&lt;br /&gt;
    Point = New Spoint(newx, newy);&lt;br /&gt;
  }&lt;br /&gt;
  Function New(newpoint As SPoint) {&lt;br /&gt;
    Point = newpoint;&lt;br /&gt;
  }&lt;br /&gt;
   Function X () As Integer {&lt;br /&gt;
    Return Point.X;&lt;br /&gt;
  }&lt;br /&gt;
   Function Y () As Integer {&lt;br /&gt;
    Return Point.Y;&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Classes in STNE can be extremely useful for self documenting code and for maintaining a small memory footprint for your script. Although STNE script classes are more simplistic that a full classful language, this does not detract much from the the usefulness of them. &lt;br /&gt;
&lt;br /&gt;
Code used for this exercise:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Var Radius As Double&lt;br /&gt;
  Function New() {&lt;br /&gt;
    ;&lt;br /&gt;
  }&lt;br /&gt;
  Function New(r As Double) {&lt;br /&gt;
    Radius = r;&lt;br /&gt;
  }&lt;br /&gt;
  Function Radius(c As Double) As Double {&lt;br /&gt;
    Return Math.Sqrt(c / MyMath.Pi);&lt;br /&gt;
  }&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or MyMath.Pi * Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
  Function Circumference() As Double {&lt;br /&gt;
    Return MyMath.Circumference(Radius);&lt;br /&gt;
  }&lt;br /&gt;
  Function Output (message As String) {&lt;br /&gt;
     WriteLine (&amp;quot;MyMath: &amp;quot; &amp;amp; message);&lt;br /&gt;
  }&lt;br /&gt;
  Function ShowCircumference() {&lt;br /&gt;
    MyMath.Output(&amp;quot;C=&amp;quot; &amp;amp; This.Circumference);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Class MyPoint {&lt;br /&gt;
  Var Point As SPoint;&lt;br /&gt;
  New(newx As Integer, newy As Integer) {&lt;br /&gt;
    Point = New Spoint(newx, newy);&lt;br /&gt;
  }&lt;br /&gt;
  New(newpoint As SPoint) {&lt;br /&gt;
    Point = newpoint;&lt;br /&gt;
  }&lt;br /&gt;
   Function X () As Integer {&lt;br /&gt;
    Return Point.X;&lt;br /&gt;
  }&lt;br /&gt;
   Function Y () As Integer {&lt;br /&gt;
    Return Point.Y;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine(MyMath.Circumference(3));&lt;br /&gt;
Var m As MyMath = New MyMath(3);&lt;br /&gt;
WriteLine(m.Circumference());&lt;br /&gt;
&lt;br /&gt;
MyMath.Output(MyMath.Circumference(3));&lt;br /&gt;
&lt;br /&gt;
MyMath.ShowCircumference (3);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 21:19, 18 October 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:STNE_Classes</id>
		<title>Scripting:STNE Classes</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:STNE_Classes"/>
				<updated>2011-10-18T19:19:26Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Classes in STNE&lt;br /&gt;
&lt;br /&gt;
Firstly, you need to understand that the script compiler is not a binary compiler. It is a front end lexical analyzer (lex an) for Visual Basic and .Net. The reason you need to understand this is because it means that operator syntax comes from VB, so there are some differences that you might not expect. It also means that you can use a VB reference for some of the operators (such as logical not, and null pointer reference). Since the lex an reprocesses into VB (Keep in mind this comes from experience with the engine, not from direct knowledge) this can be quite helpful, and confusing at the same time.&lt;br /&gt;
&lt;br /&gt;
Classes in STNE are similar to classes in a fully classful language, with a few major exceptions:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The classes are not inheritable&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The use of the This pointer is required to access class methods from within the class&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Declarations are used as static references to the class&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;There is no scoping of variables or methods (private/protected/public)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Operator overloading has not been tested by myself, but I doubt it's included.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Since classes are not inheritable, there is no method or variable overloading&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also some caveats you should be aware of that pertain to the lexical analyzer. &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;Additional ending braces (}) can cause the lex an to issue no warnings during compile, yet not producing usable code&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Prototyping is not supported (to the best of my knowledge)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Since prototyping is not supported, implicit casting is used with varibales, with the default type being String (This includes declarations of varibales). &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Function or method mismatches can cause a null pointer exception during compile, without giving a reference point as to where (eg no line number of the occurrence)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;Line terminators (eg ';') are not necessary. A new line compliments the ; if the code is written on one line. (Not recommended, but usable)&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While there are many other anomalies, the basic lex an is sound enough to do some rather fancy coding. Seeing how this feature is left out of many online games, the engine is laudable. Even better, while there is more work necessary to make is robust, it is actually maintained along with STNE changes.&lt;br /&gt;
&lt;br /&gt;
So, why bother to write a classfull script? &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Data objects can be reused and even stored in memory in lists&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Rather than suck server memory dry (which will abort your script), you can instantiate the class and then free the memory when complete&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;You can avoid memory sucking multi-dimensional arrays&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;You can write more complete self documenting code that is easier to maintain&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To create a static class, all you need to is declare it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  …&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Once it is declared, any method declared is also available. This of course doesn't work well with variables... They need memory allocation. You can create a 'property' of the class by simply returning a static value as thus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that when we called Pi from Circumference, we used the accessor MyMath. Since this is going to be used statically, you do not want to use a This pointer, as that requires you to instantiate the class. The majority of the functionality you will want from a class is handled by the static methods, but you have to remember that while you can call a static method from an instantiation, the inverse is not true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return This.Pi * radius * radius; // Or MyMath.Pi * Math.Pow(radius, 2.0);&lt;br /&gt;
}&lt;br /&gt;
// This will fail miserably. Since the class cannot be instantiated in this form&lt;br /&gt;
Var cir As Double = MyMath.Circumference(3.0);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to create an instantiated class, you need to have two components. The new method in the class, and the assignment in the code. The new method can be empty, but it has to exist to instantiate the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Var Radius As Double&lt;br /&gt;
  Function New() {&lt;br /&gt;
    ; // Null instruction, essentially a placeholder&lt;br /&gt;
  }&lt;br /&gt;
  Function New(r As Double) {&lt;br /&gt;
    Radius = r;&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to access a method within the class, you need to use a reference pointer (Either statically via the class name, or dynamically via the This pointer). The lex an will only look for functions that are global to the script if you don't specifically reference the class. In most cases, this is not an issue (annoying yes, an issue, not really) unless you name a global function the same as a class method. Name your global functions differently than your class functions, it will help you in the long run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Output (message As String) {&lt;br /&gt;
     WriteLine (“MyMath: “ &amp;amp; message);&lt;br /&gt;
  }&lt;br /&gt;
  Function ShowCircumference() {&lt;br /&gt;
    MyMath.Output(This.Circumference);&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, notice the lack of the function parameter list in the call to This.Circumference within ShowCircumference(). If there are no parameters necessary (eg a procedure), the parameter list can be left off (As if you were accessing a variable in the class).&lt;br /&gt;
&lt;br /&gt;
In order to free the memory used by an instantiation, you have to either leave the scope of the delcartion (return from a function), or assign the reference to a null pointer. The next time the garbage collector runs, it will free the memory. The garbage is a mechanism that free resources and performs other various maintenance operations automatically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function C (cir As Double) As Double {&lt;br /&gt;
  Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
  Return mmath.Circumference(cir);&lt;br /&gt;
} // Pointer is now unassigned, the garbage collector will reclaim the memory&lt;br /&gt;
&lt;br /&gt;
Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
…&lt;br /&gt;
mmath = Nothing; // Let the garbage collector reclaim the memory&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To use another class within you classes, you just need to instantiate the other class and manipulate it like you would with any other function. To allow access to the methods of that class, you simply wrap the other functions methods within your own.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyPoint {&lt;br /&gt;
  Var Point As SPoint;&lt;br /&gt;
  Function New(newx As Integer, newy As Integer) {&lt;br /&gt;
    Point = New Spoint(newx, newy);&lt;br /&gt;
  }&lt;br /&gt;
  Function New(newpoint As SPoint) {&lt;br /&gt;
    Point = newpoint;&lt;br /&gt;
  }&lt;br /&gt;
   Function X () As Integer {&lt;br /&gt;
    Return Point.X;&lt;br /&gt;
  }&lt;br /&gt;
   Function Y () As Integer {&lt;br /&gt;
    Return Point.Y;&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Classes in STNE can be extremely useful for self documenting code and for maintaining a small memory footprint for your script. Although STNE script classes are more simplistic that a full classful language, this does not detract much from the the usefulness of them. &lt;br /&gt;
&lt;br /&gt;
Code used for this exercise:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Var Radius As Double&lt;br /&gt;
  Function New() {&lt;br /&gt;
    ;&lt;br /&gt;
  }&lt;br /&gt;
  Function New(r As Double) {&lt;br /&gt;
    Radius = r;&lt;br /&gt;
  }&lt;br /&gt;
  Function Radius(c As Double) As Double {&lt;br /&gt;
    Return Math.Sqrt(c / MyMath.Pi);&lt;br /&gt;
  }&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or MyMath.Pi * Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
  Function Circumference() As Double {&lt;br /&gt;
    Return MyMath.Circumference(Radius);&lt;br /&gt;
  }&lt;br /&gt;
  Function Output (message As String) {&lt;br /&gt;
     WriteLine (&amp;quot;MyMath: &amp;quot; &amp;amp; message);&lt;br /&gt;
  }&lt;br /&gt;
  Function ShowCircumference() {&lt;br /&gt;
    MyMath.Output(&amp;quot;C=&amp;quot; &amp;amp; This.Circumference);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Class MyPoint {&lt;br /&gt;
  Var Point As SPoint;&lt;br /&gt;
  New(newx As Integer, newy As Integer) {&lt;br /&gt;
    Point = New Spoint(newx, newy);&lt;br /&gt;
  }&lt;br /&gt;
  New(newpoint As SPoint) {&lt;br /&gt;
    Point = newpoint;&lt;br /&gt;
  }&lt;br /&gt;
   Function X () As Integer {&lt;br /&gt;
    Return Point.X;&lt;br /&gt;
  }&lt;br /&gt;
   Function Y () As Integer {&lt;br /&gt;
    Return Point.Y;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine(MyMath.Circumference(3));&lt;br /&gt;
Var m As MyMath = New MyMath(3);&lt;br /&gt;
WriteLine(m.Circumference());&lt;br /&gt;
&lt;br /&gt;
MyMath.Output(MyMath.Circumference(3));&lt;br /&gt;
&lt;br /&gt;
MyMath.ShowCircumference (3);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 21:19, 18 October 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:STNE_Classes</id>
		<title>Scripting:STNE Classes</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:STNE_Classes"/>
				<updated>2011-10-18T19:18:43Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: Created page with &amp;quot;Classes in STNE  Firstly, you need to understand that the script compiler is not a binary compiler. It is a front end lexical analyzer (lex an) for Visual Basic and .Net. The rea...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Classes in STNE&lt;br /&gt;
&lt;br /&gt;
Firstly, you need to understand that the script compiler is not a binary compiler. It is a front end lexical analyzer (lex an) for Visual Basic and .Net. The reason you need to understand this is because it means that operator syntax comes from VB, so there are some differences that you might not expect. It also means that you can use a VB reference for some of the operators (such as logical not, and null pointer reference). Since the lex an reprocesses into VB (Keep in mind this comes from experience with the engine, not from direct knowledge) this can be quite helpful, and confusing at the same time.&lt;br /&gt;
&lt;br /&gt;
Classes in STNE are similar to classes in a fully classful language, with a few major exceptions:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The classes are not inheritable&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The use of the This pointer is required to access class methods from within the class&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Declarations are used as static references to the class&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;There is no scoping of variables or methods (private/protected/public)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Operator overloading has not been tested by myself, but I doubt it's included.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Since classes are not inheritable, there is no method or variable overloading&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also some caveats you should be aware of that pertain to the lexical analyzer. &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;Additional ending braces (}) can cause the lex an to issue no warnings during compile, yet not producing usable code&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Prototyping is not supported (to the best of my knowledge)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Since prototyping is not supported, implicit casting is used with varibales, with the default type being String (This includes declarations of varibales). &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Function or method mismatches can cause a null pointer exception during compile, without giving a reference point as to where (eg no line number of the occurrence)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;Line terminators (eg ';') are not necessary. A new line compliments the ; if the code is written on one line. (Not recommended, but usable)&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While there are many other anomalies, the basic lex an is sound enough to do some rather fancy coding. Seeing how this feature is left out of many online games, the engine is laudable. Even better, while there is more work necessary to make is robust, it is actually maintained along with STNE changes.&lt;br /&gt;
&lt;br /&gt;
So, why bother to write a classfull script? &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Data objects can be reused and even stored in memory in lists&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Rather than suck server memory dry (which will abort your script), you can instantiate the class and then free the memory when complete&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;You can avoid memory sucking multi-dimensional arrays&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;You can write more complete self documenting code that is easier to maintain&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To create a static class, all you need to is declare it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  …&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Once it is declared, any method declared is also available. This of course doesn't work well with variables... They need memory allocation. You can create a 'property' of the class by simply returning a static value as thus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that when we called Pi from Circumference, we used the accessor MyMath. Since this is going to be used statically, you do not want to use a This pointer, as that requires you to instantiate the class. The majority of the functionality you will want from a class is handled by the static methods, but you have to remember that while you can call a static method from an instantiation, the inverse is not true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return This.Pi * radius * radius; // Or MyMath.Pi * Math.Pow(radius, 2.0);&lt;br /&gt;
}&lt;br /&gt;
// This will fail miserably. Since the class cannot be instantiated in this form&lt;br /&gt;
Var cir As Double = MyMath.Circumference(3.0);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to create an instantiated class, you need to have two components. The new method in the class, and the assignment in the code. The new method can be empty, but it has to exist to instantiate the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Var Radius As Double&lt;br /&gt;
  Function New() {&lt;br /&gt;
    ; // Null instruction, essentially a placeholder&lt;br /&gt;
  }&lt;br /&gt;
  Function New(r As Double) {&lt;br /&gt;
    Radius = r;&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to access a method within the class, you need to use a reference pointer (Either statically via the class name, or dynamically via the This pointer). The lex an will only look for functions that are global to the script if you don't specifically reference the class. In most cases, this is not an issue (annoying yes, an issue, not really) unless you name a global function the same as a class method. Name your global functions differently than your class functions, it will help you in the long run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Output (message As String) {&lt;br /&gt;
     WriteLine (“MyMath: “ &amp;amp; message);&lt;br /&gt;
  }&lt;br /&gt;
  Function ShowCircumference() {&lt;br /&gt;
    MyMath.Output(This.Circumference);&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, notice the lack of the function parameter list in the call to This.Circumference within ShowCircumference(). If there are no parameters necessary (eg a procedure), the parameter list can be left off (As if you were accessing a variable in the class).&lt;br /&gt;
&lt;br /&gt;
In order to free the memory used by an instantiation, you have to either leave the scope of the delcartion (return from a function), or assign the reference to a null pointer. The next time the garbage collector runs, it will free the memory. The garbage is a mechanism that free resources and performs other various maintenance operations automatically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function C (cir As Double) As Double {&lt;br /&gt;
  Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
  Return mmath.Circumference(cir);&lt;br /&gt;
} // Pointer is now unassigned, the garbage collector will reclaim the memory&lt;br /&gt;
&lt;br /&gt;
Var mmath As MyMath = New MyMath(); // This could be written Var mmath As New MyMath();&lt;br /&gt;
…&lt;br /&gt;
mmath = Nothing; // Let the garbage collector reclaim the memory&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To use another class within you classes, you just need to instantiate the other class and manipulate it like you would with any other function. To allow access to the methods of that class, you simply wrap the other functions methods within your own.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyPoint {&lt;br /&gt;
  Var Point As SPoint;&lt;br /&gt;
  Function New(newx As Integer, newy As Integer) {&lt;br /&gt;
    Point = New Spoint(newx, newy);&lt;br /&gt;
  }&lt;br /&gt;
  Function New(newpoint As SPoint) {&lt;br /&gt;
    Point = newpoint;&lt;br /&gt;
  }&lt;br /&gt;
   Function X () As Integer {&lt;br /&gt;
    Return Point.X;&lt;br /&gt;
  }&lt;br /&gt;
   Function Y () As Integer {&lt;br /&gt;
    Return Point.Y;&lt;br /&gt;
  }&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Classes in STNE can be extremely useful for self documenting code and for maintaining a small memory footprint for your script. Although STNE script classes are more simplistic that a full classful language, this does not detract much from the the usefulness of them. &lt;br /&gt;
&lt;br /&gt;
Code used for this exercise:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class MyMath {&lt;br /&gt;
  Var Radius As Double&lt;br /&gt;
  Function New() {&lt;br /&gt;
    ;&lt;br /&gt;
  }&lt;br /&gt;
  Function New(r As Double) {&lt;br /&gt;
    Radius = r;&lt;br /&gt;
  }&lt;br /&gt;
  Function Radius(c As Double) As Double {&lt;br /&gt;
    Return Math.Sqrt(c / MyMath.Pi);&lt;br /&gt;
  }&lt;br /&gt;
  Function Pi() As Double { Return 3.14; }&lt;br /&gt;
  Function Circumference(radius As Double) As Double {&lt;br /&gt;
    Return MyMath.Pi * radius * radius; // Or MyMath.Pi * Math.Pow(radius, 2.0);&lt;br /&gt;
  }&lt;br /&gt;
  Function Circumference() As Double {&lt;br /&gt;
    Return MyMath.Circumference(Radius);&lt;br /&gt;
  }&lt;br /&gt;
  Function Output (message As String) {&lt;br /&gt;
     WriteLine (&amp;quot;MyMath: &amp;quot; &amp;amp; message);&lt;br /&gt;
  }&lt;br /&gt;
  Function ShowCircumference() {&lt;br /&gt;
    MyMath.Output(&amp;quot;C=&amp;quot; &amp;amp; This.Circumference);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Class MyPoint {&lt;br /&gt;
  Var Point As SPoint;&lt;br /&gt;
  New(newx As Integer, newy As Integer) {&lt;br /&gt;
    Point = New Spoint(newx, newy);&lt;br /&gt;
  }&lt;br /&gt;
  New(newpoint As SPoint) {&lt;br /&gt;
    Point = newpoint;&lt;br /&gt;
  }&lt;br /&gt;
   Function X () As Integer {&lt;br /&gt;
    Return Point.X;&lt;br /&gt;
  }&lt;br /&gt;
   Function Y () As Integer {&lt;br /&gt;
    Return Point.Y;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WriteLine(MyMath.Circumference(3));&lt;br /&gt;
Var m As MyMath = New MyMath(3);&lt;br /&gt;
WriteLine(m.Circumference());&lt;br /&gt;
&lt;br /&gt;
MyMath.Output(MyMath.Circumference(3));&lt;br /&gt;
&lt;br /&gt;
MyMath.ShowCircumference (3);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Main_page</id>
		<title>Scripting:Main page</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Main_page"/>
				<updated>2011-10-18T19:18:21Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: /* Topics: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scripting]]&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
{{CreateScriptingArticle}}&lt;br /&gt;
&lt;br /&gt;
This section of the Wiki is intended to document the scripting engine found in the game. Most scripting related pages in STNE can be found from the main menu trough Database -&amp;gt; Scripting.&lt;br /&gt;
&lt;br /&gt;
=== Topics: ===&lt;br /&gt;
* [[Scripting:Syntax|Syntax]]&lt;br /&gt;
* [[Scripting:Operators|Operators]]&lt;br /&gt;
* [[Scripting:Interfaces|Interfaces]]&lt;br /&gt;
&lt;br /&gt;
* [[Scripting:Basic course|Basic course]] (mostly translated)&lt;br /&gt;
* [[Scripting:Script_editor|The external script editor]]&lt;br /&gt;
* [[Scripting:InvokeItem|A tutorial on scripting the portal InvokeItem()]]&lt;br /&gt;
* [[Scripting:InfoBar Links|A tutorial on scripting for an InfoBar link]]&lt;br /&gt;
* [[Scripting:Data Storage|A tutorial on understanding STNE non volatile storage]]&lt;br /&gt;
* [[Scripting:STNE Classes|A tutorial on understanding STNE classes]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Data_Storage</id>
		<title>Scripting:Data Storage</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Data_Storage"/>
				<updated>2011-10-10T05:43:53Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Understanding script data (STNE Tables)&lt;br /&gt;
&lt;br /&gt;
Data Tables in STNE are not the same as tables in a RDBMS, they don't have direct indexes, they are cascading, and understanding them can be a bit confusing at times. Essentially, there is a parent object, called CDataNodeStorage, and children, called CDataNode and CDataNodeList. The parent only has directly the child  CDataNode. CDataNode has the child  CDataNodeList, and  CDataNodeList has the child  CDataNode. I little confusing, I know. So here's a mapping:&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
CDataNodeStorage-&amp;gt;CDataNod&amp;lt;br&amp;gt;&lt;br /&gt;
CDataNode-&amp;gt; CDataNodeList&amp;lt;br&amp;gt;&lt;br /&gt;
CDataNodeList-&amp;gt;CDataNode&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
All CDataNodes are locatable from CDataNodeStorage&amp;lt;br&amp;gt;&lt;br /&gt;
All single values are accessed via a CDataNode&amp;lt;br&amp;gt;&lt;br /&gt;
All multiple values are accessed from a CDataNodeList&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
This is important to remember, because each has a unique function. CDataNodeList is a list of items, like sectors or colonies, and CDataNode has only one item. If you have a need for a list, but not assignment, you can use the CDataNodeList to do this.&lt;br /&gt;
&lt;br /&gt;
Let's take a small example and break it down:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TableVersion=10.1;&lt;br /&gt;
Colonies &lt;br /&gt;
{&lt;br /&gt;
  Earth='500|400';&lt;br /&gt;
  Mars='500|401';&lt;br /&gt;
  Venus='400|402';&lt;br /&gt;
}&lt;br /&gt;
Allies&lt;br /&gt;
{&lt;br /&gt;
  12345;&lt;br /&gt;
  67890;&lt;br /&gt;
}&lt;br /&gt;
Production&lt;br /&gt;
{&lt;br /&gt;
  Earth&lt;br /&gt;
  {&lt;br /&gt;
    Photons=2;&lt;br /&gt;
    Duranium=8;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
First, you need some way to access the table. This is done with CDataNodeStorage. The way to open the pointer depends on if it is local or remote(on another account). For local storage,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var db As New CDataNodeStorage(String, Boolean);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where the TableName is a string of the name, and the boolean is table creation (true to create, false to fail instead if the table doesn't exit). For remote storage,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var db As CDataNodeStorage.LoadFromUser(String, Integer);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where String is the name of the table, and Integer is the user ID (the table does not open cross server, so there is no designator for EN1 vs DE3 etc)&lt;br /&gt;
&lt;br /&gt;
Next is accessing the data. The first entry, TableVersion, has the value of 10.1, a double. The value would be accessed as such:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var value As Double = db.Items.Item('TableVersion').asDouble;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that we told the Item method to retrieve the value as a double. STNE via VB .NET has the tendency of casting doubles to ints not in a truncate fashion, but as a function of ceiling, and to drop the decimal when casting to a String. Therefore, when possible, always be specific on the type.&lt;br /&gt;
&lt;br /&gt;
The next entry is Colonies, which is actually a multiple value. First, you access the key, then the list below it, like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Location As CDataNodeList = db.Items.Item('Colonies').Items;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a direct assignment, rather than creating a CDataNode and the accessing the list from there. If you prefer or need to access the node independently, you can do it in multiple steps:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Node As CDataNode = db.Items.Item('Colonies');&lt;br /&gt;
Var NodeList As CDataNodeList = Node.Items;&lt;br /&gt;
Var Location As String = NodeList.Item('Earth').AsString;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Normally, the only reason to access the list from the parent node is to pass it to another function or method.&lt;br /&gt;
To access a value from the list:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Location As String = db.Items.Item('Colonies').Items.Item('Earth').AsString;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since the value is a string (denoted by the single quotes), I specified the type.&lt;br /&gt;
&lt;br /&gt;
The next entry, Allies has no values, just a list of keys. These are useful for items that you need to maintain a list of, but not values. Access is the same as a list of keys and values, but since you aren't retrieving the values, you would usually use ContainsKey to check it it's in the list:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
If (db.Items.Item('Allies').Items.ContainsKey(12345)) { &lt;br /&gt;
  // Do something&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Production is a cascaded value. This one is slightly more complex, but from what you have learned above, it is fairly straightforward:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Photons As Integer = db.Items.Item('Production').Items.Item('Earth').Items.Item('Photons').asInteger;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As a multiple statement, it looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var NodeList As CDataNodeList = db.Items.Item('Production').Items;&lt;br /&gt;
Var NodeListColony As CDataNodeList = NodeList.item('Earth').Items;&lt;br /&gt;
Var Photons As Integer = NodeListColony.Item('Photons').asInteger;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Node that .Items was called twice (well, 3 times but the first is for any access). We don't actually care what the value of the key is, since it's an index. Then we get the subindex for a particular colony (Earth), then a particular production (Photons).&lt;br /&gt;
&lt;br /&gt;
Writing to the keys is comparable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
db.Items.AddDouble(' TableVersion', 10.1);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Colonies')) {&lt;br /&gt;
  db.Items.Add('Colonies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Colonies').Items.AddString('Earth', “500|400”);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Allies')) { &lt;br /&gt;
  db.Items.Add('Allies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Allies').Items.Add(12345);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Production')) {&lt;br /&gt;
  db.Items.Add('Production');&lt;br /&gt;
}&lt;br /&gt;
If (NOT db.Items.Item('Production').Items.ContainsKey('Earth')) {&lt;br /&gt;
  db.Items.Item('Production').Items.ContainsKey('Earth');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Production').Items.Item('Earth').Items.AddInteger('Photons', 2);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For Allies, since there is no value, so you need to use the generic .Add method. The code above will overwrite the values if they already exist, it's simple code so it doesn't check for the previous existence of anything but the index path, and creates them if the indexes don't exist.&lt;br /&gt;
&lt;br /&gt;
To delete a value, use the .Remove() method. It has a comparable form as .Add:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
db.Items.Remove('TableVersion');&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
Some caveats for script storage&lt;br /&gt;
&amp;lt;li&amp;gt;Local tables can not be renamed or deleted.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Remote tables can not be created&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;LoadFromUser() can open local tables, but seems to abort the script unexpectedly from time to time, with no error.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Multiple access code is weak. At least from an extension. I hit 'Exceded table limit' errors from time to time, and I am under quota. I simply open the table, hit edit, and save, then the deactivate and re execute the script and it works as expected again.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is a script with the above snippets in a complete form:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Node As CDataNode;&lt;br /&gt;
Var NodeList As CDataNodeList;&lt;br /&gt;
Var NodeListColony As CDataNodeList;&lt;br /&gt;
Var Location As String;&lt;br /&gt;
Var Value As Double;&lt;br /&gt;
Var Photons As Integer;&lt;br /&gt;
Var Plasma As Integer;&lt;br /&gt;
&lt;br /&gt;
Var db As New CDataNodeStorage(&amp;quot;9046&amp;quot;, True);&lt;br /&gt;
&lt;br /&gt;
// Get some current values, as one line fetches&lt;br /&gt;
Value = db.Items.Item('TableVersion').asDouble;&lt;br /&gt;
WriteLine(value);&lt;br /&gt;
&lt;br /&gt;
Location = db.Items.Item('Colonies').Items.Item('Earth').asString;&lt;br /&gt;
WriteLine(Location);&lt;br /&gt;
&lt;br /&gt;
If (db.Items.Item('Allies').Items.ContainsKey(12345)) { &lt;br /&gt;
  WriteLine(&amp;quot;Found 12345&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Photons = db.Items.Item('Production').Items.Item('Earth').Items.Item('Photons').asInteger;&lt;br /&gt;
WriteLine(Photons);&lt;br /&gt;
&lt;br /&gt;
// Now create and alter some keys&lt;br /&gt;
db.Items.AddDouble('TableVersion', 10.2);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Colonies')) {&lt;br /&gt;
  db.Items.Add('Colonies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Colonies').Items.AddString('Mercury', '400|400');&lt;br /&gt;
If (NOT db.Items.ContainsKey('Allies')) { &lt;br /&gt;
  db.Items.Add('Allies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Allies').Items.Add(23456);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Production')) {&lt;br /&gt;
  db.Items.Add('Production');&lt;br /&gt;
}&lt;br /&gt;
If (NOT db.Items.Item('Production').Items.ContainsKey('Earth')) {&lt;br /&gt;
  db.Items.Item('Production').Items.ContainsKey('Earth');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Production').Items.Item('Earth').Items.AddInteger('Plasma', 4);&lt;br /&gt;
&lt;br /&gt;
// Get the added/changes values, as multi line fetches&lt;br /&gt;
Value = db.Items.Item('TableVersion').asDouble;&lt;br /&gt;
WriteLine(value);&lt;br /&gt;
&lt;br /&gt;
Node = db.Items.Item('Colonies');&lt;br /&gt;
NodeList = Node.Items;&lt;br /&gt;
Location = NodeList.Item('Mercury').asString;&lt;br /&gt;
WriteLine(Location);&lt;br /&gt;
&lt;br /&gt;
If (db.Items.Item('Allies').Items.ContainsKey(23456)) { &lt;br /&gt;
  WriteLine(&amp;quot;Found 23456&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
NodeList = db.Items.Item('Production').Items;&lt;br /&gt;
NodeListColony = NodeList.item('Earth').Items;&lt;br /&gt;
Plasma = NodeListColony.Item('Plasma').asInteger;&lt;br /&gt;
WriteLine(Plasma);&lt;br /&gt;
&lt;br /&gt;
// Remove the added keys&lt;br /&gt;
db.Items.Item('Colonies').Items.Remove('Mercury');&lt;br /&gt;
db.Items.Item('Allies').Items.Remove(23456);&lt;br /&gt;
db.Items.Item('Production').Items.Item('Earth').Items.Remove('Plasma');&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 07:27, 10 October 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Data_Storage</id>
		<title>Scripting:Data Storage</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Data_Storage"/>
				<updated>2011-10-10T05:41:45Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Understanding script data (STNE Tables)&lt;br /&gt;
&lt;br /&gt;
Data Tables in STNE are not the same as tables in a RDBMS, they don't have direct indexes, they are cascading, and understanding them can be a bit confusing at times. Essentially, there is a parent object, called CDataNodeStorage, and children, called CDataNode and CDataNodeList. The parent only has directly the child  CDataNode. CDataNode has the child  CDataNodeList, and  CDataNodeList has the child  CDataNode. I little confusing, I know. So here's a mapping:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
CDataNodeStorage-&amp;gt;CDataNod&amp;lt;br&amp;gt;&lt;br /&gt;
CDataNode-&amp;gt; CDataNodeList&amp;lt;br&amp;gt;&lt;br /&gt;
CDataNodeList-&amp;gt;CDataNode&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
All CDataNodes are locatable from CDataNodeStorage&lt;br /&gt;
All single values are accessed via a CDataNode&lt;br /&gt;
All multiple values are accessed from a CDataNodeList&lt;br /&gt;
&lt;br /&gt;
This is important to remember, because each has a unique function. CDataNodeList is a list of items, like sectors or colonies, and CDataNode has only item.  If you have a need for a list, but not assignment, you can use the CDataNodeList to do this.&lt;br /&gt;
&lt;br /&gt;
Let's take a small example and break it down:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TableVersion=10.1;&lt;br /&gt;
Colonies &lt;br /&gt;
{&lt;br /&gt;
  Earth='500|400';&lt;br /&gt;
  Mars='500|401';&lt;br /&gt;
  Venus='400|402';&lt;br /&gt;
}&lt;br /&gt;
Allies&lt;br /&gt;
{&lt;br /&gt;
  12345;&lt;br /&gt;
  67890;&lt;br /&gt;
}&lt;br /&gt;
Production&lt;br /&gt;
{&lt;br /&gt;
  Earth&lt;br /&gt;
  {&lt;br /&gt;
    Photons=2;&lt;br /&gt;
    Duranium=8;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
First, you need some way to access the table. This is done with CDataNodeStorage. The way to open the pointer depends on if it is local or remote(on another account). For local storage,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var db As New CDataNodeStorage(String, Boolean);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where the TableName is a string of the name, and the boolean is table creation (true to create, false to fail instead if the table doesn't exit). For remote storage,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var db As CDataNodeStorage.LoadFromUser(String, Integer);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where String is the name of the table, and Integer is the user ID (the table does not open cross server, so there is no designator for EN1 vs DE3 etc)&lt;br /&gt;
&lt;br /&gt;
Next is accessing the data. The first entry, TableVersion, has the value of 10.1, a double. The value would be accessed as such:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var value As Double = db.Items.Item('TableVersion').asDouble;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that we told the Item method to retrieve the value as a double. STNE via VB .NET has the tendency of casting doubles to ints not in a truncate fashion, but as a function of ceiling, and to drop the decimal when casting to a String. Therefore, when possible, always be specific on the type.&lt;br /&gt;
&lt;br /&gt;
The next entry is Colonies, which is actually a multiple value. First, you access the key, then the list below it, like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Location As CDataNodeList = db.Items.Item('Colonies').Items;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a direct assignment, rather than creating a CDataNode and the accessing the list from there. If you prefer or need to access the node independently, you can do it in multiple steps:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Node As CDataNode = db.Items.Item('Colonies');&lt;br /&gt;
Var NodeList As CDataNodeList = Node.Items;&lt;br /&gt;
Var Location As String = NodeList.Item('Earth').AsString;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Normally, the only reason to access the list from the parent node is to pass it to another function or method.&lt;br /&gt;
To access a value from the list:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Location As String = db.Items.Item('Colonies').Items.Item('Earth').AsString;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since the value is a string (denoted by the single quotes), I specified the type.&lt;br /&gt;
&lt;br /&gt;
The next entry, Allies has no values, just a list of keys. These are useful for items that you need to maintain a list of, but not values. Access is the same as a list of keys and values, but since you aren't retrieving the values, you would usually use ContainsKey to check it it's in the list:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
If (db.Items.Item('Allies').Items.ContainsKey(12345)) { &lt;br /&gt;
  // Do something&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Production is a cascaded value. This one is slightly more complex, but from what you have learned above, it is fairly straightforward:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Photons As Integer = db.Items.Item('Production').Items.Item('Earth').Items.Item('Photons').asInteger;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As a multiple statement, it looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var NodeList As CDataNodeList = db.Items.Item('Production').Items;&lt;br /&gt;
Var NodeListColony As CDataNodeList = NodeList.item('Earth').Items;&lt;br /&gt;
Var Photons As Integer = NodeListColony.Item('Photons').asInteger;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Node that .Items was called twice (well, 3 times but the first is for any access). We don't actually care what the value of the key is, since it's an index. Then we get the subindex for a particular colony (Earth), then a particular production (Photons).&lt;br /&gt;
&lt;br /&gt;
Writing to the keys is comparable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
db.Items.AddDouble(' TableVersion', 10.1);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Colonies')) {&lt;br /&gt;
  db.Items.Add('Colonies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Colonies').Items.AddString('Earth', “500|400”);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Allies')) { &lt;br /&gt;
  db.Items.Add('Allies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Allies').Items.Add(12345);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Production')) {&lt;br /&gt;
  db.Items.Add('Production');&lt;br /&gt;
}&lt;br /&gt;
If (NOT db.Items.Item('Production').Items.ContainsKey('Earth')) {&lt;br /&gt;
  db.Items.Item('Production').Items.ContainsKey('Earth');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Production').Items.Item('Earth').Items.AddInteger('Photons', 2);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For Allies, since there is no value, so you need to use the generic .Add method. The code above will overwrite the values if they already exist, it's simple code so it doesn't check for the previous existence of anything but the index path, and creates them if the indexes don't exist.&lt;br /&gt;
&lt;br /&gt;
To delete a value, use the .Remove() method. It has a comparable form as .Add:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
db.Items.Remove('TableVersion');&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
Some caveats for script storage&lt;br /&gt;
&amp;lt;li&amp;gt;Local tables can not be renamed or deleted.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Remote tables can not be created&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;LoadFromUser() can open local tables, but seems to abort the script unexpectedly from time to time, with no error.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Multiple access code is weak. At least from an extension. I hit 'Exceded table limit' errors from time to time, and I am under quota. I simply open the table, hit edit, and save, then the deactivate and re execute the script and it works as expected again.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is a script with the above snippets in a complete form:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Node As CDataNode;&lt;br /&gt;
Var NodeList As CDataNodeList;&lt;br /&gt;
Var NodeListColony As CDataNodeList;&lt;br /&gt;
Var Location As String;&lt;br /&gt;
Var Value As Double;&lt;br /&gt;
Var Photons As Integer;&lt;br /&gt;
Var Plasma As Integer;&lt;br /&gt;
&lt;br /&gt;
Var db As New CDataNodeStorage(&amp;quot;9046&amp;quot;, True);&lt;br /&gt;
&lt;br /&gt;
// Get some current values, as one line fetches&lt;br /&gt;
Value = db.Items.Item('TableVersion').asDouble;&lt;br /&gt;
WriteLine(value);&lt;br /&gt;
&lt;br /&gt;
Location = db.Items.Item('Colonies').Items.Item('Earth').asString;&lt;br /&gt;
WriteLine(Location);&lt;br /&gt;
&lt;br /&gt;
If (db.Items.Item('Allies').Items.ContainsKey(12345)) { &lt;br /&gt;
  WriteLine(&amp;quot;Found 12345&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Photons = db.Items.Item('Production').Items.Item('Earth').Items.Item('Photons').asInteger;&lt;br /&gt;
WriteLine(Photons);&lt;br /&gt;
&lt;br /&gt;
// Now create and alter some keys&lt;br /&gt;
db.Items.AddDouble('TableVersion', 10.2);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Colonies')) {&lt;br /&gt;
  db.Items.Add('Colonies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Colonies').Items.AddString('Mercury', '400|400');&lt;br /&gt;
If (NOT db.Items.ContainsKey('Allies')) { &lt;br /&gt;
  db.Items.Add('Allies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Allies').Items.Add(23456);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Production')) {&lt;br /&gt;
  db.Items.Add('Production');&lt;br /&gt;
}&lt;br /&gt;
If (NOT db.Items.Item('Production').Items.ContainsKey('Earth')) {&lt;br /&gt;
  db.Items.Item('Production').Items.ContainsKey('Earth');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Production').Items.Item('Earth').Items.AddInteger('Plasma', 4);&lt;br /&gt;
&lt;br /&gt;
// Get the added/changes values, as multi line fetches&lt;br /&gt;
Value = db.Items.Item('TableVersion').asDouble;&lt;br /&gt;
WriteLine(value);&lt;br /&gt;
&lt;br /&gt;
Node = db.Items.Item('Colonies');&lt;br /&gt;
NodeList = Node.Items;&lt;br /&gt;
Location = NodeList.Item('Mercury').asString;&lt;br /&gt;
WriteLine(Location);&lt;br /&gt;
&lt;br /&gt;
If (db.Items.Item('Allies').Items.ContainsKey(23456)) { &lt;br /&gt;
  WriteLine(&amp;quot;Found 23456&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
NodeList = db.Items.Item('Production').Items;&lt;br /&gt;
NodeListColony = NodeList.item('Earth').Items;&lt;br /&gt;
Plasma = NodeListColony.Item('Plasma').asInteger;&lt;br /&gt;
WriteLine(Plasma);&lt;br /&gt;
&lt;br /&gt;
// Remove the added keys&lt;br /&gt;
db.Items.Item('Colonies').Items.Remove('Mercury');&lt;br /&gt;
db.Items.Item('Allies').Items.Remove(23456);&lt;br /&gt;
db.Items.Item('Production').Items.Item('Earth').Items.Remove('Plasma');&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 07:27, 10 October 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Data_Storage</id>
		<title>Scripting:Data Storage</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Data_Storage"/>
				<updated>2011-10-10T05:27:53Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Understanding script data (STNE Tables)&lt;br /&gt;
&lt;br /&gt;
Data Tables in STNE are not the same as tables in a RDBMS, they don't have direct indexes, they are cascading, and understanding them can be a bit confusing at times. Essentially, there is a parent object, called CDataNodeStorage, and children, called CDataNode and CDataNodeList. The parent only has directly the child  CDataNode. CDataNode has the child  CDataNodeList, and  CDataNodeList has the child  CdataNode. I little confusing, I know. So here's a mapping:&lt;br /&gt;
&lt;br /&gt;
CDataNodeStorage-&amp;gt;CDataNode &lt;br /&gt;
CDataNode-&amp;gt; CDataNodeList&lt;br /&gt;
CDataNodeList-&amp;gt;CDataNode &lt;br /&gt;
&lt;br /&gt;
All CdataNodes are locatable from CDataNodeStorage&lt;br /&gt;
All single values are accessed via a CDataNode&lt;br /&gt;
All multiple values are accessed from a CDataNodeList&lt;br /&gt;
&lt;br /&gt;
This is important to remember, because each has a unique function. CDataNodeList is a list of items, like sectors or colonies, and CdataNode has only item.  If you have a need for a list, but not assignment, you can use the CDataNodeList to do this.&lt;br /&gt;
&lt;br /&gt;
Let's take a small example and break it down&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TableVersion=10.1;&lt;br /&gt;
Colonies &lt;br /&gt;
{&lt;br /&gt;
  Earth='500|400';&lt;br /&gt;
  Mars='500|401';&lt;br /&gt;
  Venus='400|402';&lt;br /&gt;
}&lt;br /&gt;
Allies&lt;br /&gt;
{&lt;br /&gt;
  12345;&lt;br /&gt;
  67890;&lt;br /&gt;
}&lt;br /&gt;
Production&lt;br /&gt;
{&lt;br /&gt;
  Earth&lt;br /&gt;
  {&lt;br /&gt;
    Photons=2;&lt;br /&gt;
    Duranium=8;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
First, you need some way to access the table. This is done with CDataNodeStorage. The way to open the pointer depends on if it is local or remote(on another account). For local storage,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var db As New CdataNodeStorage(String, Boolean);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where the TableName is a string of the name, and the boolean is table creation (true to create, false to fail instead if the table doesn't exit). For remote storage,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var db AsCDataNodeStorage.LoadFromUser(String, Integer);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where String is the name of the table, and Integer is the user ID (the table does not open cross server, so there is no designator for EN1 vs DE3 etc)&lt;br /&gt;
&lt;br /&gt;
Next is accessing the data. The first entry, TableVersion, has the value of 10.1, a double. The value would be accessed as such:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var value As Double = db.Items.Item('TableVersion').asDouble;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that we told item method to retrieve the value as a double. STNE via .NET has the tendency of casting doubles to ints not in a truncate fashion, but as a function of ceiling, and to drop the decimal when casting to a String. Therefore, when possible, always be specific on the type.&lt;br /&gt;
&lt;br /&gt;
The next entry is Colonies, which is actually a multiple value. First, you access the key, then the list below it, like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Location As CdataNodeList = db.Items.Item('Colonies').Items;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a direct assignment, rather than creating a CdataNode and the accessing the list from there. If you prefer or need to access the node independently, you can do it in multiple steps:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Node As CDataNode = db.Items.Item('Colonies');&lt;br /&gt;
Var NodeList As CDataNodeList = Node.Items;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Normally, the only reason to access the list from the parent node is to pass it to another function or method.&lt;br /&gt;
To access a value from the list:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Location As String = db.Items.Item('Colonies').Items.Item('Earth').AsString;&lt;br /&gt;
Var Location As String = NodeList.Item('Earth').AsString;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since the value is a string (denoted by the single quotes), I specified the type.&lt;br /&gt;
&lt;br /&gt;
The next entry, Allies has no values, just a list of keys. These are useful for items that you need to maintain a list of, but not values. Access is the same as a list of keys and values, but since you aren't retrieving the values, you would usually use ContainsKey to check it it's in the list:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
If (db.Items.Item('Allies').Items.ContainsKey(12345)) { &lt;br /&gt;
  // Do something&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Production is a cascaded value. This one is slightly more complex, but from what you have learned above, it is fairly straightforward:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Photons As Integer = db.Items.Item('Production').Items.Item('Earth').Items.Item('Photons').asInteger;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As a multiple statement, it looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var NodeList As CDataNodeList = db.Items.Item('Production').Items;&lt;br /&gt;
Var NodeListColony As CDataNodeList = NodeList.item('Earth').Items;&lt;br /&gt;
Var Photons As Integer = NodeListColony.Item('Photons').asInteger;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Node that .Items was called twice (well, 3 times but the first is for any access). We don't actually care what the value of the key is, since it's an index. Then we get the subindex for a particular colony (Earth), then a particular production (Photons).&lt;br /&gt;
&lt;br /&gt;
Writing to the keys is comparable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
db.Items.AddDouble(' TableVersion', 10.1);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Colonies')) {&lt;br /&gt;
  db.Items.Add('Colonies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Colonies').Items.AddString('Earth', “500|400”);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Allies')) { &lt;br /&gt;
  db.Items.Add('Allies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Allies').Items.Add(12345);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Production')) {&lt;br /&gt;
  db.Items.Add('Production');&lt;br /&gt;
}&lt;br /&gt;
If (NOT db.Items.Item('Production').Items.ContainsKey('Earth')) {&lt;br /&gt;
  db.Items.Item('Production').Items.ContainsKey('Earth');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Production').Items.Item('Earth').Items.AddInteger('Photons', 2);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For Allies, since there is no value, so you need to use the generic .Add method. The code above will overwrite the values if they already exist, it's simple code so it doesn't check for the previous existence of anything but the index path, and creates them if the indexes don't exist.&lt;br /&gt;
&lt;br /&gt;
To delete a value, use the .Remove() method. It has a comparable form as .Add:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
db.Items.Remove('TableVersion');&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Some caveats for script storage&lt;br /&gt;
- Local tables can not be renamed or deleted.&lt;br /&gt;
- Remote tables can not be created&lt;br /&gt;
- LoadFromUser() can open local tables, but seems to abort the script unexpectedly from time to time, with no error.&lt;br /&gt;
- Multiple access code is weak. At least from an extension. I hit 'Exceded table limit' errors from time to time, and I am under quota. I simply open the table, hit edit, and save, then the deactivate and re execute the script and it works as expected again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is a script with the above snippets in a complete form:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Node As CdataNode;&lt;br /&gt;
Var NodeList As CDataNodeList;&lt;br /&gt;
Var NodeListColony As CDataNodeList;&lt;br /&gt;
Var Location As String;&lt;br /&gt;
Var Value As Double;&lt;br /&gt;
Var Photons As Integer;&lt;br /&gt;
Var Plasma As Integer;&lt;br /&gt;
&lt;br /&gt;
Var db As New CDataNodeStorage(&amp;quot;9046&amp;quot;, True);&lt;br /&gt;
&lt;br /&gt;
// Get some current values&lt;br /&gt;
Value = db.Items.Item('TableVersion').asDouble;&lt;br /&gt;
WriteLine(value);&lt;br /&gt;
&lt;br /&gt;
Location = db.Items.Item('Colonies').Items.Item('Earth').asString;&lt;br /&gt;
WriteLine(Location);&lt;br /&gt;
&lt;br /&gt;
If (db.Items.Item('Allies').Items.ContainsKey(12345)) { &lt;br /&gt;
  WriteLine(&amp;quot;Found 12345&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Photons = db.Items.Item('Production').Items.Item('Earth').Items.Item('Photons').asInteger;&lt;br /&gt;
WriteLine(Photons);&lt;br /&gt;
&lt;br /&gt;
// Now create and alter some keys&lt;br /&gt;
db.Items.AddDouble('TableVersion', 10.2);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Colonies')) {&lt;br /&gt;
  db.Items.Add('Colonies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Colonies').Items.AddString('Mercury', '400|400');&lt;br /&gt;
If (NOT db.Items.ContainsKey('Allies')) { &lt;br /&gt;
  db.Items.Add('Allies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Allies').Items.Add(23456);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Production')) {&lt;br /&gt;
  db.Items.Add('Production');&lt;br /&gt;
}&lt;br /&gt;
If (NOT db.Items.Item('Production').Items.ContainsKey('Earth')) {&lt;br /&gt;
  db.Items.Item('Production').Items.ContainsKey('Earth');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Production').Items.Item('Earth').Items.AddInteger('Plasma', 4);&lt;br /&gt;
&lt;br /&gt;
// And check them&lt;br /&gt;
Value = db.Items.Item('TableVersion').asDouble;&lt;br /&gt;
WriteLine(value);&lt;br /&gt;
&lt;br /&gt;
Node = db.Items.Item('Colonies');&lt;br /&gt;
NodeList = Node.Items;&lt;br /&gt;
Location = NodeList.Item('Mercury').asString;&lt;br /&gt;
WriteLine(Location);&lt;br /&gt;
&lt;br /&gt;
If (db.Items.Item('Allies').Items.ContainsKey(23456)) { &lt;br /&gt;
  WriteLine(&amp;quot;Found 23456&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
NodeList = db.Items.Item('Production').Items;&lt;br /&gt;
NodeListColony = NodeList.item('Earth').Items;&lt;br /&gt;
Plasma = NodeListColony.Item('Plasma').asInteger;&lt;br /&gt;
WriteLine(Plasma);&lt;br /&gt;
&lt;br /&gt;
// Remove the added keys&lt;br /&gt;
db.Items.Item('Colonies').Items.Remove('Mercury');&lt;br /&gt;
db.Items.Item('Allies').Items.Remove(23456);&lt;br /&gt;
db.Items.Item('Production').Items.Item('Earth').Items.Remove('Plasma');&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 07:27, 10 October 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Data_Storage</id>
		<title>Scripting:Data Storage</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Data_Storage"/>
				<updated>2011-10-10T05:26:13Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: Created page with &amp;quot;Understanding script data (STNE Tables)  Data Tables in STNE are not the same as tables in a RDBMS, they don't have direct indexes, they are cascading, and understanding them can...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Understanding script data (STNE Tables)&lt;br /&gt;
&lt;br /&gt;
Data Tables in STNE are not the same as tables in a RDBMS, they don't have direct indexes, they are cascading, and understanding them can be a bit confusing at times. Essentially, there is a parent object, called CDataNodeStorage, and children, called CDataNode and CDataNodeList. The parent only has directly the child  CDataNode. CDataNode has the child  CDataNodeList, and  CDataNodeList has the child  CdataNode. I little confusing, I know. So here's a mapping:&lt;br /&gt;
&lt;br /&gt;
CDataNodeStorage-&amp;gt;CDataNode &lt;br /&gt;
CDataNode-&amp;gt; CDataNodeList&lt;br /&gt;
CDataNodeList-&amp;gt;CDataNode &lt;br /&gt;
&lt;br /&gt;
All CdataNodes are locatable from CDataNodeStorage&lt;br /&gt;
All single values are accessed via a CDataNode&lt;br /&gt;
All multiple values are accessed from a CDataNodeList&lt;br /&gt;
&lt;br /&gt;
This is important to remember, because each has a unique function. CDataNodeList is a list of items, like sectors or colonies, and CdataNode has only item.  If you have a need for a list, but not assignment, you can use the CDataNodeList to do this.&lt;br /&gt;
&lt;br /&gt;
Let's take a small example and break it down&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TableVersion=10.1;&lt;br /&gt;
Colonies &lt;br /&gt;
{&lt;br /&gt;
  Earth='500|400';&lt;br /&gt;
  Mars='500|401';&lt;br /&gt;
  Venus='400|402';&lt;br /&gt;
}&lt;br /&gt;
Allies&lt;br /&gt;
{&lt;br /&gt;
  12345;&lt;br /&gt;
  67890;&lt;br /&gt;
}&lt;br /&gt;
Production&lt;br /&gt;
{&lt;br /&gt;
  Earth&lt;br /&gt;
  {&lt;br /&gt;
    Photons=2;&lt;br /&gt;
    Duranium=8;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
First, you need some way to access the table. This is done with CDataNodeStorage. The way to open the pointer depends on if it is local or remote(on another account). For local storage,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var db As New CdataNodeStorage(String, Boolean);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where the TableName is a string of the name, and the boolean is table creation (true to create, false to fail instead). For remote storage,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var db AsCDataNodeStorage.LoadFromUser(String, Integer);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where String is the name of the table, and Integer is the user ID (the table does not open cross server, so there is no designator for EN1 vs DE3 etc)&lt;br /&gt;
&lt;br /&gt;
Next is accessing the data. The first entry, TableVersion, has the value of 10.1, a double. The value would be accessed as such:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var value As Double = db.Items.Item('TableVersion').asDouble;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that we told item method to retrieve the value as a double. STNE via .NET has the tendency of casting doubles to ints not in a truncate fashion, but as a function of ceiling, and to drop the decimal when casting to a String. Therefore, when possible, always be specific on the type.&lt;br /&gt;
&lt;br /&gt;
The next entry is Colonies, which is actually a multiple value. First, you access the key, then the list below it, like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Location As CdataNodeList = db.Items.Item('Colonies').Items;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a direct assignment, rather than creating a CdataNode and the accessing the list from there. If you prefer or need to access the node independently, you can do it in multiple steps:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Node As CDataNode = db.Items.Item('Colonies');&lt;br /&gt;
Var NodeList As CDataNodeList = Node.Items;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Normally, the only reason to access the list from the parent node is to pass it to another function or method.&lt;br /&gt;
To access a value from the list:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Location As String = db.Items.Item('Colonies').Items.Item('Earth').AsString;&lt;br /&gt;
Var Location As String = NodeList.Item('Earth').AsString;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Since the value is a string (denoted by the single quotes), I specified the type.&lt;br /&gt;
&lt;br /&gt;
The next entry, Allies has no values, just a list of keys. These are useful for items that you need to maintain a list of, but not values. Access is the same as a list of keys and values, but since you aren't retrieving the values, you would usually use ContainsKey to check it it's in the list:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
If (db.Items.Item('Allies').Items.ContainsKey(12345)) { &lt;br /&gt;
  // Do something&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Production is a cascaded value. This one is slightly more complex, but from what you have learned above, it is fairly straightforward:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Photons As Integer = db.Items.Item('Production').Items.Item('Earth').Items.Item('Photons').asInteger;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As a multiple statement, it looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var NodeList As CDataNodeList = db.Items.Item('Production').Items;&lt;br /&gt;
Var NodeListColony As CDataNodeList = NodeList.item('Earth').Items;&lt;br /&gt;
Var Photons As Integer = NodeListColony.Item('Photons').asInteger;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Node that .Items was called twice (well, 3 times but the first is for any access). We don't actually care what the value of the key is, since it's an index. Then we get the subindex for a particular colony (Earth), then a particular production (Photons).&lt;br /&gt;
&lt;br /&gt;
Writing to the keys is comparable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
db.Items.AddDouble(' TableVersion', 10.1);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Colonies')) {&lt;br /&gt;
  db.Items.Add('Colonies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Colonies').Items.AddString('Earth', “500|400”);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Allies')) { &lt;br /&gt;
  db.Items.Add('Allies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Allies').Items.Add(12345);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Production')) {&lt;br /&gt;
  db.Items.Add('Production');&lt;br /&gt;
}&lt;br /&gt;
If (NOT db.Items.Item('Production').Items.ContainsKey('Earth')) {&lt;br /&gt;
  db.Items.Item('Production').Items.ContainsKey('Earth');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Production').Items.Item('Earth').Items.AddInteger('Photons', 2);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For Allies, since there is no value, so you need to use the generic .Add method. The code above will overwrite the values if they already exist, it's simple code so it doesn't check for the previous existence of anything but the index path, and creates them if the indexes don't exist.&lt;br /&gt;
&lt;br /&gt;
To delete a value, use the .Remove() method. It has a comparable form as .Add:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
db.Items.Remove('TableVersion');&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Some caveats for script storage&lt;br /&gt;
- Local tables can not be renamed or deleted.&lt;br /&gt;
- Remote tables can not be created&lt;br /&gt;
- LoadFromUser() can open local tables, but seems to abort the script unexpectedly from time to time, with no error.&lt;br /&gt;
- Multiple access code is weak. At least from an extension. I hit 'Exceded table limit' errors from time to time, and I am under quota. I simply open the table, hit edit, and save, then the deactivate and re execute the script and it works as expected again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is a script with the above snippets in a complete form:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var Node As CdataNode;&lt;br /&gt;
Var NodeList As CDataNodeList;&lt;br /&gt;
Var NodeListColony As CDataNodeList;&lt;br /&gt;
Var Location As String;&lt;br /&gt;
Var Value As Double;&lt;br /&gt;
Var Photons As Integer;&lt;br /&gt;
Var Plasma As Integer;&lt;br /&gt;
&lt;br /&gt;
Var db As New CDataNodeStorage(&amp;quot;9046&amp;quot;, True);&lt;br /&gt;
&lt;br /&gt;
// Get some current values&lt;br /&gt;
Value = db.Items.Item('TableVersion').asDouble;&lt;br /&gt;
WriteLine(value);&lt;br /&gt;
&lt;br /&gt;
Location = db.Items.Item('Colonies').Items.Item('Earth').asString;&lt;br /&gt;
WriteLine(Location);&lt;br /&gt;
&lt;br /&gt;
If (db.Items.Item('Allies').Items.ContainsKey(12345)) { &lt;br /&gt;
  WriteLine(&amp;quot;Found 12345&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Photons = db.Items.Item('Production').Items.Item('Earth').Items.Item('Photons').asInteger;&lt;br /&gt;
WriteLine(Photons);&lt;br /&gt;
&lt;br /&gt;
// Now create and alter some keys&lt;br /&gt;
db.Items.AddDouble('TableVersion', 10.2);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Colonies')) {&lt;br /&gt;
  db.Items.Add('Colonies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Colonies').Items.AddString('Mercury', '400|400');&lt;br /&gt;
If (NOT db.Items.ContainsKey('Allies')) { &lt;br /&gt;
  db.Items.Add('Allies');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Allies').Items.Add(23456);&lt;br /&gt;
If (NOT db.Items.ContainsKey('Production')) {&lt;br /&gt;
  db.Items.Add('Production');&lt;br /&gt;
}&lt;br /&gt;
If (NOT db.Items.Item('Production').Items.ContainsKey('Earth')) {&lt;br /&gt;
  db.Items.Item('Production').Items.ContainsKey('Earth');&lt;br /&gt;
}&lt;br /&gt;
db.Items.Item('Production').Items.Item('Earth').Items.AddInteger('Plasma', 4);&lt;br /&gt;
&lt;br /&gt;
// And check them&lt;br /&gt;
Value = db.Items.Item('TableVersion').asDouble;&lt;br /&gt;
WriteLine(value);&lt;br /&gt;
&lt;br /&gt;
Node = db.Items.Item('Colonies');&lt;br /&gt;
NodeList = Node.Items;&lt;br /&gt;
Location = NodeList.Item('Mercury').asString;&lt;br /&gt;
WriteLine(Location);&lt;br /&gt;
&lt;br /&gt;
If (db.Items.Item('Allies').Items.ContainsKey(23456)) { &lt;br /&gt;
  WriteLine(&amp;quot;Found 23456&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
NodeList = db.Items.Item('Production').Items;&lt;br /&gt;
NodeListColony = NodeList.item('Earth').Items;&lt;br /&gt;
Plasma = NodeListColony.Item('Plasma').asInteger;&lt;br /&gt;
WriteLine(Plasma);&lt;br /&gt;
&lt;br /&gt;
// Remove the added keys&lt;br /&gt;
db.Items.Item('Colonies').Items.Remove('Mercury');&lt;br /&gt;
db.Items.Item('Allies').Items.Remove(23456);&lt;br /&gt;
db.Items.Item('Production').Items.Item('Earth').Items.Remove('Plasma');&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Main_page</id>
		<title>Scripting:Main page</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Main_page"/>
				<updated>2011-10-10T05:21:39Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: /* Topics: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scripting]]&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
{{CreateScriptingArticle}}&lt;br /&gt;
&lt;br /&gt;
This section of the Wiki is intended to document the scripting engine found in the game. Most scripting related pages in STNE can be found from the main menu trough Database -&amp;gt; Scripting.&lt;br /&gt;
&lt;br /&gt;
=== Topics: ===&lt;br /&gt;
* [[Scripting:Syntax|Syntax]]&lt;br /&gt;
* [[Scripting:Operators|Operators]]&lt;br /&gt;
* [[Scripting:Interfaces|Interfaces]]&lt;br /&gt;
&lt;br /&gt;
* [[Scripting:Basic course|Basic course]] (mostly translated)&lt;br /&gt;
* [[Scripting:Script_editor|The external script editor]]&lt;br /&gt;
* [[Scripting:InvokeItem|A tutorial on scripting the portal InvokeItem()]]&lt;br /&gt;
* [[Scripting:InfoBar Links|A tutorial on scripting for an InfoBar link]]&lt;br /&gt;
* [[Scripting:Data Storage|A tutorial on understanding STNE non volatile storage]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:InfoBar_Links</id>
		<title>Scripting:InfoBar Links</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:InfoBar_Links"/>
				<updated>2011-10-09T04:37:32Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Understanding InfoBar Links&lt;br /&gt;
&lt;br /&gt;
The STNE engine allows for extensions accessible for the 'InfoBar', an area at the top of the UI (user interface) primary pane. The intent it seems is to allow extensibility to the UI, and allow a certain level of customizations. These could include notes, coordinates, a list alliance members, etc. The InfoBar itself you have probably seen, it is the area where [You have a new message] appears. &lt;br /&gt;
&lt;br /&gt;
To understand how to create an InfoBar application, one must first understand how it actually manages to get to the UI. This is done by CallBack methods. A callback is similar to system signal handlers in concept. When you tell the script to 'hook' a callback, it is added to a list of code to process every time that callback happens (with the exception that unlike a system signal, it can be pre filtered). A script can only hook a specific callback once, so if you need to have 3 individual methods happen for a particular callback event, you add them to a single function and call them all from there (In a normal driver or signal handler, you would not call the handler from a class, and this is good methodology to follow even with scripts) The following is an example of callback handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function RegisterHooks() {&lt;br /&gt;
  ScriptContext.EnableExtension();&lt;br /&gt;
  ScriptContext.RegisterEvent(EGuiEventType.InfoBarAfterCreate, AddressOf CB_InfoBarAfterCreate);&lt;br /&gt;
  ScriptContext.ActivateEvents();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function CB_InfoBarAfterCreate(CBEvent As CGuiEventOnInfoBarAfterCreate) {&lt;br /&gt;
  // processing for event goes here, create the link, the output, etc.&lt;br /&gt;
  Var LinkItem As String = &amp;quot;my_infobar_app&amp;quot;;&lt;br /&gt;
  Var Div As CHtmlDiv;&lt;br /&gt;
  InfoBarLink(CBEvent, LinkItem);&lt;br /&gt;
  Div = InfoBarDiv(CBEvent, LinkItem);&lt;br /&gt;
  Div.Style.Add('display', 'none'); &lt;br /&gt;
  Div.Add(&amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RegisterHooks();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
RegisterHooks is a function called from the main body of the script, and the function itself handles adding the entry point onto the callback stack. Firstly, it sets up for being an extension via EnableExtensions. Next, it adds a handler to the callback stack, giving the code reference via AddressOf. Lastly, it lets the script engine know it's ready to handle events. Normally you will have any validation (checking data storage, initializing variables, etc) happening between EnableExtension and RegisterEvent. This function is called only at script initialization, which should be when you click on “Execute Script”, but experience tells me it gets called occasionally in other circumstances (the script seems to like to run from the main body after an STNE restart).&lt;br /&gt;
&lt;br /&gt;
Once you have the callback hooked, you need the InfoBar link. For an InfoBar application to work, it needs two more components, other than the output. The first is a clickable link item, which usually contains the name of the script. The other is an area upon which to place your actual output. While the output can be appended from a different callback method, this is not the usual case. Firstly, set up the link:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function InfoBarLink(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) {&lt;br /&gt;
  Var InfoBarAlignRight As Boolean = True;&lt;br /&gt;
  Var UrlCon As CHtmlControl;&lt;br /&gt;
  Var LinkText As String = &amp;quot;My InfoBar App&amp;quot;;&lt;br /&gt;
  // Create the app bar link&lt;br /&gt;
  Var Url As CJsAction = CUrlBuilder.JsToggleElement(LinkItem);&lt;br /&gt;
  UrlCon = CControlBuilder.BracketLink(Url, LinkText);&lt;br /&gt;
  Var UrlSmall As New CHtmlSmall();&lt;br /&gt;
  UrlSmall.Add(UrlCon)&lt;br /&gt;
  CBEvent.CreateItem(InfoBarAlignRight).Add(UrlSmall.GuiControl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function simply sets up a toggle-able link on the InfoBar... It does not actually display anything other than the link, and clicking on it will do nothing, because no data is attached to it. The first line declares the function, and expects the first passed parameter to be of type  CGuiEventOnInfoBarAfterCreate, which is itself a child of the class CGuiEvent. CGuiEvent could be used instead, if this handler was to process multiple callbacks, but you loose accessibility to anything specific to the child (unless you cast it back to it's particular type). The declaration of InfoBarAlignRight is for clarity. If it was false, it would align on the left. LinkText is literally the text the link will have. JsToggleElement is how the UI adds the javascript code to toggle the output (a div tag) between visible and hidden. BracketLink adds [ and ] around the text. CHtmlSmall applies the small HTML tag to the link. The CreateItem is how the script adds the newly created link into the UI, on the InfoBar.&lt;br /&gt;
&lt;br /&gt;
Now that we have the link, we need to add the output area for the link. This is done by creating a layered div tag. Why layered? So the output stays precisely where you want it, and it actually hides when necessary. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function InfoBarDiv(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) As CHtmlDiv {&lt;br /&gt;
  Var BorderColor As String = &amp;quot;#16344E&amp;quot;;&lt;br /&gt;
  Var OuterDiv As New CHtmlDiv();&lt;br /&gt;
  Var Div As New CHtmlDiv();&lt;br /&gt;
  &lt;br /&gt;
  CBEvent.Page.Body.Controls.Insert(0, OuterDiv.GuiControl);&lt;br /&gt;
  OuterDiv.Style.Add('position', 'absolute');&lt;br /&gt;
  OuterDiv.Width = '99%';&lt;br /&gt;
  OuterDiv.Style.Add('z-index', '255'); &lt;br /&gt;
  &lt;br /&gt;
  OuterDiv.Add(Div);&lt;br /&gt;
  Div.Style.Add('position', 'absolute');&lt;br /&gt;
  Div.Style.Add('top', '0');&lt;br /&gt;
  Div.Style.Add('right', '0');&lt;br /&gt;
  Div.Style.Add('z-index', '255');&lt;br /&gt;
  Div.Style.Add('background-color', 'black');&lt;br /&gt;
  Div.Style.Add('border-style', 'solid');&lt;br /&gt;
  Div.Style.Add('border-color', BorderColor);&lt;br /&gt;
  Div.Style.Add('border-width', '1px');&lt;br /&gt;
  Div.ID = LinkItem; &lt;br /&gt;
  Return Div;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually the InfoBar creation and the div creation are in the same function or method, but for purposes of example I have split them into two functions. The first part is the setup and assignment. LinkItem is the name of the inner div, and it is usually similar to the link name. Keep in mind that if you create two scripts and name the div the same, they will both appear and hide when either script link is toggled, so you want the inner div name to be unique. The middle of the function sets up the inner div output area. The width is 1% short of maximum, because some browsers (notably Opera) tend to cut the right border off if it is 100%. The Z-Index ensures it's appears above normal output. The last part of the function sets up the inner div, with a black background and the standard STNE blue border 1 pixel wide. The alignment for the output is top right of the outer div, which is created just below the InfoBar. The output is adjusted to the smallest possible area that still displays the output. The following is the entire script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#UseInterface Web, Gui;&lt;br /&gt;
&lt;br /&gt;
Function InfoBarLink(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) {&lt;br /&gt;
  Var InfoBarAlignRight As Boolean = True;&lt;br /&gt;
  Var UrlCon As CHtmlControl;&lt;br /&gt;
  Var LinkText As String = &amp;quot;My InfoBar App&amp;quot;;&lt;br /&gt;
  // Create the app bar link&lt;br /&gt;
  Var Url As CJsAction = CUrlBuilder.JsToggleElement(LinkItem);&lt;br /&gt;
  UrlCon = CControlBuilder.BracketLink(Url, LinkText);&lt;br /&gt;
  Var UrlSmall As New CHtmlSmall();&lt;br /&gt;
  UrlSmall.Add(UrlCon)&lt;br /&gt;
  CBEvent.CreateItem(InfoBarAlignRight).Add(UrlSmall.GuiControl);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function InfoBarDiv(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) As CHtmlDiv {&lt;br /&gt;
  Var BorderColor As String = &amp;quot;#16344E&amp;quot;;&lt;br /&gt;
  Var OuterDiv As New CHtmlDiv();&lt;br /&gt;
  Var Div As New CHtmlDiv();&lt;br /&gt;
  &lt;br /&gt;
  CBEvent.Page.Body.Controls.Insert(0, OuterDiv.GuiControl);&lt;br /&gt;
  OuterDiv.Style.Add('position', 'absolute');&lt;br /&gt;
  OuterDiv.Width = '99%';&lt;br /&gt;
  OuterDiv.Style.Add('z-index', '255'); &lt;br /&gt;
  &lt;br /&gt;
  OuterDiv.Add(Div);&lt;br /&gt;
  Div.Style.Add('position', 'absolute');&lt;br /&gt;
  Div.Style.Add('top', '0');&lt;br /&gt;
  Div.Style.Add('right', '0');&lt;br /&gt;
  Div.Style.Add('z-index', '255');&lt;br /&gt;
  Div.Style.Add('background-color', 'black');&lt;br /&gt;
  Div.Style.Add('border-style', 'solid');&lt;br /&gt;
  Div.Style.Add('border-color', BorderColor);&lt;br /&gt;
  Div.Style.Add('border-width', '1px');&lt;br /&gt;
  Div.ID = LinkItem; &lt;br /&gt;
  Return Div;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Function RegisterHooks() {&lt;br /&gt;
  ScriptContext.EnableExtension();&lt;br /&gt;
  ScriptContext.RegisterEvent(EGuiEventType.InfoBarAfterCreate, AddressOf CB_InfoBarAfterCreate);&lt;br /&gt;
  ScriptContext.ActivateEvents();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function CB_InfoBarAfterCreate(CBEvent As CGuiEventOnInfoBarAfterCreate) {&lt;br /&gt;
  // processing for event goes here, create the link, the output, etc.&lt;br /&gt;
  Var LinkItem As String = &amp;quot;my_infobar_app&amp;quot;;&lt;br /&gt;
  Var Div As CHtmlDiv;&lt;br /&gt;
  InfoBarLink(CBEvent, LinkItem);&lt;br /&gt;
  Div = InfoBarDiv(CBEvent, LinkItem);&lt;br /&gt;
  Div.Style.Add('display', 'none'); // See notes below&lt;br /&gt;
  Div.Add(&amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RegisterHooks();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Normally, at the Div.Add in CB_ InfoBarAfterCreate, you would add your output table or div instead of a text string. Also, you would toggle the output with a URL Parameter, with something like this in CB_ InfoBarAfterCreate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  Var ShowDiv As Boolean = False;&lt;br /&gt;
  // option processing here, usually returning the status of ShowDiv, like Showdiv = ProcessOptions()&lt;br /&gt;
  // … table/div output creation, like Div.Add(function());&lt;br /&gt;
  If (ShowDiv) {&lt;br /&gt;
    Div.Style.Add('display', 'block');&lt;br /&gt;
  } Else {&lt;br /&gt;
    Div.Style.Add('display', 'none');&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
But URL/Form parameter passing and processing is for another tutorial&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 06:19, 9 October 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:InfoBar_Links</id>
		<title>Scripting:InfoBar Links</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:InfoBar_Links"/>
				<updated>2011-10-09T04:26:50Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Understanding InfoBar Links&lt;br /&gt;
&lt;br /&gt;
The STNE engine allows for extensions accessible for the 'InfoBar', an area at the top of the UI (user interface) primary pane. The intent it seems is to allow extensibility to the UI, and allow a certain level of customizations. These could include notes, coordinates, a list alliance members, etc. The InfoBar itself you have probably seen, it is the area where [You have a new message] appears. &lt;br /&gt;
&lt;br /&gt;
To understand how to create an InfoBar application, one must first understand how it actually manages to get to the UI. This is done by CallBack methods. A callback is similar to system signal handlers in concept. When you tell the script to 'hook' a callback, it is added to a list of code to process every time that callback happens (with the exception that unlike a system signal, it can be pre filtered). A script can only hook a specific callback once, so if you need to have 3 individual methods happen for a particular callback event, you add them to a single function and call them all from there (In a normal driver or signal handler, you would not call the handler from a class, and this is good methodology to follow even with scripts) The following is an example of callback handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function RegisterHooks() {&lt;br /&gt;
  ScriptContext.EnableExtension();&lt;br /&gt;
  ScriptContext.RegisterEvent(EGuiEventType.InfoBarAfterCreate, AddressOf CB_InfoBarAfterCreate);&lt;br /&gt;
  ScriptContext.ActivateEvents();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function CB_InfoBarAfterCreate(CBEvent As CGuiEventOnInfoBarAfterCreate) {&lt;br /&gt;
  // processing for event goes here, create the link, the output, etc.&lt;br /&gt;
  Var LinkItem As String = &amp;quot;my_infobar_app&amp;quot;;&lt;br /&gt;
  Var Div As CHtmlDiv;&lt;br /&gt;
  InfoBarLink(CBEvent, LinkItem);&lt;br /&gt;
  Div = InfoBarDiv(CBEvent, LinkItem);&lt;br /&gt;
  Div.Style.Add('display', 'none'); &lt;br /&gt;
  Div.Add(&amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RegisterHooks();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
RegisterHooks is a function called from the main body of the script, and the function itself handles adding the entry point onto the callback stack. Firstly, it sets up for being an extension via EnableExtensions. Next, it adds a handler to the callback stack, giving the code reference via AddressOf. Lastly, it lets the script engine know it's ready to handle events. Normally you will have any validation (checking data storage, initializing variables, etc) happening between EnableExtension and RegisterEvent. This function is called only at script initialization, which should be when you click on “Execute Script”, but experience tells me it gets called occasionally in other circumstances (the script seems to like to run from the main body after an STNE restart).&lt;br /&gt;
&lt;br /&gt;
Once you have the callback hooked, you need the InfoBar link. For an InfoBar application to work, it needs two more components, other than the output. The first is a clickable link item, which usually contains the name of the script. The other is an area upon which to place your actual output. While the output can be appended from a different callback method, this is not the usual case. Firstly, set up the link:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function InfoBarLink(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) {&lt;br /&gt;
  Var InfoBarAlignRight As Boolean = True;&lt;br /&gt;
  Var UrlCon As CHtmlControl;&lt;br /&gt;
  Var LinkText As String = &amp;quot;My InfoBar App&amp;quot;;&lt;br /&gt;
  // Create the app bar link&lt;br /&gt;
  Var Url As CJsAction = CUrlBuilder.JsToggleElement(LinkItem);&lt;br /&gt;
  UrlCon = CControlBuilder.BracketLink(Url, LinkText);&lt;br /&gt;
  Var UrlSmall As New CHtmlSmall();&lt;br /&gt;
  UrlSmall.Add(UrlCon)&lt;br /&gt;
  CBEvent.CreateItem(InfoBarAlignRight).Add(UrlSmall.GuiControl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function simply sets up a toggle-able link on the InfoBar... It does not actually display anything, and clicking on it will do nothing, because no data is attached to it. The first line declares the function, and expects the passed parameter to be of type  CGuiEventOnInfoBarAfterCreate, which is itself a child of the class CGuiEvent. CGuiEvent could be used instead, if this handler was to process multiple callbacks, but you loose accessibility to anything specific to the child (unless you cast it back to it's particular type). The declaration of InfoBarAlignRight is for clarity. If it was false, it would align on the left. LinkText is literally the text the link will have. JsToggleElement is how the UI adds the javascript code to toggle the output (a div tag) between visible and hidden. BracketLink adds [ and ] around the text. ChtmlSmall applies the small HTML tag to the link. The CreateItem is how the script adds the newly created link into the UI, on the infobar.&lt;br /&gt;
&lt;br /&gt;
Now that we have the link, we need to add the output area for the link. This is done by creating a layered div tag. Why layered? So the output stays precisely where you want it, and it actually hides when necessary. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function InfoBarDiv(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) As CHtmlDiv {&lt;br /&gt;
  Var BorderColor As String = &amp;quot;#16344E&amp;quot;;&lt;br /&gt;
  Var OuterDiv As New CHtmlDiv();&lt;br /&gt;
  Var Div As New CHtmlDiv();&lt;br /&gt;
  &lt;br /&gt;
  CBEvent.Page.Body.Controls.Insert(0, OuterDiv.GuiControl);&lt;br /&gt;
  OuterDiv.Style.Add('position', 'absolute');&lt;br /&gt;
  OuterDiv.Width = '99%';&lt;br /&gt;
  OuterDiv.Style.Add('z-index', '255'); &lt;br /&gt;
  &lt;br /&gt;
  OuterDiv.Add(Div);&lt;br /&gt;
  Div.Style.Add('position', 'absolute');&lt;br /&gt;
  Div.Style.Add('top', '0');&lt;br /&gt;
  Div.Style.Add('right', '0');&lt;br /&gt;
  Div.Style.Add('z-index', '255');&lt;br /&gt;
  Div.Style.Add('background-color', 'black');&lt;br /&gt;
  Div.Style.Add('border-style', 'solid');&lt;br /&gt;
  Div.Style.Add('border-color', BorderColor);&lt;br /&gt;
  Div.Style.Add('border-width', '1px');&lt;br /&gt;
  Div.ID = LinkItem; &lt;br /&gt;
  Return Div;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually the InfoBar creation and the div creation are in the same function or method, but for purposes of example I have split them into two functions. The first part is the setup and assignment. LinkItem is the name of the inner div, and it is usually the similar to the link name. Keep in mind that if you create two scripts and name the Div the same, they will both appear and hide when either script link is toggled, so you want the inner div name to be unique. The middle of the function sets up the div attached to the control (the link). Since it was the last one added, it is the on the top of the stack, thus control at position 0. The width is 1% short of maximum, because some browsers (notably Opera) tends to cut the right border off if it is 100%. The Z-Index ensures it's appears above normal output. The last part of the function sets up the inner div, with a black background and the standard STNE blue border 1 pixel wide. The alignment for the output is top right, of the outer div, which is created just below the InfoBar. The output is adjusted to the smallest possible area that still displays the output. The following is the entire script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#UseInterface Web, Gui;&lt;br /&gt;
&lt;br /&gt;
Function InfoBarLink(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) {&lt;br /&gt;
  Var InfoBarAlignRight As Boolean = True;&lt;br /&gt;
  Var UrlCon As CHtmlControl;&lt;br /&gt;
  Var LinkText As String = &amp;quot;My InfoBar App&amp;quot;;&lt;br /&gt;
  // Create the app bar link&lt;br /&gt;
  Var Url As CJsAction = CUrlBuilder.JsToggleElement(LinkItem);&lt;br /&gt;
  UrlCon = CControlBuilder.BracketLink(Url, LinkText);&lt;br /&gt;
  Var UrlSmall As New CHtmlSmall();&lt;br /&gt;
  UrlSmall.Add(UrlCon)&lt;br /&gt;
  CBEvent.CreateItem(InfoBarAlignRight).Add(UrlSmall.GuiControl);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function InfoBarDiv(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) As CHtmlDiv {&lt;br /&gt;
  Var BorderColor As String = &amp;quot;#16344E&amp;quot;;&lt;br /&gt;
  Var OuterDiv As New CHtmlDiv();&lt;br /&gt;
  Var Div As New CHtmlDiv();&lt;br /&gt;
  &lt;br /&gt;
  CBEvent.Page.Body.Controls.Insert(0, OuterDiv.GuiControl);&lt;br /&gt;
  OuterDiv.Style.Add('position', 'absolute');&lt;br /&gt;
  OuterDiv.Width = '99%';&lt;br /&gt;
  OuterDiv.Style.Add('z-index', '255'); &lt;br /&gt;
  &lt;br /&gt;
  OuterDiv.Add(Div);&lt;br /&gt;
  Div.Style.Add('position', 'absolute');&lt;br /&gt;
  Div.Style.Add('top', '0');&lt;br /&gt;
  Div.Style.Add('right', '0');&lt;br /&gt;
  Div.Style.Add('z-index', '255');&lt;br /&gt;
  Div.Style.Add('background-color', 'black');&lt;br /&gt;
  Div.Style.Add('border-style', 'solid');&lt;br /&gt;
  Div.Style.Add('border-color', BorderColor);&lt;br /&gt;
  Div.Style.Add('border-width', '1px');&lt;br /&gt;
  Div.ID = LinkItem; &lt;br /&gt;
  Return Div;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Function RegisterHooks() {&lt;br /&gt;
  ScriptContext.EnableExtension();&lt;br /&gt;
  ScriptContext.RegisterEvent(EGuiEventType.InfoBarAfterCreate, AddressOf CB_InfoBarAfterCreate);&lt;br /&gt;
  ScriptContext.ActivateEvents();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function CB_InfoBarAfterCreate(CBEvent As CGuiEventOnInfoBarAfterCreate) {&lt;br /&gt;
  // processing for event goes here, create the link, the output, etc.&lt;br /&gt;
  Var LinkItem As String = &amp;quot;my_infobar_app&amp;quot;;&lt;br /&gt;
  Var Div As CHtmlDiv;&lt;br /&gt;
  InfoBarLink(CBEvent, LinkItem);&lt;br /&gt;
  Div = InfoBarDiv(CBEvent, LinkItem);&lt;br /&gt;
  Div.Style.Add('display', 'none'); // See notes below&lt;br /&gt;
  Div.Add(&amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RegisterHooks();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Normally, at the Div.Add in CB_ InfoBarAfterCreate, you would add your output table or div instead of a text string. Also, you would toggle the output with a URL Parameter, with something like this in CB_ InfoBarAfterCreate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  Var ShowDiv As Boolean = False;&lt;br /&gt;
  // option processing here, usually returning the status of ShowDiv, like Showdiv = ProcessOptions()&lt;br /&gt;
  // … table/div output creation, like Div.Add(function());&lt;br /&gt;
  If (ShowDiv) {&lt;br /&gt;
    Div.Style.Add('display', 'block');&lt;br /&gt;
  } Else {&lt;br /&gt;
    Div.Style.Add('display', 'none');&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
But URL/Form parameter passing and processing is for another tutorial&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 06:19, 9 October 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:InfoBar_Links</id>
		<title>Scripting:InfoBar Links</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:InfoBar_Links"/>
				<updated>2011-10-09T04:21:38Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Understanding InfoBar Links&lt;br /&gt;
&lt;br /&gt;
The STNE engine allows for extensions accessible for the 'InfoBar', an area at the top of the UI (user interface) primary pane. The intent it seems is to allow extensibility to the UI, and allow a certain level of customizations. These could include notes, coordinates, a list alliance members, etc. The InfoBar itself you have probably seen, it is the area where [You have a new message] appears. &lt;br /&gt;
&lt;br /&gt;
To understand how to create an InfoBar application, one must first understand how it actually manages to get to the UI. This is done by CallBack methods. A callback is similar to system signal handlers in concept. When you tell the script to 'hook' a callback, it is added to a list of code to process every time that callback happens (with the exception that unlike a system signal, it can be pre filtered). A script can only hook a specific callback once, so if you need to have 3 individual methods happen for a particular callback event, you add them to a single function and call them all from there (In a normal driver or signal handler, you would not call the handler from a class, and this is good methodology to follow even with scripts) The following is an example of callback handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function RegisterHooks() {&lt;br /&gt;
  ScriptContext.EnableExtension();&lt;br /&gt;
  ScriptContext.RegisterEvent(EGuiEventType.InfoBarAfterCreate, AddressOf CB_InfoBarAfterCreate);&lt;br /&gt;
  ScriptContext.ActivateEvents();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function CB_InfoBarAfterCreate(CBEvent As CGuiEventOnInfoBarAfterCreate) {&lt;br /&gt;
  // processing for event goes here, create the link, the output, etc.&lt;br /&gt;
  Var LinkItem As String = &amp;quot;my_infobar_app&amp;quot;;&lt;br /&gt;
  Var Div As CHtmlDiv;&lt;br /&gt;
  InfoBarLink(CBEvent, LinkItem);&lt;br /&gt;
  Div = InfoBarDiv(CBEvent, LinkItem);&lt;br /&gt;
  Div.Style.Add('display', 'none'); &lt;br /&gt;
  Div.Add(&amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RegisterHooks();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
RegisterHooks is a function called from the main body of the script, and the function itself handles adding the entry point onto the callback stack. Firstly, it sets up for being an extension via EnableExtensions. Next, it adds a handler to the callback stack, giving the code reference via AddressOf. Lastly, it lets the script engine know it's ready to handle events. Normally you will have any validation (checking data storage, initializing variables, etc) happening between EnableExtension and RegisterEvent. This function is called only at script initialization, which should be when you click on “Execute Script”, but experience tells me it gets called occasionally in other circumstances (the script seems to like to run from the main body after an STNE restart).&lt;br /&gt;
&lt;br /&gt;
Once you have the callback hooked, you need the InfoBar link. For an InfoBar application to work, it needs two more components, other than the output. The first is a clickable link item, which usually contains the name of the script. The other is an area upon which to place your actual output. While the output can be appended from a different callback method, this is not the usual case. Firstly, set up the link:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function InfoBarLink(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) {&lt;br /&gt;
  Var InfoBarAlignRight As Boolean = True;&lt;br /&gt;
  Var UrlCon As CHtmlControl;&lt;br /&gt;
  Var LinkText As String = &amp;quot;My InfoBar App&amp;quot;;&lt;br /&gt;
  // Create the app bar link&lt;br /&gt;
  Var Url As CJsAction = CUrlBuilder.JsToggleElement(LinkItem);&lt;br /&gt;
  UrlCon = CControlBuilder.BracketLink(Url, LinkText);&lt;br /&gt;
  Var UrlSmall As New CHtmlSmall();&lt;br /&gt;
  UrlSmall.Add(UrlCon)&lt;br /&gt;
  CBEvent.CreateItem(InfoBarAlignRight).Add(UrlSmall.GuiControl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function simply sets up a toggle-able link on the InfoBar... It does not actually display anything, and clicking on it will do nothing, because no data is attached to it. The first line declares the function, and expects the passed parameter to be of type  CGuiEventOnInfoBarAfterCreate, which is itself a child of the class CguiEvent. CguiEvent could be used instead, if this handler was to process multiple callbacks, but you loose accessibility to anything specific to the child (unless you cast it back to it's particular type). The declaration of InfoBarAlignRight is for clarity. If it was false, it would align on the left. LinkText is literally the text the link will have. JsToggleElement is how the UI adds the javascript code to toggle the output (a div tag) between visible and hidden. BracketLink adds [ and ] around the text. ChtmlSmall applies the &amp;amp;LT;small&amp;amp;GT; HTML tag to the link. The CreateItem is how the script adds the newly created link into the UI, on the infobar.&lt;br /&gt;
&lt;br /&gt;
Now that we have the link, we need to add the output area for the link. This is done by creating a layered div tag. Why layered? So the output stays precisely where you want it, and it actually hides when necessary. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function InfoBarDiv(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) As CHtmlDiv {&lt;br /&gt;
  Var BorderColor As String = &amp;quot;#16344E&amp;quot;;&lt;br /&gt;
  Var OuterDiv As New CHtmlDiv();&lt;br /&gt;
  Var Div As New CHtmlDiv();&lt;br /&gt;
  &lt;br /&gt;
  CBEvent.Page.Body.Controls.Insert(0, OuterDiv.GuiControl);&lt;br /&gt;
  OuterDiv.Style.Add('position', 'absolute');&lt;br /&gt;
  OuterDiv.Width = '99%';&lt;br /&gt;
  OuterDiv.Style.Add('z-index', '255'); &lt;br /&gt;
  &lt;br /&gt;
  OuterDiv.Add(Div);&lt;br /&gt;
  Div.Style.Add('position', 'absolute');&lt;br /&gt;
  Div.Style.Add('top', '0');&lt;br /&gt;
  Div.Style.Add('right', '0');&lt;br /&gt;
  Div.Style.Add('z-index', '255');&lt;br /&gt;
  Div.Style.Add('background-color', 'black');&lt;br /&gt;
  Div.Style.Add('border-style', 'solid');&lt;br /&gt;
  Div.Style.Add('border-color', BorderColor);&lt;br /&gt;
  Div.Style.Add('border-width', '1px');&lt;br /&gt;
  Div.ID = LinkItem; &lt;br /&gt;
  Return Div;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually the InfoBar creation and the div creation are in the same function or method, but for purposes of example I have split them into two functions. The first part is the setup and assignment. LinkItem is the name of the inner div, and it is usually the similar to the link name. Keep in mind that if you create two scripts and name the Div the same, they will both appear and hide when either script link is toggled, so you want the inner div name to be unique. The middle of the function sets up the div attached to the control (the link). Since it was the last one added, it is the on the top of the stack, thus control at position 0. The width is 1% short of maximum, because some browsers (notably Opera) tends to cut the right border off if it is 100%. The Z-Index ensures it's appears above normal output. The last part of the function sets up the inner div, with a black background and the standard STNE blue border 1 pixel wide. The alignment for the output is top right, of the outer div, which is created just below the InfoBar. The output is adjusted to the smallest possible area that still displays the output. The following is the entire script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#UseInterface Web, Gui;&lt;br /&gt;
&lt;br /&gt;
Function InfoBarLink(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) {&lt;br /&gt;
  Var InfoBarAlignRight As Boolean = True;&lt;br /&gt;
  Var UrlCon As CHtmlControl;&lt;br /&gt;
  Var LinkText As String = &amp;quot;My InfoBar App&amp;quot;;&lt;br /&gt;
  // Create the app bar link&lt;br /&gt;
  Var Url As CJsAction = CUrlBuilder.JsToggleElement(LinkItem);&lt;br /&gt;
  UrlCon = CControlBuilder.BracketLink(Url, LinkText);&lt;br /&gt;
  Var UrlSmall As New CHtmlSmall();&lt;br /&gt;
  UrlSmall.Add(UrlCon)&lt;br /&gt;
  CBEvent.CreateItem(InfoBarAlignRight).Add(UrlSmall.GuiControl);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function InfoBarDiv(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) As CHtmlDiv {&lt;br /&gt;
  Var BorderColor As String = &amp;quot;#16344E&amp;quot;;&lt;br /&gt;
  Var OuterDiv As New CHtmlDiv();&lt;br /&gt;
  Var Div As New CHtmlDiv();&lt;br /&gt;
  &lt;br /&gt;
  CBEvent.Page.Body.Controls.Insert(0, OuterDiv.GuiControl);&lt;br /&gt;
  OuterDiv.Style.Add('position', 'absolute');&lt;br /&gt;
  OuterDiv.Width = '99%';&lt;br /&gt;
  OuterDiv.Style.Add('z-index', '255'); &lt;br /&gt;
  &lt;br /&gt;
  OuterDiv.Add(Div);&lt;br /&gt;
  Div.Style.Add('position', 'absolute');&lt;br /&gt;
  Div.Style.Add('top', '0');&lt;br /&gt;
  Div.Style.Add('right', '0');&lt;br /&gt;
  Div.Style.Add('z-index', '255');&lt;br /&gt;
  Div.Style.Add('background-color', 'black');&lt;br /&gt;
  Div.Style.Add('border-style', 'solid');&lt;br /&gt;
  Div.Style.Add('border-color', BorderColor);&lt;br /&gt;
  Div.Style.Add('border-width', '1px');&lt;br /&gt;
  Div.ID = LinkItem; &lt;br /&gt;
  Return Div;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Function RegisterHooks() {&lt;br /&gt;
  ScriptContext.EnableExtension();&lt;br /&gt;
  ScriptContext.RegisterEvent(EGuiEventType.InfoBarAfterCreate, AddressOf CB_InfoBarAfterCreate);&lt;br /&gt;
  ScriptContext.ActivateEvents();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function CB_InfoBarAfterCreate(CBEvent As CGuiEventOnInfoBarAfterCreate) {&lt;br /&gt;
  // processing for event goes here, create the link, the output, etc.&lt;br /&gt;
  Var LinkItem As String = &amp;quot;my_infobar_app&amp;quot;;&lt;br /&gt;
  Var Div As CHtmlDiv;&lt;br /&gt;
  InfoBarLink(CBEvent, LinkItem);&lt;br /&gt;
  Div = InfoBarDiv(CBEvent, LinkItem);&lt;br /&gt;
  Div.Style.Add('display', 'none'); // See notes below&lt;br /&gt;
  Div.Add(&amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RegisterHooks();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Normally, at the Div.Add in CB_ InfoBarAfterCreate, you would add your output table or div instead of a text string. Also, you would toggle the output with a URL Parameter, with something like this in CB_ InfoBarAfterCreate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  Var ShowDiv As Boolean = False;&lt;br /&gt;
  // option processing here, usually returning the status of ShowDiv, like Showdiv = ProcessOptions()&lt;br /&gt;
  // … table/div output creation, like Div.Add(function());&lt;br /&gt;
  If (ShowDiv) {&lt;br /&gt;
    Div.Style.Add('display', 'block');&lt;br /&gt;
  } Else {&lt;br /&gt;
    Div.Style.Add('display', 'none');&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
But URL/Form parameter passing and processing is for another tutorial&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 06:19, 9 October 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:InfoBar_Links</id>
		<title>Scripting:InfoBar Links</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:InfoBar_Links"/>
				<updated>2011-10-09T04:20:46Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Understanding InfoBar Links&lt;br /&gt;
&lt;br /&gt;
The STNE engine allows for extensions accessible fro the 'InfoBar', an area at the top of the UI (user interface) primary pane. The intent it seems is to allow extensibility to the UI, and allow a certain level of customizations. These could include notes, coordinates, a list alliance members, etc. The InfoBar itself you have probably seen, it is the area where [You have a new message] appears. &lt;br /&gt;
&lt;br /&gt;
To understand how to create an InfoBar application, one must first understand how it actually manages to get to the UI. This is done by CallBack methods. A callback is similar to system signal handlers in concept. When you tell the script to 'hook' a callback, it is added to a list of code to process every time that callback happens (with the exception that unlike a system signal, it can be pre filtered). A script can only hook a specific callback once, so if you need to have 3 individual methods happen for a particular callback event, you add them to a single function and call them all from there (In a normal driver or signal handler, you would not call the handler from a class, and this is good methodology to follow even with scripts) The following is an example of callback handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function RegisterHooks() {&lt;br /&gt;
  ScriptContext.EnableExtension();&lt;br /&gt;
  ScriptContext.RegisterEvent(EGuiEventType.InfoBarAfterCreate, AddressOf CB_InfoBarAfterCreate);&lt;br /&gt;
  ScriptContext.ActivateEvents();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function CB_InfoBarAfterCreate(CBEvent As CGuiEventOnInfoBarAfterCreate) {&lt;br /&gt;
  // processing for event goes here, create the link, the output, etc.&lt;br /&gt;
  Var LinkItem As String = &amp;quot;my_infobar_app&amp;quot;;&lt;br /&gt;
  Var Div As CHtmlDiv;&lt;br /&gt;
  InfoBarLink(CBEvent, LinkItem);&lt;br /&gt;
  Div = InfoBarDiv(CBEvent, LinkItem);&lt;br /&gt;
  Div.Style.Add('display', 'none'); &lt;br /&gt;
  Div.Add(&amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RegisterHooks();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
RegisterHooks is a function called from the main body of the script, and the function itself handles adding the entry point onto the callback stack. Firstly, it sets up for being an extension via EnableExtensions. Next, it adds a handler to the callback stack, giving the code reference via AddressOf. Lastly, it lets the script engine know it's ready to handle events. Normally you will have any validation (checking data storage, initializing variables, etc) happening between EnableExtension and RegisterEvent. This function is called only at script initialization, which should be when you click on “Execute Script”, but experience tells me it gets called occasionally in other circumstances (the script seems to like to run from the main body after an STNE restart).&lt;br /&gt;
&lt;br /&gt;
Once you have the callback hooked, you need the InfoBar link. For an InfoBar application to work, it needs two more components, other than the output. The first is a clickable link item, which usually contains the name of the script. The other is an area upon which to place your actual output. While the output can be appended from a different callback method, this is not the usual case. Firstly, set up the link:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function InfoBarLink(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) {&lt;br /&gt;
  Var InfoBarAlignRight As Boolean = True;&lt;br /&gt;
  Var UrlCon As CHtmlControl;&lt;br /&gt;
  Var LinkText As String = &amp;quot;My InfoBar App&amp;quot;;&lt;br /&gt;
  // Create the app bar link&lt;br /&gt;
  Var Url As CJsAction = CUrlBuilder.JsToggleElement(LinkItem);&lt;br /&gt;
  UrlCon = CControlBuilder.BracketLink(Url, LinkText);&lt;br /&gt;
  Var UrlSmall As New CHtmlSmall();&lt;br /&gt;
  UrlSmall.Add(UrlCon)&lt;br /&gt;
  CBEvent.CreateItem(InfoBarAlignRight).Add(UrlSmall.GuiControl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function simply sets up a toggle-able link on the InfoBar... It does not actually display anything, and clicking on it will do nothing, because no data is attached to it. The first line declares the function, and expects the passed parameter to be of type  CGuiEventOnInfoBarAfterCreate, which is itself a child of the class CguiEvent. CguiEvent could be used instead, if this handler was to process multiple callbacks, but you loose accessibility to anything specific to the child (unless you cast it back to it's particular type). The declaration of InfoBarAlignRight is for clarity. If it was false, it would align on the left. LinkText is literally the text the link will have. JsToggleElement is how the UI adds the javascript code to toggle the output (a div tag) between visible and hidden. BracketLink adds [ and ] around the text. ChtmlSmall applies the &amp;amp;LT;small&amp;amp;GT; HTML tag to the link. The CreateItem is how the script adds the newly created link into the UI, on the infobar.&lt;br /&gt;
&lt;br /&gt;
Now that we have the link, we need to add the output area for the link. This is done by creating a layered div tag. Why layered? So the output stays precisely where you want it, and it actually hides when necessary. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function InfoBarDiv(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) As CHtmlDiv {&lt;br /&gt;
  Var BorderColor As String = &amp;quot;#16344E&amp;quot;;&lt;br /&gt;
  Var OuterDiv As New CHtmlDiv();&lt;br /&gt;
  Var Div As New CHtmlDiv();&lt;br /&gt;
  &lt;br /&gt;
  CBEvent.Page.Body.Controls.Insert(0, OuterDiv.GuiControl);&lt;br /&gt;
  OuterDiv.Style.Add('position', 'absolute');&lt;br /&gt;
  OuterDiv.Width = '99%';&lt;br /&gt;
  OuterDiv.Style.Add('z-index', '255'); &lt;br /&gt;
  &lt;br /&gt;
  OuterDiv.Add(Div);&lt;br /&gt;
  Div.Style.Add('position', 'absolute');&lt;br /&gt;
  Div.Style.Add('top', '0');&lt;br /&gt;
  Div.Style.Add('right', '0');&lt;br /&gt;
  Div.Style.Add('z-index', '255');&lt;br /&gt;
  Div.Style.Add('background-color', 'black');&lt;br /&gt;
  Div.Style.Add('border-style', 'solid');&lt;br /&gt;
  Div.Style.Add('border-color', BorderColor);&lt;br /&gt;
  Div.Style.Add('border-width', '1px');&lt;br /&gt;
  Div.ID = LinkItem; &lt;br /&gt;
  Return Div;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually the InfoBar creation and the div creation are in the same function or method, but for purposes of example I have split them into two functions. The first part is the setup and assignment. LinkItem is the name of the inner div, and it is usually the similar to the link name. Keep in mind that if you create two scripts and name the Div the same, they will both appear and hide when either script link is toggled, so you want the inner div name to be unique. The middle of the function sets up the div attached to the control (the link). Since it was the last one added, it is the on the top of the stack, thus control at position 0. The width is 1% short of maximum, because some browsers (notably Opera) tends to cut the right border off if it is 100%. The Z-Index ensures it's appears above normal output. The last part of the function sets up the inner div, with a black background and the standard STNE blue border 1 pixel wide. The alignment for the output is top right, of the outer div, which is created just below the InfoBar. The output is adjusted to the smallest possible area that still displays the output. The following is the entire script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#UseInterface Web, Gui;&lt;br /&gt;
&lt;br /&gt;
Function InfoBarLink(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) {&lt;br /&gt;
  Var InfoBarAlignRight As Boolean = True;&lt;br /&gt;
  Var UrlCon As CHtmlControl;&lt;br /&gt;
  Var LinkText As String = &amp;quot;My InfoBar App&amp;quot;;&lt;br /&gt;
  // Create the app bar link&lt;br /&gt;
  Var Url As CJsAction = CUrlBuilder.JsToggleElement(LinkItem);&lt;br /&gt;
  UrlCon = CControlBuilder.BracketLink(Url, LinkText);&lt;br /&gt;
  Var UrlSmall As New CHtmlSmall();&lt;br /&gt;
  UrlSmall.Add(UrlCon)&lt;br /&gt;
  CBEvent.CreateItem(InfoBarAlignRight).Add(UrlSmall.GuiControl);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function InfoBarDiv(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) As CHtmlDiv {&lt;br /&gt;
  Var BorderColor As String = &amp;quot;#16344E&amp;quot;;&lt;br /&gt;
  Var OuterDiv As New CHtmlDiv();&lt;br /&gt;
  Var Div As New CHtmlDiv();&lt;br /&gt;
  &lt;br /&gt;
  CBEvent.Page.Body.Controls.Insert(0, OuterDiv.GuiControl);&lt;br /&gt;
  OuterDiv.Style.Add('position', 'absolute');&lt;br /&gt;
  OuterDiv.Width = '99%';&lt;br /&gt;
  OuterDiv.Style.Add('z-index', '255'); &lt;br /&gt;
  &lt;br /&gt;
  OuterDiv.Add(Div);&lt;br /&gt;
  Div.Style.Add('position', 'absolute');&lt;br /&gt;
  Div.Style.Add('top', '0');&lt;br /&gt;
  Div.Style.Add('right', '0');&lt;br /&gt;
  Div.Style.Add('z-index', '255');&lt;br /&gt;
  Div.Style.Add('background-color', 'black');&lt;br /&gt;
  Div.Style.Add('border-style', 'solid');&lt;br /&gt;
  Div.Style.Add('border-color', BorderColor);&lt;br /&gt;
  Div.Style.Add('border-width', '1px');&lt;br /&gt;
  Div.ID = LinkItem; &lt;br /&gt;
  Return Div;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Function RegisterHooks() {&lt;br /&gt;
  ScriptContext.EnableExtension();&lt;br /&gt;
  ScriptContext.RegisterEvent(EGuiEventType.InfoBarAfterCreate, AddressOf CB_InfoBarAfterCreate);&lt;br /&gt;
  ScriptContext.ActivateEvents();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function CB_InfoBarAfterCreate(CBEvent As CGuiEventOnInfoBarAfterCreate) {&lt;br /&gt;
  // processing for event goes here, create the link, the output, etc.&lt;br /&gt;
  Var LinkItem As String = &amp;quot;my_infobar_app&amp;quot;;&lt;br /&gt;
  Var Div As CHtmlDiv;&lt;br /&gt;
  InfoBarLink(CBEvent, LinkItem);&lt;br /&gt;
  Div = InfoBarDiv(CBEvent, LinkItem);&lt;br /&gt;
  Div.Style.Add('display', 'none'); // See notes below&lt;br /&gt;
  Div.Add(&amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RegisterHooks();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Normally, at the Div.Add in CB_ InfoBarAfterCreate, you would add your output table or div instead of a text string. Also, you would toggle the output with a URL Parameter, with something like this in CB_ InfoBarAfterCreate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  Var ShowDiv As Boolean = False;&lt;br /&gt;
  // option processing here, usually returning the status of ShowDiv, like Showdiv = ProcessOptions()&lt;br /&gt;
  // … table/div output creation, like Div.Add(function());&lt;br /&gt;
  If (ShowDiv) {&lt;br /&gt;
    Div.Style.Add('display', 'block');&lt;br /&gt;
  } Else {&lt;br /&gt;
    Div.Style.Add('display', 'none');&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
But URL/Form parameter passing and processing is for another tutorial&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 06:19, 9 October 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:InfoBar_Links</id>
		<title>Scripting:InfoBar Links</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:InfoBar_Links"/>
				<updated>2011-10-09T04:19:28Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: Created page with &amp;quot;Understanding InfoBar Links  The STNE engine allows for extensions accessible fro the 'InfoBar', an area at the top of the UI (user interface) primary pane. The intent it seems i...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Understanding InfoBar Links&lt;br /&gt;
&lt;br /&gt;
The STNE engine allows for extensions accessible fro the 'InfoBar', an area at the top of the UI (user interface) primary pane. The intent it seems is to allow extensibility to the UI, and allow a certain level of customizations. These could include notes, coordinates, a list alliance members, etc. The InfoBar itself you have probably seen, it is the area where [You have a new message] appears. &lt;br /&gt;
&lt;br /&gt;
To understand how to create an InfoBar application, one must first understand how it actually manages to get to the UI. This is done by CallBack methods. A callback is similar to system signal handlers in concept. When you tell the script to 'hook' a callback, it is added to a list of code to process every time that callback happens (with the exception that unlike a system signal, it can be pre filtered). A script can only hook a specific callback once, so if you need to have 3 individual methods happen for a particular callback event, you add them to a single function and call them all from there (In a normal driver or signal handler, you would not call the handler from a class, and this is good methodology to follow even with scripts) The following is an example of callback handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function RegisterHooks() {&lt;br /&gt;
  ScriptContext.EnableExtension();&lt;br /&gt;
  ScriptContext.RegisterEvent(EGuiEventType.InfoBarAfterCreate, AddressOf CB_InfoBarAfterCreate);&lt;br /&gt;
  ScriptContext.ActivateEvents();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function CB_InfoBarAfterCreate(CBEvent As CGuiEventOnInfoBarAfterCreate) {&lt;br /&gt;
  // processing for event goes here, create the link, the output, etc.&lt;br /&gt;
  Var LinkItem As String = &amp;quot;my_infobar_app&amp;quot;;&lt;br /&gt;
  Var Div As CHtmlDiv;&lt;br /&gt;
  InfoBarLink(CBEvent, LinkItem);&lt;br /&gt;
  Div = InfoBarDiv(CBEvent, LinkItem);&lt;br /&gt;
  Div.Style.Add('display', 'none'); &lt;br /&gt;
  Div.Add(&amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RegisterHooks();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
RegisterHooks is a function called from the main body of the script, and the function itself handles adding the entry point onto the callback stack. Firstly, it sets up for being an extension via EnableExtensions. Next, it adds a handler to the callback stack, giving the code reference via AddressOf. Lastly, it lets the script engine know it's ready to handle events. Normally you will have any validation (checking data storage, initializing variables, etc) happening between EnableExtension and RegisterEvent. This function is called only at script initialization, which should be when you click on “Execute Script”, but experience tells me it gets called occasionally in other circumstances (the script seems to like to run from the main body after an STNE restart).&lt;br /&gt;
&lt;br /&gt;
Once you have the callback hooked, you need the InfoBar link. For an InfoBar application to work, it needs two more components, other than the output. The first is a clickable link item, which usually contains the name of the script. The other is an area upon which to place your actual output. While the output can be appended from a different callback method, this is not the usual case. Firstly, set up the link:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function InfoBarLink(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) {&lt;br /&gt;
  Var InfoBarAlignRight As Boolean = True;&lt;br /&gt;
  Var UrlCon As CHtmlControl;&lt;br /&gt;
  Var LinkText As String = &amp;quot;My InfoBar App&amp;quot;;&lt;br /&gt;
  // Create the app bar link&lt;br /&gt;
  Var Url As CJsAction = CUrlBuilder.JsToggleElement(LinkItem);&lt;br /&gt;
  UrlCon = CControlBuilder.BracketLink(Url, LinkText);&lt;br /&gt;
  Var UrlSmall As New CHtmlSmall();&lt;br /&gt;
  UrlSmall.Add(UrlCon)&lt;br /&gt;
  CBEvent.CreateItem(InfoBarAlignRight).Add(UrlSmall.GuiControl);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function simply sets up a toggle-able link on the InfoBar... It does not actually display anything, and clicking on it will do nothing, because no data is attached to it. The first line declares the function, and expects the passed parameter to be of type  CGuiEventOnInfoBarAfterCreate, which is itself a child of the class CguiEvent. CguiEvent could be used instead, if this handler was to process multiple callbacks, but you loose accessibility to anything specific to the child (unless you cast it back to it's particular type). The declaration of InfoBarAlignRight is for clarity. If it was false, it would align on the left. LinkText is literally the text the link will have. JsToggleElement is how the UI adds the javascript code to toggle the output (a div tag) between visible and hidden. BracketLink adds [ and ] around the text. ChtmlSmall applies the &amp;amp;LT;small&amp;amp;GT; HTML tag to the link. The CreateItem is how the script adds the newly created link into the UI, on the infobar.&lt;br /&gt;
&lt;br /&gt;
Now that we have the link, we need to add the output area for the link. This is done by creating a layered div tag. Why layered? So the output stays precisely where you want it, and it actually hides when necessary. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function InfoBarDiv(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) As CHtmlDiv {&lt;br /&gt;
  Var BorderColor As String = &amp;quot;#16344E&amp;quot;;&lt;br /&gt;
  Var OuterDiv As New CHtmlDiv();&lt;br /&gt;
  Var Div As New CHtmlDiv();&lt;br /&gt;
  &lt;br /&gt;
  CBEvent.Page.Body.Controls.Insert(0, OuterDiv.GuiControl);&lt;br /&gt;
  OuterDiv.Style.Add('position', 'absolute');&lt;br /&gt;
  OuterDiv.Width = '99%';&lt;br /&gt;
  OuterDiv.Style.Add('z-index', '255'); &lt;br /&gt;
  &lt;br /&gt;
  OuterDiv.Add(Div);&lt;br /&gt;
  Div.Style.Add('position', 'absolute');&lt;br /&gt;
  Div.Style.Add('top', '0');&lt;br /&gt;
  Div.Style.Add('right', '0');&lt;br /&gt;
  Div.Style.Add('z-index', '255');&lt;br /&gt;
  Div.Style.Add('background-color', 'black');&lt;br /&gt;
  Div.Style.Add('border-style', 'solid');&lt;br /&gt;
  Div.Style.Add('border-color', BorderColor);&lt;br /&gt;
  Div.Style.Add('border-width', '1px');&lt;br /&gt;
  Div.ID = LinkItem; &lt;br /&gt;
  Return Div;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually the InfoBar creation and the div creation are in the same function or method, but for purposes of example I have split them into two functions. The first part is the setup and assignment. LinkItem is the name of the inner div, and it is usually the similar to the link name. Keep in mind that if you create two scripts and name the Div the same, they will both appear and hide when either script link is toggled, so you want the inner div name to be unique. The middle of the function sets up the div attached to the control (the link). Since it was the last one added, it is the on the top of the stack, thus control at position 0. The width is 1% short of maximum, because some browsers (notably Opera) tends to cut the right border off if it is 100%. The Z-Index ensures it's appears above normal output. The last part of the function sets up the inner div, with a black background and the standard STNE blue border 1 pixel wide. The alignment for the output is top right, of the outer div, which is created just below the InfoBar. The output is adjusted to the smallest possible area that still displays the output. The following is the entire script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#UseInterface Web, Gui;&lt;br /&gt;
&lt;br /&gt;
Function InfoBarLink(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) {&lt;br /&gt;
  Var InfoBarAlignRight As Boolean = True;&lt;br /&gt;
  Var UrlCon As CHtmlControl;&lt;br /&gt;
  Var LinkText As String = &amp;quot;My InfoBar App&amp;quot;;&lt;br /&gt;
  // Create the app bar link&lt;br /&gt;
  Var Url As CJsAction = CUrlBuilder.JsToggleElement(LinkItem);&lt;br /&gt;
  UrlCon = CControlBuilder.BracketLink(Url, LinkText);&lt;br /&gt;
  Var UrlSmall As New CHtmlSmall();&lt;br /&gt;
  UrlSmall.Add(UrlCon)&lt;br /&gt;
  CBEvent.CreateItem(InfoBarAlignRight).Add(UrlSmall.GuiControl);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function InfoBarDiv(CBEvent As CGuiEventOnInfoBarAfterCreate, LinkItem As String) As CHtmlDiv {&lt;br /&gt;
  Var BorderColor As String = &amp;quot;#16344E&amp;quot;;&lt;br /&gt;
  Var OuterDiv As New CHtmlDiv();&lt;br /&gt;
  Var Div As New CHtmlDiv();&lt;br /&gt;
  &lt;br /&gt;
  CBEvent.Page.Body.Controls.Insert(0, OuterDiv.GuiControl);&lt;br /&gt;
  OuterDiv.Style.Add('position', 'absolute');&lt;br /&gt;
  OuterDiv.Width = '99%';&lt;br /&gt;
  OuterDiv.Style.Add('z-index', '255'); &lt;br /&gt;
  &lt;br /&gt;
  OuterDiv.Add(Div);&lt;br /&gt;
  Div.Style.Add('position', 'absolute');&lt;br /&gt;
  Div.Style.Add('top', '0');&lt;br /&gt;
  Div.Style.Add('right', '0');&lt;br /&gt;
  Div.Style.Add('z-index', '255');&lt;br /&gt;
  Div.Style.Add('background-color', 'black');&lt;br /&gt;
  Div.Style.Add('border-style', 'solid');&lt;br /&gt;
  Div.Style.Add('border-color', BorderColor);&lt;br /&gt;
  Div.Style.Add('border-width', '1px');&lt;br /&gt;
  Div.ID = LinkItem; &lt;br /&gt;
  Return Div;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Function RegisterHooks() {&lt;br /&gt;
  ScriptContext.EnableExtension();&lt;br /&gt;
  ScriptContext.RegisterEvent(EGuiEventType.InfoBarAfterCreate, AddressOf CB_InfoBarAfterCreate);&lt;br /&gt;
  ScriptContext.ActivateEvents();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function CB_InfoBarAfterCreate(CBEvent As CGuiEventOnInfoBarAfterCreate) {&lt;br /&gt;
  // processing for event goes here, create the link, the output, etc.&lt;br /&gt;
  Var LinkItem As String = &amp;quot;my_infobar_app&amp;quot;;&lt;br /&gt;
  Var Div As CHtmlDiv;&lt;br /&gt;
  InfoBarLink(CBEvent, LinkItem);&lt;br /&gt;
  Div = InfoBarDiv(CBEvent, LinkItem);&lt;br /&gt;
  Div.Style.Add('display', 'none'); // See notes below&lt;br /&gt;
  Div.Add(&amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RegisterHooks();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Normally, at the Div.Add in CB_ InfoBarAfterCreate, you would add your output table or div instead of a text string. Also, you would toggle the output with a URL Parameter, with something like this in CB_ InfoBarAfterCreate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  Var ShowDiv As Boolean = False;&lt;br /&gt;
  // option processing here, usually returning the status of ShowDiv, like Showdiv = ProcessOptions()&lt;br /&gt;
  // … table/div output creation, like Div.Add(function());&lt;br /&gt;
  If (ShowDiv) {&lt;br /&gt;
    Div.Style.Add('display', 'block');&lt;br /&gt;
  } Else {&lt;br /&gt;
    Div.Style.Add('display', 'none');&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
But URL/Form parameter passing and processing is for another tutorial&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 06:19, 9 October 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Main_page</id>
		<title>Scripting:Main page</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Main_page"/>
				<updated>2011-10-09T04:14:56Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: /* Topics: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scripting]]&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
{{CreateScriptingArticle}}&lt;br /&gt;
&lt;br /&gt;
This section of the Wiki is intended to document the scripting engine found in the game. Most scripting related pages in STNE can be found from the main menu trough Database -&amp;gt; Scripting.&lt;br /&gt;
&lt;br /&gt;
=== Topics: ===&lt;br /&gt;
* [[Scripting:Syntax|Syntax]]&lt;br /&gt;
* [[Scripting:Operators|Operators]]&lt;br /&gt;
* [[Scripting:Interfaces|Interfaces]]&lt;br /&gt;
&lt;br /&gt;
* [[Scripting:Basic course|Basic course]] (mostly translated)&lt;br /&gt;
* [[Scripting:Script_editor|The external script editor]]&lt;br /&gt;
* [[Scripting:InvokeItem|A tutorial on scripting the portal InvokeItem()]]&lt;br /&gt;
* [[Scripting:InfoBar Links|A tutorial on scripting for an InfoBar link]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:InvokeItem</id>
		<title>Scripting:InvokeItem</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:InvokeItem"/>
				<updated>2011-09-16T05:38:17Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ship.InvokeItem is one of those multiplexing calls, comparable to (although completely different invocation wise from) the old dos int 21h or hardware ioctl calls. While at first it may look daunting, it's actually very simply. The caveat is that the sub function calls have to be documented, and as so far I can find only one well documented rendition, gates. So, for a quick tour of InvokeItem, in regards to it's use with a gate.&lt;br /&gt;
&lt;br /&gt;
Firstly, the syntax must be clear. InvokeItem takes up to, and should include, 3 parameters. Firstly, the ID of the item to invoke against. For a gate, this is the portal generator (not a transponder). From the helm view, towards the bottom of the page, is the transponder/generator list. In that list, it's the only one named “Portal Generator”, and the only one not prefixed by “PT-”. To the right of the name is the ID, that's the number you want. This number is unique, so you can't just use the same number on a different gate and expect good results. GIGO (garbage in, garbage out), as always.&lt;br /&gt;
&lt;br /&gt;
Secondly, you need to have a sub function to call. These are free form text fields, and as of the time of this writing, I can find absolutely 0 enumerators for the sub function name (Hint: this would be a GREAT addition to the scripting engine, perhaps an enum of InvokeItemCommands.ItemType.CommandList). The one documented for the gate, broken down by usage, along with known status and caveats are:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
User Portal Commands:&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserList – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserCreate – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserRemove – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserUsed – Does not reset accumulator&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLimit – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLevel – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLocked – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserShipType – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
Alliance Portal Commands:&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyList – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyCreate – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyRemove – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyUsed – Does not reset accumulator&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLimit- Does not return current limit&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLevel – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLocked – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyShipType – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
User and Alliance Portal Commands, all fail if the user does not exist on the gate (kinda silly, IMHO. Limits usefulness to require the user exist... Why not just fall back to the alliance calls?):&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAvailableMaxUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;LevelUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ShipTypeAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ShipTypeIsAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
General Gate Data:&lt;br /&gt;
&amp;lt;li&amp;gt;ReceiveModMax – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ReceiveModMin – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAvailableMax – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;CreatedItemExists – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;CalcDistanceToTransponder – Not functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thirdly, you need a parameter list. Not just any parameter list, but again matching expected parameter names with expected parameter values. For the user sub functions, the primary is UserID. For alliance sub functions, AllyID. For user and ally sub functions, UserID. For most of the others, ItemID. &lt;br /&gt;
&lt;br /&gt;
And, lastly, you need to know the return type. Getting the data is great, but returning it to be used is the goal. Now, to tie this all together.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var b As Boolean;&lt;br /&gt;
Var ship As New CMyShip(123456);&lt;br /&gt;
Var pg As Integer = 789012;&lt;br /&gt;
Var uid As Integer = 34567;&lt;br /&gt;
CreateUser(uid);&lt;br /&gt;
&lt;br /&gt;
Function CreateUser (user2check As Integer) {&lt;br /&gt;
  Var command As String = &amp;quot;RightsUserList&amp;quot;;&lt;br /&gt;
  Var parameters As New CSortedStringObjectList();&lt;br /&gt;
  Var val As CIntegerList = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
  If (NOT val.Contains(user2check)) {&lt;br /&gt;
    command = &amp;quot;RightsUserCreate&amp;quot;;&lt;br /&gt;
    parameters.Add(&amp;quot;UserID&amp;quot;, user2check);&lt;br /&gt;
    b = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
    If (NOT b) {&lt;br /&gt;
      WriteLine (&amp;quot;User Creation failed!&amp;quot;);&lt;br /&gt;
    } Else {&lt;br /&gt;
      WriteLine(&amp;quot;New gate user ID: &amp;quot; &amp;amp; user2check;&lt;br /&gt;
    }&lt;br /&gt;
  } Else {&lt;br /&gt;
    WriteLine (&amp;quot;User &amp;quot; &amp;amp; user2check &amp;amp; &amp;quot; already exists&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This small function checks for a user, and creates them if they don't exist. The next question, at least in my mind, was “How do I know I have the right PG?” You have two options. One is CreatedItemExists, followed by a call to  a sub function with a known value or range of values (because a mistaken transponder ID would also exist), the other is just call the sub function. In the case of multiplexing functions, the normal behavior is to return an error condition on fail, not abort. At least InvokeItem for gates follows this protocol.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function CheckPG(ship As CMyShip, pg As Integer) As Boolean {&lt;br /&gt;
  Var parameters As New CSortedStringObjectList();&lt;br /&gt;
  Var command As String = &amp;quot;RightsUserList&amp;quot;;&lt;br /&gt;
  Var val As CIntegerList = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
  // Error condition is 0 entries in the list&lt;br /&gt;
  If (val.Count = 0) { &lt;br /&gt;
    Return False;&lt;br /&gt;
  }&lt;br /&gt;
  Return True;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, there you have it. It's fairly straightforward, with a little practice you can do the majority of your gate configuration via the scripting engine. For the documented passed parameters and return values, from your gate go to Administration-&amp;gt;Scripting. They are as of the time of this writing, deemed experimental and subject to change.&lt;br /&gt;
&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 07:21, 16 September 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:InvokeItem</id>
		<title>Scripting:InvokeItem</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:InvokeItem"/>
				<updated>2011-09-16T05:34:05Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ship.InvokeItem is one of those multiplexing calls, comparable to (although completely different invocation wise from) the old dos int 21h or hardware ioctl calls. While at first it may look daunting, it's actually very simply. The caveat is that the sub function calls have to be documented, and as so far I can find only one well documented rendition, gates. So, for a quick tour of InvokeItem, in regards to it's use with a gate.&lt;br /&gt;
&lt;br /&gt;
Firstly, the syntax must be clear. InvokeItem takes up to, and should include, 3 parameters. Firstly, the ID of the item to invoke against. For a gate, this is the portal generator (not a transponder). From the helm view, towards the bottom of the page, is the transponder/generator list. In that list, it's the only one named “Portal Generator”, and the only one not prefixed by “PT-”. To the right of the name is the ID, that's the number you want. This number is unique, so you can't just use the same number on a different gate and expect good results. GIGO (garbage in, garbage out), as always.&lt;br /&gt;
&lt;br /&gt;
Secondly, you need to have a sub function to call. These are free form text fields, and as of the time of this writing, I can find absolutely 0 enumerators for the sub function name (Hint: this would be a GREAT addition to the scripting engine, perhaps an enum of InvokeItemCommands.ItemType.CommandList). The one documented for the gate, broken down by usage, along with known status and caveats are:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
User Portal Commands:&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserList – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserCreate – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserRemove – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserUsed – Does not reset accumulator&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLimit – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLevel – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLocked – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserShipType – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
Alliance Portal Commands:&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyList – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyCreate – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyRemove – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyUsed – Does not reset accumulator&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLimit- Does not return current limit&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLevel – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLocked – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyShipType – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
User and Alliance Portal Commands, all fail if the user does not exist on the gate (kinda silly, IMHO. Limits usefulness to require the user exist... Why not just fall back to the alliance calls?):&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAvailableMaxUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;LevelUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ShipTypeAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ShipTypeIsAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
General Gate Data:&lt;br /&gt;
&amp;lt;li&amp;gt;ReceiveModMax – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ReceiveModMin – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAvailableMax – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;CreatedItemExists – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;CalcDistanceToTransponder – Not functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thirdly, you need a parameter list. Not just any parameter list, but again matching expected parameter names with expected parameter values. For the user sub functions, the primary is UserID. For alliance sub functions, AllyID. For user and ally sub functions, UserID. For most of the others, ItemID. &lt;br /&gt;
&lt;br /&gt;
And, lastly, you need to know the return type. Getting the data is great, but returning it to be used is the goal. Now, to tie this all together.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var b As Boolean;&lt;br /&gt;
Var ship As New CMyShip(123456);&lt;br /&gt;
Var pg As Integer = 789012;&lt;br /&gt;
Var uid As Integer = 34567;&lt;br /&gt;
CreateUser(uid);&lt;br /&gt;
&lt;br /&gt;
Function CreateUser (user2check As Integer) {&lt;br /&gt;
  Var command As String = &amp;quot;RightsUserList&amp;quot;;&lt;br /&gt;
  Var parameters As New CSortedStringObjectList();&lt;br /&gt;
  Var val As CIntegerList = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
  If (NOT val.Contains(user2check)) {&lt;br /&gt;
    command = &amp;quot;RightsUserCreate&amp;quot;;&lt;br /&gt;
    parameters.Add(&amp;quot;UserID&amp;quot;, user2check);&lt;br /&gt;
    b = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
    If (NOT b) {&lt;br /&gt;
      WriteLine (&amp;quot;User Creation failed!&amp;quot;);&lt;br /&gt;
    } Else {&lt;br /&gt;
      WriteLine(&amp;quot;New gate user ID: &amp;quot; &amp;amp; user2check;&lt;br /&gt;
    }&lt;br /&gt;
  } Else {&lt;br /&gt;
    WriteLine (&amp;quot;User &amp;quot; &amp;amp; user2check &amp;amp; &amp;quot; already exists&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This small function checks for a user, and creates them if they don't exist. The next question, at least in my mind, was “How do I know I have the right PG?” You have two options. One is CreatedItemExists, followed by a call to  a sub function with a known value or range of values (because a mistaken transponder ID would also exist), the other is just call the sub function. In the case of multiplexing functions, the normal behavior is to return an error condition on fail, not abort. At least InvokeItem for gates follows this protocol.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function CheckPG(ship As CMyShip, pg As Integer) As Boolean {&lt;br /&gt;
  Var parameters As New CsortedStringObjectList();&lt;br /&gt;
  Var val As CIntegerList = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
  // Error condition is 0 entries in the list&lt;br /&gt;
  If (val.Count = 0) { &lt;br /&gt;
    Return False;&lt;br /&gt;
  }&lt;br /&gt;
  Return True;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, there you have it. It's fairly straightforward, with a little practice you can do the majority of your gate configuration via the scripting engine. For the documented passed parameters and return values, from your gate go to Administration-&amp;gt;Scripting. They are as of the time of this writing, deemed experimental and subject to change.&lt;br /&gt;
&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 07:21, 16 September 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:InvokeItem</id>
		<title>Scripting:InvokeItem</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:InvokeItem"/>
				<updated>2011-09-16T05:32:38Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ship.InvokeItem is one of those multiplexing calls, comparable to (although completely different invocation wise from) the old dos int 21h or hardware ioctl calls. While at first it may look daunting, it's actually very simply. The caveat is that the sub function calls have to be documented, and as so far I can find only one well documented rendition, gates. So, for a quick tour of InvokeItem, in regards to it's use with a gate.&lt;br /&gt;
&lt;br /&gt;
Firstly, the syntax must be clear. InvokeItem takes up to, and should include, 3 parameters. Firstly, the ID of the item to invoke against. For a gate, this is the portal generator (not a transponder). From the helm view, towards the bottom of the page, is the transponder/generator list. In that list, it's the only one named “Portal Generator”, and the only one not prefixed by “PT-”. To the right of the name is the ID, that's the number you want. This number is unique, so you can't just use the same number on a different gate and expect good results. GIGO (garbage in, garbage out), as always.&lt;br /&gt;
&lt;br /&gt;
Secondly, you need to have a sub function to call. These are free form text fields, and as of the time of this writing, I can find absolutely 0 enumerators for the sub function name (Hint: this would be a GREAT addition to the scripting engine, perhaps an enum of InvokeItemCommands.ItemType.CommandList). The one documented for the gate, broken down by usage, along with known status and caveats are:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
User Portal Commands:&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserList – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserCreate – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserRemove – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserUsed – Does not reset accumulator&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLimit – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLevel – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLocked – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserShipType – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
Alliance Portal Commands:&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyList – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyCreate – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyRemove – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyUsed – Does not reset accumulator&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLimit- Does not return current limit&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLevel – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLocked – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyShipType – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
User and Alliance Portal Commands, all fail if the user does not exist on the gate (kinda silly, IMHO. Limits usefulness to require the user exist... Why not just fall back to the alliance calls?):&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAvailableMaxUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;LevelUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ShipTypeAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ShipTypeIsAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
General Gate Data:&lt;br /&gt;
&amp;lt;li&amp;gt;ReceiveModMax – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ReceiveModMin – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAvailableMax – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;CreatedItemExists – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;CalcDistanceToTransponder – Not functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thirdly, you need a parameter list. Not just any parameter list, but again matching expected parameter names with expected parameter values. For the user sub functions, the primary is UserID. For alliance sub functions, AllyID. For user and ally sub functions, UserID. For most of the others, ItemID. &lt;br /&gt;
&lt;br /&gt;
And, lastly, you need to know the return type. Getting the data is great, but returning it to be used is the goal. Now, to tie this all together.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var b As Boolean;&lt;br /&gt;
Var ship As New CMyShip(439375);&lt;br /&gt;
Var pg As Integer = 235960;&lt;br /&gt;
Var uid As Integer = 67811;&lt;br /&gt;
CreateUser(uid);&lt;br /&gt;
&lt;br /&gt;
Function CreateUser (user2check As Integer) {&lt;br /&gt;
  Var command As String = &amp;quot;RightsUserList&amp;quot;;&lt;br /&gt;
  Var parameters As New CSortedStringObjectList();&lt;br /&gt;
  Var val As CIntegerList = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
  If (NOT val.Contains(user2check)) {&lt;br /&gt;
    command = &amp;quot;RightsUserCreate&amp;quot;;&lt;br /&gt;
    parameters.Add(&amp;quot;UserID&amp;quot;, user2check);&lt;br /&gt;
    b = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
    If (NOT b) {&lt;br /&gt;
      WriteLine (&amp;quot;User Creation failed!&amp;quot;);&lt;br /&gt;
    } Else {&lt;br /&gt;
      WriteLine(&amp;quot;New gate user ID: &amp;quot; &amp;amp; user2check;&lt;br /&gt;
    }&lt;br /&gt;
  } Else {&lt;br /&gt;
    WriteLine (&amp;quot;User &amp;quot; &amp;amp; user2check &amp;amp; &amp;quot; already exists&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This small function checks for a user, and creates them if they don't exist. The next question, at least in my mind, was “How do I know I have the right PG?” You have two options. One is CreatedItemExists, followed by a call to  a sub function with a known value or range of values (because a mistaken transponder ID would also exist), the other is just call the sub function. In the case of multiplexing functions, the normal behavior is to return an error condition on fail, not abort. At least InvokeItem for gates follows this protocol.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function CheckPG(ship As CMyShip, pg As Integer) As Boolean {&lt;br /&gt;
  Var parameters As New CsortedStringObjectList();&lt;br /&gt;
  Var val As CIntegerList = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
  // Error condition is 0 entries in the list&lt;br /&gt;
  If (val.Count = 0) { &lt;br /&gt;
    Return False;&lt;br /&gt;
  }&lt;br /&gt;
  Return True;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, there you have it. It's fairly straightforward, with a little practice you can do the majority of your gate configuration via the scripting engine. For the documented passed parameters and return values, from your gate go to Administration-&amp;gt;Scripting. They are as of the time of this writing, deemed experimental and subject to change.&lt;br /&gt;
&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 07:21, 16 September 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:InvokeItem</id>
		<title>Scripting:InvokeItem</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:InvokeItem"/>
				<updated>2011-09-16T05:25:18Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ship.InvokeItem is one of those multiplexing calls, comparable to (although completely different invocation wise from) the old dos int 21h or hardware ioctl calls. While at first it may look daunting, it's actually very simply. The caveat is that the sub function calls have to be documented, and as so far I can find only one well documented rendition, gates. So, for a quick tour of InvokeItem, in regards to it's use with a gate.&lt;br /&gt;
&lt;br /&gt;
Firstly, the syntax must be clear. InvokeItem takes up to, and should include, 3 parameters. Firstly, the ID of the item to invoke against. For a gate, this is the portal generator (not a transponder). From the helm view, towards the bottom of the page, is the transponder/generator list. In that list, it's the only one named “Portal Generator”, and the only one not prefixed by “PT-”. To the right of the name is the ID, that's the number you want. This number is unique, so you can't just use the same number on a different gate and expect good results. GIGO (garbage in, garbage out), as always.&lt;br /&gt;
&lt;br /&gt;
Secondly, you need to have a sub function to call. These are free form text fields, and as of the time of this writing, I can find absolutely 0 enumerators for the sub function name (Hint: this would be a GREAT addition to the scripting engine, perhaps an enum of InvokeItemCommands.ItemType.CommandList). The one documented for the gate, broken down by usage, along with known status and caveats are:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
User Portal Commands:&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserList – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserCreate – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserRemove – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserUsed – Does not reset accumulator&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLimit – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLevel – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLocked – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserShipType – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
Alliance Portal Commands:&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyList – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyCreate – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyRemove – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyUsed – Does not reset accumulator&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLimit- Does not return current limit&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLevel – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLocked – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyShipType – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
User and Alliance Portal Commands, all fail if the user does not exist on the gate (kinda silly, IMHO. Limits usefulness to require the user exist... Why not just fall back to the alliance calls?):&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAvailableMaxUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;LevelUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ShipTypeAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ShipTypeIsAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
General Gate Data:&lt;br /&gt;
&amp;lt;li&amp;gt;ReceiveModMax – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ReceiveModMin – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAvailableMax – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;CreatedItemExists – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;CalcDistanceToTransponder – Not functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thirdly, you need a parameter list. Not just any parameter list, but again matching expected parameter names with expected parameter values. For the user sub functions, the primary is UserID. For alliance sub functions, AllyID. For user and ally sub functions, UserID. For most of the others, ItemID. &lt;br /&gt;
&lt;br /&gt;
And, lastly, you need to know the return type. Getting the data is great, but returning it to be used is the goal. Now, to tie this all together.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var b As Boolean;&lt;br /&gt;
Var ship As New CMyShip(123456);&lt;br /&gt;
Var pg As Integer = 789012;&lt;br /&gt;
Var user2check = 56599;&lt;br /&gt;
Var command As String = &amp;quot;RightsUserList&amp;quot;;&lt;br /&gt;
Var parameters As New CsortedStringObjectList();&lt;br /&gt;
Var val As CIntegerList = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
If (NOT val.Contains(user2check)) {&lt;br /&gt;
  command = &amp;quot;RightsUserCreate&amp;quot;;&lt;br /&gt;
  Parameters.Add(&amp;quot;UserID&amp;quot;, user2check);&lt;br /&gt;
  b = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
  If (NOT b) {&lt;br /&gt;
    WriteLine (&amp;quot;User Creation failed!&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    WriteLine(&amp;quot;New gate user ID: &amp;quot; &amp;amp; user2check;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This small function checks for a user, and creates them if they don't exist. The next question, at least in my mind, was “How do I know I have the right PG?” You have two options. One is CreatedItemExists, followed by a call to  a sub function with a known value or range of values (because a mistaken transponder ID would also exist), the other is just call the sub function. In the case of multiplexing functions, the normal behavior is to return an error condition on fail, not abort. At least InvokeItem for gates follows this protocol.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function CheckPG(ship As CMyShip, pg As Integer) As Boolean {&lt;br /&gt;
  Var parameters As New CsortedStringObjectList();&lt;br /&gt;
  Var val As CIntegerList = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
  // Error condition is 0 entries in the list&lt;br /&gt;
  If (val.Count = 0) { &lt;br /&gt;
    Return False;&lt;br /&gt;
  }&lt;br /&gt;
  Return True;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, there you have it. It's fairly straightforward, with a little practice you can do the majority of your gate configuration via the scripting engine. For the documented passed parameters and return values, from your gate go to Administration-&amp;gt;Scripting. They are as of the time of this writing, deemed experimental and subject to change.&lt;br /&gt;
&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 07:21, 16 September 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:InvokeItem</id>
		<title>Scripting:InvokeItem</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:InvokeItem"/>
				<updated>2011-09-16T05:21:57Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: Created page with &amp;quot;Ship.InvokeItem is one of those multiplexing calls, comparable to (although completely different invocation wise from) the old dos int 21h or hardware ioctl calls. While at first...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ship.InvokeItem is one of those multiplexing calls, comparable to (although completely different invocation wise from) the old dos int 21h or hardware ioctl calls. While at first it may look daunting, it's actually very simply. The caveat is that the sub function calls have to be documented, and as so far I can find only one well documented rendition, gates. So, for a quick tour of InvokeItem, in regards to it's use with a gate.&lt;br /&gt;
&lt;br /&gt;
Firstly, the syntax must be clear. InvokeItem takes up to, and should include, 3 parameters. Firstly, the ID of the item to invoke against. For a gate, this is the portal generator (not a transponder). From the helm view, towards the bottom of the page, is the transponder/generator list. In that list, it's the only one named “Portal Generator”, and the only one not prefixed by “PT-”. To the right of the name is the ID, that's the number you want. This number is unique, so you can't just use the same number on a different gate and expect good results. GIGO (garbage in, garbage out), as always.&lt;br /&gt;
&lt;br /&gt;
Secondly, you need to have a sub function to call. These are free form text fields, and as of the time of this writing, I can find absolutely 0 enumerators for the sub function name (Hint: this would be a GREAT addition to the scripting engine, perhaps an enum of InvokeItemCommands.ItemType.CommandList). The one documented for the gate, broken down by usage, along with known status and caveats are:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
User Portal Commands:&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserList – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserCreate – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserRemove – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserUsed – Does not reset accumulator&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLimit – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLevel – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserLocked – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsUserShipType – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
Alliance Portal Commands:&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyList – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyCreate – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyRemove – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyUsed – Does not reset accumulator&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLimit- Does not return current limit&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLevel – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyLocked – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RightsAllyShipType – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
User and Alliance Portal Commands, all fail if the user does not exist on the gate (kinda silly, IMHO. Limits usefulness to require the user exist... Why not just fall back to the alliance calls?):&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAvailableMaxUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;LevelUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ShipTypeAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ShipTypeIsAllowedUserAndAlly - Probably&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
General Gate Data:&lt;br /&gt;
&amp;lt;li&amp;gt;ReceiveModMax – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ReceiveModMin – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;DeflectorAvailableMax – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;CreatedItemExists – Fully functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;CalcDistanceToTransponder – Not functioning&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thirdly, you need a parameter list. Not just any parameter list, but again matching expected parameter names with expected parameter values. For the user sub functions, the primary is UserID. For alliance sub functions, AllyID. For user and ally sub functions, UserID. For most of the others, ItemID. &lt;br /&gt;
&lt;br /&gt;
And, lastly, you need to know the return type. Getting the data is great, but returning it to be used is the goal. Now, to tie this all together.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Var b As Boolean;&lt;br /&gt;
Var ship As New CMyShip(123456);&lt;br /&gt;
Var pg As Integer = 789012;&lt;br /&gt;
Var user2check = 56599;&lt;br /&gt;
Var command As String = &amp;quot;RightsUserList&amp;quot;;&lt;br /&gt;
Var parameters As New CsortedStringObjectList();&lt;br /&gt;
Var val As CIntegerList = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
If (NOT val.Contains(user2check)) {&lt;br /&gt;
  command = &amp;quot;RightsUserCreate&amp;quot;;&lt;br /&gt;
  Parameters.Add(&amp;quot;UserID&amp;quot;, user2check);&lt;br /&gt;
  b = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
  If (NOT c) {&lt;br /&gt;
    WriteLine (&amp;quot;User Creation failed!&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    WriteLine(&amp;quot;New gate user ID: &amp;quot; &amp;amp; user2check;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This small function checks for a user, and creates them if they don't exist. The next question, at least in my mind, was “How do I know I have the right PG?” You have two options. One is CreatedItemExists, followed by a call to  a sub function with a known value or range of values (because a mistaken transponder ID would also exist), the other is just call the sub function. In the case of multiplexing functions, the normal behavior is to return an error condition on fail, not abort. At least InvokeItem for gates follows this protocol.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Function CheckPG(ship As CMyShip, pg As Integer) As Boolean {&lt;br /&gt;
  Var parameters As New CsortedStringObjectList();&lt;br /&gt;
  Var val As CIntegerList = ship.InvokeItem(pg, command, parameters);&lt;br /&gt;
  // Error condition is 0 entries in the list&lt;br /&gt;
  If (val.Count = 0) { &lt;br /&gt;
    Return False;&lt;br /&gt;
  }&lt;br /&gt;
  Return True;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, there you have it. It's fairly straightforward, with a little practice you can do the majority of your gate configuration via the scripting engine. For the documented passed parameters and return values, from your gate go to Administration-&amp;gt;Scripting. They are as of the time of this writing, deemed experimental and subject to change.&lt;br /&gt;
&lt;br /&gt;
--[[Player:Miltiades|Miltiades (En-1:56599)]] 07:21, 16 September 2011 (CEST)&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	<entry>
		<id>http://wiki.en.stne.net/index.php/Scripting:Main_page</id>
		<title>Scripting:Main page</title>
		<link rel="alternate" type="text/html" href="http://wiki.en.stne.net/index.php/Scripting:Main_page"/>
				<updated>2011-09-16T05:04:55Z</updated>
		
		<summary type="html">&lt;p&gt;Miltiades: /* Topics: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scripting]]&lt;br /&gt;
{{ScriptingMenu}}&lt;br /&gt;
{{CreateScriptingArticle}}&lt;br /&gt;
&lt;br /&gt;
This section of the Wiki is intended to document the scripting engine found in the game. Most scripting related pages in STNE can be found from the main menu trough Database -&amp;gt; Scripting.&lt;br /&gt;
&lt;br /&gt;
=== Topics: ===&lt;br /&gt;
* [[Scripting:Syntax|Syntax]]&lt;br /&gt;
* [[Scripting:Operators|Operators]]&lt;br /&gt;
* [[Scripting:Interfaces|Interfaces]]&lt;br /&gt;
&lt;br /&gt;
* [[Scripting:Basic course|Basic course]] (mostly translated)&lt;br /&gt;
* [[Scripting:Script_editor|The external script editor]]&lt;br /&gt;
* [[Scripting:InvokeItem|A tutorial on scripting the portal InvokeItem()]]&lt;/div&gt;</summary>
		<author><name>Miltiades</name></author>	</entry>

	</feed>