[Space Engineers/C#] In-Game Programming – Teil 1

Mit dieser Serie möchte ich gerne hin und wieder ein paar Dinge bezüglich der In-Game Programmierung in Space Engineers behandeln um Leuten die In-Game Programmierung, welche in C# erfolgen muss, nahe zu bringen. Zuerst einmal lautet die Frage warum überhaupt C#? Die Entwickler von Space Engineers entwickelten im Laufe der Zeit ihre eigene Engine, genannt VRAGE. Space Engineers und auch Medieval Engineers verwenden VRAGE 2.0, die älteren MinerWars Teile hingegen die VRAGE 1.0. Die VRAGE Engine wiederum basierte ursprünglich auf XNA, Microsoft Framework für Spieleentwicklung in C#. Marek Rosa, CEO und Founder der Keen Software House Firma, welche diese Spiele entwickeln kommentierte auf Facebook einen Eintrag zum Thema XNA:

Marek Rosa FireFox Bancroft: we abandoned XNA more than year ago. Now it’s DirectX only

C# ist eine Programmiersprache die generell nur auf dem Windows Betriebssystem läuft obwohl es das sogenannte Mono-Projekt gibt, welches C# ebenso auf Linux und Mac lauffähig macht, zumindest rudimentär. Die Unity Engine verwendet Mono um C# Skripts zu kompilieren. Aber das nur als kleinen Einstieg und background information, zurück zum eigentlichen Thema: Programmierung in Space Engineers.

In Space Engineers (von nun an abgekürzt durch SE) gibt es einen Block namens: Programmierbarer Block (orig.: Probammable Block). Hat man diesen Block auf einem kleinen- oder großen Schiff oder auf einer Station platziert kann man diesen mit K öffnen und dann den Code bearbeiten oder ausführen lassen. Ich schreibe den Code vorher aber ganz gerne in einem Editor, weil man dann die offizielle Dokumentation zur In-Game Programmierung geöffnet lassen und nachschauen kann. Danach ein einfaches Copy & Paste, wo dann im Spiel der Code überprüft und ggf. korrigiert werden kann. Hier der link zur offiziellen Dokumentation, zur Zeit nur auf Englisch verfügbar:

Official Guide: Programmable Block

 Anmerken sollte ich noch, dass nicht alles aus C# auch automatisch in SE nutzbar ist. Zum Zeitpunkt wo ich diesen Artikel schreibe sind noch Probleme bekannt, welche auch im offiziellen Guide erwähnt werden. Unter anderem gibt es bei manchen Systemkonfigurationen, hauptsächlich 64-bit Systeme, Probleme bei foreach-Loops. for-Loops sind aber möglich und müssen stattdessen verwendet werden.

Jedes Programm benötigt einen Einstiegspunkt, einen Punkt der dem Programm bekannt sein muss. Und in dem C# Fall und ebenso auch in SE ist dies eine Methode namens Main. Unser komplett leeres Grundgerüst sieht also wie folgt aus:

void Main
{
	//Hier kommt später unser Code rein
}

Innerhalb der geschweiften Klammern müssen wir unseren Code, die Logik reinschreiben. // markiert die gesamte Zeile als Kommentar und wird vom Compiler nicht berücksichtigt. Zudem können Kommentare auch so aussehen:

void Main
{
	/*
	 * Hier kommt später unser Code rein
	 * Und dies ist ein mehrzeiliger
	 * Kommentar.
	*/
}

Der nächste wichtige Aspekt ist zu wissen wie wir Zugriff auf die Blöcke bekommen. Im übrigen ist es aktuell nur möglich Zugriff auf die Blöcke zu bekommen, welche auf demselben Grid sind wie der programmierbare Block. In einem früheren Blogeintrag von Marek Rosa (hier, Inspiration: hier), konnte ich ihn zu einigen Dingen inspirieren die hoffentlich, bald ins Spiel aufgenommen werden. Auf das Grid bekommen wir über GridTerminalSystem Zugriff. Dabei gibt es drei Möglichkeiten Blöcke zu bekommen.

  • GetBlocksOfType<T>: Bei dieser Methode können wir alle Blöcke eines bestimmten Typs abrufen. Die Typen sind unterschiedlich. Jeder Block hat seinen eigenen Typ (Antenne, Leuchtfeuer, Bohrer, etc.). Zudem haben alle Blöcke aber zwei gemeinsame Typen die vererbt werden. Diese sind IMyCubeBlock und IMyTerminalBlock.
  • SearchBlocksOfName: Bei dieser Methode können wir alle Blöcke die einen bestimmten Namen haben abrufen. Zum Beispiel nennen wir die Blöcke alle Light, dann würden wir all diese Blöcke bekommen. Komplet typenunabhängig.
  • GetBlockWithName: Wie SearchBlocksOfName, nur rufen wir bei dieser Methode nur einen einzigen Block und keine Liste von Blöcken ab.

Die Blöcke dir wir dann von der Methode erhalten müssen aber zwischengespeichert werden. Dieses machen wir mit Listen. Nun folgen drei Beispiele, jeweils ein Beispiel zu jeder Methode die oben beschrieben ist.

List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();

void Main() 
{ 
	GridTerminalSystem.GetBlocksOfType<IMyTerminalBlock>(blocks);
}
List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();

void Main() 
{ 
	GridTerminalSystem.SearchBlocksOfName("Lights", blocks);
}
IMyTerminalBlock block;

void Main() 
{ 
	GridTerminalSystem.GetBlockWithName("Light", block);
}

Im letzten Code-Beispiel verwende ich keine Liste, da wir ja nur einen Block abrufen. Zu erwähnen ist hier, dass wir aber lieber unsere Variablen “leeren”, bevor wir das GridTerminalSystem verwenden. Dies würden wir bei Listen wie folgt tun:

blocks.Clear();

In der kommenden Zeit werde ich des Öfteren Skripte posten und diese erklären und auch im Steam Workshop zur Verfügung stellen.

4 Comments

Add Yours →

Hi SmattyCore,

ich weiß der Beitrag ist Jahre alt, aber ich würde gern etwas in SE programmieren und habe keine Ahnung wie das geht.
Habe dir bei Steam ne Anfrage geschickt.
Vllt hast du Zeit und Lust mir das mal zu erklären.

Mfg, ..,-Era

Hey Smattycore 🙂
Ich habe deinen Artikel mit großem Interesse gelesen und habe vor meinen eigenen Script zu schreiben.
Ich wollte dich fragen ob man denn mittlerweile (da der Artikel wie oben schon genannt bereits veraltet ist) mit dem programmierbaren Block auf andere Grids auf denen sich ebenfalls programmierbare Blöcke, Antennen und Zeitschaltuhren befinden zugreifen kann.

Ich habe vor eine Art autopilot für Drohnen zu schreiben welchen man von einer Basis aus starten und wieder beenden kann ohne immer zu den Drohnen laufen zu müssen, damit man gegebenenfalls mehrere Drohnen gleichzeitig aktivieren und reaktivieren kann.

Habe eine idee für ein ausgeklügeltes Drohnen-Verteidigungssystem, die Blaupausen für Drohnen, Station und Serverraum sind schon fertig, ich muss nurnoch den Script schreiben 😅

Ps.: unter angegebenem Namen bin ich auch auf Steam zu finden, solltest du mich persönlich kontaktieren wollen.

Liebe Grüße

Schreibe einen Kommentar