# Skript-Anleitung

Schreib Lua-Skripte, die deine Sprites zeichnen und bearbeiten, führe Bibliotheksskripte und Generatoren aus und füge eigene Fenster und Menübefehle hinzu.

_Die Tastenkürzel sind für Windows und Linux notiert. Auf einem Mac nimmst du ⌘ Cmd statt Ctrl und ⌥ Option statt Alt._

Skripte sind Lua-Programme, die auf dem geöffneten Sprite arbeiten. Sie steuern dieselbe Engine wie
der Editor: Alles, was du von Hand an Werkzeugen, Ebenen, Frames, Cels, Tags, Slices, Tiles und
Paletteneinträgen ändern kannst, kann ein Skript per Code ändern. Nutze sie, um Kunst zu erzeugen
(Bäume, Steine, Texturen, Sternenfelder), um eine mühsame Bearbeitung zu wiederholen oder um den Menüs
eigene Befehle hinzuzufügen.

Neu im Scripting? [Dein erstes Skript](https://pxstud.io/de/docs/scripting/first-script.md) führt dich durch das Schreiben und Ausführen
eines Skripts. Diese Seite behandelt alles drumherum.

## Das Menü Skripte

| Eintrag | Funktion |
| - | - |
| Skripte > Neues Skript... | Benennt ein neues Skript und öffnet es im Bedienfeld Skripte. |
| Skripte > Mein Skript öffnen... | Listet deine Skripte auf: Wähle eines, um es zu öffnen, oder benenne es um oder lösche es. Die letzten fünf, die du geöffnet hast, stehen im Menü darunter. |
| Skripte > Skriptbibliothek durchsuchen... | Die Skriptbibliothek: geteilte Skripte durchsuchen, ausführen, forken und mit Herz markieren, einschließlich der offiziellen Generatoren. Siehe [Die Bibliothek](https://pxstud.io/de/docs/manual/guides/library.md). |
| Skripte > Skriptbefehle... | Installiert Menübefehle aus deinen Skripten ([unten](https://pxstud.io/de/docs/scripting/guide.md#script-commands)). |
| Skripte > Skripting-API | Öffnet die Referenz der [Scripting-API](https://pxstud.io/de/docs/scripting.md) in einem neuen Tab. |

Jeder davon steht auch in der Befehlspalette (`Ctrl+K`).

## Das Bedienfeld Skripte

Das Bedienfeld **Skripte** öffnet sich, wenn du ein Skript erstellst oder öffnest (in den
Standard-Layouts rechts von der Leinwand angedockt, damit du einem Skript beim Zeichnen zusehen kannst;
auf dem Handy davor). Ansicht > Bedienfelder > Skripte blendet es ein und aus, und ein Neuladen öffnet das
Skript wieder, das du offen hattest (seinen zuletzt gespeicherten Entwurf). Es hat einen Code-Editor mit
Lua-Hervorhebung, Vorschlägen für jede `app.`-Funktion beim Tippen und einer Beschreibung, wenn du auf
eine zeigst. Unter dem Code zeigt ein Ausgabebereich, was das Skript ausgibt, und jeden Fehler.

![Das Bedienfeld Skripte mit dem Code eines Skripts, oben die Symbolleiste und darunter die Ausgabe](https://pxstud.io/scripting/images/first-script-panel.light.webp)

_Das Bedienfeld Skripte_

Oben, von links nach rechts:

- **Der Name des Skripts.** Doppelklick darauf, um das Skript umzubenennen. Ein `*` bedeutet
  ungespeicherte Änderungen; daneben steht „Entwurf“ für ein Skript, das du nicht veröffentlicht hast,
  oder die Version, die du bearbeitest („v2“, „v2 · bearbeitet“).
- **Privat** oder **Geteilt**: wer das Skript in der Bibliothek sehen kann. Klick darauf, um es zu ändern.
- **Skript-API-Referenz** (das Buch) öffnet die Referenz in einem neuen Tab.
- **Ausführen** (die Wiedergabe-Schaltfläche) führt das Skript auf dem aktiven Sprite aus; ein Skript mit
  einem [Konfigurationsformular](https://pxstud.io/de/docs/scripting/guide.md#config-forms) fragt zuerst nach seinen Werten. Während es läuft, treten
  die Steuerelemente der Ausführung an seine Stelle ([unten](https://pxstud.io/de/docs/scripting/guide.md#running-pausing-and-stopping)).
- **Entwurf speichern** (die Diskette) speichert das Skript in diesem Browser.
- **Veröffentlichen** fragt nach einem optionalen Versionshinweis, speichert dann das Skript und
  veröffentlicht es als neue Version.
- **Skripteinstellungen** (die Regler) öffnet die Einstellungen des Skripts: seine Tags, wer es sehen
  kann, sein Konfigurationsformular und seine veröffentlichten Versionen.
- **Bedienfeld ausblenden** schließt das Bedienfeld. Das geöffnete Skript bleibt im Menü Datei bei den
  Sprites aufgelistet: Wähle dort seinen Namen, um das Bedienfeld wieder anzuzeigen.

Das Skript von jemand anderem (mit **Code ansehen** in der Bibliothek geöffnet) ist schreibgeschützt.
Seine Symbolleiste hat **Forken** statt Entwurf speichern und Veröffentlichen: Das kopiert es in ein neues
Skript von dir, das du bearbeiten kannst.

## Ausführen, Pausieren und Stoppen

Ein Skript läuft auf dem Sprite, den du gerade ansiehst, und du siehst ihm beim Zeichnen zu. Egal wie
viel es ändert, ein Durchlauf ist **ein Rückgängig-Schritt**: `Ctrl+Z` nimmt den ganzen Durchlauf zurück.

Skripte haben **kein Zeitlimit**. Solange eines läuft, kannst du es mit seinen Steuerelementen vorzeitig
beenden:

| Steuerelement | Funktion |
| - | - |
| **Pause** / **Fortsetzen** | Hält das Skript dort an, wo es ist, auch mitten in einer Schleife, und macht später weiter. |
| **Stopp** | Beendet das Skript und behält, was es bisher getan hat. |
| **Stopp & zurücksetzen** | Beendet das Skript und macht alles rückgängig, was es geändert hat. |

Im Bedienfeld Skripte sind das kleine Schaltflächen in der Symbolleiste. Ein Skript, das aus der
Bibliothek ausgeführt wird, bedeckt den Editor mit einem Fenster, das seinen Namen, seine Ausgabe und
dieselben drei Steuerelemente zeigt, bis es fertig ist.

Wenn ein Skript fehlschlägt, zeigt die Ausgabe den Fehler; im Bedienfeld ist die Zeile hervorgehoben,
in der es fehlgeschlagen ist. Ein Skript kann nicht auf einer gesperrten Ebene malen: Der Befehl wird
abgelehnt, und das Skript bricht mit einem Fehler ab.

## Skripte schreiben

Jede Funktion steckt in der Tabelle `app`. Die [Scripting-API](https://pxstud.io/de/docs/scripting.md) dokumentiert jede
einzelne, aus dem Editor selbst erzeugt, in Abschnitten:

- [Drawing](https://pxstud.io/de/docs/scripting/drawing.md): die Werkzeuge als Befehle (`app.drawLine`, `app.floodFill`,
  `app.drawIsoShape`...), [Images](https://pxstud.io/de/docs/scripting/images.md) zum Arbeiten Pixel für Pixel und
  [Pixels](https://pxstud.io/de/docs/scripting/pixels.md) für flache Pixellisten, Füllungen und die Pipette;
- [Document](https://pxstud.io/de/docs/scripting/document.md), [Layers](https://pxstud.io/de/docs/scripting/layers.md),
  [Frames](https://pxstud.io/de/docs/scripting/frames.md), [Cels](https://pxstud.io/de/docs/scripting/cels.md),
  [Selection](https://pxstud.io/de/docs/scripting/selection.md), [Slices](https://pxstud.io/de/docs/scripting/slices.md) und
  [Tilemaps](https://pxstud.io/de/docs/scripting/tilemaps.md);
- [Palette](https://pxstud.io/de/docs/scripting/palette.md), [Adjustments](https://pxstud.io/de/docs/scripting/adjustments.md) und
  [Brushes](https://pxstud.io/de/docs/scripting/brushes.md);
- Hilfsmittel: [Color](https://pxstud.io/de/docs/scripting/color.md)-Mathematik, [Random](https://pxstud.io/de/docs/scripting/random.md)-Zahlen mit
  Seed und der [Editing context](https://pxstud.io/de/docs/scripting/context.md) (die aktuellen Farben, der Pinsel und die
  Werkzeugoptionen).

Ein paar Dinge, die du wissen solltest:

- **Fang mit `print(app.describe())` an.** `app.describe()` liefert die ganze Struktur des Sprites:
  Ebenen, Frames, Cels, Tags, Slices, die Auswahl und die aktuellen Einstellungen.
- **Einstellungen, die du weglässt, kommen vom Editor.** Ein Zeichenbefehl ohne Farbe verwendet die
  Vordergrundfarbe; ohne Pinsel den aktuellen Pinsel; und so weiter für jede Werkzeugoption.
- **Auswahl und Symmetrie gelten nur, wenn du es verlangst.** Übergib `respectSelection = true`, um
  weiter innerhalb der Auswahl zu malen, und `symmetry = app.getContext().symmetry`, um zu spiegeln.
- **Arbeite Pixel für Pixel in einem Image.** `app.getImage(layer, frame)` liest ein Cel in ein Image
  ein, das im Skript lebt; `img:getPixel` und `img:setPixel` sind günstig, also kannst du über beliebig
  viele Pixel schleifen und es danach einmal mit `app.putImage(layer, frame, img)` zurückschreiben. Jeder
  Aufruf von `app.*` ist ein Weg zum Editor, die Methoden eines Images nicht. Bei indizierten Sprites
  arbeiten `img:getIndex` und `img:setIndex` mit Palettenindizes.
- **Nutze `app.random` für Zufall.** Ein mit `app.random.new(seed)` erzeugter Generator liefert bei
  gleichem Seed dieselben Zahlen, sodass sich ein Durchlauf exakt wiederholen lässt. Auch `pairs()`
  besucht die Schlüssel einer Tabelle bei jedem Durchlauf in derselben Reihenfolge.
- **Nutze `app.color` für Farbmathematik.** Mischen, Farbreihen und Abstufungen werden in einem
  wahrnehmungsbasierten Farbraum berechnet, was besser aussieht als das Mitteln von Hex-Werten.
- **Gib etwas aus, um Dinge zu prüfen.** `print(...)` schreibt in den Ausgabebereich; Tabellen werden
  vollständig ausgegeben.

Dieses Beispiel streut etwa Sterne auf eine neue Ebene; ändere den Seed für einen anderen Himmel:

```lua
local layer = app.addLayer("Stars")
local frame = app.getActiveFrameId()

local rng = app.random.new(42)                        -- same seed, same stars
local colors = app.color.ramp({ "#5a6b9e", "#ffffff" }, 4)

local img = app.getImage(layer, frame)                -- the layer's pixels, inside the script
for i = 1, img.width * img.height // 40 do
  img:setPixel(rng:int(0, img.width - 1), rng:int(0, img.height - 1), rng:pick(colors))
end
app.putImage(layer, frame, img)                       -- written back as one change
```

## Konfigurationsformulare

Ein Skript kann vor dem Ausführen nach Einstellungen fragen: Wenn du **Ausführen** wählst (in der
Bibliothek oder im Bedienfeld Skripte), öffnet sich ein Formular mit seinen Feldern (Zahlen, Text,
Kontrollkästchen, Auswahlen, Farben sowie ein Pinsel oder eine Palette aus deinen eigenen Bibliotheken),
und das Skript liest, was du eingegeben hast, als Tabelle `app.config`. Felder können je nach früheren
Auswahlen angezeigt oder ausgeblendet werden. **Zufall** würfelt neue Werte innerhalb der vom Autor des
Skripts gewählten Bereiche, für schnelle Varianten. Die offiziellen Generatoren funktionieren alle so.

Um einem deiner Skripte ein Formular zu geben, schreib es als JSON in **Konfigurationsformular (JSON)**
in den Einstellungen des Skripts, in der Form, die die Referenz [Config forms](https://pxstud.io/de/docs/scripting/config-forms.md)
beschreibt; die Einstellungen sagen dir vor dem Speichern, was daran nicht stimmt. Das Formular ist Teil
des Entwurfs und jeder veröffentlichten Version. Ein Skript sollte trotzdem jedes Feld als optional lesen
und auf eigene Voreinstellungen zurückfallen. Für Eingaben, während ein Skript läuft, öffne stattdessen
ein Skriptfenster.

## Skriptfenster

Ein Skript kann mit `Dialog{}` ein eigenes Fenster öffnen, so gebaut, wie Aseprite-Skripte sie bauen:
Beschriftungen, Text- und Zahlenfelder, Regler, Kontrollkästchen, Optionsfelder, Dropdown-Listen,
Farbfelder, Reihen von Farbfeldern, Schaltflächen und eine Dateiauswahl (nur kleine Textdateien).

```lua
local dlg = Dialog{ title = "Quick Fill" }
dlg:color{ id = "paint", label = "Color", color = "#3a8f4a" }
dlg:button{ id = "fill", text = "Fill layer", onclick = function()
  local layer, frame = app.getActiveLayerId(), app.getActiveFrameId()
  app.floodFill(layer, frame, 0, 0, { color = dlg.data.paint })
end }
dlg:show{ wait = false }
```

- `dlg:show{ wait = false }` öffnet ein **schwebendes Fenster**, und das Skript wartet untätig, während du
  weiterzeichnest; jeder Tastendruck oder jede Änderung, auf die es reagiert, ist ein eigener
  Rückgängig-Schritt. Ohne `wait = false` ist das Fenster modal: Der Editor ist gesperrt, bis du es
  schließt.
- Die Titelleiste des Fensters nennt das Skript und kennzeichnet es als Fenster eines Skripts, und alles
  darin ist einfacher Text, sodass ein Skript sein Fenster nicht als Teil des Editors ausgeben kann.
- Das Schließen des Fensters beendet das Skript; das Stoppen des Skripts schließt seine Fenster.

Die Referenz [Dialogs and commands](https://pxstud.io/de/docs/scripting/dialogs.md) enthält jedes Widget mit seinen Optionen.

## Skriptbefehle

Ein Skript kann den Menüs des Editors **Befehle** hinzufügen, genau wie ein Aseprite-Plugin. Definiere
eine Funktion `init(plugin)`, die sie mit `plugin:newCommand` registriert:

```lua
local function mirror()
  app.flip("horizontal", app.getActiveLayerId())
end

function init(plugin)
  plugin:newCommand{ id = "mirror", title = "Mirror Layer", group = "layer", onclick = mirror }
end
```

Speichere das Skript, wähle dann Skripte > Skriptbefehle... und drück neben ihm auf **Installieren**. Der
Befehl erscheint nun:

- in dem Menü, das sein `group` nennt (`file`, `file_import`, `edit`, `edit_transform`, `edit_fx`,
  `edit_adjustments`, `sprite`, `layer`, `frame`, `select` oder `view`), angezeigt mit dem Namen des
  Skripts; ohne Gruppe unter Skripte, in einem Untermenü mit dem Namen des Skripts;
- in der Befehlspalette;
- in Einstellungen > Tastenkürzel..., wo du ihm ein Tastenkürzel geben kannst.

Das Ausführen des Befehls führt dein gespeichertes Skript und dann das `onclick` des Befehls aus, als ein
Rückgängig-Schritt. Nachdem du geändert hast, welche Befehle ein Skript registriert, drück auf **Neu
installieren**; **Entfernen** nimmt sie aus den Menüs. Ein Skript kann bis zu 32 Befehle hinzufügen.
Installierte Befehle werden in diesem Browser gespeichert.

Um Befehle aus dem Skript von jemand anderem zu installieren, forke es zuerst in deine Skripte.

## Speichern und Veröffentlichen

Deine Skripte werden wie deine Sprites in diesem Browser gespeichert und funktionieren offline. Mit
[Sync](https://pxstud.io/de/docs/manual/concepts/how-work-is-organized.md#where-things-are-kept) werden sie zusätzlich in
deinem Konto und auf deinen anderen Geräten aufbewahrt.

**Veröffentlichen** teilt ein Skript in der Skriptbibliothek. Jedes Skript beginnt als **Privat**, sodass
nur du es sehen kannst; wähle **In der Bibliothek geteilt** in seinen Einstellungen (**Skripteinstellungen**
oder das Abzeichen Privat), um es aufzulisten. Dann gilt:

- **Entwurf speichern** hält deine Änderungen privat. Wer die Bibliothek nutzt, bekommt immer deine zuletzt
  veröffentlichte Version, nie den Entwurf.
- **Veröffentlichen** speichert den Entwurf und macht ihn mit dem Versionshinweis, den du eintippst (im
  Versionsverlauf angezeigt), zur nächsten nummerierten Version. Veröffentlichte Versionen ändern sich nie;
  veröffentliche erneut, um eine neue zu erstellen.
- Die Einstellungen des Skripts listen jede veröffentlichte Version auf. **Code ansehen** öffnet eine alte
  schreibgeschützt, und **In meinen Entwurf übernehmen** kopiert sie in deinen Entwurf.
- Ein Skript kann bis zu 3 Tags haben, die Leuten helfen, es in der Bibliothek zu finden.

Zum Veröffentlichen brauchst du ein Konto mit Sync bei pxstud.io. Skripte auszuführen, zu forken und mit
Herz zu markieren (mit einem kostenlosen Konto) steht unter [Die Bibliothek](https://pxstud.io/de/docs/manual/guides/library.md).

## Was Skripte nicht können

Skripte laufen in einer Sandbox, daher ist das Ausführen eines Skripts von jemand anderem sicher:

- **Kein Netzwerk, keine Dateien, kein Nachladen von Code.** Ein Skript kann weder das Internet noch deine
  Dateien erreichen (abgesehen von einer Textdatei, die du in seinem Fenster auswählst) und kann keinen
  anderen Code laden. Die Lua-Bibliotheken `io`, `os` und `debug` gibt es nicht; `string`, `math`, `table`,
  `utf8` und `coroutine` schon.

- **Nur der geöffnete Sprite.** Ein Skript bearbeitet den Sprite, auf dem du es ausgeführt hast, als ein
  Rückgängig-Schritt. Es kann keine Sprites öffnen, speichern, exportieren, schließen oder löschen, die
  Zwischenablage nicht nutzen und weder Ansicht noch Bedienfelder ändern.

- **Deine Bibliotheken nur, wenn du daraus wählst.** Ein Skript sieht einen deiner gespeicherten Pinsel
  oder eine deiner Paletten nur dann, wenn sein Konfigurationsformular danach fragt und du sie auswählst.

- **Ein Speicherbudget.** Ein Durchlauf kann nicht mehr als eine bestimmte Menge Speicher belegen: für
  seine Images, seine Lua-Daten, die Pixel, die er zum Sprite hinzufügt, und den Rückgängig-Schritt, den
  er aufbaut. Darüber hinaus wird das Skript mit einem Fehler gestoppt, der sagt, welches, und was es bisher
  getan hat, bleibt als ein Rückgängig-Schritt erhalten, sodass ein außer Kontrolle geratenes Skript weder
  den Editor zum Absturz bringen noch deine früheren Schritte aus dem Änderungsverlauf verdrängen kann.

Es gibt kein Zeitlimit; ein Skript, das außer Kontrolle gerät, lässt sich immer pausieren oder stoppen.

## Die offiziellen Generatoren

Die Skriptbibliothek von pxstud.io hat einen Satz offizieller Skripte, markiert mit **Offiziell**:
Generatoren für Verläufe, Schachbretter, Rausch-Füllungen, Ziegelwände, Kopfsteinpflaster, Holzdielen,
Gras- und Wassertexturen, Blitze, Tornados, Regenbögen, Kometen, Galaxien, Planeten, Sterne, Bäume,
Büsche und Felsen. Melde dich mit einem kostenlosen Konto an, öffne Skripte > Skriptbibliothek durchsuchen..., wähle
**Offiziell** und drück bei einem auf **Ausführen**: Füll sein Formular aus (oder drück auf **Zufall**),
und es zeichnet auf deinen Sprite. Fork eines, um zu lesen, wie es gemacht ist, oder um es zu ändern.
