English version below | Workshop Demo | Releases
- Was ist EmpyrionScripting?
- π Quickstart: Dein erstes Script in 5 Minuten
- Installation
- Grundkonzepte
- Sprache & Zeitzone
- Inventar & Container
- Items filtern & suchen
- Bedingungen & Logik
- Anzeige-Features
- Berechnungen
- Automatisierung: Verschieben & BefΓΌllen
- Lichter steuern
- GerΓ€te steuern
- Signale
- Teleporter-Steuerung
- Chat & Teleport
- Dialoge
- JSON & Datenstrukturen
- Fliegen
- Datenbankzugriff
- Externe Daten (AddOn DLLs)
- SaveGame-Scripte
- Elevated Scripte
- Script-Priorisierung
- C# Scripting Interface
- Konfiguration & Performance
- Vordefinierte ID-Listen
- Erz- und Barren-IDs
EmpyrionScripting ist eine Mod fΓΌr Empyrion: Galactic Survival, die es ermΓΆglicht, Echtzeit-Spielinformationen dynamisch auf LCD-Bildschirmen in Schiffen und Basen anzuzeigen. Das System nutzt die Handlebars-Template-Sprache.
Was ist mΓΆglich?
- π¦ Inventar aller Container live anzeigen
β οΈ Warnungen anzeigen wenn Ressourcen ausgehen- π‘ Lichter automatisch ein-/ausschalten
- π Items zwischen Containern automatisch verschieben
- β½ Treibstoff- und O2-Tanks automatisch befΓΌllen
- π‘ Signale auslΓΆsen und ΓΌberwachen
- π¬ Chat-Nachrichten senden
- π€ Autonomes Fliegen (ohne Pilot)
- Und vieles mehrβ¦
Tutorials & Videos:
| Link | Beschreibung |
|---|---|
| YouTube (Olly) | EinfΓΌhrungsvideo |
| YouTube | Tutorial 2 |
| YouTube | Tutorial 3 |
| YouTube (A11) | Γnderungen in A11 |
| YouTube | Tutorial 5 |
| YouTube | Tutorial 6 |
| YouTube | Tutorial 7 |
| Workshop Sephrajin | DSEV LCD Script Tutorial |
| Workshop Noob | Scripting Tutorial Ship |
| Workshop ASTIC | Vega AI Beispielschiff |
| Beginners Guide | Einsteiger-Anleitung (englisch) |
- EmpyrionScripting.zip herunterladen
- ZIP in das Verzeichnis
[Empyrion]\Content\Mods\entpacken - Wichtig fΓΌr Singleplayer: Das Spiel ohne EAC starten (im Steam-Launcher βStart without EAC" wΓ€hlen)
β οΈ Custom Scenario (z.B. ReforgedEden): Bei Verwendung eines benutzerdefinierten Szenarios muss in der Konfigurationsdatei[SaveGame]\Mods\EmpyrionScripting\Configuration.jsonder Pfad zum Szenario angegeben werden:
"OverrideScenarioPath": "[Steam]\\steamapps\\workshop\\content\\383120\\3143225812"
Du benΓΆtigst mindestens 2 LCD-Bildschirme auf deinem Schiff oder deiner Basis:
| LCD | Name im Control Panel | Zweck |
|---|---|---|
| Script-LCD (Eingabe) | Muss mit Script: beginnen, z.B. Script:MeinScript |
EnthΓ€lt den Script-Code |
| Ausgabe-LCD (Anzeige) | Beliebiger eindeutiger Name, z.B. LCD Inventar |
Zeigt das Ergebnis an |
π‘ Tipp: Das Script-LCD kann unsichtbar gemacht werden (Schriftfarbe auf transparent setzen). Es muss nicht sichtbar sein.
Γffne das Script-LCD (Rechtsklick β Manage β Text) und gib ein:
Targets:LCD Inventar
=== Mein Inventar ===
{{#items E.S 'Mein Container'}}
{{Count}}x {{i18n Key}}
{{/items}}
| Element | Bedeutung |
|---|---|
Targets:LCD Inventar |
Ergebnis wird auf dem LCD βLCD Inventar" angezeigt |
{{#items E.S 'Mein Container'}} |
Liest Inhalt des Containers βMein Container" |
{{Count}}x {{i18n Key}} |
Gibt Anzahl und lokalisierten Item-Namen aus |
{{/items}} |
Ende des Blocks |
Klicke auf den Container im Control Panel und gib ihm den exakten Namen Mein Container.
Das Ausgabe-LCD βLCD Inventar" zeigt nun automatisch den Inhalt des Containers und aktualisiert sich periodisch.
| Problem | LΓΆsung |
|---|---|
| LCD zeigt nichts | Script-LCD-Name muss mit Script: beginnen |
| Container nicht gefunden | Name muss exakt ΓΌbereinstimmen (GroΓ-/Kleinschreibung!) |
| Kein Update | Struktur braucht Strom und muss eingeschaltet sein |
| Alter Inhalt | Script-LCD muss eingeschaltet sein (oder PrioritΓ€t β₯ 1 verwenden) |
Vorbereitung:
- Container benennen:
Erzlager - Script-LCD benennen:
Script:ErzAnzeige - Ausgabe-LCD benennen:
LCD Erze
Script-Inhalt (ins Script-LCD):
Targets:LCD Erze
=== Erze im Lager ===
{{#items E.S 'Erzlager'}}
{{Count}}x {{i18n Key}}
{{/items}}
- EmpyrionScripting.zip herunterladen
- ZIP in das Verzeichnis
[Empyrion]\Content\Mods\entpacken
- EmpyrionScripting.zip herunterladen
- ZIP in das Verzeichnis
[Empyrion]\Content\Mods\entpacken - Spiel ohne EAC starten (Steam-Launcher)
β οΈ Custom Scenario (z.B. ReforgedEden): Bei Verwendung eines benutzerdefinierten Szenarios muss in der Konfigurationsdatei[SaveGame]\Mods\EmpyrionScripting\Configuration.jsonder Pfad zum Szenario angegeben werden:"OverrideScenarioPath": "[Steam]\\steamapps\\workshop\\content\\383120\\3143225812"
Das System trennt Logik (Script-LCD) und Anzeige (Ausgabe-LCD):
- Script-LCD: Name beginnt zwingend mit
Script:. EnthΓ€lt den Handlebars-Template-Code. - Ausgabe-LCD: Beliebiger Name. Wird in
Targets:referenziert.
Script-LCD Name: Script:TankStatus
Ausgabe-LCD Name: LCD Tanks
Die erste Zeile eines Scripts definiert die Ausgabe-LCDs:
Targets:LCD Ausgabe β Ein einzelnes LCD
Targets:LCD Eins;LCD Zwei β Mehrere LCDs (durch ; getrennt)
Targets:LCD Ausgabe* β Alle LCDs, deren Name mit "LCD Ausgabe" beginnt (Wildcard *)
Script:LCD Ausgabe* β Zielname wird direkt aus dem Script-LCD-Namen entnommen
π‘ Kurzform ohne
Targets:-Zeile: Wenn das Script-LCD selbst den NamenScript:TargetpatterntrΓ€gt, wird der Teil nachScript:automatisch als Zielpattern verwendet β eine separateTargets:-Zeile ist dann nicht nΓΆtig. Wildcards (*) werden dabei vollstΓ€ndig unterstΓΌtzt, sodass z.B. ein Script-LCD namensScript:Anzeige*alle LCDs adressiert, deren Name mitAnzeigebeginnt.
| Variable | Beschreibung |
|---|---|
E.S |
Die aktuelle Struktur (Schiff/Basis), auf der das Script lΓ€uft |
E.S.Items |
Alle Items aller Container der aktuellen Struktur |
E.S.Pilot |
Der aktuelle Pilot der Struktur |
E.Faction |
Die Fraktion der Struktur |
P.Players |
Alle Spieler die gerade auf der Struktur aktiv sind |
@root |
Zugriff auf den Root-Kontext (z.B. @root.Ids.Ore) |
EmpyrionScripting nutzt Handlebars.Net:
| Syntax | Bedeutung |
|---|---|
{{Variable}} |
Gibt den Wert einer Variable aus |
{{#block}}...{{/block}} |
Block-Helper (Schleife oder Bedingung) |
{{#block}}...{{else}}...{{/block}} |
Block mit Alternativ-Zweig |
{{helper arg1 arg2}} |
Helper mit Parametern |
@root.Data.key |
Auf gespeicherte Daten zugreifen |
Erstelle ein LCD mit dem Namen CultureInfo und gib folgenden JSON-Inhalt ein:
{
"LanguageTag": "de-DE",
"i18nDefault": "Deutsch",
"UTCplusTimezone": 1
}| Parameter | Beschreibung | Beispiel |
|---|---|---|
LanguageTag |
Sprachcode nach LCID-Standard | "de-DE", "en-US" |
i18nDefault |
Standard-Sprache fΓΌr Item-Namen | "Deutsch", "English" |
UTCplusTimezone |
Zeitzone als UTC-Offset | 1 fΓΌr MEZ, 2 fΓΌr MESZ |
Fehler bei der Konfiguration werden in einem LCD namens
CultureInfoDebugangezeigt.
Zeigt Inhalt eines oder mehrerer Container an:
Targets:LCD Inventar
=== Container-Inhalt ===
{{#items E.S 'MeinContainer'}}
{{Count}}x {{i18n Key}}
{{/items}}
Mehrere Container oder Wildcards:
{{#items E.S 'Kiste1;Kiste2;KΓΌhlschrank*'}}
{{Count}}x {{i18n Key}}
{{/items}}
Targets:LCD Alle Items
Alle Items auf dem Schiff:
{{#each E.S.Items}}
- {{Count}}x {{i18n Key}} (ID: {{Id}})
{{/each}}
Gibt eine Liste zurΓΌck, die mit anderen Befehlen weiterverarbeitet werden kann:
{{#getitems E.S 'Lager1;Lager2'}}
{{Count}}x {{i18n Key}}
{{/getitems}}
Zeigt nur Items mit bestimmten IDs an. Nicht vorhandene Items erscheinen mit Anzahl 0:
Targets:LCD Erze
Meine Erze:
{{#itemlist E.S.Items '4297,4298,4299'}}
{{Count}}x {{i18n Key}}
{{/itemlist}}
Mit vordefinierten Listen (empfohlen):
Targets:LCD Alle Erze
{{#itemlist E.S.Items @root.Ids.Ore}}
{{Count}}x {{i18n Key}}
{{/itemlist}}
Listen kombinieren mit concat:
{{#itemlist E.S.Items (concat @root.Ids.WeaponSV @root.Ids.WeaponHV)}}
{{Count}}x {{i18n Key}}
{{/itemlist}}
Targets:LCD Inventar sortiert
{{#orderedeach E.S.Items '-Count'}}
{{Count}}x {{i18n Key}}
{{/orderedeach}}
-Count= absteigend,+Count= aufsteigend. Mehrere Felder:'-Count,+Key'
{{#orderbylist E.S.Items '4297;4298;4299'}}
{{Count}}x {{i18n Key}}
{{/orderbylist}}
itemlistarray verhΓ€lt sich wie itemlist, ΓΌbergibt aber das gefilterte Ergebnis als Array an den inneren Block β damit kΓΆnnen weitere Verarbeitungen (z.B. mit orderedeach) darauf angewendet werden:
{{#itemlistarray E.S.Items '4297;4298;4299'}}
{{#orderedeach this '-Count'}}
{{Count}}x {{i18n Key}}
{{/orderedeach}}
{{/itemlistarray}}
Unterschied zu
itemlist:itemlistiteriert direkt ΓΌber Items (Element fΓΌr Element),itemlistarrayliefert das gesamte Array auf einmal fΓΌr weitere Verarbeitung.
Wandelt eine Semikolon- oder Komma-getrennte Liste von Item-Namen in ihre numerischen IDs um:
{{maptoid 'IronOre;CopperOre;GoldOre'}}
Ausgabe: 4297;4298;4299
Kombination mit itemlist:
Targets:LCD Meine Items
{{#itemlist E.S.Items (maptoid 'IronOre;CopperOre')}}
{{Count}}x {{i18n Key}}
{{/itemlist}}
maptoidnutzt das gleiche Name-zu-ID-Mapping wie die vordefinierten Listen (@root.Ids.*). Nicht gefundene Namen werden still ignoriert.
{{#test Count geq 100}}
Mehr als 100 vorhanden!
{{else}}
Weniger als 100 vorhanden.
{{/test}}
| Operator | Bedeutung | Beispiel |
|---|---|---|
eq oder = |
Gleich | {{#test Name eq 'IronOre'}} |
neq oder != |
Ungleich | {{#test Count neq 0}} |
leq oder <= |
Kleiner oder gleich | {{#test Count leq 1000}} |
le oder < |
Kleiner | {{#test Count le 100}} |
geq oder >= |
GrΓΆΓer oder gleich | {{#test Count geq 500}} |
ge oder > |
GrΓΆΓer | {{#test TankFuel ge 50}} |
in |
In einer Liste | {{#test Id in '4297,4298'}} |
BereichsprΓΌfung mit in:
{{#test Id in '4296-4302'}}
Erz-ID zwischen 4296 und 4302
{{/test}}
Erze die weniger als 500 StΓΌck vorhanden sind:
Targets:LCD Warnung
Niedrige BestΓ€nde:
{{#itemlist E.S.Items @root.Ids.Ore}}
{{#test Count le 500}}
β οΈ {{Count}}x {{i18n Key}}
{{/test}}
{{/itemlist}}
Leere Erze anzeigen:
{{#itemlist E.S.Items @root.Ids.Ore}}
{{#test Count leq 0}}
β {{i18n Key}} β LEER!
{{/test}}
{{/itemlist}}
{{#if E.S.Pilot.Id}}
Pilot: {{E.S.Pilot.Name}}
{{else}}
Kein Pilot an Bord
{{/if}}
{{#if (not E.S.Pilot.Id)}}
Kein Pilot an Bord
{{/if}}
{{#regex Name 'Iron.*'}}
Gefunden: {{.}}
{{/regex}}
Targets:LCD Zeit
Aktuelle Zeit:
{{datetime}} β Datum und Uhrzeit (Standard)
{{datetime 'HH:mm'}} β Nur Uhrzeit (z.B. 14:30)
{{datetime 'dd.MM.yyyy'}} β Nur Datum (z.B. 24.12.2024)
{{datetime 'dd MMM HH:mm:ss'}} β Kombiniert (z.B. 24 Dez 14:30:00)
{{datetime 'HH:mm' '+2'}} β Mit +2 Stunden Offset
DateTime Format-Strings Dokumentation
Wenn zu viele Items gleichzeitig auf einem LCD nicht passen:
Targets:LCD Inventar
{{#scroll 8 3}}
{{#items E.S 'Grosses Lager'}}
{{Count}}x {{i18n Key}}
{{/items}}
{{/scroll}}
Parameter: {{#scroll AnzahlZeilen VerzΓΆgerungSekunden [SchrittweiteZeilen]}}
{{#scroll 5 2 2}} β 5 sichtbare Zeilen, 2 Sekunden Pause, 2 Zeilen pro Schritt
Wechselt zwischen Inhalten in einem Zeitintervall (in Sekunden):
Targets:LCD Status
{{#intervall 5}}
Inhalt A (5 Sekunden)
{{else}}
Inhalt B (5 Sekunden)
{{/intervall}}
Zwei Container abwechselnd anzeigen:
Targets:LCD KΓΌhlschrΓ€nke
{{#intervall 3}}
KΓΌhlschrank 1:
{{#items E.S 'KΓΌhlschrank 1'}}
{{Count}}x {{i18n Key}}
{{/items}}
{{else}}
KΓΌhlschrank 2:
{{#items E.S 'KΓΌhlschrank 2'}}
{{Count}}x {{i18n Key}}
{{/items}}
{{/intervall}}
{{color 'ff0000'}} β Rot
{{color '00ff00'}} β GrΓΌn
{{color '0000ff'}} β Blau
{{color 'ffffff'}} β WeiΓ
{{color 'ffff00'}} β Gelb
{{bgcolor '000000'}} β Schwarz
{{bgcolor '1a1a1a'}} β Dunkelgrau
{{fontsize 8}} β Klein
{{fontsize 15}} β Mittel (Standard)
{{fontsize 25}} β GroΓ
{{bar TankFuel 0 1000 20}} β Einfacher Balken (20 Zeichen breit)
{{bar TankFuel 0 1000 20 'β' 'β'}} β Mit eigenen FΓΌll-/Hintergrundzeichen
{{bar Count 0 500 15 '|' '-' 'r'}} β RechtsbΓΌndig ('r')
Targets:LCD Alarm
{{#test TankFuel le 20}}
{{#intervall 1}}
{{color 'ff0000'}}β οΈ TREIBSTOFF KRITISCH!
{{else}}
{{color 'ffff00'}}β οΈ TREIBSTOFF KRITISCH!
{{/intervall}}
{{else}}
{{color '00ff00'}}β Treibstoff OK
{{/test}}
{{#steps 0 100 10 2}}
Fortschritt: {{this}}%
{{/steps}}
{{#random 1 6}}
WΓΌrfelergebnis: {{this}}
{{/random}}
math gibt das Ergebnis direkt aus. calc kann inline in anderen AusdrΓΌcken verwendet werden:
{{math Count * 5}} β Ausgabe: Ergebnis
{{math TankFuel / TankFuelMax 2}} β Division, 2 Nachkommastellen
{{bar (calc TankFuel / TankMax * 100) 0 100 20}} β calc inline
| Operator | Bedeutung |
|---|---|
+ |
Addition |
- |
Subtraktion |
* |
Multiplikation |
/ |
Division |
% |
Modulo |
{{min A B}} β Kleinerer Wert der beiden
{{max A B}} β GrΓΆΓerer Wert der beiden
{{abs Value}} β Absoluter Wert
{{int Value}} β Ganzzahliger Anteil (Abrunden)
{{distance PosA PosB}} β Distanz zwischen zwei Vektoren
{{distance PosA PosB '0.0'}} β Mit Formatstring (eine Nachkommastelle)
{{#use (vector 100 200 300)}}
Mein Vektor: {{X}} / {{Y}} / {{Z}}
{{/use}}
Spielzeit: {{gameticks}} Ticks
= {{math gameticks / 20 0}} Sekunden
= {{math gameticks / 1200 1}} Minuten
Verschiebt Items von einem Container in einen anderen (innerhalb oder zwischen Strukturen):
{{move Item @root.E.S 'Ziellager'}}
{{move Item @root.E.S 'Ziellager' 500}} β Maximal 500 im Zielcontainer lassen
FΓΌllt Treibstoff-, O2- oder Pentaxid-Tanks auf:
{{fill Item @root.E.S 'FuelTank'}} β Auf 100% auffΓΌllen
{{fill Item @root.E.S 'FuelTank' 80}} β Maximal auf 80% auffΓΌllen
Praxisbeispiel: Automatische Treibstoff-AuffΓΌllung
Targets:LCD Tankstatus
=== Tankstatus ===
{{#items E.S 'Versorgungscontainer'}}
{{#test Key eq 'EnergyCell'}}
{{fill this @root.E.S 'Haupttank'}}
Treibstoff wird nachgefΓΌlltβ¦
{{/test}}
{{/items}}
Baut eine Struktur ab und befΓΆrdert die Teile in einen Container:
{{deconstruct Entity 'Schrottlager'}}
β οΈ Der Kern der Struktur mussCore-Destruct-[ID]heiΓen (ID = Entity-ID der Struktur).
Kosten: Standard 100 Geldkarten pro 10 BlΓΆcke (DeconstructSalaryin Configuration.json).
Wie deconstruct, gibt aber Rohstoffe laut Rezepten zurΓΌck:
{{recycle Entity 'Recyclinglager'}}
β οΈ Kern mussCore-Recycle-[ID]heiΓen. Kosten: Standard 200 Geldkarten pro 10 BlΓΆcke.
LΓΆscht unwiderruflich alle Items in einem Container:
{{trashcontainer E.S 'MΓΌll'}}
β οΈ Keine Wildcards erlaubt. Exakter Container-Name erforderlich!
{{harvest E.S Device gx gy gz}}
{{harvest E.S Device gx gy gz true}} β true = tote Pflanzen ebenfalls entfernen
BenΓΆtigt einen GΓ€rtner-NPC (Crew) und Geld im KΓΌhlschrank als Bezahlung.
{{pickupplants E.S Device gx gy gz}} β Pflanzen aufnehmen
{{replantplants E.S Target}} β Wieder einpflanzen (nur ohne Playfield-Wechsel!)
{{#lights E.S 'AlarmLicht*'}}
{{lightcolor this 'ff0000'}}
{{/lights}}
| Befehl | Beschreibung |
|---|---|
{{lightcolor light 'ff0000'}} |
Farbe setzen (RGB Hex) |
{{lightblink light 1 0.5 0}} |
Blinken: Intervall(s), LΓ€nge(s), Offset(s) |
{{lightintensity light 1.5}} |
Helligkeit setzen |
{{lightrange light 10}} |
Reichweite setzen |
{{lightspotangle light 45}} |
Spotwinkel setzen |
{{lighttype light 'Spot'}} |
Typ: Spot, Directional, Point, Area, Rectangle, Disc |
Targets:LCD LichtStatus
{{#test TankFuel le 100}}
{{#lights E.S 'AlarmLicht*'}}
{{lightcolor this 'ff0000'}}
{{lightblink this 1 0.5 0}}
{{/lights}}
β οΈ Treibstoff niedrig!
{{else}}
{{#lights E.S 'AlarmLicht*'}}
{{lightcolor this '00ff00'}}
{{lightblink this 0 0 0}}
{{/lights}}
β Alles OK
{{/test}}
{{#devices E.S 'Generator*'}}
{{setactive this true}}
{{/devices}}
{{#devicesoftype E.S 'Generator'}}
{{setactive this false}}
{{/devicesoftype}}
{{setactive Device true}} β Einschalten
{{setactive Device false}} β Ausschalten
{{#islocked E.S 'MeinContainer'}}
Container ist gesperrt
{{else}}
Container ist frei
{{/islocked}}
{{#signals E.S 'Signal*'}}
Signal: {{Name}} β Status: {{State}}
{{/signals}}
Gibt alle Signale (ControlPanel + Block-Signale) zurΓΌck, die dem Namensmuster entsprechen. Jedes Signal hat die Eigenschaften Name, State, Index und BlockPos.
Signal Status: {{getsignal E.S 'MeinSignal'}}
Schalter: {{getswitch E.S 'MeinSchalter'}}
Alle passenden: {{getswitches E.S 'Schalter*'}}
{{setswitch E.S 'MeinSchalter' true}}
{{setswitch E.S 'MeinSchalter' false}}
{{#signalevents 'Signal1;Signal2'}}
Signal ausgelΓΆst von: {{Player.Name}} um {{Time}}
{{/signalevents}}
{{#triggerifsignalgoes 'TΓΌrsensor' true}}
TΓΌr wurde geΓΆffnet von {{Name}}!
{{/triggerifsignalgoes}}
Targets:LCD Rennzeit
{{#stopwatch 'RennStart' 'RennZiel' 'Reset'}}
Letzte Zeit: {{.}}
{{/stopwatch}}
Teleporter-GerΓ€te kΓΆnnen per Script ausgelesen und konfiguriert werden.
β οΈ Alleset*-Teleporter-Befehle sind nur in Elevated Scripts erlaubt!
{{#teleporters E.S 'Teleporter*'}}
Name: {{DeviceName}}
Ziel: {{Destination}}
Playfield: {{Playfield}}
{{/teleporters}}
Jedes Teleporter-Objekt hat folgende Eigenschaften aus ITeleporterData:
| Eigenschaft | Beschreibung |
|---|---|
DeviceName |
Name des Teleporter-GerΓ€ts |
Destination |
Zielname |
Target |
Ziel-Entity-Name |
Playfield |
Ziel-Playfield |
SolarSystemName |
Ziel-Sonnensystem |
Origin |
Herkunfts-Byte |
{{setteleporter E.S 'Teleporter1' 'ZielName'}}
{{setteleporterdevicename E.S 'Teleporter1' 'NeuerGerΓ€teName'}}
{{setteleportertarget E.S 'Teleporter1' 'ZielEntity'}}
{{setteleporterplayfield E.S 'Teleporter1' 'Akua'}}
{{setteleporterorigin E.S 'Teleporter1' 3}}
| Befehl | Argumente | Beschreibung |
|---|---|---|
setteleporter |
structure name destination | Teleporter-Ziel setzen |
setteleporterdevicename |
structure name devicename | GerΓ€tename Γ€ndern |
setteleportertarget |
structure name target | Ziel-Entity setzen |
setteleporterplayfield |
structure name playfield | Ziel-Playfield setzen |
setteleporterorigin |
structure name origin | Origin-Byte setzen |
{{chat 'Server' 'Dein Treibstoff ist fast leer!'}}
{{#chatbysignal 'EintrittsSensor' 'Basis'}}
Willkommen auf unserer Basis, {{Name}}!
{{/chatbysignal}}
{{chatglobal 'Servermeldung' 'Wartung in 10 Minuten!'}}
{{chatserver 'System' 'Server lΓ€uft normal'}}
{{chatplayer PlayerId 'System' 'Private Nachricht'}}
{{chatfaction FactionId 'System' 'Fraktionsmeldung'}}
{{teleportplayer Player 'TeleportPad'}} β Zu einem Device auf der Struktur
x y zWeltkoordinaten sind nur in Elevated Scripts erlaubt.
{{#dialog Player 'Titel' 'Nachricht'}}
OK|Abbrechen
{{/dialog}}
{{#dialogbox 'TΓΌrSignal'}}
Bitte wΓ€hlen:
MΓΆchtest du eintreten?
Ja|Nein|Abbrechen
{{/dialogbox}}
Die erste Zeile des {{else}}-Blocks = Titel, letzte Zeile = SchaltflΓ€chen, Zeilen dazwischen = Text.
{{#use (fromjson '{"name":"Test","value":42}')}}
Name: {{name}}, Wert: {{value}}
{{/use}}
{{tojson SomeObject}} β Objekt als JSON-String ausgeben
{{jsontodictionary jsonStr}} β JSON in Dictionary umwandeln
{{set 'meinKey' SomeData}} β TemporΓ€r (aktueller Script-Durchlauf)
{{#use @root.Data.meinKey}}...{{/use}} β Abrufen
{{setcache 'meinKey' SomeData}} β Persistiert zwischen Aufrufen
{{#use @root.CacheData.meinKey}}... β Abrufen
Block-Inhalt als Datenwert speichern:
{{#setblock 'meinKey'}}
Berechneter Inhalt: {{math TankFuel / TankFuelMax * 100 1}}%
{{/setblock}}
{{#use @root.Data.meinKey}}...{{/use}}
{{#setcacheblock 'meinKey'}}
{{i18n Key}}
{{/setcacheblock}}
{{#use @root.CacheData.meinKey}}...{{/use}}
setblock und setcacheblock sind wie set/setcache, speichern aber den gerenderten Inhalt des inneren Blocks statt eines ΓΌbergbenen Werts.
{{#use (createarray)}}
{{set this 'Wert1'}}
{{set this 'Wert2'}}
Erster Wert: {{lookup this 0}}
{{/use}}
{{#use (createdictionary)}}
{{set this 'schlΓΌssel' 'wert'}}
{{/use}}
{{concatarrays Array1 Array2}} β Arrays kombinieren
{{loop Array}}...{{/loop}} β Γber Array/Dictionary iterieren
lookupblock ist wie lookup, ΓΌbergibt aber den Eintrag als Objekt in einen Template-Block:
{{#use (createarray)}}
{{set this 'Alpha'}}
{{set this 'Beta'}}
{{#lookupblock this 0}}
Erster Eintrag: {{.}}
{{/lookupblock}}
{{/use}}
β οΈ Funktioniert nur, wenn kein Pilot das Schiff steuert und die Triebwerke eingeschaltet sind.
{{moveto 1000 200 -500}} β Zur Weltposition (X Y Z) fliegen
{{moveforward 10}} β Mit Geschwindigkeit 10 vorwΓ€rts fliegen
{{movestop}} β Stoppen
Zugriff auf die global.db SQLite-Datenbank des Savegames:
{{#db 'Entities' 5 '+name'}}
{{name}} ({{entityid}})
{{/db}}
Syntax: {{#db QueryName [Top] [OrderBy] [AdditionalWhereAnd] [Parameter]}}
Vordefinierte Abfragen:
| Query | Inhalt |
|---|---|
Entities |
Eigene Strukturen |
DiscoveredPOIs |
Entdeckte POIs |
TerrainPlaceables |
Platzierte Terrain-Objekte |
TerrainPlaceablesRes |
Terrain-Objekte mit Ressourcen |
Playfields |
Bekannte Playfields |
PlayfieldResources |
Ressourcen auf Playfields |
PlayerData |
Spieler-Daten |
Bookmarks |
Lesezeichen |
Standard-Parameter in Queries:
| Parameter | Wert |
|---|---|
@PlayerId |
ID des Piloten |
@FactionId |
Fraktions-ID |
@FactionGroup |
Fraktionsgruppe (int) |
@EntityId |
Struktur-ID |
Zum Erkunden der global.db empfiehlt sich der SQLiteBrowser.
In der Konfigurationsdatei kΓΆnnen eigene SQL-Queries definiert werden. Beispiel:
SELECT * FROM Structures
JOIN Entities ON Structures.entityid = Entities.entityid
JOIN Playfields ON Entities.pfid = Playfields.pfid
JOIN SolarSystems ON SolarSystems.ssid = Playfields.ssid
WHERE (isremoved = 0 AND facid = @FactionId) {additionalWhereAnd}Externe Daten aus anderen Mods oder DLLs abrufen:
{{#external 'MaxWarp'}}
Maximale Sprungreichweite: {{.}}
{{/external}}
Die DLL muss das IMod-Interface mit einem ScriptExternalDataAccess-Property implementieren:
public class ExternalDataAccess : IMod
{
public IDictionary<string, Func<IEntity, object[], object>> ScriptExternalDataAccess { get; }
public ExternalDataAccess()
{
ScriptExternalDataAccess = new Dictionary<string, Func<IEntity, object[], object>>()
{
["Navigation"] = (entity, args) => entity?.Structure?.Pilot?.Id > 0 ? Navigation(entity) : null,
["MaxWarp" ] = (entity, args) => entity?.Structure?.Pilot?.Id > 0 ? (object)MaxWarp(entity) : null,
};
}
}DLL-Pfad in der Konfigurationsdatei registrieren (Basispfad = Mod-Verzeichnis im Savegame):
"AddOnAssemblies": [
"..\\EmpyrionGalaxyNavigator\\EmpyrionGalaxyNavigatorDataAccess.dll"
]Scripte kΓΆnnen direkt im SaveGame-Verzeichnis hinterlegt werden:
[SaveGame]\Mods\EmpyrionScripting\Scripts\
Dieser Pfad ist ΓΌber @root.MainScriptPath abrufbar.
Script-AuflΓΆsung nach PrioritΓ€t:
EntityId(z.B.12345.hbs)PlayfieldName\EntityName(z.B.Akua\MeinSchiff.hbs)PlayfieldName\EntityType(z.B.Akua\CV.hbs)EntityName(z.B.MeinSchiff.hbs)EntityType(z.B.BA.hbs)PlayfieldName(z.B.Akua.hbs)- Direkt im Verzeichnis
EntityType:
BA(Base),CV(Capital Vessel),SV(Small Vessel),HV(Hover Vessel)
{{#readfile @root.MainScriptPath 'config.txt'}}
Zeile 1: {{lookup this 0}}
{{else}}
Datei nicht gefunden
{{/readfile}}
{{#writefile @root.MainScriptPath 'ausgabe.txt'}}
Inhalt der Datei
{{/writefile}}
{{#fileexists @root.MainScriptPath 'config.txt'}}
Datei existiert!
{{/fileexists}}
{{#filelist @root.MainScriptPath '*.hbs' true}}
{{this}}
{{/filelist}}
Sendet eine Server-Chatnachricht direkt an einen einzelnen Spieler (nur SaveGame-Scripte):
{{#sendmessagetoplayer PlayerId}}
Hallo, dein Schiff ist in einer Gefahrenzone!
{{/sendmessagetoplayer}}
Der innere Block wird als Nachrichtentext gerendert. PlayerId ist die numerische Entity-ID des Spielers.
{{setdamage Block 100}} β Schaden eines Blocks auf 100 setzen
{{settype Block 4297}} β Block-Typ-ID Γ€ndern
Erweiterte Berechtigungen fΓΌr Scripte in SaveGame-Verzeichnissen oder auf Admin-Strukturen:
{{lockdevice E.S 'MeinContainer'}}
{{additems Container 4297 100}} β 100x IronOre hinzufΓΌgen
{{removeitems Container 4297 50}} β 50x IronOre entfernen
{{replaceblocks Entity '4297' 0}} β Block entfernen (0 = lΓΆschen)
{{settype Block TypeId}} β Block-Typ Γ€ndern (nur SaveGame)
{{setdamage Block 100}} β Schaden setzen (nur SaveGame)
Wenn viele Scripte auf einer Struktur laufen, kann die AusfΓΌhrungshΓ€ufigkeit gesteuert werden:
Script:MeinScript β Jeder Zyklus (nur wenn LCD eingeschaltet)
0Script:MeinScript β Wie oben
1Script:MeinScript β Jeder Zyklus (auch wenn LCD ausgeschaltet!)
3Script:MeinScript β Jeden 3. Zyklus
5Script:MeinScript β Jeden 5. Zyklus
AusfΓΌhrungsreihenfolge mit PrioritΓ€ten 1, 3, 4:
Zyklus 1: Script(1), Script(3), Script(4) β alle laufen
Zyklus 2: Script(1)
Zyklus 3: Script(1), Script(3)
Zyklus 4: Script(1), Script(4)
Zyklus 5: Script(1)
Zyklus 6: Script(1), Script(3)
...
| PrioritΓ€t | AusfΓΌhrung | LCD muss eingeschaltet sein |
|---|---|---|
| 0 oder keine | Jeden Zyklus | Ja |
| 1β9 | Jeden N-ten Zyklus | Nein |
Konfigurationsdatei: [SaveGame]\Mods\EmpyrionScripting\Configuration.json
| Einstellung | Standard | Beschreibung |
|---|---|---|
InGameScriptsIntervallMS |
1000 | ScriptausfΓΌhrungsintervall in Millisekunden |
SaveGameScriptsIntervallMS |
10000 | Intervall fΓΌr SaveGame-Scripte (ms) |
UseEveryNthGameUpdateCycle |
10 | Nur jeden N-ten GameUpdate-Aufruf verarbeiten |
ScriptsSyncExecution |
2 | Scripte pro Zyklus (synchron im Spielthread) |
ScriptsParallelExecution |
2 | Scripte pro Zyklus (parallel im Hintergrund) |
ScriptLoopSyncTimeLimiterMS |
200 | Maximale Laufzeit pro Zyklus fΓΌr synchrone Scripte (ms) |
ScriptLoopBackgroundTimeLimiterMS |
2000 | Maximale Laufzeit pro Zyklus fΓΌr Hintergrund-Scripte (ms) |
DeviceLockOnlyAllowedEveryXCycles |
10 | DeviceLock-Scripte nur alle X Zyklen ausfΓΌhren |
ProcessMaxBlocksPerCycle |
200 | Maximale BlΓΆcke pro Zyklus |
ExecMethod |
ThreadPool |
AusfΓΌhrungsmethode: None, ThreadPool, Direct, BackgroundWorker |
DelayStartForNSecondsOnPlayfieldLoad |
30 | VerzΓΆgerung beim Spielfeldladen in Sekunden |
π‘ Tipp: Die Standardwerte sind sehr konservativ. Werte verdoppeln (und
SaveGameScriptsIntervallMShalbieren) fΓΌr flΓΌssigere Script-AusfΓΌhrung β kann jedoch zu Micro-Rucklern fΓΌhren.
| Einstellung | Standard | Beschreibung |
|---|---|---|
LogLevel |
Message |
Log-Level: None, Message, Debug |
ScriptTracking |
false |
Script-AusfΓΌhrungszeiten tracken (Ausgabe in ScriptTrackingDebug-LCD) |
ScriptTrackingError |
false |
Fehler-Tracking fΓΌr Scripte aktivieren |
DetailedScriptsInfoData |
false |
Detaillierte Script-Infodaten erfassen |
| Einstellung | Standard | Beschreibung |
|---|---|---|
CsScriptsAllowedFor |
Player |
Wer C#-Scripte ausfΓΌhren darf: Player, Moderator, GameMaster, Admin |
EntityAccessMaxDistance |
500 | Maximale Entfernung (in BlΓΆcken) fΓΌr den Zugriff auf andere Strukturen |
| Einstellung | Standard | Beschreibung |
|---|---|---|
MaxStoredEventsPerSignal |
10 | Maximale Anzahl gespeicherter Events pro Signal |
| Einstellung | Standard | Beschreibung |
|---|---|---|
OverrideScenarioPath |
(leer) | Pfad zum Szenario-Verzeichnis (erforderlich fΓΌr Custom Scenarios im Singleplayer, z.B. ReforgedEden) |
AddOnAssemblies |
[] |
Liste von zusΓ€tzlichen DLL-Pfaden (relativ zum Mod-Verzeichnis im Savegame) |
| Einstellung | Standard | Beschreibung |
|---|---|---|
GardenerSalary |
10Γ MoneyCard |
Bezahlung pro Gardener-Aktion |
DeconstructSalary |
10Γ MoneyCard |
Bezahlung pro Dekonstruktions-Aktion |
RecycleSalary |
20Γ MoneyCard |
Bezahlung pro Recycling-Aktion |
AmountPerNumberOfBlocks |
10 | Anzahl der BlΓΆcke pro Gehaltseinheit |
DeconstructBlockSubstitutions |
(Liste) | BlΓΆcke, die beim Dekonstruieren durch 0 ersetzt werden (z.B. Alien-Container) |
| Einstellung | Standard | Beschreibung |
|---|---|---|
NumberSpaceReplace |
" " |
Zeichen als Leerzeichen-Ersatz in Zahlenausgaben |
BarStandardValueSign |
β |
Zeichen fΓΌr den gefΓΌllten Teil eines Balkens |
BarStandardSpaceSign |
β |
Zeichen fΓΌr den leeren Teil eines Balkens |
Definiert welche Items in Struktur-Tanks gefΓΌllt werden kΓΆnnen und in welchen Mengen:
"StructureTank": {
"Oxygen": [{ "ItemName": "OxygenBottleLarge", "Amount": 250, "EcfAmountTag": "O2Value" }],
"Fuel": [{ "ItemName": "FusionCell", "Amount": 300, "EcfAmountTag": "FuelValue" },
{ "ItemName": "EnergyCellLarge", "Amount": 150, "EcfAmountTag": "FuelValue" },
{ "ItemName": "EnergyCell", "Amount": 30, "EcfAmountTag": "FuelValue" }],
"Pentaxid": [{ "ItemName": "PentaxidCrystal", "Amount": 1 }]
}FΓΌr Treibstoff, O2 etc. kann die Menge automatisch aus der ECF-Konfiguration des Szenarios ermittelt werden:
{
"ItemName": "EnergyCellLarge",
"Amount": 250,
"EcfAmountTag": "FuelValue"
},
{
"ItemName": "OxygenBottleLarge",
"Amount": 250,
"EcfAmountTag": "O2Value"
}Automatische Ermittlung deaktivieren: "EcfAmountTag": ""
Diese Listen kΓΆnnen in Scripts ΓΌber @root.Ids.ListenName verwendet werden.
Konfigurationspfad: [SaveGame]\Mods\EmpyrionScripting\Configuration.json (Abschnitt "Ids")
Hinweis: Abschnitt
"Ids"aus der Configuration.json lΓΆschen, um Originalzustand wiederherzustellen.
Verwendung in Scripts:
{{#itemlist E.S.Items @root.Ids.Ore}}
{{Count}}x {{i18n Key}}
{{/itemlist}}
{{#itemlist E.S.Items (concat @root.Ids.WeaponSV @root.Ids.WeaponHV)}}
{{Count}}x {{i18n Key}}
{{/itemlist}}
| Liste | Inhalt |
|---|---|
Ore |
Alle Erze |
Ingot |
Alle Barren / Verarbeitete Erze |
Components |
Baukomponenten (Vanilla) |
EdenComponents |
Eden-Mod Komponenten |
Medic |
Medizinische Items |
Food |
Lebensmittel |
Ingredient |
Zutaten (alle) |
IngredientBasic |
Basis-Zutaten |
IngredientExtra |
Extra-Zutaten |
IngredientExtraMod |
ZusΓ€tzliche Mod-Zutaten |
Tools |
Werkzeuge |
Armor |
RΓΌstungen |
ArmorMod |
RΓΌstungsmodifikationen |
Sprout |
Setzlinge / Pflanzensamen |
BlockL |
GroΓe BlΓΆcke (CV/BA) |
BlockS |
Kleine BlΓΆcke (SV/HV) |
DeviceL |
GerΓ€te (CV/BA) |
DeviceS |
GerΓ€te (SV/HV) |
WeaponPlayer |
Spieler-Waffen |
WeaponHV |
HV-Waffen |
WeaponSV |
SV-Waffen |
WeaponCV |
CV-Waffen |
WeaponBA |
BA-Waffen |
WeaponPlayerUpgrades |
Waffen-Upgrades |
WeaponPlayerEpic |
Epic-Waffen |
AmmoPlayer |
Spieler-Munition |
AmmoHV |
HV-Munition |
AmmoSV |
SV-Munition |
AmmoCV |
CV-Munition |
AmmoBA |
BA-Munition |
AmmoAllEnergy |
Alle Energie-Munition |
AmmoAllProjectile |
Alle Projektil-Munition |
AmmoAllRocket |
Alle Raketen |
Deco |
Dekorations-BlΓΆcke |
DataPads |
Data Pads / Chips |
Oxygen |
Sauerstoffflaschen |
Fuel |
Treibstoffzellen |
Pentaxid |
Pentaxid-Kristalle |
OreFurnace |
Im Ofen schmelzbare Erze |
Deconstruct |
FΓΌr Dekonstruktion vorgesehene BlΓΆcke |
Gardeners |
GΓ€rtner-NPC |
FΓΌr das Deconstruct-Script zu lΓΆschende BlΓΆcke:
"RemoveBlocks" = ",ContainerUltraRare,AlienContainer,AlienContainerRare,..."
Die Listen beginnen und enden mit einem Komma, damit sie mit concat kombiniert werden kΓΆnnen:
(concat @root.Ids.WeaponHV @root.Ids.WeaponSV @root.Ids.WeaponCV)
(concat '1234,5568' @root.Ids.ArmorMod)
| ID | Interner Name | Deutsch |
|---|---|---|
| 4296 | MagnesiumOre | Magnesiumerz |
| 4297 | IronOre | Eisenerz |
| 4298 | CobaltOre | Kobalterz |
| 4299 | SiliconOre | Siliziumerz |
| 4300 | NeodymiumOre | Neodymiumerz |
| 4301 | CopperOre | Kupfererz |
| 4302 | PromethiumOre | Promethiumerz |
| 4317 | ErestrumOre | Erestrumerz |
| 4318 | ZascosiumOre | Zascosiumerz |
| 4332 | SathiumOre | Sathiumerz |
| 4341 | PentaxidOre | Pentaxiderz |
| 4345 | GoldOre | Golderz |
| 4359 | TitaniumOre | Titanerz |
| ID | Interner Name | Deutsch |
|---|---|---|
| 4319 | MagnesiumPowder | Magnesiumpulver |
| 4320 | IronIngot | Eisenbarren |
| 4321 | CobaltIngot | Kobaltbarren |
| 4322 | SiliconIngot | Siliziumbarren |
| 4323 | NeodymiumIngot | Neodymiumbarren |
| 4324 | CopperIngot | Kupferbarren |
| 4325 | PromethiumPellets | Promethium-Pellets |
| 4326 | ErestrumIngot | Erestrumbarren |
| 4327 | ZascosiumIngot | Zascosiumbarren |
| 4328 | CrushedStone | Zerkleinerter Stein |
| 4329 | RockDust | Steinstaub |
| 4333 | SathiumIngot | Sathiumbarren |
| 4342 | PentaxidCrystal | Pentaxid-Kristalle |
| 4346 | GoldIngot | Goldbarren |
| 4360 | TitaniumRods | TitanstΓ€be |
| Eigenschaft | Beschreibung |
|---|---|
Id |
Eindeutige ID (Token: TokenId * 100000 + ItemId) |
IsToken |
true wenn Token |
ItemId |
Token-unabhΓ€ngiger Teil der ID |
TokenId |
Token-ID (falls zutreffend) |
Count |
Anzahl |
Key |
Interner Item-Name |
Name |
Anzeigename |
| Funktion | Beschreibung |
|---|---|
{{concat a b c}} |
Werte zusammenfΓΌgen |
{{substring text 0 10}} |
Teilstring ab Index 0, max. 10 Zeichen |
{{replace text 'alt' 'neu'}} |
Text ersetzen |
{{split text ',' true}} |
Text aufteilen, leere EintrΓ€ge entfernen |
{{trim text}} |
Leerzeichen/Zeichen am Rand entfernen |
{{startswith text 'abc'}} |
Beginnt mit 'abc'? |
{{endsswith text 'xyz'}} |
Endet mit 'xyz'? (Hinweis: doppeltes 's' ist korrekt) |
{{chararray text}} |
Text als Zeichen-Array |
{{selectlines text 0 5}} |
Zeilen 0β5 aus Text |
{{format data '0.00'}} |
Formatierte Ausgabe |
{{i18n Key 'English'}} |
Item-Name in Sprache |
{{structtoglobalpos E.S (vector 10 0 5)}} β Strukturposition β Weltkoordinaten
{{globaltostructpos E.S GlobalPos}} β Weltkoordinaten β Strukturposition
{{#use (block E.S 10 0 5)}}
Block an Position 10/0/5: {{Type}}
{{/use}}
{{gettexture Block 'T'}} β Textur der Oberseite lesen (T=Top, B=Bottom, N/S/W/E)
{{settexture Block 123 'T,B'}} β Textur von Ober- und Unterseite setzen
{{getcolor Block 'T'}} β Farb-ID der Oberseite lesen
{{setcolor Block 5 'N,S'}} β Farbe von Nord- und SΓΌdseite setzen
{{setlockcode Block 1234}} β Sperr-Code eines Containers/GerΓ€ts setzen
{{#blocks E.S 0 0 0 10 10 10}} β Alle BlΓΆcke im Bereich (0,0,0) bis (10,10,10)
{{/blocks}}
{{#devices E.S 'AnzeigePanel'}}
{{settext this 'Hallo Welt!'}}
{{setcolor this 'ff0000'}}
{{setbgcolor this '000000'}}
{{setfontsize this 20}}
{{/devices}}
{{gettext LcdDevice}} β Text eines LCD lesen
{{settext LcdDevice 'Text'}} β Text setzen
{{settextblock LcdDevice}} β Text aus innenliegendem Block setzen
{{setcolor LcdDevice 'ff0000'}} β Textfarbe setzen (RGB Hex)
{{setbgcolor LcdDevice '000000'}} β Hintergrundfarbe setzen (RGB Hex)
{{setfontsize LcdDevice 20}} β SchriftgrΓΆΓe des LCD-GerΓ€ts direkt setzen
{{#toid 'IronOre;CobaltOre'}} β Namen β IDs
...
{{/toid}}
{{#toname '4297;4298'}} β IDs β Namen
...
{{/toname}}
{{configid 'IronOre'}} β Konfigurations-ID fΓΌr Item-Name
{{configattr 4297 'Mass'}} β Attribut fΓΌr Item-ID
{{configattrbyname 'IronOre' 'Mass'}} β Attribut fΓΌr Item-Name
{{resourcesforid 4297}} β Rezept-Ressourcen fΓΌr Item
Der Helper resourcesforid liefert die fΓΌr einen Block/Item benΓΆtigten Ressourcen (Rezept) als Key/Value-Collection (ID => Menge). Er nimmt eine einzelne ID als Argument und erlaubt, im Inneren des Blocks mit den gefundenen Ressourcen zu arbeiten. Beispiel:
Targets:LCD Rezepte
Rezept fΓΌr {{configattr 4297 'Name'}}:
{{#resourcesforid 4297}}
{{#each this}}
- {{this}}x {{configattr @key 'Name'}} (ID: {{@key}})
{{/each}}
{{else}}
Keine Rohstoffe gefunden.
{{/resourcesforid}}
Hinweise:
- Die Menge ist vom Typ Zahl (double) und kann Bruchteile enthalten (z.B. bei Komponenten, die pro Output anteilig berechnet werden).
- Innerhalb des Blocks ist der Context die Dictionary-Collection; deshalb wird mit
{{#each this}}ΓΌber die EintrΓ€ge iteriert und@key/thisverwendet.
Neben Handlebars-Templates kΓΆnnen Scripte auch in C# geschrieben werden. DafΓΌr muss die Dateiendung .cs statt .hbs verwendet werden.
| Dateiendung | Sprache | Beschreibung |
|---|---|---|
.hbs |
Handlebars-Template | Standard-Scripting |
.cs |
C# (Roslyn-kompiliert) | VollstΓ€ndige C#-Logik |
.dll |
Kompilierte Assembly | Vorkompilierte DLL |
π‘ Vorteil von C#-Scripten: Komplexe Logik, Schleifen, eigene Klassen, Typ-Sicherheit. Nachteil: BenΓΆtigt Grundkenntnisse in C#.
Ein C#-Script implementiert eine Run-Methode, die von der Mod aufgerufen wird:
using EmpyrionScripting.Interface;
public class MyScript
{
public static void Run(IScriptModData root)
{
var csRoot = root.CsRoot;
// Alle Items im Container lesen
var items = csRoot.Items(root.E.S, "MeinContainer");
// Ausgabe auf LCD
var output = new System.Text.StringBuilder();
foreach (var item in items)
output.AppendLine($"{item.Count}x {item.Name}");
// Auf allen LCD-Panels mit passendem Namen anzeigen
var displays = csRoot.Devices(root.E.S, "LCD*");
foreach (var lcd in csRoot.GetDevices<Eleon.Modding.ILcd>(displays))
lcd.SetText(output.ToString());
}
}Jedes C#-Script erhΓ€lt ein IScriptModData-Objekt als Einstiegspunkt:
| Eigenschaft | Typ | Beschreibung |
|---|---|---|
E |
IEntityData |
Die aktuelle EntitΓ€t (Schiff/Basis) |
P |
IPlayfieldData |
Das aktuelle Playfield |
CsRoot |
ICsScriptFunctions |
C#-Hilfsfunktionen (Γquivalent zu Handlebars-Helfern) |
Data |
ConcurrentDictionary<string,object> |
TemporΓ€rer Datenspeicher (wie {{set}}) |
CacheData |
ConcurrentDictionary<string,object> |
Persistenter Cache (wie {{setcache}}) |
Ids |
Dictionary<string,string> |
Vordefinierte ID-Listen |
GameTicks |
ulong |
Aktuelle Spielzeit in Ticks |
CycleCounter |
int |
Script-AusfΓΌhrungszΓ€hler |
IsElevatedScript |
bool |
Ob das Script Elevated-Rechte hat |
ConfigEcfAccess |
IConfigEcfAccess |
Zugriff auf ECF-Konfiguration |
GameOptionsYamlSettings |
IDictionary<string,object> |
Spieloptionen aus YAML |
DateTimeNow |
DateTime |
Aktuelle Datum/Uhrzeit |
Version |
string |
Mod-Version |
Console |
IConsoleMock |
Konsolenausgabe fΓΌr Debugging |
SignalEventStore |
IEventStore |
Signal-Event-Speicher |
| Eigenschaft | Beschreibung |
|---|---|
Id |
Entity-ID |
Name |
Name der EntitΓ€t |
EntityType |
Typ (BA, CV, SV, HV, β¦) |
Faction |
Fraktionsdaten |
Pos |
Position im Weltkoordinatensystem |
Forward |
VorwΓ€rtsvektor |
S |
IStructureData β Strukturdaten |
IsLocal / IsPoi / IsProxy |
EntitΓ€ts-Flags |
BelongsTo |
ID der ΓΌbergeordneten EntitΓ€t |
DockedTo |
ID der Dock-Zielstruktur |
ScriptInfos |
Informationen ΓΌber laufende Scripte |
IsElevated |
Ob Elevated-Rechte vorhanden |
Methoden: MoveForward(speed), MoveTo(direction), MoveStop(), GetCurrent(), GetCurrentPlayfield()
| Eigenschaft | Beschreibung |
|---|---|
AllCustomDeviceNames |
Alle benutzerdefinierten GerΓ€tenamen |
Items |
Alle Item-Stacks (alle Container) |
ControlPanelSignals |
Signale aus dem Control Panel |
BlockSignals |
Block-Signale |
Passengers |
Alle Passagiere |
Pilot |
Aktueller Pilot |
Players |
Alle Spieler auf der Struktur |
DockedE |
Angedockte EntitΓ€ten |
OxygenTank / FuelTank / PentaxidTank |
Tank-Wrapper |
DamageLevel |
Schadensgrad (0β1) |
IsPowerd |
Ist die Struktur mit Strom versorgt? |
IsReady |
Ist die Struktur bereit? |
IsShieldActive / ShieldLevel |
Schildstatus |
BlockCount / TriangleCount / LightCount |
Statistiken |
TotalMass |
Gesamtmasse |
HasLandClaimDevice |
Hat ein Land Claim Device? |
MinPos / MaxPos |
Begrenzungsquader |
SizeClass |
GrΓΆΓenklasse |
LastVisitedTicks |
Letzte Besucher-Zeit |
PlayerCreatedSteamId |
SteamID des Erstellers |
Methoden: GlobalToStructPos(pos), StructToGlobalPos(pos), GetCurrent()
| Eigenschaft | Beschreibung |
|---|---|
Id |
Spieler-ID |
Name |
Spielername |
Health / HealthMax |
Gesundheit |
Oxygen / OxygenMax |
Sauerstoff |
Stamina / StaminaMax |
Ausdauer |
Food / FoodMax |
Nahrung |
BodyTemp |
KΓΆrpertemperatur |
Radiation |
Strahlungslevel |
Credits |
Guthaben |
ExperiencePoints |
Erfahrungspunkte |
Kills / Died |
Statistiken |
FactionData / FactionRole |
Fraktionsdaten |
Origin |
Herkunfts-Byte |
Bag / Toolbar |
Inventar (ItemStack-Liste) |
IsPilot |
Ist gerade Pilot? |
DrivingEntity / CurrentStructure |
Aktuelle EntitΓ€t |
SteamId / SteamOwnerId |
Steam-IDs |
HomeBaseId |
Heimatbasis-ID |
Ping |
Ping in ms |
UpgradePoints |
Upgrade-Punkte |
Methoden: Teleport(pos), Teleport(playfieldName, pos, rot)
| Methode | Beschreibung |
|---|---|
Items(structure, names) |
Items aus Containern lesen |
Move(item, structure, names, maxLimit?) |
Items verschieben |
Fill(item, structure, type, maxLimit?) |
Tank befΓΌllen |
Devices(structure, names) |
GerΓ€te nach Namen suchen |
DevicesOfType(structure, type) |
GerΓ€te nach Typ suchen |
GetDevices<T>(block[]) |
GerΓ€te als typisiertes Interface |
GetBlockDevices<T>(structure, names) |
Block+GerΓ€t-Tupel liefern |
Block(structure, x, y, z) |
Einzelnen Block abrufen |
EntitiesById(ids) |
EntitΓ€ten nach IDs suchen |
EntitiesByName(names) |
EntitΓ€ten nach Namen suchen |
Scroll(content, lines, delay, step?) |
Scroll-Puffer berechnen |
Bar(data, min, max, length, barChar?, bgChar?) |
Fortschrittsbalken erzeugen |
Format(data, format) |
Wert formatieren |
I18n(id) / I18n(id, language) |
Item-Name ΓΌbersetzen |
ToId(names) |
Item-Namen β IDs |
ToName(ids) |
IDs β Item-Namen |
ConfigById(id) |
ECF-Block nach ID |
ConfigByName(name) |
ECF-Block nach Name |
ConfigFindAttribute(id, name) |
ECF-Attribut abrufen |
ResourcesForBlockById(id) |
Rezept-Ressourcen fΓΌr Item |
ShowDialog(playerId, config, handler, value) |
Dialog anzeigen |
WithLockedDevice(structure, block, action, lockFailed?) |
Mit gegesperrtem GerΓ€t arbeiten |
IsLocked(structure, block) |
GerΓ€t gesperrt? |
FunctionNeedsMainThread(error) |
Main-Thread prΓΌfen |
I18nDefaultLanguage |
Standard-Γbersetzungssprache |
SaveGame-Scripte (in [SaveGame]\Mods\EmpyrionScripting\Scripts\) verwenden IScriptSaveGameRootData (erweitert IScriptModData):
| Eigenschaft | Beschreibung |
|---|---|
MainScriptPath |
Pfad zum Script-Verzeichnis |
ModApi |
Zugriff auf die Mod-API |
ScriptPath |
Pfad des aktuellen Scripts |
using EmpyrionScripting.Interface;
public class MySaveGameScript
{
public static void Run(IScriptSaveGameRootData root)
{
// Spieler-Liste aus der Datenbank abrufen ist hier mΓΆglich
var modApi = root.ModApi;
// ... erweiterte Funktionen
}
}using EmpyrionScripting.Interface;
using System.Text;
public class FuelMonitor
{
public static void Run(IScriptModData root)
{
var csRoot = root.CsRoot;
var structure = root.E.S;
// Treibstoff-Items suchen
var items = csRoot.Items(structure, "Treibstoffcontainer");
var sb = new StringBuilder();
sb.AppendLine("=== Treibstoffstatus ===");
foreach (var item in items)
{
if (item.Key == "EnergyCell")
{
sb.AppendLine($"Treibstoff: {item.Count} Zellen");
// Warnung bei weniger als 100
if (item.Count < 100)
sb.AppendLine("β οΈ TREIBSTOFF KRITISCH!");
}
}
// Auf LCD ausgeben
var lcds = csRoot.GetDevices<Eleon.Modding.ILcd>(
csRoot.Devices(structure, "LCD Status"));
foreach (var lcd in lcds)
lcd.SetText(sb.ToString());
}
}Deutsche Version oben | Workshop Demo | Releases
- What is EmpyrionScripting?
- π Quickstart: Your first script in 5 minutes
- Installation
- Core Concepts
- Language & Timezone
- Inventory & Containers
- Filtering & Searching Items
- Conditions & Logic
- Display Features
- Math & Calculations
- Automation: Moving & Filling
- Controlling Lights
- Controlling Devices
- Signals
- Teleporter Control
- Chat & Teleport
- Dialogs
- JSON & Data Structures
- Flying
- Database Access
- External Data (AddOn DLLs)
- SaveGame Scripts
- Elevated Scripts
- Script Prioritization
- C# Scripting Interface
- Configuration & Performance
- Predefined ID Lists
- Ore and Ingot IDs
EmpyrionScripting is a mod for Empyrion: Galactic Survival that allows displaying real-time game information dynamically on LCD screens in ships and bases. It uses the Handlebars template language.
What is possible?
- π¦ Display live inventory of all containers
β οΈ Show warnings when resources run low- π‘ Automatically switch lights on/off
- π Automatically move items between containers
- β½ Automatically fill fuel and O2 tanks
- π‘ Trigger and monitor signals
- π¬ Send chat messages
- π€ Autonomous flight (no pilot required)
- And much moreβ¦
Tutorials & Videos:
| Link | Description |
|---|---|
| YouTube (Olly) | Introductory video |
| YouTube | Tutorial 2 |
| YouTube | Tutorial 3 |
| YouTube (A11 changes) | What's new in A11 |
| YouTube | Tutorial 5 |
| YouTube | Tutorial 6 |
| Workshop Sephrajin | DSEV LCD Script Tutorial |
| Workshop Noob | Scripting Tutorial Ship |
| Workshop ASTIC | Vega AI example ship |
| Beginners Guide | Beginners guide |
| Beginners Guide Video | Beginners guide video |
- Download EmpyrionScripting.zip
- Extract to
[Empyrion]\Content\Mods\ - Important for Singleplayer: Start the game without EAC (select "Start without EAC" in the Steam launcher)
β οΈ Custom Scenario (e.g. ReforgedEden): When using a custom scenario, you must set the scenario path in[SaveGame]\Mods\EmpyrionScripting\Configuration.json:
"OverrideScenarioPath": "[Steam]\\steamapps\\workshop\\content\\383120\\3143225812"
You need at least 2 LCD screens on your ship or base:
| LCD | Name in Control Panel | Purpose |
|---|---|---|
| Script LCD (Input) | Must start with Script:, e.g. Script:MyScript |
Contains the script code |
| Output LCD (Display) | Any unique name, e.g. LCD Inventory |
Shows the result |
π‘ Tip: The Script LCD can be made invisible (set font color to transparent). It doesn't need to be visible.
Open the Script LCD (right-click β Manage β Text) and enter:
Targets:LCD Inventory
=== My Inventory ===
{{#items E.S 'My Container'}}
{{Count}}x {{i18n Key}}
{{/items}}
| Element | Meaning |
|---|---|
Targets:LCD Inventory |
Result is displayed on the LCD named "LCD Inventory" |
{{#items E.S 'My Container'}} |
Reads the contents of the container "My Container" |
{{Count}}x {{i18n Key}} |
Outputs count and localized item name |
{{/items}} |
End of block |
Click on the container in the Control Panel and give it the exact name My Container.
The "LCD Inventory" output LCD will now automatically display the container contents and update periodically.
| Problem | Solution |
|---|---|
| LCD shows nothing | Script LCD name must start with Script: |
| Container not found | Name must match exactly (case-sensitive!) |
| No updates | Structure needs power and must be switched on |
| Stale content | Script LCD must be switched on (or use priority β₯ 1) |
Preparation:
- Name a container:
Ore Storage - Name a Script LCD:
Script:OreDisplay - Name an Output LCD:
LCD Ores
Script content (into the Script LCD):
Targets:LCD Ores
=== Ores in Storage ===
{{#items E.S 'Ore Storage'}}
{{Count}}x {{i18n Key}}
{{/items}}
- Download EmpyrionScripting.zip
- Extract to
[Empyrion]\Content\Mods\
- Download EmpyrionScripting.zip
- Extract to
[Empyrion]\Content\Mods\ - Start the game without EAC (Steam launcher)
β οΈ Custom Scenario (e.g. ReforgedEden): When using a custom scenario, you must set the scenario path in[SaveGame]\Mods\EmpyrionScripting\Configuration.json:"OverrideScenarioPath": "[Steam]\\steamapps\\workshop\\content\\383120\\3143225812"
The system separates logic (Script LCD) from display (Output LCD):
- Script LCD: Name must begin with
Script:. Contains the Handlebars template code. - Output LCD: Any unique name. Referenced in
Targets:.
Script LCD name: Script:TankStatus
Output LCD name: LCD Tanks
The first line of a script defines which LCDs receive the output:
Targets:LCD Output β A single LCD
Targets:LCD One;LCD Two β Multiple LCDs (separated by ;)
Targets:LCD Output* β All LCDs whose name starts with "LCD Output" (wildcard *)
Script:LCD Output* β Target name taken from the Script LCD name
π‘ Shorthand without a
Targets:line: If the Script LCD itself is namedScript:Targetpattern, the part afterScript:is automatically used as the target pattern β no separateTargets:line needed. Wildcards (*) are fully supported, so a Script LCD namedScript:Display*will address all LCDs whose name starts withDisplay.
| Variable | Description |
|---|---|
E.S |
The current structure (ship/base) the script runs on |
E.S.Items |
All items from all containers of the current structure |
E.S.Pilot |
The current pilot of the structure |
E.Faction |
The faction of the structure |
P.Players |
All players currently active on the structure |
@root |
Access to the root context (e.g. @root.Ids.Ore) |
EmpyrionScripting uses Handlebars.Net:
| Syntax | Meaning |
|---|---|
{{Variable}} |
Outputs a variable's value |
{{#block}}...{{/block}} |
Block helper (loop or condition) |
{{#block}}...{{else}}...{{/block}} |
Block with alternative branch |
{{helper arg1 arg2}} |
Helper with parameters |
@root.Data.key |
Access stored data |
Create an LCD named CultureInfo and enter the following JSON content:
{
"LanguageTag": "en-US",
"i18nDefault": "English",
"UTCplusTimezone": 0
}| Parameter | Description | Example |
|---|---|---|
LanguageTag |
Language code per LCID standard | "en-US", "de-DE" |
i18nDefault |
Default language for item names | "English", "Deutsch" |
UTCplusTimezone |
Timezone as UTC offset in hours | 0 for UTC, -5 for EST |
Errors in the configuration are displayed in an LCD named
CultureInfoDebug.
Targets:LCD Inventory
=== Container Contents ===
{{#items E.S 'MyContainer'}}
{{Count}}x {{i18n Key}}
{{/items}}
Multiple containers or wildcards:
{{#items E.S 'Box1;Box2;Fridge*'}}
{{Count}}x {{i18n Key}}
{{/items}}
Targets:LCD All Items
All items on the ship:
{{#each E.S.Items}}
- {{Count}}x {{i18n Key}} (ID: {{Id}})
{{/each}}
Returns a list that can be further processed by other commands:
{{#getitems E.S 'Storage1;Storage2'}}
{{Count}}x {{i18n Key}}
{{/getitems}}
Shows only items with specific IDs. Missing items appear with count 0:
Targets:LCD Ores
My Ores:
{{#itemlist E.S.Items '4297,4298,4299'}}
{{Count}}x {{i18n Key}}
{{/itemlist}}
With predefined lists (recommended):
Targets:LCD All Ores
{{#itemlist E.S.Items @root.Ids.Ore}}
{{Count}}x {{i18n Key}}
{{/itemlist}}
Combining lists with concat:
{{#itemlist E.S.Items (concat @root.Ids.WeaponSV @root.Ids.WeaponHV)}}
{{Count}}x {{i18n Key}}
{{/itemlist}}
Targets:LCD Sorted Inventory
{{#orderedeach E.S.Items '-Count'}}
{{Count}}x {{i18n Key}}
{{/orderedeach}}
-Count= descending,+Count= ascending. Multiple fields:'-Count,+Key'
{{#orderbylist E.S.Items '4297;4298;4299'}}
{{Count}}x {{i18n Key}}
{{/orderbylist}}
itemlistarray works like itemlist but passes the filtered result as an array to the inner block β allowing further processing (e.g. with orderedeach):
{{#itemlistarray E.S.Items '4297;4298;4299'}}
{{#orderedeach this '-Count'}}
{{Count}}x {{i18n Key}}
{{/orderedeach}}
{{/itemlistarray}}
Difference from
itemlist:itemlistiterates directly over items one-by-one,itemlistarraydelivers the whole array at once for further processing.
Converts a semicolon- or comma-separated list of item names into their numeric IDs:
{{maptoid 'IronOre;CopperOre;GoldOre'}}
Output: 4297;4298;4299
Combined with itemlist:
Targets:LCD My Items
{{#itemlist E.S.Items (maptoid 'IronOre;CopperOre')}}
{{Count}}x {{i18n Key}}
{{/itemlist}}
maptoiduses the same name-to-ID mapping as predefined lists (@root.Ids.*). Unknown names are silently ignored.
{{#test Count geq 100}}
More than 100 available!
{{else}}
Less than 100 available.
{{/test}}
| Operator | Meaning | Example |
|---|---|---|
eq or = |
Equal | {{#test Name eq 'IronOre'}} |
neq or != |
Not equal | {{#test Count neq 0}} |
leq or <= |
Less than or equal | {{#test Count leq 1000}} |
le or < |
Less than | {{#test Count le 100}} |
geq or >= |
Greater than or equal | {{#test Count geq 500}} |
ge or > |
Greater than | {{#test TankFuel ge 50}} |
in |
In a list | {{#test Id in '4297,4298'}} |
Range check with in:
{{#test Id in '4296-4302'}}
Ore ID is between 4296 and 4302
{{/test}}
Ores below 500 units:
Targets:LCD Warnings
Low stock:
{{#itemlist E.S.Items @root.Ids.Ore}}
{{#test Count le 500}}
β οΈ {{Count}}x {{i18n Key}}
{{/test}}
{{/itemlist}}
Show depleted ores:
{{#itemlist E.S.Items @root.Ids.Ore}}
{{#test Count leq 0}}
β {{i18n Key}} β EMPTY!
{{/test}}
{{/itemlist}}
{{#if E.S.Pilot.Id}}
Pilot: {{E.S.Pilot.Name}}
{{else}}
No pilot on board
{{/if}}
{{#if (not E.S.Pilot.Id)}}
No pilot on board
{{/if}}
{{#regex Name 'Iron.*'}}
Found: {{.}}
{{/regex}}
Targets:LCD Time
Current time:
{{datetime}} β Date and time (default)
{{datetime 'HH:mm'}} β Time only (e.g. 14:30)
{{datetime 'MM/dd/yyyy'}} β Date only (e.g. 12/24/2024)
{{datetime 'dd MMM HH:mm:ss'}} β Combined (e.g. 24 Dec 14:30:00)
{{datetime 'HH:mm' '+2'}} β With +2 hours offset
DateTime format strings documentation
When too many items don't fit on the LCD at once:
Targets:LCD Inventory
{{#scroll 8 3}}
{{#items E.S 'Large Storage'}}
{{Count}}x {{i18n Key}}
{{/items}}
{{/scroll}}
Parameters: {{#scroll Lines Delay [StepSize]}}
{{#scroll 5 2 2}} β 5 visible lines, 2 second pause, 2 lines per step
Alternates between content at a time interval (in seconds):
Targets:LCD Status
{{#intervall 5}}
Content A (shown for 5 seconds)
{{else}}
Content B (shown for 5 seconds)
{{/intervall}}
Alternating two containers:
Targets:LCD Fridges
{{#intervall 3}}
Fridge 1:
{{#items E.S 'Fridge 1'}}
{{Count}}x {{i18n Key}}
{{/items}}
{{else}}
Fridge 2:
{{#items E.S 'Fridge 2'}}
{{Count}}x {{i18n Key}}
{{/items}}
{{/intervall}}
{{color 'ff0000'}} β Red
{{color '00ff00'}} β Green
{{color '0000ff'}} β Blue
{{color 'ffffff'}} β White
{{color 'ffff00'}} β Yellow
{{bgcolor '000000'}} β Black
{{bgcolor '1a1a1a'}} β Dark gray
{{fontsize 8}} β Small
{{fontsize 15}} β Medium (default)
{{fontsize 25}} β Large
{{bar TankFuel 0 1000 20}} β Simple bar (20 chars wide)
{{bar TankFuel 0 1000 20 'β' 'β'}} β Custom fill/background chars
{{bar Count 0 500 15 '|' '-' 'r'}} β Right-aligned ('r')
Targets:LCD Alarm
{{#test TankFuel le 20}}
{{#intervall 1}}
{{color 'ff0000'}}β οΈ FUEL CRITICAL!
{{else}}
{{color 'ffff00'}}β οΈ FUEL CRITICAL!
{{/intervall}}
{{else}}
{{color '00ff00'}}β Fuel OK
{{/test}}
{{#steps 0 100 10 2}}
Progress: {{this}}%
{{/steps}}
{{#random 1 6}}
Dice roll: {{this}}
{{/random}}
math outputs the result directly. calc can be used inline in other expressions:
{{math Count * 5}} β Output: result
{{math TankFuel / TankFuelMax 2}} β Division, 2 decimal places
{{bar (calc TankFuel / TankMax * 100) 0 100 20}} β calc used inline
| Operator | Meaning |
|---|---|
+ |
Addition |
- |
Subtraction |
* |
Multiplication |
/ |
Division |
% |
Modulo |
{{min A B}} β Smaller of the two values
{{max A B}} β Larger of the two values
{{abs Value}} β Absolute value
{{int Value}} β Integer part (floor)
{{distance PosA PosB}} β Distance between two vectors
{{distance PosA PosB '0.0'}} β With format string (one decimal place)
{{#use (vector 100 200 300)}}
My vector: {{X}} / {{Y}} / {{Z}}
{{/use}}
Game time: {{gameticks}} ticks
= {{math gameticks / 20 0}} seconds
= {{math gameticks / 1200 1}} minutes
Moves items from one container to another (within or between structures):
{{move Item @root.E.S 'TargetStorage'}}
{{move Item @root.E.S 'TargetStorage' 500}} β Maximum 500 items in target container
Fills fuel, O2, or pentaxid tanks:
{{fill Item @root.E.S 'FuelTank'}} β Fill to 100%
{{fill Item @root.E.S 'FuelTank' 80}} β Fill to maximum 80%
Practical example: Automatic fuel refilling
Targets:LCD Tank Status
=== Tank Status ===
{{#items E.S 'Supply Container'}}
{{#test Key eq 'EnergyCell'}}
{{fill this @root.E.S 'Main Tank'}}
Filling fuelβ¦
{{/test}}
{{/items}}
Dismantles a structure and puts the parts in a container:
{{deconstruct Entity 'ScrapStorage'}}
β οΈ The core of the structure must be namedCore-Destruct-[ID](where ID is the entity ID of the structure).
Costs: default 100 credits per 10 blocks (DeconstructSalaryin Configuration.json).
Like deconstruct, but returns raw materials based on recipes:
{{recycle Entity 'RecycleStorage'}}
β οΈ Core must be namedCore-Recycle-[ID]. Costs: default 200 credits per 10 blocks.
Permanently deletes all items in a container:
{{trashcontainer E.S 'Trash'}}
β οΈ No wildcards allowed. Exact container name required!
{{harvest E.S Device gx gy gz}}
{{harvest E.S Device gx gy gz true}} β true = also remove dead plants
Requires a Gardener NPC (crew) and money in the fridge as payment.
{{pickupplants E.S Device gx gy gz}} β Pick up plants
{{replantplants E.S Target}} β Replant (only without playfield change!)
{{#lights E.S 'AlarmLight*'}}
{{lightcolor this 'ff0000'}}
{{/lights}}
| Command | Description |
|---|---|
{{lightcolor light 'ff0000'}} |
Set color (RGB hex) |
{{lightblink light 1 0.5 0}} |
Blink: interval(s), length(s), offset(s) |
{{lightintensity light 1.5}} |
Set brightness |
{{lightrange light 10}} |
Set range |
{{lightspotangle light 45}} |
Set spot angle |
{{lighttype light 'Spot'}} |
Type: Spot, Directional, Point, Area, Rectangle, Disc |
Targets:LCD Light Status
{{#test TankFuel le 100}}
{{#lights E.S 'AlarmLight*'}}
{{lightcolor this 'ff0000'}}
{{lightblink this 1 0.5 0}}
{{/lights}}
β οΈ Fuel low!
{{else}}
{{#lights E.S 'AlarmLight*'}}
{{lightcolor this '00ff00'}}
{{lightblink this 0 0 0}}
{{/lights}}
β All OK
{{/test}}
{{#devices E.S 'Generator*'}}
{{setactive this true}}
{{/devices}}
{{#devicesoftype E.S 'Generator'}}
{{setactive this false}}
{{/devicesoftype}}
{{setactive Device true}} β Turn on
{{setactive Device false}} β Turn off
{{#islocked E.S 'MyContainer'}}
Container is locked
{{else}}
Container is available
{{/islocked}}
{{#signals E.S 'Signal*'}}
Signal: {{Name}} β State: {{State}}
{{/signals}}
Returns all signals (ControlPanel + block signals) matching the name pattern. Each signal has properties Name, State, Index, and BlockPos.
Signal state: {{getsignal E.S 'MySignal'}}
Switch: {{getswitch E.S 'MySwitch'}}
All matching: {{getswitches E.S 'Switch*'}}
{{setswitch E.S 'MySwitch' true}}
{{setswitch E.S 'MySwitch' false}}
{{#signalevents 'Signal1;Signal2'}}
Signal triggered by: {{Player.Name}} at {{Time}}
{{/signalevents}}
{{#triggerifsignalgoes 'DoorSensor' true}}
Door was opened by {{Name}}!
{{/triggerifsignalgoes}}
Targets:LCD Race Time
{{#stopwatch 'RaceStart' 'RaceFinish' 'Reset'}}
Last time: {{.}}
{{/stopwatch}}
Teleporter devices can be read and configured via script.
β οΈ Allset*teleporter commands require Elevated Scripts!
{{#teleporters E.S 'Teleporter*'}}
Name: {{DeviceName}}
Destination: {{Destination}}
Playfield: {{Playfield}}
{{/teleporters}}
Each teleporter object exposes the following ITeleporterData properties:
| Property | Description |
|---|---|
DeviceName |
Device name of the teleporter |
Destination |
Destination name |
Target |
Target entity name |
Playfield |
Target playfield |
SolarSystemName |
Target solar system |
Origin |
Origin byte |
{{setteleporter E.S 'Teleporter1' 'TargetName'}}
{{setteleporterdevicename E.S 'Teleporter1' 'NewDeviceName'}}
{{setteleportertarget E.S 'Teleporter1' 'TargetEntity'}}
{{setteleporterplayfield E.S 'Teleporter1' 'Akua'}}
{{setteleporterorigin E.S 'Teleporter1' 3}}
| Command | Arguments | Description |
|---|---|---|
setteleporter |
structure name destination | Set teleporter destination |
setteleporterdevicename |
structure name devicename | Change device name |
setteleportertarget |
structure name target | Set target entity |
setteleporterplayfield |
structure name playfield | Set target playfield |
setteleporterorigin |
structure name origin | Set origin byte |
{{chat 'Server' 'Your fuel is almost empty!'}}
{{#chatbysignal 'EntrySensor' 'Base'}}
Welcome to our base, {{Name}}!
{{/chatbysignal}}
{{chatglobal 'ServerMsg' 'Maintenance in 10 minutes!'}}
{{chatserver 'System' 'Server is running normally'}}
{{chatplayer PlayerId 'System' 'Private message'}}
{{chatfaction FactionId 'System' 'Faction message'}}
{{teleportplayer Player 'TeleportPad'}} β To a device on the structure
x y zworld coordinates are only allowed in elevated scripts.
{{#dialog Player 'Title' 'Message'}}
OK|Cancel
{{/dialog}}
{{#dialogbox 'DoorSignal'}}
Please choose:
Do you want to enter?
Yes|No|Cancel
{{/dialogbox}}
First line of the {{else}} block = title, last line = buttons, lines in between = body.
{{#use (fromjson '{"name":"Test","value":42}')}}
Name: {{name}}, Value: {{value}}
{{/use}}
{{tojson SomeObject}} β Output object as JSON string
{{jsontodictionary jsonStr}} β Convert JSON to dictionary
{{set 'myKey' SomeData}} β Temporary (current script run)
{{#use @root.Data.myKey}}...{{/use}} β Retrieve
{{setcache 'myKey' SomeData}} β Persists between script runs
{{#use @root.CacheData.myKey}}... β Retrieve
Store rendered block content as data value:
{{#setblock 'myKey'}}
Calculated: {{math TankFuel / TankFuelMax * 100 1}}%
{{/setblock}}
{{#use @root.Data.myKey}}...{{/use}}
{{#setcacheblock 'myKey'}}
{{i18n Key}}
{{/setcacheblock}}
{{#use @root.CacheData.myKey}}...{{/use}}
setblock and setcacheblock are like set/setcache but store the rendered content of the inner block instead of a passed value.
{{#use (createarray)}}
{{set this 'Value1'}}
{{set this 'Value2'}}
First value: {{lookup this 0}}
{{/use}}
{{#use (createdictionary)}}
{{set this 'key' 'value'}}
{{/use}}
{{concatarrays Array1 Array2}} β Combine arrays
{{loop Array}}...{{/loop}} β Iterate over array/dictionary
lookupblock is like lookup but passes the entry as an object into a template block:
{{#use (createarray)}}
{{set this 'Alpha'}}
{{set this 'Beta'}}
{{#lookupblock this 0}}
First entry: {{.}}
{{/lookupblock}}
{{/use}}
β οΈ Only works when no pilot is controlling the ship and the engines are switched on.
{{moveto 1000 200 -500}} β Fly to world position (X Y Z)
{{moveforward 10}} β Fly forward at speed 10
{{movestop}} β Stop
Access the savegame's global.db SQLite database:
{{#db 'Entities' 5 '+name'}}
{{name}} ({{entityid}})
{{/db}}
Syntax: {{#db QueryName [Top] [OrderBy] [AdditionalWhereAnd] [Parameter]}}
Predefined queries:
| Query | Contents |
|---|---|
Entities |
Own structures |
DiscoveredPOIs |
Discovered POIs |
TerrainPlaceables |
Placed terrain objects |
TerrainPlaceablesRes |
Terrain objects with resources |
Playfields |
Known playfields |
PlayfieldResources |
Resources on playfields |
PlayerData |
Player data |
Bookmarks |
Bookmarks |
Default query parameters:
| Parameter | Value |
|---|---|
@PlayerId |
Pilot ID |
@FactionId |
Faction ID |
@FactionGroup |
Faction group (int) |
@EntityId |
Structure ID |
Use SQLiteBrowser to explore the global.db and add custom queries to the configuration.
Entities:
SELECT * FROM Structures
JOIN Entities ON Structures.entityid = Entities.entityid
JOIN Playfields ON Entities.pfid = Playfields.pfid
JOIN SolarSystems ON SolarSystems.ssid = Playfields.ssid
WHERE (isremoved = 0 AND (facgroup = 0 OR facgroup = 1) AND (facid = @PlayerId OR facid = @FactionId)) {additionalWhereAnd}PlayerData:
SELECT * FROM PlayerData
JOIN Entities ON Entities.entityid = PlayerData.entityid
JOIN Playfields ON Playfields.pfid = PlayerData.pfid
JOIN SolarSystems ON SolarSystems.ssid = Playfields.ssid
WHERE ((Entities.facgroup = 0 OR Entities.facgroup = 1 OR facgroup = 0 OR facgroup = 1)
AND (Entities.facid = @PlayerId OR facid = @PlayerId OR Entities.facid = @FactionId OR facid = @FactionId))
{additionalWhereAnd}Retrieve external data from other mods or DLLs:
{{#external 'MaxWarp'}}
Maximum jump range: {{.}}
{{/external}}
The DLL must implement the IMod interface with a ScriptExternalDataAccess property:
public class ExternalDataAccess : IMod
{
public IDictionary<string, Func<IEntity, object[], object>> ScriptExternalDataAccess { get; }
public ExternalDataAccess()
{
ScriptExternalDataAccess = new Dictionary<string, Func<IEntity, object[], object>>()
{
["Navigation"] = (entity, args) => entity?.Structure?.Pilot?.Id > 0 ? Navigation(entity) : null,
["MaxWarp" ] = (entity, args) => entity?.Structure?.Pilot?.Id > 0 ? (object)MaxWarp(entity) : null,
};
}
}Register the DLL path in the EmpyrionScripting configuration file (base path = mod directory in savegame):
"AddOnAssemblies": [
"..\\EmpyrionGalaxyNavigator\\EmpyrionGalaxyNavigatorDataAccess.dll"
]The DLL can be found in EmpyrionGalaxyNavigatorDataAccess.zip included in the ModLoader package, or downloaded from EmpyrionGalaxyNavigator releases.
Scripts can also be stored directly in the SaveGame directory:
[SaveGame]\Mods\EmpyrionScripting\Scripts\
This path is accessible via @root.MainScriptPath.
Script resolution priority:
EntityId(e.g.12345.hbs)PlayfieldName\EntityName(e.g.Akua\MyShip.hbs)PlayfieldName\EntityType(e.g.Akua\CV.hbs)EntityName(e.g.MyShip.hbs)EntityType(e.g.BA.hbs)PlayfieldName(e.g.Akua.hbs)- In the directory itself
EntityType:
BA(Base),CV(Capital Vessel),SV(Small Vessel),HV(Hover Vessel)
{{#readfile @root.MainScriptPath 'config.txt'}}
Line 1: {{lookup this 0}}
{{else}}
File not found
{{/readfile}}
{{#writefile @root.MainScriptPath 'output.txt'}}
File content
{{/writefile}}
{{#fileexists @root.MainScriptPath 'config.txt'}}
File exists!
{{/fileexists}}
{{#filelist @root.MainScriptPath '*.hbs' true}}
{{this}}
{{/filelist}}
Sends a server chat message directly to a single player (SaveGame scripts only):
{{#sendmessagetoplayer PlayerId}}
Hello, your ship is in a danger zone!
{{/sendmessagetoplayer}}
The inner block is rendered as the message text. PlayerId is the numeric entity ID of the player.
{{setdamage Block 100}} β Set damage of a block to 100
{{settype Block 4297}} β Change block type ID
Extended permissions for scripts running in SaveGame directories or on admin structures:
{{lockdevice E.S 'MyContainer'}}
{{additems Container 4297 100}} β Add 100x IronOre
{{removeitems Container 4297 50}} β Remove 50x IronOre
{{replaceblocks Entity '4297' 0}} β Remove block (0 = delete)
{{settype Block TypeId}} β Change block type (SaveGame only)
{{setdamage Block 100}} β Set damage (SaveGame only)
When many scripts run on a structure, control execution frequency:
Script:MyScript β Every cycle (only when LCD is on)
0Script:MyScript β Same as above
1Script:MyScript β Every cycle (even when LCD is off!)
3Script:MyScript β Every 3rd cycle
5Script:MyScript β Every 5th cycle
Execution order with priorities 1, 3, 4:
Cycle 1: Script(1), Script(3), Script(4) β all run
Cycle 2: Script(1)
Cycle 3: Script(1), Script(3)
Cycle 4: Script(1), Script(4)
Cycle 5: Script(1)
Cycle 6: Script(1), Script(3)
...
| Priority | Execution | LCD must be on |
|---|---|---|
| 0 or none | Every cycle | Yes |
| 1β9 | Every Nth cycle | No |
In addition to Handlebars templates, scripts can be written in C#. Use the .cs extension instead of .hbs.
| Extension | Language | Description |
|---|---|---|
.hbs |
Handlebars template | Standard scripting |
.cs |
C# (Roslyn-compiled) | Full C# logic |
.dll |
Compiled assembly | Pre-compiled DLL |
π‘ Advantage of C# scripts: Complex logic, loops, custom classes, type safety. Disadvantage: Requires basic C# knowledge.
A C# script implements a Run method called by the mod:
using EmpyrionScripting.Interface;
public class MyScript
{
public static void Run(IScriptModData root)
{
var csRoot = root.CsRoot;
// Read all items in a container
var items = csRoot.Items(root.E.S, "MyContainer");
// Build output
var output = new System.Text.StringBuilder();
foreach (var item in items)
output.AppendLine($"{item.Count}x {item.Name}");
// Display on all LCDs with matching name
var displays = csRoot.Devices(root.E.S, "LCD*");
foreach (var lcd in csRoot.GetDevices<Eleon.Modding.ILcd>(displays))
lcd.SetText(output.ToString());
}
}Every C# script receives an IScriptModData object as entry point:
| Property | Type | Description |
|---|---|---|
E |
IEntityData |
The current entity (ship/base) |
P |
IPlayfieldData |
The current playfield |
CsRoot |
ICsScriptFunctions |
C# helper functions |
Data |
ConcurrentDictionary<string,object> |
Temp data store (like {{set}}) |
CacheData |
ConcurrentDictionary<string,object> |
Persistent cache (like {{setcache}}) |
Ids |
Dictionary<string,string> |
Predefined ID lists |
GameTicks |
ulong |
Current game time in ticks |
CycleCounter |
int |
Script execution counter |
IsElevatedScript |
bool |
Whether script has elevated rights |
ConfigEcfAccess |
IConfigEcfAccess |
Access to ECF configuration |
GameOptionsYamlSettings |
IDictionary<string,object> |
Game options from YAML |
DateTimeNow |
DateTime |
Current date/time |
Version |
string |
Mod version |
Console |
IConsoleMock |
Console output for debugging |
SignalEventStore |
IEventStore |
Signal event storage |
| Property | Description |
|---|---|
Id |
Entity ID |
Name |
Entity name |
EntityType |
Type (BA, CV, SV, HV, β¦) |
Faction |
Faction data |
Pos |
World coordinate position |
Forward |
Forward vector |
S |
IStructureData β structure data |
IsLocal / IsPoi / IsProxy |
Entity flags |
BelongsTo |
Parent entity ID |
DockedTo |
Docked-to structure ID |
ScriptInfos |
Running scripts info |
IsElevated |
Whether elevated rights are active |
Methods: MoveForward(speed), MoveTo(direction), MoveStop(), GetCurrent(), GetCurrentPlayfield()
| Property | Description |
|---|---|
AllCustomDeviceNames |
All custom device names |
Items |
All item stacks (all containers) |
ControlPanelSignals |
Control panel signals |
BlockSignals |
Block signals |
Passengers |
All passengers |
Pilot |
Current pilot |
Players |
All players on structure |
DockedE |
Docked entities |
OxygenTank / FuelTank / PentaxidTank |
Tank wrappers |
DamageLevel |
Damage level (0β1) |
IsPowerd |
Is structure powered? |
IsReady |
Is structure ready? |
IsShieldActive / ShieldLevel |
Shield status |
BlockCount / TriangleCount / LightCount |
Statistics |
TotalMass |
Total mass |
HasLandClaimDevice |
Has a land claim device? |
MinPos / MaxPos |
Bounding box |
SizeClass |
Size class |
LastVisitedTicks |
Last visitor time |
PlayerCreatedSteamId |
Creator's Steam ID |
Methods: GlobalToStructPos(pos), StructToGlobalPos(pos), GetCurrent()
| Method | Description |
|---|---|
Items(structure, names) |
Read items from containers |
Move(item, structure, names, maxLimit?) |
Move items |
Fill(item, structure, type, maxLimit?) |
Fill a tank |
Devices(structure, names) |
Find devices by name |
DevicesOfType(structure, type) |
Find devices by type |
GetDevices<T>(block[]) |
Get devices as typed interface |
GetBlockDevices<T>(structure, names) |
Get block+device tuples |
Block(structure, x, y, z) |
Get a single block |
EntitiesById(ids) |
Find entities by IDs |
EntitiesByName(names) |
Find entities by name |
Scroll(content, lines, delay, step?) |
Calculate scroll buffer |
Bar(data, min, max, length, barChar?, bgChar?) |
Create progress bar string |
Format(data, format) |
Format a value |
I18n(id) / I18n(id, language) |
Translate item name |
ToId(names) |
Item names β IDs |
ToName(ids) |
IDs β item names |
ConfigById(id) |
ECF block by ID |
ConfigByName(name) |
ECF block by name |
ConfigFindAttribute(id, name) |
Get ECF attribute |
ResourcesForBlockById(id) |
Recipe resources for item |
ShowDialog(playerId, config, handler, value) |
Show dialog |
WithLockedDevice(structure, block, action, lockFailed?) |
Work with locked device |
IsLocked(structure, block) |
Is device locked? |
FunctionNeedsMainThread(error) |
Check if main thread required |
I18nDefaultLanguage |
Default translation language |
SaveGame scripts (in [SaveGame]\Mods\EmpyrionScripting\Scripts\) use IScriptSaveGameRootData (extends IScriptModData):
| Property | Description |
|---|---|
MainScriptPath |
Path to the scripts directory |
ModApi |
Access to the Mod API |
ScriptPath |
Path of the current script |
using EmpyrionScripting.Interface;
using System.Text;
public class FuelMonitor
{
public static void Run(IScriptModData root)
{
var csRoot = root.CsRoot;
var structure = root.E.S;
// Find fuel items
var items = csRoot.Items(structure, "FuelContainer");
var sb = new StringBuilder();
sb.AppendLine("=== Fuel Status ===");
foreach (var item in items)
{
if (item.Key == "EnergyCell")
{
sb.AppendLine($"Fuel: {item.Count} cells");
if (item.Count < 100)
sb.AppendLine("β οΈ FUEL CRITICAL!");
}
}
// Write to LCD
var lcds = csRoot.GetDevices<Eleon.Modding.ILcd>(
csRoot.Devices(structure, "LCD Status"));
foreach (var lcd in lcds)
lcd.SetText(sb.ToString());
}
}Configuration file: [SaveGame]\Mods\EmpyrionScripting\Configuration.json
| Setting | Default | Description |
|---|---|---|
InGameScriptsIntervallMS |
1000 | Script execution interval in milliseconds |
SaveGameScriptsIntervallMS |
10000 | Interval for SaveGame scripts (ms) |
UseEveryNthGameUpdateCycle |
10 | Only process every Nth GameUpdate call |
ScriptsSyncExecution |
2 | Scripts per cycle (synchronous in game thread) |
ScriptsParallelExecution |
2 | Scripts per cycle (parallel in background) |
ScriptLoopSyncTimeLimiterMS |
200 | Maximum runtime per cycle for synchronous scripts (ms) |
ScriptLoopBackgroundTimeLimiterMS |
2000 | Maximum runtime per cycle for background scripts (ms) |
DeviceLockOnlyAllowedEveryXCycles |
10 | DeviceLock scripts only run every X cycles |
ProcessMaxBlocksPerCycle |
200 | Maximum blocks processed per cycle |
ExecMethod |
ThreadPool |
Execution method: None, ThreadPool, Direct, BackgroundWorker |
DelayStartForNSecondsOnPlayfieldLoad |
30 | Delay on playfield load in seconds |
π‘ Tip: Default values are very conservative. Doubling them (and halving
SaveGameScriptsIntervallMS) makes scripts run more smoothly β but may cause micro-stutters.
| Setting | Default | Description |
|---|---|---|
LogLevel |
Message |
Log level: None, Message, Debug |
ScriptTracking |
false |
Track script execution times (output in ScriptTrackingDebug LCD) |
ScriptTrackingError |
false |
Enable error tracking for scripts |
DetailedScriptsInfoData |
false |
Collect detailed script info data |
| Setting | Default | Description |
|---|---|---|
CsScriptsAllowedFor |
Player |
Who may run C# scripts: Player, Moderator, GameMaster, Admin |
EntityAccessMaxDistance |
500 | Maximum distance (in blocks) for accessing other structures |
| Setting | Default | Description |
|---|---|---|
MaxStoredEventsPerSignal |
10 | Maximum number of stored events per signal |
| Setting | Default | Description |
|---|---|---|
OverrideScenarioPath |
(empty) | Path to the scenario directory (required for custom scenarios in singleplayer, e.g. ReforgedEden) |
AddOnAssemblies |
[] |
List of additional DLL paths (relative to the mod directory in the savegame) |
| Setting | Default | Description |
|---|---|---|
GardenerSalary |
10Γ MoneyCard |
Payment per Gardener action |
DeconstructSalary |
10Γ MoneyCard |
Payment per deconstruct action |
RecycleSalary |
20Γ MoneyCard |
Payment per recycle action |
AmountPerNumberOfBlocks |
10 | Number of blocks per salary unit |
DeconstructBlockSubstitutions |
(list) | Blocks replaced by 0 during deconstruction (e.g. alien containers) |
| Setting | Default | Description |
|---|---|---|
NumberSpaceReplace |
" " |
Character used as space replacement in number output |
BarStandardValueSign |
β |
Character for the filled part of a progress bar |
BarStandardSpaceSign |
β |
Character for the empty part of a progress bar |
Defines which items can be used to fill structure tanks and in what quantities:
"StructureTank": {
"Oxygen": [{ "ItemName": "OxygenBottleLarge", "Amount": 250, "EcfAmountTag": "O2Value" }],
"Fuel": [{ "ItemName": "FusionCell", "Amount": 300, "EcfAmountTag": "FuelValue" },
{ "ItemName": "EnergyCellLarge", "Amount": 150, "EcfAmountTag": "FuelValue" },
{ "ItemName": "EnergyCell", "Amount": 30, "EcfAmountTag": "FuelValue" }],
"Pentaxid": [{ "ItemName": "PentaxidCrystal", "Amount": 1 }]
}For fuel, O2, etc., the amount can be automatically determined from the ECF configuration of the scenario:
{
"ItemName": "EnergyCellLarge",
"Amount": 250,
"EcfAmountTag": "FuelValue"
},
{
"ItemName": "OxygenBottleLarge",
"Amount": 250,
"EcfAmountTag": "O2Value"
}Disable automatic determination: "EcfAmountTag": ""
These lists can be used in scripts via @root.Ids.ListName.
Configuration path: [SaveGame]\Mods\EmpyrionScripting\Configuration.json (section "Ids")
Note: Delete the
"Ids"section from Configuration.json to restore the original lists.
Usage in scripts:
{{#itemlist E.S.Items @root.Ids.Ore}}
{{Count}}x {{i18n Key}}
{{/itemlist}}
{{#itemlist E.S.Items (concat @root.Ids.WeaponSV @root.Ids.WeaponHV)}}
{{Count}}x {{i18n Key}}
{{/itemlist}}
| List | Contents |
|---|---|
Ore |
All ores |
Ingot |
All ingots / processed ores |
Components |
Crafting components (vanilla) |
EdenComponents |
Eden mod components |
Medic |
Medical items |
Food |
Food items |
Ingredient |
Ingredients (all) |
IngredientBasic |
Basic ingredients |
IngredientExtra |
Extra ingredients |
IngredientExtraMod |
Additional mod ingredients |
Tools |
Tools |
Armor |
Armor sets |
ArmorMod |
Armor modifications |
Sprout |
Seedlings / plant seeds |
BlockL |
Large blocks (CV/BA) |
BlockS |
Small blocks (SV/HV) |
DeviceL |
Devices (CV/BA) |
DeviceS |
Devices (SV/HV) |
WeaponPlayer |
Player weapons |
WeaponHV |
HV weapons |
WeaponSV |
SV weapons |
WeaponCV |
CV weapons |
WeaponBA |
BA weapons |
WeaponPlayerUpgrades |
Weapon upgrade kits |
WeaponPlayerEpic |
Epic weapons |
AmmoPlayer |
Player ammo |
AmmoHV |
HV ammo |
AmmoSV |
SV ammo |
AmmoCV |
CV ammo |
AmmoBA |
BA ammo |
AmmoAllEnergy |
All energy ammo |
AmmoAllProjectile |
All projectile ammo |
AmmoAllRocket |
All rockets |
Deco |
Decoration blocks |
DataPads |
Data pads / chips |
Oxygen |
Oxygen bottles |
Fuel |
Fuel cells |
Pentaxid |
Pentaxid crystals |
OreFurnace |
Ores that can be smelted |
Deconstruct |
Blocks designated for deconstruction |
Gardeners |
Gardener NPCs |
Lists begin and end with a comma so they can be combined with concat:
(concat @root.Ids.WeaponHV @root.Ids.WeaponSV @root.Ids.WeaponCV)
(concat '1234,5568' @root.Ids.ArmorMod)
| ID | Internal Name | English |
|---|---|---|
| 4296 | MagnesiumOre | Magnesium Ore |
| 4297 | IronOre | Iron Ore |
| 4298 | CobaltOre | Cobalt Ore |
| 4299 | SiliconOre | Silicon Ore |
| 4300 | NeodymiumOre | Neodymium Ore |
| 4301 | CopperOre | Copper Ore |
| 4302 | PromethiumOre | Promethium Ore |
| 4317 | ErestrumOre | Erestrum Ore |
| 4318 | ZascosiumOre | Zascosium Ore |
| 4332 | SathiumOre | Sathium Ore |
| 4341 | PentaxidOre | Pentaxid Ore |
| 4345 | GoldOre | Gold Ore |
| 4359 | TitaniumOre | Titanium Ore |
| ID | Internal Name | English |
|---|---|---|
| 4319 | MagnesiumPowder | Magnesium Powder |
| 4320 | IronIngot | Iron Ingot |
| 4321 | CobaltIngot | Cobalt Ingot |
| 4322 | SiliconIngot | Silicon Ingot |
| 4323 | NeodymiumIngot | Neodymium Ingot |
| 4324 | CopperIngot | Copper Ingot |
| 4325 | PromethiumPellets | Promethium Pellets |
| 4326 | ErestrumIngot | Erestrum Ingot |
| 4327 | ZascosiumIngot | Zascosium Ingot |
| 4328 | CrushedStone | Crushed Stone |
| 4329 | RockDust | Rock Dust |
| 4333 | SathiumIngot | Sathium Ingot |
| 4342 | PentaxidCrystal | Pentaxid Crystal |
| 4346 | GoldIngot | Gold Ingot |
| 4360 | TitaniumRods | Titanium Rods |
| Property | Description |
|---|---|
Id |
Unique ID (tokens: TokenId * 100000 + ItemId) |
IsToken |
true if it's a token |
ItemId |
Token-independent part of the ID |
TokenId |
Token ID (if applicable) |
Count |
Quantity |
Key |
Internal item name |
Name |
Display name |
| Function | Description |
|---|---|
{{concat a b c}} |
Concatenate values |
{{substring text 0 10}} |
Substring from index 0, max 10 chars |
{{replace text 'old' 'new'}} |
Replace text |
{{split text ',' true}} |
Split text, remove empty entries |
{{trim text}} |
Remove whitespace/chars from edges |
{{startswith text 'abc'}} |
Does text start with 'abc'? |
{{endsswith text 'xyz'}} |
Does text end with 'xyz'? (note: double 's' is intentional) |
{{chararray text}} |
Text as character array |
{{selectlines text 0 5}} |
Lines 0β5 from text |
{{format data '0.00'}} |
Formatted output |
{{i18n Key 'English'}} |
Item name in specified language |
{{structtoglobalpos E.S (vector 10 0 5)}} β Structure pos β World coordinates
{{globaltostructpos E.S GlobalPos}} β World coordinates β Structure pos
{{#use (block E.S 10 0 5)}}
Block at position 10/0/5: {{Type}}
{{/use}}
{{gettexture Block 'T'}} β Get texture ID of top face (T=Top, B=Bottom, N/S/W/E)
{{settexture Block 123 'T,B'}} β Set texture on top and bottom face
{{getcolor Block 'T'}} β Get color ID of top face
{{setcolor Block 5 'N,S'}} β Set color on north and south face
{{setlockcode Block 1234}} β Set lock code on a container/device
{{#blocks E.S 0 0 0 10 10 10}} β All blocks in range (0,0,0) to (10,10,10)
{{/blocks}}
{{#devices E.S 'DisplayPanel'}}
{{settext this 'Hello World!'}}
{{setcolor this 'ff0000'}}
{{setbgcolor this '000000'}}
{{setfontsize this 20}}
{{/devices}}
{{gettext LcdDevice}} β Read text of an LCD
{{settext LcdDevice 'Text'}} β Set text
{{settextblock LcdDevice}} β Set text from nested block
{{setcolor LcdDevice 'ff0000'}} β Set text color (RGB hex)
{{setbgcolor LcdDevice '000000'}} β Set background color (RGB hex)
{{setfontsize LcdDevice 20}} β Set font size on LCD device directly
The resourcesforid helper returns the required resources (recipe) for a block/item as a Key/Value collection (ID => amount). It accepts a single ID as argument and allows you to work with the found resources inside the block. Example:
Targets:LCD Recipes
Recipe for {{configattr 4297 'Name'}}:
{{#resourcesforid 4297}}
{{#each this}}
- {{this}}x {{configattr @key 'Name'}} (ID: {{@key}})
{{/each}}
{{else}}
No resources found.
{{/resourcesforid}}
Notes:
- Amounts are numeric (double) and may contain fractions (for components calculated per output).
- Inside the block the context is the dictionary collection; therefore use
{{#each this}}to iterate and access@key/this.
{{#toid 'IronOre;CobaltOre'}} β Names β IDs
...
{{/toid}}
{{#toname '4297;4298'}} β IDs β Names
...
{{/toname}}
{{configid 'IronOre'}} β Config ID for item name
{{configattr 4297 'Mass'}} β Attribute for item ID
{{configattrbyname 'IronOre' 'Mass'}} β Attribute for item name
{{resourcesforid 4297}} β Recipe resources for item
ASTIC/TC

