Neuer Tab: Pixel Editor #130

Closed
opened 2026-09-17 20:56:09 +02:00 by admin · 4 comments

Eine vorhandene Texture bearbeiten, Pixel für Pixel. Pipette darf natürlich nicht fehlen.

Eine vorhandene Texture bearbeiten, Pixel für Pixel. Pipette darf natürlich nicht fehlen.
admin added this to the Development project 2026-09-17 20:56:29 +02:00
meleki referenced this issue from a commit 2026-09-20 20:52:02 +02:00
A picture in the editor may now be drawn instead of uploaded, which is the piece #129 (Vector art) and #130 (Pixel editor) both need and neither could build alone: TextureRef.file has been a file name on the server, isTextureFile() checking a sha256 hash plus an extension and TextureLibrary fetching it over HTTP, so an asset that paints its own image had nowhere to put itself - the key now also takes the form gen:<assetId>@<revision>, which an uploaded file can never look like, and everything that only passes a ref along (sprite, tile, tilemap mesh, particle source, shaders, aspect ratio) is untouched because it still sees a Texture; the revision is a string, not a counter, which is the one deviation from the plan in the issue and costs nothing - gen:a1@7 and gen:a1@c0ffee go through the same door, so a generator may fingerprint its own content instead of relying on every command to remember to bump a number; two registries keyed by asset type as a plain string, so a plugin may bring its own type - registerPictureSource(type, read) in the new core/model/generated.ts tells the model canvas size and revision and resolvePicture() builds the ref from it (no rect, no slice, smooth from props.filter like a texture), and registerPictureGenerator(type, draw) in the new viewport/generatedPictures.ts hands out the finished texture, projectPictureFactory(() => state.project) tying the two together per session in App.ts; invalidation is a rule instead of guesswork at twenty call sites: GeneratedPictures<T> holds one picture per asset keyed on the revision and frees the old one as soon as the new is drawn, TextureLibrary destroying it and dropping the crops cut from it, while a generator that cannot draw yet is not remembered but asked again next time - the class imports Pixi as a type only, so the whole bookkeeping is measurable without a GPU; carried along are the picture picker (a drawn asset sits among the textures by name, without frames), the delete warning (counts tiles and animations for it too) and the asset context menu, where "Create sprite from picture" now covers it while "Create animation from texture" stays texture-only because it needs frames; one finding while probing - crop() could not have cut a generated texture at all, a RenderTexture having no source.resource to draw back from and drawImage running onto null, so it is handed out whole, a drawn picture having no sheet whose neighbouring row could bleed in; 18 new unit tests, 10 in tests/core/generated-picture.test.ts (building and splitting the key, an uploaded file is not one, no registry means no picture, resolving to canvas size, a new revision is a new key, a canvas without a size, the filter, the sprite size, picker order) and 8 in tests/viewport/generated-pictures.test.ts (drawing once, freeing the old revision and only for its own asset, null is not remembered, no key means nothing drawn, a session change gives everything back, peek), and three counter-checks hold: dropping generated assets from resolvePicture fails 5 of the 10 core tests, not freeing the old revision fails 1 viewport test, and narrowing the picker back to textures fails 3; no e2e check and the check sum stays 1157, because without a generator the groundwork shows nothing in the browser - that evidence comes with #129 (#185)
admin added the question label 2026-09-21 08:06:49 +02:00
admin moved this to Next in Development on 2026-09-21 13:25:58 +02:00
Owner

Grundrichtung entschieden: B. Pixel Art wird eine eigene Asset-Art, so wie Vector Art. Die Pixel liegen im Projekt, dazu kommen Ebenen, Palette und Frames. Der Tab rastert das Ergebnis zu einem Bild, das Sprites, Animationen und Tilemaps verwenden können. Eine vorhandene Textur lässt sich als Startpunkt importieren.

Zu jeder Frage steht mein Vorschlag dabei. Ein „passt“ pro Punkt reicht.

1. Wo liegen die Pixeldaten?

Ein Projekt wird heute als ein ganzes JSON per PUT gespeichert, und nginx lässt höchstens 1 MB pro Request durch. Ein einziges 256x256-Bild in RGBA sind roh 256 kB, und mit Ebenen und Frames wird das schnell ein Vielfaches davon.

  • a) Im Projekt-JSON, je Ebene und Frame als PNG in Base64. Das ist einfach, stößt aber bald an die 1-MB-Grenze.
  • b) Als eigene Dateien auf dem Server, inhaltsadressiert wie Texturen. Das Projekt hält dann nur die Hashes. Beim Speichern werden geänderte Ebenen zuerst hochgeladen.
  • Vorschlag: b. Undo bleibt lokal im Tab (Pixel-Diffs), und hochgeladen wird erst beim Speichern.

2. Farben: indiziert oder frei?

  • a) Indiziert: Jeder Pixel ist ein Index in die Palette. Wenn du eine Palettenfarbe änderst, ändert sich das ganze Bild mit. Damit gehen später auch Palette-Swaps (Gegner in anderer Farbe).
  • b) Frei (RGBA): Die Palette ist nur eine Farbauswahl.
  • Vorschlag: a, mit Transparenz als Index 0. Beim Import werden die Farben auf höchstens 256 reduziert.
  • Außerdem: Palette je Asset oder je Projekt (mehrere Assets teilen sich eine)? Vorschlag: je Projekt als eigenes kleines Asset, und das Pixel-Art-Asset verweist darauf.

3. Leinwand

  • Standardgröße? Vorschlag 32x32, höchstens 512x512.
  • Größe ändern mit Anker (oben links / Mitte / …). Was übersteht, wird abgeschnitten, und das ist ein Undo-Schritt.

4. Ebenen

Vorschlag für die erste Fassung: Ebenen anlegen, löschen, umbenennen, umsortieren, sichtbar/unsichtbar, Deckkraft, nach unten zusammenführen. Keine Blend-Modi außer Normal. Soll noch etwas dazu, oder ist das schon zu viel?

5. Frames / Animation

  • Die Frames gehören zum Asset, und jeder Frame hat dieselben Ebenen (wie in Aseprite).
  • Das Ergebnis ist ein Sheet mit Frames wie bei einer geschnittenen Textur, sodass ein bestehendes Animation-Asset die Frames direkt verwenden kann.
  • Frame-Dauer: bleibt im Animation-Asset (Vorschlag) oder kommt auch in den Pixel-Tab?
  • Onion Skin (vorheriger/nächster Frame halbtransparent)? Vorschlag: ja, schaltbar.
  • Eine Vorschau, die im Tab abspielt? Vorschlag: ja, klein in einer Ecke.

6. Werkzeuge der ersten Fassung

Vorschlag: Stift, Radierer, Füllen (zusammenhängend oder alle Pixel gleicher Farbe), Pipette (Alt+Klick), Linie, Rechteck, Ellipse (Umriss/gefüllt), Rechteckauswahl samt Verschieben / Kopieren / Einfügen, Spiegeln der Auswahl oder Ebene. Pinselgröße 1 bis 8 px.
Später als eigenes Issue: Symmetrie-Zeichnen, Lasso, Dithering-Pinsel, Farbe ersetzen. Passt diese Aufteilung?

7. Import aus Textur

  • Importiert werden eine ganze Textur oder nur ihre geschnittenen Frames. Aus einem Sheet werden dann Pixel-Art-Frames.
  • Was passiert mit der Original-Textur? Vorschlag: Sie bleibt unberührt. Ein Knopf „Verwendungen umhängen“ tauscht die Textur in Sprites/Animationen gegen das neue Asset. Oder soll das automatisch passieren?
  • Bilder mit mehr als 256 Farben: reduzieren (Vorschlag) oder ablehnen?

8. Wo man Pixel Art verwenden kann

Vorschlag: überall, wo heute eine Textur oder Vector Art geht (Sprite, Animation, Tileset, Texturfüllung aus #186), über denselben Bildpfad wie Vector Art. Dazu ein Export als PNG zum Herunterladen. Fehlt noch ein Ort?

9. Ansicht und Bedienung

  • Zoom in ganzen Stufen (1x bis 32x), Pixelraster ab 8x, Schachbrett-Hintergrund für Transparenz.
  • Kachelvorschau (das Bild 3x3 nebeneinander) für Tiles? Vorschlag: ja, schaltbar.
  • Tastenkürzel wie in Aseprite: B Stift, E Radierer, G Füllen, I Pipette, L Linie, U Rechteck/Ellipse, M Auswahl, X Farben tauschen, [ ] Pinselgröße. Passt das, oder kollidiert etwas mit bestehenden Kürzeln im Editor?
  • Undo: ein Strich ist ein Schritt.

10. Aufteilung

Das ist zu viel für ein einziges Issue. Vorschlag:

  1. #130: Asset-Art, Leinwand, Palette, Werkzeuge aus Punkt 6 ohne Auswahl, Verwendung als Bild. Eine Ebene, ein Frame.
  2. Ebenen
  3. Frames, Onion Skin, Vorschau
  4. Import aus Textur und Verwendungen umhängen
  5. Auswahl, Kopieren/Einfügen, Spiegeln

Die Folge-Issues lege ich an, sobald du die Aufteilung bestätigst. Sie landen in keiner Spalte, bis du sie einplanst.

**Grundrichtung entschieden: B.** Pixel Art wird eine eigene Asset-Art, so wie Vector Art. Die Pixel liegen im Projekt, dazu kommen Ebenen, Palette und Frames. Der Tab rastert das Ergebnis zu einem Bild, das Sprites, Animationen und Tilemaps verwenden können. Eine vorhandene Textur lässt sich als Startpunkt importieren. Zu jeder Frage steht mein Vorschlag dabei. Ein „passt“ pro Punkt reicht. ## 1. Wo liegen die Pixeldaten? Ein Projekt wird heute als **ein ganzes JSON per PUT** gespeichert, und nginx lässt höchstens **1 MB** pro Request durch. Ein einziges 256x256-Bild in RGBA sind roh 256 kB, und mit Ebenen und Frames wird das schnell ein Vielfaches davon. - **a)** Im Projekt-JSON, je Ebene und Frame als PNG in Base64. Das ist einfach, stößt aber bald an die 1-MB-Grenze. - **b)** Als eigene Dateien auf dem Server, inhaltsadressiert wie Texturen. Das Projekt hält dann nur die Hashes. Beim Speichern werden geänderte Ebenen zuerst hochgeladen. - **Vorschlag: b.** Undo bleibt lokal im Tab (Pixel-Diffs), und hochgeladen wird erst beim Speichern. ## 2. Farben: indiziert oder frei? - **a) Indiziert:** Jeder Pixel ist ein Index in die Palette. Wenn du eine Palettenfarbe änderst, ändert sich das ganze Bild mit. Damit gehen später auch Palette-Swaps (Gegner in anderer Farbe). - **b) Frei (RGBA):** Die Palette ist nur eine Farbauswahl. - **Vorschlag: a**, mit Transparenz als Index 0. Beim Import werden die Farben auf höchstens 256 reduziert. - Außerdem: **Palette je Asset oder je Projekt** (mehrere Assets teilen sich eine)? Vorschlag: je Projekt als eigenes kleines Asset, und das Pixel-Art-Asset verweist darauf. ## 3. Leinwand - Standardgröße? Vorschlag **32x32**, höchstens **512x512**. - Größe ändern mit Anker (oben links / Mitte / …). Was übersteht, wird abgeschnitten, und das ist ein Undo-Schritt. ## 4. Ebenen Vorschlag für die erste Fassung: Ebenen anlegen, löschen, umbenennen, umsortieren, sichtbar/unsichtbar, Deckkraft, nach unten zusammenführen. **Keine Blend-Modi** außer Normal. Soll noch etwas dazu, oder ist das schon zu viel? ## 5. Frames / Animation - Die Frames gehören zum Asset, und jeder Frame hat dieselben Ebenen (wie in Aseprite). - Das Ergebnis ist ein Sheet mit Frames wie bei einer geschnittenen Textur, sodass ein bestehendes **Animation-Asset** die Frames direkt verwenden kann. - **Frame-Dauer:** bleibt im Animation-Asset (Vorschlag) oder kommt auch in den Pixel-Tab? - **Onion Skin** (vorheriger/nächster Frame halbtransparent)? Vorschlag: ja, schaltbar. - Eine Vorschau, die im Tab abspielt? Vorschlag: ja, klein in einer Ecke. ## 6. Werkzeuge der ersten Fassung Vorschlag: **Stift, Radierer, Füllen** (zusammenhängend oder alle Pixel gleicher Farbe), **Pipette** (Alt+Klick), **Linie, Rechteck, Ellipse** (Umriss/gefüllt), **Rechteckauswahl samt Verschieben / Kopieren / Einfügen**, **Spiegeln** der Auswahl oder Ebene. Pinselgröße 1 bis 8 px. Später als eigenes Issue: Symmetrie-Zeichnen, Lasso, Dithering-Pinsel, Farbe ersetzen. Passt diese Aufteilung? ## 7. Import aus Textur - Importiert werden eine ganze Textur oder nur ihre geschnittenen Frames. Aus einem Sheet werden dann Pixel-Art-Frames. - **Was passiert mit der Original-Textur?** Vorschlag: Sie bleibt unberührt. Ein Knopf „Verwendungen umhängen“ tauscht die Textur in Sprites/Animationen gegen das neue Asset. Oder soll das automatisch passieren? - Bilder mit mehr als 256 Farben: reduzieren (Vorschlag) oder ablehnen? ## 8. Wo man Pixel Art verwenden kann Vorschlag: überall, wo heute eine Textur oder Vector Art geht (Sprite, Animation, Tileset, Texturfüllung aus #186), über denselben Bildpfad wie Vector Art. Dazu ein **Export als PNG** zum Herunterladen. Fehlt noch ein Ort? ## 9. Ansicht und Bedienung - Zoom in ganzen Stufen (1x bis 32x), Pixelraster ab 8x, Schachbrett-Hintergrund für Transparenz. - **Kachelvorschau** (das Bild 3x3 nebeneinander) für Tiles? Vorschlag: ja, schaltbar. - Tastenkürzel wie in Aseprite: B Stift, E Radierer, G Füllen, I Pipette, L Linie, U Rechteck/Ellipse, M Auswahl, X Farben tauschen, [ ] Pinselgröße. Passt das, oder kollidiert etwas mit bestehenden Kürzeln im Editor? - Undo: ein Strich ist ein Schritt. ## 10. Aufteilung Das ist zu viel für ein einziges Issue. Vorschlag: 1. **#130:** Asset-Art, Leinwand, Palette, Werkzeuge aus Punkt 6 ohne Auswahl, Verwendung als Bild. Eine Ebene, ein Frame. 2. Ebenen 3. Frames, Onion Skin, Vorschau 4. Import aus Textur und Verwendungen umhängen 5. Auswahl, Kopieren/Einfügen, Spiegeln Die Folge-Issues lege ich an, sobald du die Aufteilung bestätigst. Sie landen in keiner Spalte, bis du sie einplanst.
Author
  1. dein vorschlag (b)
  2. indiziert klingt gut, passt
  3. vorschlag passt
  4. vorschlag passt
  5. vorschlag passt perfekt
  6. vorschlag hat schon ein riesige pattern, wenn du das so hinbekommst, sehr gerne
  7. import kann man einstweilen komplett weglassen, eigenes issue
  8. vorschlag passt, export als png => eigenes issue
  9. vorschlag passt, aber tastenkürzel kann man weglassen
  10. 1, 2 und 3 in ein issue (das hier), 4 eigenes issue, 5 eigenes issue
1. dein vorschlag (b) 2. indiziert klingt gut, passt 3. vorschlag passt 4. vorschlag passt 5. vorschlag passt perfekt 6. vorschlag hat schon ein riesige pattern, wenn du das so hinbekommst, sehr gerne 7. import kann man einstweilen komplett weglassen, eigenes issue 8. vorschlag passt, export als png => eigenes issue 9. vorschlag passt, aber tastenkürzel kann man weglassen 10. 1, 2 und 3 in ein issue (das hier), 4 eigenes issue, 5 eigenes issue
Owner

Umfang festgelegt (nach den Antworten oben):

In diesem Issue:

  • Asset-Art Pixel Art. Die Pixeldaten liegen als eigene Dateien auf dem Server, inhaltsadressiert wie Texturen. Das Projekt hält nur die Hashes.
  • Indizierte Farben, Index 0 = transparent. Die Palette ist ein eigenes Asset, auf das mehrere Pixel-Art-Assets verweisen können.
  • Leinwand 32x32 als Standard, höchstens 512x512, Größe ändern mit Anker.
  • Ebenen: anlegen, löschen, umbenennen, umsortieren, sichtbar, Deckkraft, nach unten zusammenführen.
  • Frames mit denselben Ebenen, Ergebnis als Sheet für Animation-Assets, Onion Skin schaltbar, kleine Vorschau.
  • Werkzeuge: Stift, Radierer, Füllen (zusammenhängend / gleiche Farbe), Pipette, Linie, Rechteck, Ellipse (Umriss/gefüllt), Pinselgröße 1 bis 8.
  • Zoom 1x bis 32x, Raster ab 8x, Schachbrett, Kachelvorschau 3x3. Keine Tastenkürzel. Undo: ein Strich ist ein Schritt.
  • Verwendung überall, wo heute ein Bild geht (Sprite, Animation, Tileset, Texturfüllung).

Abgetrennt:

  • #197 Import aus Textur und Verwendungen umhängen
  • #198 Auswahl, Kopieren/Einfügen und Spiegeln
  • #199 Export als PNG
  • #200 weitere Werkzeuge (Symmetrie, Lasso, Dithering, Farbe ersetzen)
**Umfang festgelegt** (nach den Antworten oben): In diesem Issue: - Asset-Art **Pixel Art**. Die Pixeldaten liegen als eigene Dateien auf dem Server, inhaltsadressiert wie Texturen. Das Projekt hält nur die Hashes. - **Indizierte Farben**, Index 0 = transparent. Die Palette ist ein eigenes Asset, auf das mehrere Pixel-Art-Assets verweisen können. - Leinwand 32x32 als Standard, höchstens 512x512, Größe ändern mit Anker. - **Ebenen**: anlegen, löschen, umbenennen, umsortieren, sichtbar, Deckkraft, nach unten zusammenführen. - **Frames** mit denselben Ebenen, Ergebnis als Sheet für Animation-Assets, Onion Skin schaltbar, kleine Vorschau. - Werkzeuge: Stift, Radierer, Füllen (zusammenhängend / gleiche Farbe), Pipette, Linie, Rechteck, Ellipse (Umriss/gefüllt), Pinselgröße 1 bis 8. - Zoom 1x bis 32x, Raster ab 8x, Schachbrett, Kachelvorschau 3x3. **Keine Tastenkürzel.** Undo: ein Strich ist ein Schritt. - Verwendung überall, wo heute ein Bild geht (Sprite, Animation, Tileset, Texturfüllung). Abgetrennt: - #197 Import aus Textur und Verwendungen umhängen - #198 Auswahl, Kopieren/Einfügen und Spiegeln - #199 Export als PNG - #200 weitere Werkzeuge (Symmetrie, Lasso, Dithering, Farbe ersetzen)
admin removed the question label 2026-09-21 16:25:06 +02:00
Owner

Umgesetzt in 66d6aaf, Doku im Wiki unter Pixel Art.

Was dazukommt

  • Zwei neue Asset-Arten: Pixel art und Palette. Die erste Pixel Art eines Projekts bekommt im selben Undo-Schritt eine Palette mit den 16 PICO-8-Farben. Jedes Pixel ist ein Index in die Palette, 0 ist transparent. Eine geänderte Palettenfarbe ändert jedes Bild mit, das die Palette nutzt.
  • Pixeldaten als eigene Dateien: Jede Ebene auf jedem Frame liegt als data/pixels/<sha256>.px auf dem Server, das Projekt hält nur die Namen. Hochgeladen wird vor dem Speichern des Projekts (neue Route POST ?r=pixels).
  • Werkzeuge: Stift, Radierer, Füllen (zusammenhängend oder alle Pixel dieser Farbe), Pipette, Linie, Rechteck und Ellipse (Umriss oder gefüllt), Pinsel 1 bis 8 px.
  • Ebenen: anlegen, löschen, umbenennen, umsortieren, ausblenden, Deckkraft, nach unten zusammenführen.
  • Frames: anlegen, duplizieren, löschen, umsortieren, Onion Skin und eine kleine Vorschau, die abspielt.
  • Ansicht: Zoom 1x bis 32x in ganzen Stufen, Raster ab 8x, Kachelvorschau 3x3, Resize… mit 3x3-Anker.
  • Verwendung: Alle Frames liegen nebeneinander in einem Bild, jeder Frame ist ein Ausschnitt wie bei einer geschnittenen Textur. Die Texture-Zeile bietet „Asset / Frame 2“ an, im Kontextmenü gibt es Create animation from frames.

Entscheidungen

  • Beim Zusammenführen geht die Deckkraft der oberen Ebene verloren, indizierte Farben kennen keine Mischfarben.
  • Nur die letzte Palettenfarbe ist löschbar, sonst verrutschen die Indizes in allen Bildern.
  • Undo speichert je Strich die ganze Ebene statt Pixel-Diffs.
  • Alt+Klick als Pipette gibt es trotzdem, weil es eine Maus-Geste ist und kein Tastenkürzel.
  • Die Palette wird nur im Pixel-Tab bearbeitet.

Folge-Issues

#197 Import aus Textur, #198 Auswahl/Kopieren/Spiegeln, #199 PNG-Export, #200 weitere Werkzeuge.

Tests

  • ./check.sh: 136 Dateien, 2049 Tests (vorher 135 / 2011), davon 34 neu in tests/core/pixel-art.test.ts.
  • e2e-Modul 48 frisch: ALL PASSED, 29 Checks, Konsole leer.
  • Gegenproben greifen: fünf an den Unit-Tests, die Reihenfolge Hochladen vor Speichern, und im Browser nicht hochgeladene Zellen.
  • Check-Summe 1259 ist gerechnet (1232 in CI gemessen + 27), gemessen wird sie im nächsten CI-Lauf.
Umgesetzt in 66d6aaf, Doku im Wiki unter [Pixel Art](https://git.nockal.com/meleki/game-maker/wiki/Pixel-Art). ## Was dazukommt - **Zwei neue Asset-Arten: Pixel art und Palette.** Die erste Pixel Art eines Projekts bekommt im selben Undo-Schritt eine Palette mit den 16 PICO-8-Farben. Jedes Pixel ist ein Index in die Palette, 0 ist transparent. Eine geänderte Palettenfarbe ändert jedes Bild mit, das die Palette nutzt. - **Pixeldaten als eigene Dateien:** Jede Ebene auf jedem Frame liegt als `data/pixels/<sha256>.px` auf dem Server, das Projekt hält nur die Namen. Hochgeladen wird vor dem Speichern des Projekts (neue Route `POST ?r=pixels`). - **Werkzeuge:** Stift, Radierer, Füllen (zusammenhängend oder alle Pixel dieser Farbe), Pipette, Linie, Rechteck und Ellipse (Umriss oder gefüllt), Pinsel 1 bis 8 px. - **Ebenen:** anlegen, löschen, umbenennen, umsortieren, ausblenden, Deckkraft, nach unten zusammenführen. - **Frames:** anlegen, duplizieren, löschen, umsortieren, Onion Skin und eine kleine Vorschau, die abspielt. - **Ansicht:** Zoom 1x bis 32x in ganzen Stufen, Raster ab 8x, Kachelvorschau 3x3, **Resize…** mit 3x3-Anker. - **Verwendung:** Alle Frames liegen nebeneinander in einem Bild, jeder Frame ist ein Ausschnitt wie bei einer geschnittenen Textur. Die Texture-Zeile bietet „Asset / Frame 2“ an, im Kontextmenü gibt es **Create animation from frames**. ## Entscheidungen - Beim Zusammenführen geht die Deckkraft der oberen Ebene verloren, indizierte Farben kennen keine Mischfarben. - Nur die letzte Palettenfarbe ist löschbar, sonst verrutschen die Indizes in allen Bildern. - Undo speichert je Strich die ganze Ebene statt Pixel-Diffs. - Alt+Klick als Pipette gibt es trotzdem, weil es eine Maus-Geste ist und kein Tastenkürzel. - Die Palette wird nur im Pixel-Tab bearbeitet. ## Folge-Issues #197 Import aus Textur, #198 Auswahl/Kopieren/Spiegeln, #199 PNG-Export, #200 weitere Werkzeuge. ## Tests - `./check.sh`: 136 Dateien, 2049 Tests (vorher 135 / 2011), davon 34 neu in `tests/core/pixel-art.test.ts`. - e2e-Modul 48 frisch: ALL PASSED, 29 Checks, Konsole leer. - Gegenproben greifen: fünf an den Unit-Tests, die Reihenfolge Hochladen vor Speichern, und im Browser nicht hochgeladene Zellen. - Check-Summe 1259 ist gerechnet (1232 in CI gemessen + 27), gemessen wird sie im nächsten CI-Lauf.
admin moved this to Done in Development on 2026-09-21 17:35:00 +02:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#130