<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>GameAP-Blog</title><link>https://blog.gameap.com/de/</link><description>Neueste Beiträge aus dem GameAP-Blog</description><language>de-DE</language><generator>Hugo 0.164.0</generator><atom:link href="https://blog.gameap.com/de/index.xml" rel="self" type="application/rss+xml"/><lastBuildDate>Sat, 08 Aug 2026 13:00:00 +0300</lastBuildDate><item><title>Wie veröffentlichen Sie Ihr Plugin?</title><link>https://blog.gameap.com/de/guides/publishing-plugins/</link><pubDate>Sat, 08 Aug 2026 13:00:00 +0300</pubDate><guid>https://blog.gameap.com/de/guides/publishing-plugins/</guid><description>GameAP-Plugins auf plugins.gameap.dev veröffentlichen: Plugin anlegen, Versionen über das Dashboard und aus CI hochladen, Moderation.</description><content:encoded>&lt;p&gt;GameAP-Plugins werden auf &lt;a href="https://plugins.gameap.dev" target="_blank" rel="noopener"&gt;plugins.gameap.dev&lt;/a&gt; veröffentlicht — von
dort installieren Nutzer sie direkt aus dem Panel. Diese Anleitung führt durch den gesamten Weg:
vom Anlegen des Plugin-Eintrags bis zum automatischen Ausliefern neuer Versionen aus CI.&lt;/p&gt;
&lt;p&gt;Vorausgesetzt wird, dass Ihr Plugin bereits geschrieben ist und zu einer &lt;code&gt;.wasm&lt;/code&gt; gebaut wird.
Außerdem brauchen Sie ein Konto auf plugins.gameap.dev: entweder eine normale Registrierung mit
E-Mail-Bestätigung oder die Anmeldung über GitHub, GitLab oder Google.&lt;/p&gt;
&lt;p&gt;Es gibt zwei Wege, eine Version hochzuladen: manuell über das Dashboard oder über die API aus CI.
Beginnen Sie mit dem Dashboard und steigen Sie auf CI um, sobald Ihr Build stabil läuft.&lt;/p&gt;
&lt;h2 id="schritt-1-ein-entwicklerkonto"&gt;Schritt 1. Ein Entwicklerkonto &lt;a class="hanchor" href="#schritt-1-ein-entwicklerkonto" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Das Veröffentlichen von Plugins erfordert ein Konto mit Entwicklerstatus. Dieser wird kostenlos
und sofort vergeben — Sie müssen lediglich die Veröffentlichungsregeln akzeptieren.&lt;/p&gt;
&lt;p&gt;Klicken Sie im Plugin-Marktplatz auf &lt;strong&gt;Publish your plugin&lt;/strong&gt; („Ihr Plugin veröffentlichen“) — die
Schaltfläche in der oberen rechten Ecke.&lt;/p&gt;
&lt;figure&gt;&lt;a class="zoom" href="https://blog.gameap.com/de/guides/publishing-plugins/publish-plugins.de.png" target="_blank" rel="noopener"&gt;&lt;picture&gt;
 &lt;source type="image/webp" srcset="https://blog.gameap.com/de/guides/publishing-plugins/publish-plugins.de_hu_5159adbc8240679d.webp 480w, https://blog.gameap.com/de/guides/publishing-plugins/publish-plugins.de_hu_e87690acd34e62fd.webp 800w, https://blog.gameap.com/de/guides/publishing-plugins/publish-plugins.de_hu_d5e0ccee4c05e9e0.webp 1200w" sizes="(min-width: 860px) 808px, 100vw"&gt;
 &lt;img src="https://blog.gameap.com/de/guides/publishing-plugins/publish-plugins.de_hu_948bf2e9ae7b63c.png" srcset="https://blog.gameap.com/de/guides/publishing-plugins/publish-plugins.de_hu_2603f5b6f5388b0d.png 480w, https://blog.gameap.com/de/guides/publishing-plugins/publish-plugins.de_hu_1ef640ba0eb0d06.png 800w, https://blog.gameap.com/de/guides/publishing-plugins/publish-plugins.de_hu_948bf2e9ae7b63c.png 1200w" sizes="(min-width: 860px) 808px, 100vw" width="1200" height="756" alt="Die Schaltfläche „Publish your plugin“ im Plugin-Marktplatz" loading="lazy" decoding="async"&gt;
 &lt;/picture&gt;&lt;/a&gt;&lt;figcaption&gt;Der Plugin-Marktplatz&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Die Seite mit den Veröffentlichungsregeln öffnet sich. Kurz gesagt, wozu Sie sich verpflichten:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Funktionierende, hochwertige Plugins&lt;/strong&gt; — nur funktionsfähige, getestete Plugins, die das
halten, was ihre Beschreibung verspricht.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kein schädlicher Code&lt;/strong&gt; — keine Backdoors, versteckten Miner oder verschleierte Logik; jede
Erhebung von Nutzerdaten muss klar offengelegt werden.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rechte und Lizenzierung&lt;/strong&gt; — Sie besitzen den Code oder dürfen ihn verbreiten, Lizenzen Dritter
werden eingehalten, und die Lizenz Ihres Plugins ist angegeben.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GameAP-Kompatibilität&lt;/strong&gt; — das Plugin funktioniert mit aktuellen Panel-Releases und erfüllt
die Anforderungen an das Plugin-Format.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Updates und Support&lt;/strong&gt; — kritische Fehler und Sicherheitsprobleme werden innerhalb einer
angemessenen Frist behoben, und Nutzermeldungen erhalten eine Antwort.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Moderation&lt;/strong&gt; — jedes Plugin und jede Version wird geprüft, und ein Plugin, das gegen die
Regeln verstößt, kann jederzeit entfernt werden.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kein Spam und keine Duplikate&lt;/strong&gt; — keine irreführenden Namen, kein Keyword-Stuffing.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Der vollständige Text steht auf der Seite selbst — lesen Sie ihn am besten ganz.&lt;/p&gt;
&lt;!-- Screenshot: Seite mit den Veröffentlichungsregeln und der Schaltfläche "Agree" → publish-rules.de.png / publish-rules.en.png --&gt;
&lt;p&gt;Klicken Sie unten auf &lt;strong&gt;Agree&lt;/strong&gt; („Zustimmen“). Die Rolle wird sofort vergeben, ohne Prüfung und
Wartezeit: In der Seitenleiste erscheint der Bereich &lt;strong&gt;Developer&lt;/strong&gt; („Entwickler“) mit Dashboard,
My Plugins, New Plugin und Support, und eine E-Mail teilt Ihnen mit, dass Sie nun Entwickler sind.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hinweis.&lt;/strong&gt; Die Regeln können nur mit einer bestätigten E-Mail-Adresse akzeptiert werden:
Andernfalls bleibt die Schaltfläche &lt;strong&gt;Agree&lt;/strong&gt; deaktiviert, und die Seite zeigt eine Erinnerung,
Ihre Adresse zu bestätigen. Konten, die über GitHub, GitLab oder Google erstellt wurden, gelten
sofort als bestätigt.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Die Schaltfläche &lt;strong&gt;Publish your plugin&lt;/strong&gt; ist für alle sichtbar, auch für Besucher, die nicht
angemeldet sind. Ohne Sitzung zeigt die Regelseite stattdessen &lt;strong&gt;Log in to agree&lt;/strong&gt; („Anmelden, um
zuzustimmen“) — nach der Anmeldung kehren Sie zu den Regeln zurück.&lt;/p&gt;
&lt;h2 id="schritt-2-das-plugin-anlegen"&gt;Schritt 2. Das Plugin anlegen &lt;a class="hanchor" href="#schritt-2-das-plugin-anlegen" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Wählen Sie im linken Menü &lt;strong&gt;New Plugin&lt;/strong&gt; („Neues Plugin“) — das Erstellungsformular öffnet sich.&lt;/p&gt;
&lt;figure&gt;&lt;a class="zoom" href="https://blog.gameap.com/de/guides/publishing-plugins/new-plugin.de.png" target="_blank" rel="noopener"&gt;&lt;picture&gt;
 &lt;source type="image/webp" srcset="https://blog.gameap.com/de/guides/publishing-plugins/new-plugin.de_hu_66c90ae02a704edc.webp 480w, https://blog.gameap.com/de/guides/publishing-plugins/new-plugin.de_hu_ed73830ca4a7af69.webp 800w, https://blog.gameap.com/de/guides/publishing-plugins/new-plugin.de_hu_5b9135d573b083bb.webp 1200w" sizes="(min-width: 860px) 808px, 100vw"&gt;
 &lt;img src="https://blog.gameap.com/de/guides/publishing-plugins/new-plugin.de_hu_ed7a4092b897f55.png" srcset="https://blog.gameap.com/de/guides/publishing-plugins/new-plugin.de_hu_df39b9d938ca9d05.png 480w, https://blog.gameap.com/de/guides/publishing-plugins/new-plugin.de_hu_2ce3df4183fea9ad.png 800w, https://blog.gameap.com/de/guides/publishing-plugins/new-plugin.de_hu_ed7a4092b897f55.png 1200w" sizes="(min-width: 860px) 808px, 100vw" width="1200" height="662" alt="Das Formular zum Anlegen eines Plugins im Dashboard von plugins.gameap.dev" loading="lazy" decoding="async"&gt;
 &lt;/picture&gt;&lt;/a&gt;&lt;figcaption&gt;Ein neues Plugin anlegen&lt;/figcaption&gt;&lt;/figure&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Feld&lt;/th&gt;
					&lt;th&gt;Pflicht&lt;/th&gt;
					&lt;th&gt;Was gehört hinein&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Name&lt;/td&gt;
					&lt;td&gt;ja&lt;/td&gt;
					&lt;td&gt;Bis zu 255 Zeichen&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Summary&lt;/td&gt;
					&lt;td&gt;ja&lt;/td&gt;
					&lt;td&gt;Ein einziger Satz für die Katalogkarte, bis zu 500 Zeichen&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Description&lt;/td&gt;
					&lt;td&gt;ja&lt;/td&gt;
					&lt;td&gt;Vollständige Beschreibung in Markdown — das Feld hat eine Formatierungs-Symbolleiste&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Category&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;Eine der drei unten&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Labels&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;Stichwörter, über die sich das Plugin leichter finden lässt&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;License&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;Freier Text: &lt;code&gt;MIT&lt;/code&gt;, &lt;code&gt;GPL-3.0&lt;/code&gt;, &lt;code&gt;Proprietary&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Source URL&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;Link zu den Quellen, falls sie offen sind&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Repository URL&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;Link zum Repository&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Homepage URL&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;Website des Plugins oder des Autors&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Die Kategorien:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Server Management&lt;/strong&gt; („Serververwaltung“) — die meisten Plugins. Alles, was Aktionen auf einem
Gameserver hinzufügt.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Files&lt;/strong&gt; („Dateien“) — Erweiterungen des Dateimanagers: Editoren, Viewer für bestimmte
Formate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integrations&lt;/strong&gt; („Integrationen“) — Plugins, die die Möglichkeiten des Panels wesentlich
erweitern, etwa die Datenbankverwaltung.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Das Icon kann in diesem Schritt noch nicht hochgeladen werden — das Formular weist ausdrücklich
darauf hin; der Uploader erscheint direkt nach dem Anlegen.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hinweis.&lt;/strong&gt; Source URL und Repository URL wirken sich auf mehr als den Eintrag aus. Wenn keines
der beiden Felder ausgefüllt ist, muss &lt;strong&gt;jede&lt;/strong&gt; Version ein Quellarchiv mitbringen — die
Moderatoren brauchen etwas, gegen das sie den Build prüfen können. Füllen Sie mindestens eines
der Felder aus, wenn Ihre Quellen öffentlich sind.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="schritt-3-die-plugin-id"&gt;Schritt 3. Die Plugin-ID &lt;a class="hanchor" href="#schritt-3-die-plugin-id" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Nach dem Klick auf &lt;strong&gt;Create&lt;/strong&gt; („Anlegen“) landen Sie auf der Bearbeitungsseite des Plugins. Ihr
erster Block ist die &lt;strong&gt;Plugin ID&lt;/strong&gt; — ein schreibgeschütztes Feld mit einer Kopierschaltfläche.&lt;/p&gt;
&lt;!-- Screenshot: oberer Teil der Bearbeitungsseite mit dem Feld "Plugin ID" und der Kopierschaltfläche → plugin-id.de.png / plugin-id.en.png --&gt;
&lt;p&gt;Diese ID muss in den Quellcode Ihres Plugins eingetragen werden — in das &lt;code&gt;id&lt;/code&gt;-Feld der
&lt;code&gt;PluginInfo&lt;/code&gt;-Struct, die &lt;code&gt;GetInfo&lt;/code&gt; zurückgibt. So ordnet das Panel ein installiertes Plugin
seinem Marktplatz-Eintrag zu.&lt;/p&gt;
&lt;p&gt;Die ID wird einmalig beim Anlegen erzeugt und &lt;strong&gt;kann nicht geändert werden&lt;/strong&gt;. Im Kern ist sie
eine 64-Bit-Zahl (8 zufällige Bytes) in Base32-Schreibweise — 13 lateinische Buchstaben und
Ziffern, zum Beispiel &lt;code&gt;fmqnme42gg7da&lt;/code&gt;. Dieselbe ID taucht in der URL der Plugin-Seite und in der
Adresse des CI-Endpunkts auf.&lt;/p&gt;
&lt;p&gt;Wie das in bestehenden Plugins aussieht:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/gameap/plugin-mysql/blob/main/src/lib.rs" target="_blank" rel="noopener"&gt;plugin-mysql&lt;/a&gt; — die Konstante &lt;code&gt;PLUGIN_ID&lt;/code&gt; (&lt;code&gt;fmqnme42gg7da&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gameap/plugin-goldsrc-addons/blob/main/src/lib.rs" target="_blank" rel="noopener"&gt;plugin-goldsrc-addons&lt;/a&gt; — &lt;code&gt;PLUGIN_ID&lt;/code&gt; (&lt;code&gt;ezvdsxmlu6fbk&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gameap/plugin-minecraft-modrinth/blob/main/assembly/constants.ts" target="_blank" rel="noopener"&gt;plugin-minecraft-modrinth&lt;/a&gt; — &lt;code&gt;PLUGIN_ID&lt;/code&gt; (&lt;code&gt;dshdabjp2l73a&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hinweis.&lt;/strong&gt; Tragen Sie die ID ein und bauen Sie die &lt;code&gt;.wasm&lt;/code&gt; neu, bevor Sie die erste Version
hochladen. Versionen sind unveränderlich: Sie können eine Datei nicht unter derselben Nummer
erneut hochladen — Sie müssten die Versionsnummer erhöhen.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="schritt-4-icon-und-übersetzungen"&gt;Schritt 4. Icon und Übersetzungen &lt;a class="hanchor" href="#schritt-4-icon-und-%c3%bcbersetzungen" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Dieselbe Bearbeitungsseite enthält einen Icon-Uploader: JPG, PNG, WebP oder SVG, bis zu 2 MB,
empfohlen 128×128.&lt;/p&gt;
&lt;!-- Screenshot: Icon-Uploader auf der Bearbeitungsseite → icon-upload.de.png / icon-upload.en.png --&gt;
&lt;p&gt;Die Plugin-Seite hat einen Block &lt;strong&gt;Translations&lt;/strong&gt; („Übersetzungen“). Der Katalog ist zweisprachig,
und jeder Besucher sieht den Eintrag in seiner eigenen Sprache: Ohne Übersetzung bekommt ein
russischer Nutzer die englische Beschreibung und umgekehrt. Name, Kurzbeschreibung und
Beschreibung werden pro Sprache separat übersetzt — fünf Minuten Arbeit, die den Eintrag
spürbar besser lesen lassen.&lt;/p&gt;
&lt;!-- Screenshot: Block "Translations" auf der Plugin-Seite → translations.de.png / translations.en.png --&gt;
&lt;h2 id="schritt-5-eine-version-hochladen"&gt;Schritt 5. Eine Version hochladen &lt;a class="hanchor" href="#schritt-5-eine-version-hochladen" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Suchen Sie auf der Plugin-Seite die Karte &lt;strong&gt;Versions&lt;/strong&gt; („Versionen“) und klicken Sie auf
&lt;strong&gt;Upload Version&lt;/strong&gt; („Version hochladen“).&lt;/p&gt;
&lt;figure&gt;&lt;a class="zoom" href="https://blog.gameap.com/de/guides/publishing-plugins/upload-version.de.png" target="_blank" rel="noopener"&gt;&lt;picture&gt;
 &lt;source type="image/webp" srcset="https://blog.gameap.com/de/guides/publishing-plugins/upload-version.de_hu_243bccfe940fb645.webp 480w, https://blog.gameap.com/de/guides/publishing-plugins/upload-version.de_hu_aa693942bf347d41.webp 800w, https://blog.gameap.com/de/guides/publishing-plugins/upload-version.de_hu_1f9f52625438df09.webp 1200w" sizes="(min-width: 860px) 808px, 100vw"&gt;
 &lt;img src="https://blog.gameap.com/de/guides/publishing-plugins/upload-version.de_hu_a143f910d4449488.png" srcset="https://blog.gameap.com/de/guides/publishing-plugins/upload-version.de_hu_fb2b83c72ead6ea2.png 480w, https://blog.gameap.com/de/guides/publishing-plugins/upload-version.de_hu_9724bcb241379e5.png 800w, https://blog.gameap.com/de/guides/publishing-plugins/upload-version.de_hu_a143f910d4449488.png 1200w" sizes="(min-width: 860px) 808px, 100vw" width="1200" height="611" alt="Das Formular zum Hochladen einer Plugin-Version" loading="lazy" decoding="async"&gt;
 &lt;/picture&gt;&lt;/a&gt;&lt;figcaption&gt;Eine neue Version hochladen&lt;/figcaption&gt;&lt;/figure&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Feld&lt;/th&gt;
					&lt;th&gt;Pflicht&lt;/th&gt;
					&lt;th&gt;Was gehört hinein&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Version&lt;/td&gt;
					&lt;td&gt;ja&lt;/td&gt;
					&lt;td&gt;Semantische Version: &lt;code&gt;1.0.0&lt;/code&gt;, &lt;code&gt;1.2.0-beta.1&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Plugin File&lt;/td&gt;
					&lt;td&gt;ja&lt;/td&gt;
					&lt;td&gt;Die kompilierte &lt;code&gt;.wasm&lt;/code&gt;, bis zu 100 MB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GPG Signature&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;Abgetrennte Signatur &lt;code&gt;.sig&lt;/code&gt; oder &lt;code&gt;.asc&lt;/code&gt;, bis zu 1 MB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Source Code Archive&lt;/td&gt;
					&lt;td&gt;abhängig&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;.zip&lt;/code&gt; oder &lt;code&gt;.tar.gz&lt;/code&gt;, bis zu 50 MB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Changelog&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;Was sich seit der vorherigen Version geändert hat, in Markdown&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Stable Release&lt;/td&gt;
					&lt;td&gt;—&lt;/td&gt;
					&lt;td&gt;Ein Schalter, &lt;strong&gt;standardmäßig aktiviert&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Min GameAP Version&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;Die Panel-Version, ab der Ihr Plugin funktioniert&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Die &lt;strong&gt;GPG-Signatur&lt;/strong&gt; ist optional, aber willkommen: Der Server speichert sie unverändert und
verifiziert sie nie — sie existiert, damit Nutzer die Authentizität der Datei selbst prüfen
können.&lt;/p&gt;
&lt;p&gt;Das &lt;strong&gt;Quellcode-Archiv&lt;/strong&gt; ist Pflicht, wenn beim Plugin weder Source URL noch Repository URL
ausgefüllt sind — das Formular ändert die Feldbezeichnung dann selbstständig von „(Optional)“
zu „(Required)“. Das Archiv wird nur für Moderation und Build-Verifikation verwendet; es wird
nie veröffentlicht und ist über keinen öffentlichen Endpunkt erreichbar.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hinweis.&lt;/strong&gt; Eine über das Dashboard hochgeladene Version bleibt ein &lt;strong&gt;Entwurf&lt;/strong&gt;. Bis Sie sie
zur Prüfung einreichen, sieht sie niemand.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="screenshots-der-version"&gt;Screenshots der Version &lt;a class="hanchor" href="#screenshots-der-version" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Direkt nach dem Upload öffnet sich ein zweiter Schritt — &lt;strong&gt;Add Screenshots&lt;/strong&gt; („Screenshots
hinzufügen“). Screenshots gehören zu einer bestimmten Version: JPG, PNG oder WebP, bis zu
10 Stück, jeweils 5 MB. Der Schritt kann übersprungen und später von der Versionsseite aus
nachgeholt werden.&lt;/p&gt;
&lt;h2 id="schritt-6-zur-prüfung-einreichen"&gt;Schritt 6. Zur Prüfung einreichen &lt;a class="hanchor" href="#schritt-6-zur-pr%c3%bcfung-einreichen" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Plugins durchlaufen eine Moderation — anhand genau der Veröffentlichungsregeln, die Sie in
Schritt 1 akzeptiert haben. Im Kopfbereich der Plugin-Seite gibt es die Schaltfläche
&lt;strong&gt;Submit for Review&lt;/strong&gt; („Zur Prüfung einreichen“) — sie ist nur sichtbar, solange das Plugin den
Status Draft oder Rejected hat.&lt;/p&gt;
&lt;!-- Screenshot: Kopfbereich der Plugin-Seite mit der Schaltfläche "Submit for Review" und die Versionstabelle mit Status-Badges → submit-review.de.png / submit-review.en.png --&gt;
&lt;p&gt;Ein Plugin ohne Versionen kann nicht eingereicht werden — laden Sie zuerst eine Version hoch.
Das Einreichen einer &lt;em&gt;Version&lt;/em&gt; über die Versionstabelle versetzt auch das Plugin selbst von
Draft zu Pending Review, sodass die Schaltfläche im Kopfbereich in der Regel nicht separat
gebraucht wird.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Status&lt;/th&gt;
					&lt;th&gt;Bedeutung&lt;/th&gt;
					&lt;th&gt;Was Sie tun können&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Draft&lt;/td&gt;
					&lt;td&gt;Angelegt, nirgendwo eingereicht&lt;/td&gt;
					&lt;td&gt;Bearbeiten, zur Prüfung einreichen, löschen&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pending Review&lt;/td&gt;
					&lt;td&gt;Wartet auf einen Moderator&lt;/td&gt;
					&lt;td&gt;Warten&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Rejected&lt;/td&gt;
					&lt;td&gt;Ein Moderator hat es zurückgeschickt&lt;/td&gt;
					&lt;td&gt;Korrigieren und erneut einreichen&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Released&lt;/td&gt;
					&lt;td&gt;Für alle im Katalog verfügbar&lt;/td&gt;
					&lt;td&gt;Neue Versionen hochladen&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Approved&lt;/td&gt;
					&lt;td&gt;Ein Zwischenstatus im Datenmodell&lt;/td&gt;
					&lt;td&gt;—&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Deprecated&lt;/td&gt;
					&lt;td&gt;Als veraltet markiert&lt;/td&gt;
					&lt;td&gt;Weiterhin installierbar, aber gekennzeichnet&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Retracted&lt;/td&gt;
					&lt;td&gt;Von der Veröffentlichung zurückgezogen&lt;/td&gt;
					&lt;td&gt;Nicht zur Installation verfügbar&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Nach der Freigabe wechseln Plugin und Version direkt zu &lt;strong&gt;Released&lt;/strong&gt;. Öffentlich sichtbar sind
nur Objekte in diesem Status: Wenn ein Plugin veröffentlicht ist, seine einzige Version aber noch
in der Prüfung, gibt es nichts zu installieren.&lt;/p&gt;
&lt;p&gt;Der Ablehnungsgrund kommt per E-Mail — die Plugin-Seite zeigt nur den Status, also prüfen Sie
Ihren Posteingang.&lt;/p&gt;
&lt;h2 id="deploy-tokens"&gt;Deploy-Tokens &lt;a class="hanchor" href="#deploy-tokens" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Um Versionen aus CI zu veröffentlichen, brauchen Sie ein Deploy-Token. Es befindet sich ganz
unten auf der Plugin-Seite, in der Karte &lt;strong&gt;Deploy Tokens&lt;/strong&gt;.&lt;/p&gt;
&lt;figure&gt;&lt;a class="zoom" href="https://blog.gameap.com/de/guides/publishing-plugins/token-deploy.de.png" target="_blank" rel="noopener"&gt;&lt;picture&gt;
 &lt;source type="image/webp" srcset="https://blog.gameap.com/de/guides/publishing-plugins/token-deploy.de_hu_197cb25595fb5b5f.webp 480w, https://blog.gameap.com/de/guides/publishing-plugins/token-deploy.de_hu_a9f5978f4b4c86b9.webp 800w, https://blog.gameap.com/de/guides/publishing-plugins/token-deploy.de_hu_1699d5db1124bb17.webp 1200w" sizes="(min-width: 860px) 808px, 100vw"&gt;
 &lt;img src="https://blog.gameap.com/de/guides/publishing-plugins/token-deploy.de_hu_4faa04302751dca0.png" srcset="https://blog.gameap.com/de/guides/publishing-plugins/token-deploy.de_hu_dbe4db4c7c810656.png 480w, https://blog.gameap.com/de/guides/publishing-plugins/token-deploy.de_hu_beffba6e035fdfb3.png 800w, https://blog.gameap.com/de/guides/publishing-plugins/token-deploy.de_hu_4faa04302751dca0.png 1200w" sizes="(min-width: 860px) 808px, 100vw" width="1200" height="611" alt="Die Karte „Deploy Tokens“ am Ende der Plugin-Seite" loading="lazy" decoding="async"&gt;
 &lt;/picture&gt;&lt;/a&gt;&lt;figcaption&gt;Die Karte mit den Deploy-Tokens&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Klicken Sie auf &lt;strong&gt;Create Token&lt;/strong&gt; („Token erstellen“) und füllen Sie den Dialog aus: einen Namen
(zum Beispiel &lt;code&gt;GitHub Actions&lt;/code&gt;) und optional ein Ablaufdatum.&lt;/p&gt;
&lt;figure&gt;&lt;a class="zoom" href="https://blog.gameap.com/de/guides/publishing-plugins/token-deploy-create-form.de.png" target="_blank" rel="noopener"&gt;&lt;picture&gt;
 &lt;source type="image/webp" srcset="https://blog.gameap.com/de/guides/publishing-plugins/token-deploy-create-form.de_hu_9247ea9ef3fc28dc.webp 480w, https://blog.gameap.com/de/guides/publishing-plugins/token-deploy-create-form.de_hu_bc8c408f37c39612.webp 800w" sizes="(min-width: 860px) 808px, 100vw"&gt;
 &lt;img src="https://blog.gameap.com/de/guides/publishing-plugins/token-deploy-create-form.de_hu_c4886a088e2fce6d.png" srcset="https://blog.gameap.com/de/guides/publishing-plugins/token-deploy-create-form.de_hu_e53a113cd49f24d.png 480w, https://blog.gameap.com/de/guides/publishing-plugins/token-deploy-create-form.de_hu_c4886a088e2fce6d.png 800w" sizes="(min-width: 860px) 808px, 100vw" width="800" height="514" alt="Der Dialog zum Erstellen eines Deploy-Tokens mit den Feldern „Name“ und „Expires At“" loading="lazy" decoding="async"&gt;
 &lt;/picture&gt;&lt;/a&gt;&lt;figcaption&gt;Ein Deploy-Token erstellen&lt;/figcaption&gt;&lt;/figure&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hinweis.&lt;/strong&gt; Das Token wird genau einmal angezeigt, direkt nach dem Erstellen. Auf dem Server
wird nur sein Hash gespeichert, der Wert lässt sich nicht wiederherstellen — kopieren Sie es
direkt in Ihre CI-Secrets.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Was Sie über Tokens wissen sollten:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ein Token ist an ein Plugin gebunden und kann nur dessen Versionen hochladen. Es öffnet weder
andere Plugins noch den Rest der API.&lt;/li&gt;
&lt;li&gt;Das Format ist &lt;code&gt;gapd_&lt;/code&gt; plus 43 Zeichen, insgesamt 48. Das Präfix ist für Secret-Scanner leicht
zu erkennen.&lt;/li&gt;
&lt;li&gt;Die Tabelle zeigt das Token-Präfix, das Erstellungsdatum, die letzte Verwendung und das
Ablaufdatum — praktisch, um herauszufinden, welches Token noch in Gebrauch ist.&lt;/li&gt;
&lt;li&gt;Der Widerruf wirkt sofort: Eine Pipeline mit einem widerrufenen Token schlägt beim nächsten
Lauf fehl.&lt;/li&gt;
&lt;li&gt;Ein einzelnes Plugin kann bis zu 20 Tokens haben.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="aus-ci-veröffentlichen"&gt;Aus CI veröffentlichen &lt;a class="hanchor" href="#aus-ci-ver%c3%b6ffentlichen" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Der CI-Endpunkt nimmt eine neue Version ohne interaktiven Login entgegen — er authentifiziert
sich mit einem Deploy-Token.&lt;/p&gt;
&lt;h3 id="hochladen-mit-curl"&gt;Hochladen mit curl &lt;a class="hanchor" href="#hochladen-mit-curl" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl --fail-with-body -sS &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -H &lt;span class="s2"&gt;&amp;#34;Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$GAMEAP_DEPLOY_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -F &lt;span class="s2"&gt;&amp;#34;version=1.2.3&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -F &lt;span class="s2"&gt;&amp;#34;file=@build/plugin.wasm&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -F &lt;span class="s2"&gt;&amp;#34;signature=@build/plugin.wasm.asc&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -F &lt;span class="s2"&gt;&amp;#34;changelog=Absturz beim Serverneustart behoben&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -F &lt;span class="s2"&gt;&amp;#34;min_gameap_version=4.1.0&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -F &lt;span class="s2"&gt;&amp;#34;is_stable=true&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;https://plugins.gameap.dev/api/ci/plugins/&lt;/span&gt;&lt;span class="nv"&gt;$GAMEAP_PLUGIN_ID&lt;/span&gt;&lt;span class="s2"&gt;/versions&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Die Anfrage ist ein &lt;code&gt;POST&lt;/code&gt; mit &lt;code&gt;multipart/form-data&lt;/code&gt;. Die Formularfelder:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Feld&lt;/th&gt;
					&lt;th&gt;Pflicht&lt;/th&gt;
					&lt;th&gt;Beschreibung&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;version&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;ja&lt;/td&gt;
					&lt;td&gt;Semantische Version, z. B. &lt;code&gt;1.2.3&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;file&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;ja&lt;/td&gt;
					&lt;td&gt;Die kompilierte &lt;code&gt;.wasm&lt;/code&gt;, bis zu 100 MB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;signature&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;Abgetrennte GPG-Signatur, bis zu 1 MB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;source&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;abhängig&lt;/td&gt;
					&lt;td&gt;Quellarchiv &lt;code&gt;.zip&lt;/code&gt;/&lt;code&gt;.tar.gz&lt;/code&gt; bis 50 MB; Pflicht, wenn das Plugin weder Source URL noch Repository URL hat&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;changelog&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;Release-Notes; praktisch aus einer Datei: &lt;code&gt;-F &amp;quot;changelog=&amp;lt;CHANGELOG.md&amp;quot;&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;min_gameap_version&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;Minimale GameAP-Version&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;min_plugin_api_version&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;Minimale Plugin-API-Version (das Dashboard-Formular hat dieses Feld nicht)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;is_stable&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;true&lt;/code&gt; oder &lt;code&gt;1&lt;/code&gt; markiert die Version als stabil&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;submit&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;nein&lt;/td&gt;
					&lt;td&gt;Standardmäßig &lt;code&gt;true&lt;/code&gt;; &lt;code&gt;false&lt;/code&gt; belässt die Version als Entwurf&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Setzen Sie keinen Schrägstrich ans Ende der URL.&lt;/strong&gt; Der Router beantwortet &lt;code&gt;.../versions/&lt;/code&gt; mit
einem &lt;code&gt;301&lt;/code&gt;, und curl wiederholt den &lt;code&gt;POST&lt;/code&gt;-Body bei einem Redirect nicht — der Upload würde
still zu einem &lt;code&gt;GET&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Eine erfolgreiche Antwort ist ein &lt;code&gt;201&lt;/code&gt; mit einem Body wie:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;plugin_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;fmqnme42gg7da&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;1.2.3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;file_size&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1048576&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;file_hash&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;9f86d081884c7d65...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;has_source&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pending_review&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="github-actions"&gt;GitHub Actions &lt;a class="hanchor" href="#github-actions" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Dieser Workflow wird ausgelöst, wenn ein GitHub-Release veröffentlicht wird, baut das Plugin,
signiert es — sofern ein GPG-Schlüssel in den Secrets konfiguriert ist — und lädt es zu
plugins.gameap.dev hoch. Der Release-Text wird zum Changelog, und die
Version wird nur dann als stabil markiert, wenn das Release kein Pre-Release ist.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Publish plugin&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;release&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;published]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;actions/checkout@v4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Build plugin&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;make wasm &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# muss build/plugin.wasm erzeugen&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Sign plugin&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;env.GPG_SIGNING_KEY != &amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;GPG_SIGNING_KEY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ secrets.GPG_SIGNING_KEY }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;GPG_PASSPHRASE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ secrets.GPG_PASSPHRASE }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; printf &amp;#39;%s&amp;#39; &amp;#34;$GPG_SIGNING_KEY&amp;#34; | gpg --batch --import
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; printf &amp;#39;%s&amp;#39; &amp;#34;$GPG_PASSPHRASE&amp;#34; | gpg --batch --yes \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; --pinentry-mode loopback --passphrase-fd 0 \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; --detach-sign --armor \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; -o build/plugin.wasm.asc build/plugin.wasm&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Publish to plugins.gameap.dev&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;GAMEAP_DEPLOY_TOKEN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ secrets.GAMEAP_DEPLOY_TOKEN }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;GAMEAP_PLUGIN_ID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ vars.GAMEAP_PLUGIN_ID }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;TAG&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ github.event.release.tag_name }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;RELEASE_BODY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ github.event.release.body }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;PRERELEASE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ github.event.release.prerelease }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; VERSION=&amp;#34;${TAG#v}&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; printf &amp;#39;%s&amp;#39; &amp;#34;$RELEASE_BODY&amp;#34; &amp;gt; &amp;#34;$RUNNER_TEMP/changelog.md&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; ARGS=(--fail-with-body -sS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; -H &amp;#34;Authorization: Bearer ${GAMEAP_DEPLOY_TOKEN}&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; -F &amp;#34;version=${VERSION}&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; -F &amp;#34;file=@build/plugin.wasm&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; -F &amp;#34;changelog=&amp;lt;${RUNNER_TEMP}/changelog.md&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # Signatur nur anhängen, wenn der Sign-Schritt sie erzeugt hat
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; if [ -f build/plugin.wasm.asc ]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; ARGS+=(-F &amp;#34;signature=@build/plugin.wasm.asc&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; if [ &amp;#34;$PRERELEASE&amp;#34; != &amp;#34;true&amp;#34; ]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; ARGS+=(-F &amp;#34;is_stable=true&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; else
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; ARGS+=(-F &amp;#34;is_stable=false&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; curl &amp;#34;${ARGS[@]}&amp;#34; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;https://plugins.gameap.dev/api/ci/plugins/${GAMEAP_PLUGIN_ID}/versions&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;VERSION=&amp;quot;${TAG#v}&amp;quot;&lt;/code&gt; entfernt das führende &lt;code&gt;v&lt;/code&gt;, sodass das Tag &lt;code&gt;v1.2.3&lt;/code&gt; als Version &lt;code&gt;1.2.3&lt;/code&gt;
veröffentlicht wird.&lt;/p&gt;
&lt;p&gt;Die produktive Variante dieses Workflows — mit Frontend-Build, Cargo-Cache und
HTTP-Statusprüfung — liegt in
&lt;a href="https://github.com/gameap/plugin-mysql/blob/main/.github/workflows/release.yml" target="_blank" rel="noopener"&gt;plugin-mysql&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="das-github-repository-konfigurieren"&gt;Das GitHub-Repository konfigurieren &lt;a class="hanchor" href="#das-github-repository-konfigurieren" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Token und Plugin-ID gehören nicht in den Code — sie gehören in die Repository-Einstellungen.
Öffnen Sie &lt;strong&gt;Settings → Secrets and variables (unter Security and quality) → Actions&lt;/strong&gt;.&lt;/p&gt;
&lt;figure&gt;&lt;a class="zoom" href="https://blog.gameap.com/de/guides/publishing-plugins/github-secrets-sidebar.en.png" target="_blank" rel="noopener"&gt;&lt;picture&gt;
 &lt;source type="image/webp" srcset="https://blog.gameap.com/de/guides/publishing-plugins/github-secrets-sidebar.en_hu_9541da5da7d0384f.webp 480w, https://blog.gameap.com/de/guides/publishing-plugins/github-secrets-sidebar.en_hu_d3ee64d4baa6a46f.webp 800w" sizes="(min-width: 860px) 808px, 100vw"&gt;
 &lt;img src="https://blog.gameap.com/de/guides/publishing-plugins/github-secrets-sidebar.en_hu_9963f0bb4b582211.png" srcset="https://blog.gameap.com/de/guides/publishing-plugins/github-secrets-sidebar.en_hu_a2eced0c8f3ab9c4.png 480w, https://blog.gameap.com/de/guides/publishing-plugins/github-secrets-sidebar.en_hu_9963f0bb4b582211.png 800w" sizes="(min-width: 860px) 808px, 100vw" width="800" height="844" alt="Der Punkt „Secrets and variables → Actions“ in der Seitenleiste der GitHub-Repository-Einstellungen" loading="lazy" decoding="async"&gt;
 &lt;/picture&gt;&lt;/a&gt;&lt;figcaption&gt;Der Einstellungsbereich des Repositorys&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Klicken Sie auf dem Tab &lt;strong&gt;Secrets&lt;/strong&gt; auf &lt;strong&gt;New repository secret&lt;/strong&gt; und fügen Sie hinzu:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Name&lt;/th&gt;
					&lt;th&gt;Wert&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;GAMEAP_DEPLOY_TOKEN&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Das Deploy-Token, das Sie beim Erstellen kopiert haben (beginnt mit &lt;code&gt;gapd_&lt;/code&gt;)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;GPG_SIGNING_KEY&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Ein privater GPG-Schlüssel im ASCII-Armor-Format, falls Sie Ihre Builds signieren&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;GPG_PASSPHRASE&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Die Passphrase des GPG-Schlüssels, falls dieser geschützt ist&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;figure&gt;&lt;a class="zoom" href="https://blog.gameap.com/de/guides/publishing-plugins/github-secrets.en.png" target="_blank" rel="noopener"&gt;&lt;picture&gt;
 &lt;source type="image/webp" srcset="https://blog.gameap.com/de/guides/publishing-plugins/github-secrets.en_hu_dff430a18e15af5b.webp 480w, https://blog.gameap.com/de/guides/publishing-plugins/github-secrets.en_hu_531cc5e7a73438e1.webp 800w, https://blog.gameap.com/de/guides/publishing-plugins/github-secrets.en_hu_6fdea19099fffc55.webp 1200w" sizes="(min-width: 860px) 808px, 100vw"&gt;
 &lt;img src="https://blog.gameap.com/de/guides/publishing-plugins/github-secrets.en_hu_58a93b3c3b3364b1.png" srcset="https://blog.gameap.com/de/guides/publishing-plugins/github-secrets.en_hu_88a534958aec6989.png 480w, https://blog.gameap.com/de/guides/publishing-plugins/github-secrets.en_hu_8367254b45013968.png 800w, https://blog.gameap.com/de/guides/publishing-plugins/github-secrets.en_hu_58a93b3c3b3364b1.png 1200w" sizes="(min-width: 860px) 808px, 100vw" width="1200" height="575" alt="Der Tab Secrets mit den Secrets GAMEAP_DEPLOY_TOKEN und GPG_SIGNING_KEY" loading="lazy" decoding="async"&gt;
 &lt;/picture&gt;&lt;/a&gt;&lt;figcaption&gt;Repository-Secrets&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Auf dem Tab &lt;strong&gt;Variables&lt;/strong&gt; klicken Sie auf &lt;strong&gt;New repository variable&lt;/strong&gt; und fügen Sie hinzu:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Name&lt;/th&gt;
					&lt;th&gt;Wert&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;GAMEAP_PLUGIN_ID&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Die Plugin-ID, z. B. &lt;code&gt;fmqnme42gg7da&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;figure&gt;&lt;a class="zoom" href="https://blog.gameap.com/de/guides/publishing-plugins/github-variables.en.png" target="_blank" rel="noopener"&gt;&lt;picture&gt;
 &lt;source type="image/webp" srcset="https://blog.gameap.com/de/guides/publishing-plugins/github-variables.en_hu_f38ec3bfa362fe8b.webp 480w, https://blog.gameap.com/de/guides/publishing-plugins/github-variables.en_hu_d954d987a2cc5fb6.webp 800w, https://blog.gameap.com/de/guides/publishing-plugins/github-variables.en_hu_869e19eb01ccc276.webp 1200w" sizes="(min-width: 860px) 808px, 100vw"&gt;
 &lt;img src="https://blog.gameap.com/de/guides/publishing-plugins/github-variables.en_hu_4d3d26a67a5a6e9d.png" srcset="https://blog.gameap.com/de/guides/publishing-plugins/github-variables.en_hu_b1080eb19826b888.png 480w, https://blog.gameap.com/de/guides/publishing-plugins/github-variables.en_hu_47d81d0f089d30fe.png 800w, https://blog.gameap.com/de/guides/publishing-plugins/github-variables.en_hu_4d3d26a67a5a6e9d.png 1200w" sizes="(min-width: 860px) 808px, 100vw" width="1200" height="524" alt="Der Tab Variables mit der Variable GAMEAP_PLUGIN_ID" loading="lazy" decoding="async"&gt;
 &lt;/picture&gt;&lt;/a&gt;&lt;figcaption&gt;Repository-Variablen&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Die Plugin-ID ist derselbe Base32-Bezeichner, den Sie in &lt;code&gt;PluginInfo&lt;/code&gt; eingetragen haben.
Kopieren Sie ihn mit der Schaltfläche neben dem Feld Plugin ID auf der Bearbeitungsseite oder
aus dem Block Details auf der Plugin-Seite.&lt;/p&gt;
&lt;p&gt;Die ID liegt absichtlich in den Variablen und nicht in den Secrets: Sie ist kein Geheimnis, und
wenn sie in den CI-Logs sichtbar ist, lassen sich Fehler deutlich leichter diagnostizieren. Das
Token hingegen ist immer ein Secret.&lt;/p&gt;
&lt;p&gt;So exportieren Sie einen privaten GPG-Schlüssel für &lt;code&gt;GPG_SIGNING_KEY&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gpg --armor --export-secret-keys IHRE_KEY_ID
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Veröffentlichen Sie den öffentlichen Schlüssel dort, wo Nutzer ihn finden können — etwa im
README des Plugins —, damit die Signatur überprüfbar ist.&lt;/p&gt;
&lt;h3 id="dashboard-und-ci-unterschiedliche-vorgaben"&gt;Dashboard und CI: unterschiedliche Vorgaben &lt;a class="hanchor" href="#dashboard-und-ci-unterschiedliche-vorgaben" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Was&lt;/th&gt;
					&lt;th&gt;Dashboard&lt;/th&gt;
					&lt;th&gt;CI&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Stabiles Release&lt;/td&gt;
					&lt;td&gt;Der Schalter ist standardmäßig aktiviert&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;is_stable&lt;/code&gt; ist standardmäßig &lt;strong&gt;false&lt;/strong&gt; — explizit übergeben&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Einreichen zur Prüfung&lt;/td&gt;
					&lt;td&gt;Manuell, per Schaltfläche&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;submit&lt;/code&gt; ist standardmäßig &lt;strong&gt;true&lt;/strong&gt; — die Version geht sofort in die Prüfung&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Screenshots&lt;/td&gt;
					&lt;td&gt;Werden direkt nach dem Upload angeboten&lt;/td&gt;
					&lt;td&gt;Nicht unterstützt, fügen Sie sie über das Dashboard hinzu&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Wenn CI nur die Datei hochladen und Sie die Metadaten von Hand nachpflegen wollen, übergeben Sie
&lt;code&gt;submit=false&lt;/code&gt;, und die Version bleibt ein Entwurf.&lt;/p&gt;
&lt;h3 id="fehler"&gt;Fehler &lt;a class="hanchor" href="#fehler" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Code&lt;/th&gt;
					&lt;th&gt;Ursache&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;400&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Ungültige Plugin-ID, ein fehlerhafter Multipart-Body oder kein &lt;code&gt;file&lt;/code&gt; übergeben&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;401&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Das Token fehlt, ist ungültig oder abgelaufen; der Header hat nicht die Form &lt;code&gt;Bearer gapd_...&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;403&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Das Token ist gültig, wurde aber für ein anderes Plugin ausgestellt&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;409&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Eine Version mit dieser Nummer existiert bereits&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;422&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Die Version besteht die Semver-Prüfung nicht; das Quellarchiv fehlt, ist zu groß oder kein &lt;code&gt;.zip&lt;/code&gt;/&lt;code&gt;.tar.gz&lt;/code&gt;; die Größenlimits für Datei oder Signatur sind überschritten&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Fehler-Bodies haben eine einheitliche Form:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;version already exists&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;message&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;version already exists&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;http_code&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;409&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Wiederholen Sie den Upload nach einem &lt;code&gt;5xx&lt;/code&gt;-Fehler nicht blind.&lt;/strong&gt; Das Schreiben der Version und
ihr Einreichen zur Prüfung sind keine einzelne Transaktion: Die Version kann bereits existieren,
und ein erneuter Versuch liefert &lt;code&gt;409&lt;/code&gt;. Öffnen Sie das Dashboard und prüfen Sie, was tatsächlich
passiert ist.&lt;/p&gt;
&lt;h2 id="versionen-aktualisieren-und-zurückziehen"&gt;Versionen aktualisieren und zurückziehen &lt;a class="hanchor" href="#versionen-aktualisieren-und-zur%c3%bcckziehen" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Eine neue Version wird genau wie die erste hochgeladen — über das Dashboard oder aus CI. Bereits
hochgeladene Versionen sind unveränderlich: Eine Datei unter derselben Nummer erneut hochzuladen
ist nicht möglich, der Versuch liefert &lt;code&gt;409&lt;/code&gt;. War der Build falsch, erhöhen Sie die
Patch-Version.&lt;/p&gt;
&lt;p&gt;Jede Zeile der Versionstabelle hat eigene Aktionen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Edit&lt;/strong&gt; („Bearbeiten“) — Changelog und Metadaten ändern.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Submit for Review&lt;/strong&gt; („Zur Prüfung einreichen“) — für Entwürfe und abgelehnte Versionen.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deprecate&lt;/strong&gt; („Als veraltet markieren“) — für veröffentlichte Versionen. Die Version bleibt
verfügbar, wird aber als veraltet gekennzeichnet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Retract&lt;/strong&gt; („Zurückziehen“) — für veröffentlichte und veraltete Versionen. Die Version wird
von der Veröffentlichung zurückgezogen.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nur ein Plugin im Status Draft kann gelöscht werden. Ein veröffentlichtes Plugin lässt sich nicht
entfernen — es kann zurückgezogen werden.&lt;/p&gt;
&lt;h2 id="checkliste"&gt;Checkliste &lt;a class="hanchor" href="#checkliste" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Die E-Mail ist bestätigt, die Veröffentlichungsregeln sind akzeptiert, und das Konto hat
Entwicklerstatus.&lt;/li&gt;
&lt;li&gt;Das Plugin ist angelegt, und Name sowie beide Beschreibungen sind ausgefüllt.&lt;/li&gt;
&lt;li&gt;Source URL oder Repository URL ist ausgefüllt — sonst braucht jede Version ein Quellarchiv.&lt;/li&gt;
&lt;li&gt;Die Plugin-ID steht in &lt;code&gt;PluginInfo.id&lt;/code&gt;, und die &lt;code&gt;.wasm&lt;/code&gt; wurde danach neu gebaut.&lt;/li&gt;
&lt;li&gt;Das Icon ist hochgeladen, und die Übersetzungen des Eintrags sind gepflegt.&lt;/li&gt;
&lt;li&gt;Die Version ist hochgeladen, optional ergänzt um Signatur und Screenshots.&lt;/li&gt;
&lt;li&gt;Die Version ist zur Prüfung eingereicht, nicht als Entwurf liegen geblieben.&lt;/li&gt;
&lt;li&gt;Für CI: Ein Deploy-Token ist erstellt und in den Secrets hinterlegt, die Plugin-ID steht in den
Variablen.&lt;/li&gt;
&lt;li&gt;Der Workflow hat keinen Schrägstrich am Ende der URL und übergibt &lt;code&gt;is_stable&lt;/code&gt; explizit.&lt;/li&gt;
&lt;li&gt;Nach dem Release ist bestätigt, dass Plugin und Version den Status Released haben.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>Lasttests von Gameserver-Verwaltungspanels</title><link>https://blog.gameap.com/de/news/game-panels-performance-tests/</link><pubDate>Mon, 03 Aug 2026 13:00:00 +0300</pubDate><guid>https://blog.gameap.com/de/news/game-panels-performance-tests/</guid><description>GameAP 3 und 4, PufferPanel, Pterodactyl und Pelican unter Last: der Teststand, die Methodik und die Ergebnisse der API-Benchmarks.</description><content:encoded>&lt;p&gt;Dieser Artikel handelt von Lasttests fünf populärer Verwaltungspanels für Gameserver: &lt;strong&gt;GameAP 3&lt;/strong&gt;, &lt;strong&gt;GameAP 4&lt;/strong&gt;, &lt;strong&gt;PufferPanel&lt;/strong&gt;, &lt;strong&gt;Pterodactyl&lt;/strong&gt; und &lt;strong&gt;Pelican&lt;/strong&gt;. Alle Panels werden auf derselben Hardware unter möglichst identischen Bedingungen getestet; wo sich die Bedingungen nicht angleichen ließen, ist das ausdrücklich in den &lt;a href="#einschr%c3%a4nkungen"&gt;Einschränkungen&lt;/a&gt; vermerkt.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer.&lt;/strong&gt; Dieser Artikel erscheint im Blog von GameAP, und sein Autor ist Entwickler; GameAP 3 und GameAP 4 sind zwei der fünf getesteten Panels. Das ist ein Interessenkonflikt, und Sie haben Recht, Voreingenommenheit zu erwarten. Um ihr entgegenzuwirken, ist der gesamte Test auf Nachprüfbarkeit ausgelegt: Die k6-Skripte, Konfigurationen, rohen k6-Berichte und Monitoring-Metriken jedes Durchlaufs sind in einem &lt;a href="https://github.com/et-nik/game-panels-benchmark" target="_blank" rel="noopener"&gt;GitHub-Repository&lt;/a&gt; veröffentlicht. Die Methodik lässt sich Schritt für Schritt nachvollziehen, und der Test kann auf eigener Hardware wiederholt werden. Wenn Sie meinen, ein Panel habe eine falsche Konfiguration erhalten oder eine Schlussfolgerung sei überzogen, öffnen Sie ein Issue: Es wird erneut geprüft und eine Korrektur veröffentlicht. Und noch eine Anmerkung für alle, die nur die kurze Antwort suchen: Ja, GameAP 4 hat hier die besten Zahlen geliefert.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Die Kurzfassung:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bei typischer Last (10–100 gleichzeitige Nutzer) arbeiten alle fünf Panels ohne einen einzigen Fehler; was sich unterscheidet, ist die Latenz: einstellige Millisekunden bei den Go-Panels, rund 9 ms bei GameAP 3, mehrere Dutzend Millisekunden bei Pterodactyl und Pelican.&lt;/li&gt;
&lt;li&gt;Die Durchsatzgrenze auf diesem Teststand:
&lt;ul&gt;
&lt;li&gt;1126 Anfragen/s für GameAP 4&lt;/li&gt;
&lt;li&gt;696 Anfragen/s für PufferPanel&lt;/li&gt;
&lt;li&gt;394 Anfragen/s für GameAP 3&lt;/li&gt;
&lt;li&gt;93 Anfragen/s für Pterodactyl&lt;/li&gt;
&lt;li&gt;und 76 Anfragen/s für Pelican&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Unter Überlast brechen die Panels unterschiedlich ein: Die Go-Panels beginnen, Fehler zurückzugeben; die PHP-Panels geben überhaupt keine Fehler zurück, aber die Antwortzeiten wachsen auf Sekunden und Dutzende von Sekunden.&lt;/li&gt;
&lt;li&gt;Die größte Überraschung: Bei Sättigung verbraucht MySQL bei Pterodactyl und Pelican fast einen ganzen CPU-Kern, während bei GameAP 3 — mit demselben MySQL und denselben Einstellungen — die Datenbank bei doppelt so vielen Anfragen pro Sekunde dreimal weniger ausgelastet ist.&lt;/li&gt;
&lt;/ul&gt;
&lt;style&gt;
.bench-chart { --c-g4:#2a78d6; --c-pp:#eb6834; --c-g3:#1baf7a; --c-pt:#eda100; --c-pl:#e87ba4; --c-app:#008300; --c-db:#4a3aa7; }
[data-theme="dark"] .bench-chart { --c-g4:#3987e5; --c-pp:#d95926; --c-g3:#199e70; --c-pt:#c98500; --c-pl:#d55181; --c-app:#008300; --c-db:#9085e9; }
@media (prefers-color-scheme: dark) {
 :root:not([data-theme]) .bench-chart { --c-g4:#3987e5; --c-pp:#d95926; --c-g3:#199e70; --c-pt:#c98500; --c-pl:#d55181; --c-app:#008300; --c-db:#9085e9; }
}
&lt;/style&gt;
&lt;svg class="bench-chart" viewBox="0 0 720 268" role="img" aria-label="Durchsatzgrenze: GameAP 4 — 1126 Anfragen pro Sekunde, PufferPanel — 696, GameAP 3 — 394, Pterodactyl — 93, Pelican — 76. Höher ist besser" style="max-width:100%;height:auto;font-family:var(--mono);font-size:12px"&gt;
&lt;text x="8.0" y="16.0" fill="var(--fg)" font-size="13" text-anchor="start" font-weight="600"&gt;Durchsatzgrenze&lt;/text&gt;
&lt;text x="712.0" y="16.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;höher ist besser&lt;/text&gt;
&lt;text x="8.0" y="32.0" fill="var(--muted)" font-size="11" text-anchor="start"&gt;Anfragen pro Sekunde · Median aus drei Durchläufen&lt;/text&gt;
&lt;line x1="66" y1="198.4" x2="700" y2="198.4" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="58.0" y="202.4" fill="var(--muted)" font-size="11" text-anchor="end"&gt;250&lt;/text&gt;
&lt;line x1="66" y1="160.8" x2="700" y2="160.8" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="58.0" y="164.8" fill="var(--muted)" font-size="11" text-anchor="end"&gt;500&lt;/text&gt;
&lt;line x1="66" y1="123.2" x2="700" y2="123.2" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="58.0" y="127.2" fill="var(--muted)" font-size="11" text-anchor="end"&gt;750&lt;/text&gt;
&lt;line x1="66" y1="85.6" x2="700" y2="85.6" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="58.0" y="89.6" fill="var(--muted)" font-size="11" text-anchor="end"&gt;1 000&lt;/text&gt;
&lt;line x1="66" y1="48.0" x2="700" y2="48.0" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="58.0" y="52.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;1 250&lt;/text&gt;
&lt;line x1="66" y1="236" x2="700" y2="236" stroke="var(--muted)" stroke-width="1"/&gt;
&lt;text x="58.0" y="240.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;0&lt;/text&gt;
&lt;path d="M91.4,236.0 v-165.4 a4,4 0 0 1 4,-4 h68.0 a4,4 0 0 1 4,4 v165.4 z" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x: 1 126 Anfragen/s&lt;/title&gt;&lt;/path&gt;
&lt;text x="129.4" y="58.6" fill="var(--fg)" font-size="12" text-anchor="middle" font-weight="600"&gt;1 126&lt;/text&gt;
&lt;text x="129.4" y="256.0" fill="var(--fg)" font-size="12" text-anchor="middle"&gt;GameAP 4.x&lt;/text&gt;
&lt;path d="M218.2,236.0 v-100.7 a4,4 0 0 1 4,-4 h68.0 a4,4 0 0 1 4,4 v100.7 z" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel: 696 Anfragen/s&lt;/title&gt;&lt;/path&gt;
&lt;text x="256.2" y="123.3" fill="var(--fg)" font-size="12" text-anchor="middle" font-weight="600"&gt;696&lt;/text&gt;
&lt;text x="256.2" y="256.0" fill="var(--fg)" font-size="12" text-anchor="middle"&gt;PufferPanel&lt;/text&gt;
&lt;path d="M345.0,236.0 v-55.3 a4,4 0 0 1 4,-4 h68.0 a4,4 0 0 1 4,4 v55.3 z" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x: 394 Anfragen/s&lt;/title&gt;&lt;/path&gt;
&lt;text x="383.0" y="168.7" fill="var(--fg)" font-size="12" text-anchor="middle" font-weight="600"&gt;394&lt;/text&gt;
&lt;text x="383.0" y="256.0" fill="var(--fg)" font-size="12" text-anchor="middle"&gt;GameAP 3.x&lt;/text&gt;
&lt;path d="M471.8,236.0 v-10.0 a4,4 0 0 1 4,-4 h68.0 a4,4 0 0 1 4,4 v10.0 z" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl: 93 Anfragen/s&lt;/title&gt;&lt;/path&gt;
&lt;text x="509.8" y="214.0" fill="var(--fg)" font-size="12" text-anchor="middle" font-weight="600"&gt;93&lt;/text&gt;
&lt;text x="509.8" y="256.0" fill="var(--fg)" font-size="12" text-anchor="middle"&gt;Pterodactyl&lt;/text&gt;
&lt;path d="M598.6,236.0 v-7.4 a4,4 0 0 1 4,-4 h68.0 a4,4 0 0 1 4,4 v7.4 z" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican: 76 Anfragen/s&lt;/title&gt;&lt;/path&gt;
&lt;text x="636.6" y="216.6" fill="var(--fg)" font-size="12" text-anchor="middle" font-weight="600"&gt;76&lt;/text&gt;
&lt;text x="636.6" y="256.0" fill="var(--fg)" font-size="12" text-anchor="middle"&gt;Pelican&lt;/text&gt;
&lt;/svg&gt;
&lt;h2 id="ziele"&gt;Ziele &lt;a class="hanchor" href="#ziele" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Den Bruchpunkt finden: die Grenze, bis zu der ein Panel noch ordnungsgemäß funktioniert.&lt;/li&gt;
&lt;li&gt;Die Alternativen unter möglichst ähnlichen Bedingungen vergleichen.&lt;/li&gt;
&lt;li&gt;GameAP 3 und GameAP 4 vergleichen: was genau die Neuschreibung von PHP nach Go gebracht hat.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Neben dem Gesamtvergleich aller fünf Panels sind drei Direktduelle von besonderem Interesse:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;GameAP 3.x vs. GameAP 4.x&lt;/strong&gt;: eine komplette Neuschreibung in Go mit aktualisierter Architektur.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GameAP 4.x vs. PufferPanel&lt;/strong&gt;: ein Vergleich zweier in Go geschriebener Panels.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pterodactyl vs. Pelican&lt;/strong&gt;: das Original-Panel gegen seinen Fork.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="die-panels"&gt;Die Panels &lt;a class="hanchor" href="#die-panels" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Panel&lt;/th&gt;
					&lt;th&gt;Version&lt;/th&gt;
					&lt;th&gt;Stack&lt;/th&gt;
					&lt;th&gt;Datenbank&lt;/th&gt;
					&lt;th&gt;Daemon&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 4.x&lt;/td&gt;
					&lt;td&gt;4.x&lt;/td&gt;
					&lt;td&gt;Go&lt;/td&gt;
					&lt;td&gt;PostgreSQL&lt;/td&gt;
					&lt;td&gt;gameap-daemon&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PufferPanel&lt;/td&gt;
					&lt;td&gt;3.x&lt;/td&gt;
					&lt;td&gt;Go&lt;/td&gt;
					&lt;td&gt;PostgreSQL&lt;/td&gt;
					&lt;td&gt;integriert&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 3.x&lt;/td&gt;
					&lt;td&gt;3.x&lt;/td&gt;
					&lt;td&gt;PHP 8.4 / Laravel&lt;/td&gt;
					&lt;td&gt;MySQL 8.0&lt;/td&gt;
					&lt;td&gt;gameap-daemon&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pterodactyl&lt;/td&gt;
					&lt;td&gt;1.11.x&lt;/td&gt;
					&lt;td&gt;PHP 8.4 / Laravel&lt;/td&gt;
					&lt;td&gt;MySQL 8.0&lt;/td&gt;
					&lt;td&gt;Wings (Docker)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pelican&lt;/td&gt;
					&lt;td&gt;1.0.x&lt;/td&gt;
					&lt;td&gt;PHP 8.4 / Laravel, Pterodactyl-Fork&lt;/td&gt;
					&lt;td&gt;MySQL 8.0&lt;/td&gt;
					&lt;td&gt;Wings (Docker)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Alle drei PHP-Panels betreiben zusätzlich Redis (Cache und Sessions). Die Versionen sind auf Ebene der Major-Branches erfasst, Stand April 2026, als die Durchläufe stattfanden.&lt;/p&gt;
&lt;h2 id="was-getestet-wird"&gt;Was getestet wird &lt;a class="hanchor" href="#was-getestet-wird" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;HTTP/API-Latenz bei verschiedenen Parallelitätsstufen: Lasttests (10–100 VUs);&lt;/li&gt;
&lt;li&gt;Verhalten unter Überlast (Degradation, Fehler, Ressourcenverbrauch): Stresstests (800–1200 VUs);&lt;/li&gt;
&lt;li&gt;die Durchsatzgrenze ohne Pausen zwischen den Anfragen: Durchsatztests.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nicht Gegenstand dieses Artikels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Schreibanfragen;&lt;/li&gt;
&lt;li&gt;UX, Funktionsumfang, Sicherheit, Ökosystem;&lt;/li&gt;
&lt;li&gt;die Arbeit mit echten Gameservern und ihren Dateien;&lt;/li&gt;
&lt;li&gt;Langzeitstabilität: Es wurden keine Soak- oder Spike-Tests durchgeführt.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="teststand"&gt;Teststand &lt;a class="hanchor" href="#teststand" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Server (Bare-Metal, Selectel):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPU: Intel Xeon E-2456 (Raptor Lake, 6C/12T, 3,3 GHz Basis / 5,1 GHz Turbo, 18 MB L3);&lt;/li&gt;
&lt;li&gt;RAM: 32 GB DDR5 ECC (2×16 GB, 4400 MT/s);&lt;/li&gt;
&lt;li&gt;Speicher: 2× Samsung 990 PRO 1TB NVMe im mdadm-RAID1;&lt;/li&gt;
&lt;li&gt;Hypervisor: Proxmox VE 9.1.5 auf Debian 13, Kernel 6.17.9-1-pve.&lt;/li&gt;
&lt;/ul&gt;
&lt;svg viewBox="0 0 720 330" role="img" aria-label="Diagramm des Teststands: Ein Bare-Metal-Server mit Proxmox beherbergt vier virtuelle Maschinen — k6-runner, Panel, Daemon und Monitoring" style="max-width:100%;height:auto;font-family:var(--mono);font-size:12px"&gt;
 &lt;defs&gt;
 &lt;marker id="ar-a" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"&gt;&lt;path d="M0,0L10,5L0,10z" fill="var(--accent)"/&gt;&lt;/marker&gt;
 &lt;marker id="ar-m" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"&gt;&lt;path d="M0,0L10,5L0,10z" fill="var(--muted)"/&gt;&lt;/marker&gt;
 &lt;/defs&gt;
 &lt;text x="8" y="14" fill="var(--muted)"&gt;Bare-metal · Selectel · Xeon E-2456 · 32 GB DDR5 · Proxmox VE 9&lt;/text&gt;
 &lt;rect x="8" y="26" width="704" height="296" rx="10" fill="none" stroke="var(--border)"/&gt;
 &lt;rect x="36" y="56" width="176" height="92" rx="8" fill="var(--surface)" stroke="var(--border)"/&gt;
 &lt;text x="52" y="82" fill="var(--fg)" font-weight="600" font-size="13"&gt;k6-runner&lt;/text&gt;
 &lt;text x="52" y="104" fill="var(--muted)"&gt;4 vCPU · 4 GB&lt;/text&gt;
 &lt;text x="52" y="124" fill="var(--muted)"&gt;Lastgenerator&lt;/text&gt;
 &lt;rect x="272" y="56" width="176" height="92" rx="8" fill="var(--surface)" stroke="var(--border)"/&gt;
 &lt;text x="288" y="82" fill="var(--fg)" font-weight="600" font-size="13"&gt;Panel (API)&lt;/text&gt;
 &lt;text x="288" y="104" fill="var(--muted)"&gt;4 vCPU · 8 GB · 40 GB&lt;/text&gt;
 &lt;text x="288" y="124" fill="var(--muted)"&gt;Ubuntu 24.04 LTS&lt;/text&gt;
 &lt;rect x="508" y="56" width="176" height="92" rx="8" fill="var(--surface)" stroke="var(--border)"/&gt;
 &lt;text x="524" y="82" fill="var(--fg)" font-weight="600" font-size="13"&gt;Daemon / Agent&lt;/text&gt;
 &lt;text x="524" y="104" fill="var(--muted)"&gt;6 vCPU · 12 GB · 80 GB&lt;/text&gt;
 &lt;text x="524" y="124" fill="var(--muted)"&gt;Ubuntu 24.04 LTS&lt;/text&gt;
 &lt;rect x="36" y="200" width="176" height="92" rx="8" fill="var(--surface)" stroke="var(--border)"/&gt;
 &lt;text x="52" y="226" fill="var(--fg)" font-weight="600" font-size="13"&gt;Monitoring&lt;/text&gt;
 &lt;text x="52" y="248" fill="var(--muted)"&gt;2 vCPU · 4 GB&lt;/text&gt;
 &lt;text x="52" y="268" fill="var(--muted)"&gt;Prometheus + Grafana&lt;/text&gt;
 &lt;line x1="212" y1="102" x2="266" y2="102" stroke="var(--accent)" stroke-width="1.5" marker-end="url(#ar-a)"/&gt;
 &lt;text x="239" y="92" fill="var(--accent)" font-size="11" text-anchor="middle"&gt;HTTP&lt;/text&gt;
 &lt;line x1="448" y1="102" x2="502" y2="102" stroke="var(--muted)" stroke-width="1.5" marker-end="url(#ar-m)"/&gt;
 &lt;path d="M 596 148 L 596 246 L 218 246" fill="none" stroke="var(--muted)" stroke-dasharray="4 4" marker-end="url(#ar-m)"/&gt;
 &lt;path d="M 360 148 L 360 246" fill="none" stroke="var(--muted)" stroke-dasharray="4 4"/&gt;
 &lt;text x="430" y="264" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;Metriken: node_exporter → Prometheus&lt;/text&gt;
&lt;/svg&gt;
&lt;h3 id="konfiguration-der-virtuellen-maschinen"&gt;Konfiguration der virtuellen Maschinen &lt;a class="hanchor" href="#konfiguration-der-virtuellen-maschinen" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;VM&lt;/th&gt;
					&lt;th&gt;vCPU&lt;/th&gt;
					&lt;th&gt;RAM&lt;/th&gt;
					&lt;th&gt;Festplatte&lt;/th&gt;
					&lt;th&gt;Rolle&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Panel&lt;/td&gt;
					&lt;td&gt;4&lt;/td&gt;
					&lt;td&gt;8 GB&lt;/td&gt;
					&lt;td&gt;40 GB&lt;/td&gt;
					&lt;td&gt;Verwaltungspanel (API), Ubuntu 24.04 LTS&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Daemon&lt;/td&gt;
					&lt;td&gt;6&lt;/td&gt;
					&lt;td&gt;12 GB&lt;/td&gt;
					&lt;td&gt;80 GB&lt;/td&gt;
					&lt;td&gt;Gameserver-Daemon/Agent, Ubuntu 24.04 LTS&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;k6-runner&lt;/td&gt;
					&lt;td&gt;4&lt;/td&gt;
					&lt;td&gt;4 GB&lt;/td&gt;
					&lt;td&gt;—&lt;/td&gt;
					&lt;td&gt;Lastgenerator&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Monitoring&lt;/td&gt;
					&lt;td&gt;2&lt;/td&gt;
					&lt;td&gt;4 GB&lt;/td&gt;
					&lt;td&gt;—&lt;/td&gt;
					&lt;td&gt;Prometheus + Grafana&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="host-tuning"&gt;Host-Tuning &lt;a class="hanchor" href="#host-tuning" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CPU-Governor: performance;&lt;/li&gt;
&lt;li&gt;C-States auf C1 begrenzt;&lt;/li&gt;
&lt;li&gt;Turbo Boost aktiviert;&lt;/li&gt;
&lt;li&gt;Swap auf allen virtuellen Maschinen deaktiviert.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="methodik"&gt;Methodik &lt;a class="hanchor" href="#methodik" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Die Panels werden einzeln getestet: Während ein Panel im Test ist, sind alle anderen VMs heruntergefahren, um gegenseitige Beeinflussung zu vermeiden. Während eines Durchlaufs arbeiten nur das Panel (API), der Gameserver-Daemon, der k6-Lastgenerator und der Monitoring-Stack.&lt;/p&gt;
&lt;p&gt;Jedes Panel durchlief &lt;strong&gt;drei vollständige, unabhängige Durchläufe&lt;/strong&gt; der gesamten Profilserie (18.–19. April 2026). Alle Zahlen in diesem Artikel sind &lt;strong&gt;Mediane der drei Durchläufe&lt;/strong&gt;, sofern nicht ausdrücklich anders angegeben.&lt;/p&gt;
&lt;p&gt;Die Abfolge für jedes Panel: die beiden VMs (Panel und Daemon) starten → Dienste neu starten → ein Aufwärmdurchlauf des smoke-Szenarios (1 VU, 30 s) → die Lastprofile der Reihe nach. Vor jedem Profil werden die Dienste des Panels neu gestartet; nach jedem Profil gibt es eine 60-sekündige Pause. Die Menge der neu gestarteten Dienste unterscheidet sich zwischen den Panels: Bei den PHP-Panels sind es php-fpm, nginx und MySQL (plus Redis bei GameAP 3), bei PufferPanel die Anwendung selbst, bei GameAP 4 nur nginx. Das ist eine Asymmetrie der Methodik; mehr dazu in den &lt;a href="#einschr%c3%a4nkungen"&gt;Einschränkungen&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="lastprofile"&gt;Lastprofile &lt;a class="hanchor" href="#lastprofile" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Profil&lt;/th&gt;
					&lt;th&gt;VUs&lt;/th&gt;
					&lt;th&gt;Dauer&lt;/th&gt;
					&lt;th&gt;Testart&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;smoke&lt;/td&gt;
					&lt;td&gt;1&lt;/td&gt;
					&lt;td&gt;30 s&lt;/td&gt;
					&lt;td&gt;Latenz ohne Parallelität&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;baseline&lt;/td&gt;
					&lt;td&gt;10&lt;/td&gt;
					&lt;td&gt;4,5 min&lt;/td&gt;
					&lt;td&gt;Last&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;load&lt;/td&gt;
					&lt;td&gt;20 → 50 → 100&lt;/td&gt;
					&lt;td&gt;11 min&lt;/td&gt;
					&lt;td&gt;Last&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress&lt;/td&gt;
					&lt;td&gt;50 → 100 → 200 → 400 → 800&lt;/td&gt;
					&lt;td&gt;10 min&lt;/td&gt;
					&lt;td&gt;Stress&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1000&lt;/td&gt;
					&lt;td&gt;200 → 500 → 1000, 5 min gehalten&lt;/td&gt;
					&lt;td&gt;9 min&lt;/td&gt;
					&lt;td&gt;Stress&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1200&lt;/td&gt;
					&lt;td&gt;200 → 500 → 800 → 1200, 5 min gehalten&lt;/td&gt;
					&lt;td&gt;10 min&lt;/td&gt;
					&lt;td&gt;Stress&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;max-throughput&lt;/td&gt;
					&lt;td&gt;100, ohne Think-Time&lt;/td&gt;
					&lt;td&gt;2 min 40 s&lt;/td&gt;
					&lt;td&gt;Durchsatz&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="szenario"&gt;Szenario &lt;a class="hanchor" href="#szenario" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Jede Iteration führt drei GET-Anfragen aus — diejenigen, die echte Nutzer am häufigsten stellen: die Serverliste, die Details eines zufälligen Servers aus dieser Liste und dessen Status. Zwischen den Anfragen liegt eine Pause von 0,3–0,8 s, am Ende der Iteration eine von 1–3 s. Das max-throughput-Profil führt dieselben drei Anfragen ohne Pausen aus. Anfragen, die Daten verändern (POST, PUT, DELETE usw.), kommen im Test nicht vor.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Panel&lt;/th&gt;
					&lt;th&gt;Liste&lt;/th&gt;
					&lt;th&gt;Details&lt;/th&gt;
					&lt;th&gt;Status&lt;/th&gt;
					&lt;th&gt;Einträge in der Listen-Antwort&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 3.x&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers/{id}&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;dieselbe Anfrage wie Details¹&lt;/td&gt;
					&lt;td&gt;102&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 4.x&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers/{id}&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers/{id}/status&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;102&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PufferPanel&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers/{id}&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers/{id}/status&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;20 (erste Seite)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pterodactyl&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/client&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/client/servers/{id}&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;…/{id}/resources&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;50 (erste Seite)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pelican&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/client&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/client/servers/{id}&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;…/{id}/resources&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;50 (erste Seite)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;¹ GameAP 3.x hat keinen separaten Status-Endpunkt — die Details-Anfrage wird wiederholt.&lt;/p&gt;
&lt;p&gt;Jedes Panel erhielt 100 identische Mock-Gameserver (ein Platzhalterskript, das die Uhrzeit ausgibt; die Server wurden nie installiert oder gestartet). Die Antworten der Listen-API unterscheiden sich dennoch: GameAP liefert alle Datensätze auf einmal (die Datenbank des Teststands enthielt 102), Pterodactyl und Pelican liefern die erste Seite von 50, PufferPanel die erste Seite von 20. Die durchschnittliche Antwortgröße im load-Profil beträgt 13–16 KB pro Anfrage bei vier Panels und 1,6 KB bei PufferPanel. Ein direkter panelübergreifender Vergleich der &lt;code&gt;list_servers&lt;/code&gt;-Latenz ist daher nicht ganz fair — einer der wichtigsten Vorbehalte dieses Tests.&lt;/p&gt;
&lt;h3 id="authentifizierung-und-limits"&gt;Authentifizierung und Limits &lt;a class="hanchor" href="#authentifizierung-und-limits" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;GameAP 3/4, Pterodactyl und Pelican verwenden einen API-Schlüssel (Bearer). PufferPanel verwendet OAuth2-Client-Credentials: Das Token wird einmal in &lt;code&gt;setup()&lt;/code&gt; geholt und von allen VUs wiederverwendet. Die OAuth-Anfrage selbst (~58 ms) landet in den Statistiken jedes Profils, weil &lt;code&gt;setup()&lt;/code&gt; bei jedem k6-Aufruf läuft. Im kurzen smoke-Profil (31–34 Anfragen) hebt sie die durchschnittliche Latenz von PufferPanel von ~2 auf ~3,7 ms, während der Median unverändert bleibt. Bei baseline ist sie eine Anfrage von ~2 200 — rund +0,03 ms (~2 %) auf den Mittelwert, Median und Perzentile bleiben unberührt; bei den längeren Profilen ist der Effekt vernachlässigbar.&lt;/p&gt;
&lt;p&gt;Bei Pterodactyl und Pelican wurden die API-Rate-Limits auf 10 000 Anfragen pro Minute angehoben — sonst wäre der Test am Limiter hängen geblieben, nicht am Panel.&lt;/p&gt;
&lt;h3 id="tuning-der-php-panels-identisch-bei-gameap-3-pterodactyl-und-pelican"&gt;Tuning der PHP-Panels (identisch bei GameAP 3, Pterodactyl und Pelican) &lt;a class="hanchor" href="#tuning-der-php-panels-identisch-bei-gameap-3-pterodactyl-und-pelican" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;; PHP-FPM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;pm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;dynamic, pm.max_children = 50, pm.start_servers = 10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;; OPcache&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;opcache.memory_consumption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;256, opcache.jit = tracing, opcache.jit_buffer_size = 128M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;; MySQL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;innodb_buffer_pool_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;2G, max_connections = 200, innodb_flush_log_at_trx_commit = 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="werkzeuge"&gt;Werkzeuge &lt;a class="hanchor" href="#werkzeuge" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;k6 v1.7.1; das Standard-Timeout für Anfragen beträgt 60 s;&lt;/li&gt;
&lt;li&gt;Prometheus, node_exporter 1.8.2 (VM-Metriken, 15-s-Schritt), process_exporter 0.8.7 (Prozessmetriken, 30-s-Schritt).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="das-closed-loop-lastmodell"&gt;Das Closed-Loop-Lastmodell &lt;a class="hanchor" href="#das-closed-loop-lastmodell" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;k6 arbeitet mit einem Closed-Loop-Modell: Ein virtueller Nutzer sendet die nächste Anfrage erst, wenn er die Antwort auf die vorherige erhalten hat. Wenn ein Panel langsamer wird, sinkt die tatsächliche Lastintensität automatisch. In einem offenen System — echte Nutzer, sich automatisch aktualisierende Dashboards, Integrationen — würden die Anfragen unabhängig von den Antworten weiter eintreffen, und ein degradiertes Panel käme noch schlechter weg. Denken Sie beim Lesen der Stress-Ergebnisse daran: Die Zahlen der verlangsamten Panels sind eine optimistische Schätzung. Mehr zu diesem Effekt: &lt;a href="https://www.scylladb.com/2021/04/22/on-coordinated-omission/" target="_blank" rel="noopener"&gt;Coordinated Omission&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="anmerkungen-zum-aufbau-des-teststands"&gt;Anmerkungen zum Aufbau des Teststands &lt;a class="hanchor" href="#anmerkungen-zum-aufbau-des-teststands" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ressourcen der Panel-VM während des smoke-Profils — 1 VU, bei bereits mit 100 Servern gefüllter Datenbank; Spitzenwert über das Profilfenster, Median aus drei Durchläufen:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Panel&lt;/th&gt;
					&lt;th&gt;CPU&lt;/th&gt;
					&lt;th&gt;RAM&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 4.x&lt;/td&gt;
					&lt;td&gt;0,4 %&lt;/td&gt;
					&lt;td&gt;449 MB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PufferPanel&lt;/td&gt;
					&lt;td&gt;0,6 %&lt;/td&gt;
					&lt;td&gt;462 MB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 3.x&lt;/td&gt;
					&lt;td&gt;3,2 %&lt;/td&gt;
					&lt;td&gt;1 049 MB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pterodactyl&lt;/td&gt;
					&lt;td&gt;2,3 %&lt;/td&gt;
					&lt;td&gt;1 096 MB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pelican&lt;/td&gt;
					&lt;td&gt;2,9 %&lt;/td&gt;
					&lt;td&gt;1 177 MB&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Der RAM-Wert bezieht sich auf die gesamte virtuelle Maschine (MemTotal − MemAvailable), einschließlich Betriebssystem, Datenbank und Hilfsdiensten.&lt;/p&gt;
&lt;p&gt;Anmerkungen, die beim Aufbau des Teststands gesammelt wurden:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pterodactyl&lt;/strong&gt; und &lt;strong&gt;Pelican&lt;/strong&gt; können nicht hinter NAT arbeiten — weder das Panel noch Wings: Der Browser verbindet sich direkt über HTTP/HTTPS mit Wings.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pelican&lt;/strong&gt; erfordert nach Änderungen an den Einstellungen einen Neuaufbau des Konfigurations-Caches, sonst stürzt das Panel ab.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ergebnisse"&gt;Ergebnisse &lt;a class="hanchor" href="#ergebnisse" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Alle folgenden Zahlen sind Mediane aus drei Durchläufen; die Rohberichte jedes Durchlaufs liegen im &lt;a href="https://github.com/et-nik/game-panels-benchmark" target="_blank" rel="noopener"&gt;Repository&lt;/a&gt;. Zur Reproduzierbarkeit: In den Profilen baseline, load und max-throughput weicht die Median-Latenz zwischen den Durchläufen um höchstens 6,1 % ab, der RPS um höchstens 2,7 %. smoke ist zu kurz (28–34 Anfragen pro Durchlauf), sodass die Streuung seines Medians 22 % erreicht. In den Stress-Profilen ist das Verhalten erwartungsgemäß weniger stabil: Der stress-1200-Median von GameAP 4 über die Durchläufe lag beispielsweise bei 23,7 / 24,6 / 31,9 ms.&lt;/p&gt;
&lt;h3 id="latenz-nach-laststufe"&gt;Latenz nach Laststufe &lt;a class="hanchor" href="#latenz-nach-laststufe" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;svg class="bench-chart" viewBox="0 0 720 430" role="img" aria-label="Median-Latenz nach Laststufe. Die Go-Panels bleiben bis 800–1000 VUs bei Millisekunden, die PHP-Panels klettern auf Sekunden" style="max-width:100%;height:auto;font-family:var(--mono);font-size:12px"&gt;
&lt;text x="8.0" y="16.0" fill="var(--fg)" font-size="13" text-anchor="start" font-weight="600"&gt;Median-Latenz nach Laststufe&lt;/text&gt;
&lt;text x="712.0" y="16.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;niedriger ist besser&lt;/text&gt;
&lt;text x="8.0" y="32.0" fill="var(--muted)" font-size="11" text-anchor="start"&gt;ms, logarithmische Skala · Median aus drei Durchläufen&lt;/text&gt;
&lt;line x1="56" y1="355.9" x2="540" y2="355.9" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="50.0" y="359.9" fill="var(--muted)" font-size="11" text-anchor="end"&gt;1 ms&lt;/text&gt;
&lt;line x1="56" y1="285.2" x2="540" y2="285.2" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="50.0" y="289.2" fill="var(--muted)" font-size="11" text-anchor="end"&gt;10 ms&lt;/text&gt;
&lt;line x1="56" y1="214.6" x2="540" y2="214.6" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="50.0" y="218.6" fill="var(--muted)" font-size="11" text-anchor="end"&gt;100 ms&lt;/text&gt;
&lt;line x1="56" y1="143.9" x2="540" y2="143.9" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="50.0" y="147.9" fill="var(--muted)" font-size="11" text-anchor="end"&gt;1 s&lt;/text&gt;
&lt;line x1="56" y1="73.3" x2="540" y2="73.3" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="50.0" y="77.3" fill="var(--muted)" font-size="11" text-anchor="end"&gt;10 s&lt;/text&gt;
&lt;line x1="56" y1="384" x2="540" y2="384" stroke="var(--muted)" stroke-width="1"/&gt;
&lt;text x="96.3" y="400.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;1&lt;/text&gt;
&lt;text x="177.0" y="400.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;10&lt;/text&gt;
&lt;text x="257.7" y="400.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;100&lt;/text&gt;
&lt;text x="338.3" y="400.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;800&lt;/text&gt;
&lt;text x="419.0" y="400.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;1000&lt;/text&gt;
&lt;text x="499.7" y="400.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;1200&lt;/text&gt;
&lt;text x="298.0" y="416.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;angestrebtes VU-Maximum des Profils&lt;/text&gt;
&lt;polyline points="96.3,352.7 177.0,361.9 257.7,371.9 338.3,373.1 419.0,364.2 499.7,257.6" fill="none" stroke="var(--c-g4)" stroke-width="2" stroke-linejoin="round"/&gt;
&lt;circle cx="96.3" cy="352.7" r="3.5" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x — 1 VUs: 1,11 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="177.0" cy="361.9" r="3.5" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x — 10 VUs: 0,82 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="257.7" cy="371.9" r="3.5" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x — 100 VUs: 0,59 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="338.3" cy="373.1" r="3.5" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x — 800 VUs: 0,57 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="419.0" cy="364.2" r="3.5" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x — 1000 VUs: 0,76 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="499.7" cy="257.6" r="3.5" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x — 1200 VUs: 24,6 ms&lt;/title&gt;&lt;/circle&gt;
&lt;polyline points="96.3,334.4 177.0,342.6 257.7,346.3 338.3,344.6 419.0,210.6 499.7,215.5" fill="none" stroke="var(--c-pp)" stroke-width="2" stroke-linejoin="round"/&gt;
&lt;circle cx="96.3" cy="334.4" r="3.5" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 1 VUs: 2,01 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="177.0" cy="342.6" r="3.5" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 10 VUs: 1,54 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="257.7" cy="346.3" r="3.5" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 100 VUs: 1,37 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="338.3" cy="344.6" r="3.5" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 800 VUs: 1,45 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="419.0" cy="210.6" r="3.5" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 1000 VUs: 114 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="499.7" cy="215.5" r="3.5" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 1200 VUs: 97,2 ms&lt;/title&gt;&lt;/circle&gt;
&lt;polyline points="96.3,263.7 177.0,287.7 257.7,289.2 338.3,254.0 419.0,131.9 499.7,123.3" fill="none" stroke="var(--c-g3)" stroke-width="2" stroke-linejoin="round"/&gt;
&lt;circle cx="96.3" cy="263.7" r="3.5" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x — 1 VUs: 20,2 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="177.0" cy="287.7" r="3.5" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x — 10 VUs: 9,24 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="257.7" cy="289.2" r="3.5" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x — 100 VUs: 8,78 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="338.3" cy="254.0" r="3.5" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x — 800 VUs: 27,7 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="419.0" cy="131.9" r="3.5" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x — 1000 VUs: 1 481 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="499.7" cy="123.3" r="3.5" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x — 1200 VUs: 1 958 ms&lt;/title&gt;&lt;/circle&gt;
&lt;polyline points="96.3,254.9 177.0,277.8 257.7,262.9 338.3,139.8 419.0,81.4 499.7,71.9" fill="none" stroke="var(--c-pt)" stroke-width="2" stroke-linejoin="round"/&gt;
&lt;circle cx="96.3" cy="254.9" r="3.5" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl — 1 VUs: 26,9 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="177.0" cy="277.8" r="3.5" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl — 10 VUs: 12,7 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="257.7" cy="262.9" r="3.5" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl — 100 VUs: 20,7 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="338.3" cy="139.8" r="3.5" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl — 800 VUs: 1 144 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="419.0" cy="81.4" r="3.5" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl — 1000 VUs: 7 664 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="499.7" cy="71.9" r="3.5" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl — 1200 VUs: 10 455 ms&lt;/title&gt;&lt;/circle&gt;
&lt;polyline points="96.3,252.6 177.0,270.8 257.7,233.2 338.3,131.1 419.0,71.8 499.7,65.7" fill="none" stroke="var(--c-pl)" stroke-width="2" stroke-linejoin="round"/&gt;
&lt;circle cx="96.3" cy="252.6" r="3.5" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican — 1 VUs: 29,0 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="177.0" cy="270.8" r="3.5" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican — 10 VUs: 16,0 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="257.7" cy="233.2" r="3.5" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican — 100 VUs: 54,5 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="338.3" cy="131.1" r="3.5" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican — 800 VUs: 1 520 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="419.0" cy="71.8" r="3.5" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican — 1000 VUs: 10 501 ms&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="499.7" cy="65.7" r="3.5" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican — 1200 VUs: 12 807 ms&lt;/title&gt;&lt;/circle&gt;
&lt;rect x="550" y="60.7" width="9" height="9" rx="2" fill="var(--c-pl)"/&gt;
&lt;text x="564.0" y="69.7" fill="var(--fg)" font-size="12" text-anchor="start"&gt;Pelican&lt;/text&gt;
&lt;rect x="550" y="75.7" width="9" height="9" rx="2" fill="var(--c-pt)"/&gt;
&lt;text x="564.0" y="84.7" fill="var(--fg)" font-size="12" text-anchor="start"&gt;Pterodactyl&lt;/text&gt;
&lt;rect x="550" y="118.3" width="9" height="9" rx="2" fill="var(--c-g3)"/&gt;
&lt;text x="564.0" y="127.3" fill="var(--fg)" font-size="12" text-anchor="start"&gt;GameAP 3.x&lt;/text&gt;
&lt;rect x="550" y="210.5" width="9" height="9" rx="2" fill="var(--c-pp)"/&gt;
&lt;text x="564.0" y="219.5" fill="var(--fg)" font-size="12" text-anchor="start"&gt;PufferPanel&lt;/text&gt;
&lt;rect x="550" y="252.6" width="9" height="9" rx="2" fill="var(--c-g4)"/&gt;
&lt;text x="564.0" y="261.6" fill="var(--fg)" font-size="12" text-anchor="start"&gt;GameAP 4.x&lt;/text&gt;
&lt;/svg&gt;
&lt;p&gt;Median-Latenz, ms:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Profil&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;smoke (1 VU)&lt;/td&gt;
					&lt;td&gt;1,11&lt;/td&gt;
					&lt;td&gt;2,01&lt;/td&gt;
					&lt;td&gt;20,2&lt;/td&gt;
					&lt;td&gt;26,9&lt;/td&gt;
					&lt;td&gt;29,0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;baseline (10 VUs)&lt;/td&gt;
					&lt;td&gt;0,82&lt;/td&gt;
					&lt;td&gt;1,54&lt;/td&gt;
					&lt;td&gt;9,24&lt;/td&gt;
					&lt;td&gt;12,7&lt;/td&gt;
					&lt;td&gt;16,0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;load (bis 100 VUs)&lt;/td&gt;
					&lt;td&gt;0,59&lt;/td&gt;
					&lt;td&gt;1,37&lt;/td&gt;
					&lt;td&gt;8,78&lt;/td&gt;
					&lt;td&gt;20,7&lt;/td&gt;
					&lt;td&gt;54,5&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress (bis 800 VUs)&lt;/td&gt;
					&lt;td&gt;0,57&lt;/td&gt;
					&lt;td&gt;1,45&lt;/td&gt;
					&lt;td&gt;27,7&lt;/td&gt;
					&lt;td&gt;1 144&lt;/td&gt;
					&lt;td&gt;1 520&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1000&lt;/td&gt;
					&lt;td&gt;0,76&lt;/td&gt;
					&lt;td&gt;114&lt;/td&gt;
					&lt;td&gt;1 481&lt;/td&gt;
					&lt;td&gt;7 664&lt;/td&gt;
					&lt;td&gt;10 501&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1200&lt;/td&gt;
					&lt;td&gt;24,6&lt;/td&gt;
					&lt;td&gt;97,2&lt;/td&gt;
					&lt;td&gt;1 958&lt;/td&gt;
					&lt;td&gt;10 455&lt;/td&gt;
					&lt;td&gt;12 807&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ol start="95"&gt;
&lt;li&gt;Perzentil, ms:&lt;/li&gt;
&lt;/ol&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Profil&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;smoke (1 VU)&lt;/td&gt;
					&lt;td&gt;1,69&lt;/td&gt;
					&lt;td&gt;4,98&lt;/td&gt;
					&lt;td&gt;29,2&lt;/td&gt;
					&lt;td&gt;87,0&lt;/td&gt;
					&lt;td&gt;106&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;baseline (10 VUs)&lt;/td&gt;
					&lt;td&gt;1,45&lt;/td&gt;
					&lt;td&gt;2,08&lt;/td&gt;
					&lt;td&gt;19,9&lt;/td&gt;
					&lt;td&gt;79,4&lt;/td&gt;
					&lt;td&gt;97,0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;load (bis 100 VUs)&lt;/td&gt;
					&lt;td&gt;1,20&lt;/td&gt;
					&lt;td&gt;1,85&lt;/td&gt;
					&lt;td&gt;13,2&lt;/td&gt;
					&lt;td&gt;154&lt;/td&gt;
					&lt;td&gt;473&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress (bis 800 VUs)&lt;/td&gt;
					&lt;td&gt;2,92&lt;/td&gt;
					&lt;td&gt;58,2&lt;/td&gt;
					&lt;td&gt;908&lt;/td&gt;
					&lt;td&gt;9 146&lt;/td&gt;
					&lt;td&gt;11 221&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1000&lt;/td&gt;
					&lt;td&gt;15,2&lt;/td&gt;
					&lt;td&gt;319&lt;/td&gt;
					&lt;td&gt;1 583&lt;/td&gt;
					&lt;td&gt;13 607&lt;/td&gt;
					&lt;td&gt;15 247&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1200&lt;/td&gt;
					&lt;td&gt;283&lt;/td&gt;
					&lt;td&gt;330&lt;/td&gt;
					&lt;td&gt;2 078&lt;/td&gt;
					&lt;td&gt;14 144&lt;/td&gt;
					&lt;td&gt;17 477&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Was das zeigt.&lt;/p&gt;
&lt;p&gt;Bis einschließlich 100 VUs antworten alle fünf Panels ohne einen einzigen Fehler, und die einzige Frage ist die Geschwindigkeit: Die Go-Panels bleiben bei einem Median unter 2 ms, GameAP 3 bei rund 9 ms, Pterodactyl bei 13–21 ms, Pelican bei 16–55 ms. Pelicans Median steigt bereits im load-Profil (54,5 ms, p95 — 473 ms): Wie der Ressourcen-Abschnitt zeigen wird, ist ihm bei 100 VUs praktisch die CPU ausgegangen.&lt;/p&gt;
&lt;p&gt;In den Stress-Profilen laufen die Gruppen radikal auseinander. GameAP 4 besteht 800 und 1000 VUs ohne Median-Degradation (0,6–0,8 ms), PufferPanel verlangsamt sich bei 1000 VUs auf 114 ms und beginnt, Fehler zurückzugeben, GameAP 3 hält 800 VUs bei einem Median von 28 ms (p95 — 0,9 s) und geht jenseits von 1000 auf 1,5–2 s über. Pterodactyl und Pelican antworten bereits bei 800 VUs in Sekunden und bei 1000–1200 in 8–13 s (Median).&lt;/p&gt;
&lt;p&gt;Beachtenswert ist die Kluft zwischen Median und p95 bei den PHP-Panels schon bei niedriger Last: Pterodactyls baseline-Median liegt bei 12,7 ms, sein p95 jedoch bei 79 ms. Ihr Schweif langsamer Antworten ist auch dort lang, wo das Panel insgesamt mithält.&lt;/p&gt;
&lt;h3 id="durchsatzgrenze"&gt;Durchsatzgrenze &lt;a class="hanchor" href="#durchsatzgrenze" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Das max-throughput-Profil: 100 VUs führen dieselben drei Anfragen ohne Pausen aus — 30 s Ramp-up, 2 min Haltephase, 10 s Ramp-down. Der RPS wird als Durchschnitt über das gesamte Fenster berechnet, Rampen eingeschlossen.&lt;/p&gt;
&lt;svg class="bench-chart" viewBox="0 0 720 268" role="img" aria-label="Durchsatzgrenze (max-throughput)" style="max-width:100%;height:auto;font-family:var(--mono);font-size:12px"&gt;
&lt;text x="8.0" y="16.0" fill="var(--fg)" font-size="13" text-anchor="start" font-weight="600"&gt;Durchsatzgrenze (max-throughput)&lt;/text&gt;
&lt;text x="712.0" y="16.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;höher ist besser&lt;/text&gt;
&lt;text x="8.0" y="32.0" fill="var(--muted)" font-size="11" text-anchor="start"&gt;Anfragen pro Sekunde · 100 VUs, ohne Think-Time · Median aus drei Durchläufen · 0% Fehler bei allen Panels&lt;/text&gt;
&lt;line x1="118.0" y1="48" x2="118.0" y2="238" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="118.0" y="252.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;line x1="226.4" y1="48" x2="226.4" y2="238" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="226.4" y="252.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;250&lt;/text&gt;
&lt;line x1="334.8" y1="48" x2="334.8" y2="238" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="334.8" y="252.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;500&lt;/text&gt;
&lt;line x1="443.2" y1="48" x2="443.2" y2="238" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="443.2" y="252.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;750&lt;/text&gt;
&lt;line x1="551.6" y1="48" x2="551.6" y2="238" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="551.6" y="252.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;1 000&lt;/text&gt;
&lt;line x1="660.0" y1="48" x2="660.0" y2="238" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="660.0" y="252.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;1 250&lt;/text&gt;
&lt;text x="110.0" y="76.0" fill="var(--fg)" font-size="12" text-anchor="end"&gt;GameAP 4.x&lt;/text&gt;
&lt;path d="M118.0,60.0 h484.0 a4,4 0 0 1 4,4 v14.0 a4,4 0 0 1 -4,4 h-484.0 z" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x: 1 126 Anfragen/s&lt;/title&gt;&lt;/path&gt;
&lt;text x="614.0" y="76.0" fill="var(--fg)" font-size="12" text-anchor="start" font-weight="600"&gt;1 126&lt;/text&gt;
&lt;text x="110.0" y="114.0" fill="var(--fg)" font-size="12" text-anchor="end"&gt;PufferPanel&lt;/text&gt;
&lt;path d="M118.0,98.0 h297.6 a4,4 0 0 1 4,4 v14.0 a4,4 0 0 1 -4,4 h-297.6 z" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel: 696 Anfragen/s&lt;/title&gt;&lt;/path&gt;
&lt;text x="427.6" y="114.0" fill="var(--fg)" font-size="12" text-anchor="start" font-weight="600"&gt;696&lt;/text&gt;
&lt;text x="110.0" y="152.0" fill="var(--fg)" font-size="12" text-anchor="end"&gt;GameAP 3.x&lt;/text&gt;
&lt;path d="M118.0,136.0 h166.9 a4,4 0 0 1 4,4 v14.0 a4,4 0 0 1 -4,4 h-166.9 z" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x: 394 Anfragen/s&lt;/title&gt;&lt;/path&gt;
&lt;text x="296.9" y="152.0" fill="var(--fg)" font-size="12" text-anchor="start" font-weight="600"&gt;394&lt;/text&gt;
&lt;text x="110.0" y="190.0" fill="var(--fg)" font-size="12" text-anchor="end"&gt;Pterodactyl&lt;/text&gt;
&lt;path d="M118.0,174.0 h36.5 a4,4 0 0 1 4,4 v14.0 a4,4 0 0 1 -4,4 h-36.5 z" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl: 93 Anfragen/s&lt;/title&gt;&lt;/path&gt;
&lt;text x="166.5" y="190.0" fill="var(--fg)" font-size="12" text-anchor="start" font-weight="600"&gt;93&lt;/text&gt;
&lt;text x="110.0" y="228.0" fill="var(--fg)" font-size="12" text-anchor="end"&gt;Pelican&lt;/text&gt;
&lt;path d="M118.0,212.0 h29.0 a4,4 0 0 1 4,4 v14.0 a4,4 0 0 1 -4,4 h-29.0 z" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican: 76 Anfragen/s&lt;/title&gt;&lt;/path&gt;
&lt;text x="159.0" y="228.0" fill="var(--fg)" font-size="12" text-anchor="start" font-weight="600"&gt;76&lt;/text&gt;
&lt;/svg&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Panel&lt;/th&gt;
					&lt;th&gt;RPS&lt;/th&gt;
					&lt;th&gt;Ø, ms&lt;/th&gt;
					&lt;th&gt;Median, ms&lt;/th&gt;
					&lt;th&gt;p95, ms&lt;/th&gt;
					&lt;th&gt;Fehler&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 4.x&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;1 126&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;77,6&lt;/td&gt;
					&lt;td&gt;68,9&lt;/td&gt;
					&lt;td&gt;179&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PufferPanel&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;696&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;126&lt;/td&gt;
					&lt;td&gt;121&lt;/td&gt;
					&lt;td&gt;257&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 3.x&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;394&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;222&lt;/td&gt;
					&lt;td&gt;241&lt;/td&gt;
					&lt;td&gt;302&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pterodactyl&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;93&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;941&lt;/td&gt;
					&lt;td&gt;766&lt;/td&gt;
					&lt;td&gt;1 825&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pelican&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;76&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;1 160&lt;/td&gt;
					&lt;td&gt;945&lt;/td&gt;
					&lt;td&gt;2 291&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Kein einziges Panel gab auch nur einen Fehler zurück — und doch unterscheidet sich der Durchsatz der Extreme um den Faktor 15 (1126 gegenüber 76 Anfragen/s). Dem sollte man die CPU-Auslastung gegenüberstellen: In diesem Profil läuft jedes Panel an seiner Grenze (95–100 % der CPU der VM — siehe die &lt;a href="#ressourcen-und-engp%c3%a4sse"&gt;Ressourcen-Tabelle&lt;/a&gt;). Gleiche Auslastung, um Vielfaches auseinanderliegende Ergebnisse: Panels nach „CPU-Last“ zu vergleichen, ist sinnlos; entscheidend ist, wie viel Arbeit ein Panel pro Kern erledigt.&lt;/p&gt;
&lt;h3 id="verhalten-unter-überlast"&gt;Verhalten unter Überlast &lt;a class="hanchor" href="#verhalten-unter-%c3%bcberlast" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;svg class="bench-chart" viewBox="0 0 720 316" role="img" aria-label="Fehlgeschlagene Anfragen in den Stress-Profilen. Nur die Go-Panels liefern Fehler; die PHP-Panels liefern keine, werden aber langsamer" style="max-width:100%;height:auto;font-family:var(--mono);font-size:12px"&gt;
&lt;text x="8.0" y="16.0" fill="var(--fg)" font-size="13" text-anchor="start" font-weight="600"&gt;Fehlgeschlagene Anfragen in den Stress-Profilen&lt;/text&gt;
&lt;text x="712.0" y="16.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;niedriger ist besser&lt;/text&gt;
&lt;text x="8.0" y="32.0" fill="var(--muted)" font-size="11" text-anchor="start"&gt;% aller Anfragen (HTTP ≥ 400) · Median aus drei Durchläufen&lt;/text&gt;
&lt;line x1="46" y1="236.0" x2="700" y2="236.0" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="40.0" y="240.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;0%&lt;/text&gt;
&lt;line x1="46" y1="190.0" x2="700" y2="190.0" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="40.0" y="194.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;10%&lt;/text&gt;
&lt;line x1="46" y1="144.0" x2="700" y2="144.0" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="40.0" y="148.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;20%&lt;/text&gt;
&lt;line x1="46" y1="98.0" x2="700" y2="98.0" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="40.0" y="102.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;30%&lt;/text&gt;
&lt;line x1="46" y1="52.0" x2="700" y2="52.0" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="40.0" y="56.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;40%&lt;/text&gt;
&lt;line x1="90.0" y1="236" x2="108.0" y2="236" stroke="var(--c-g4)" stroke-width="2"/&gt;
&lt;path d="M115.0,236.0 v-0.6 a0.6,0.6 0 0 1 0.6,-0.6 h22.8 a0.6,0.6 0 0 1 0.6,0.6 v0.6 z" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 800 VUs: 0,09%&lt;/title&gt;&lt;/path&gt;
&lt;line x1="146.0" y1="236" x2="164.0" y2="236" stroke="var(--c-g3)" stroke-width="2"/&gt;
&lt;line x1="174.0" y1="236" x2="192.0" y2="236" stroke="var(--c-pt)" stroke-width="2"/&gt;
&lt;line x1="202.0" y1="236" x2="220.0" y2="236" stroke="var(--c-pl)" stroke-width="2"/&gt;
&lt;text x="155.0" y="254.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;800 VUs&lt;/text&gt;
&lt;line x1="308.0" y1="236" x2="326.0" y2="236" stroke="var(--c-g4)" stroke-width="2"/&gt;
&lt;path d="M333.0,236.0 v-93.9 a4,4 0 0 1 4,-4 h16.0 a4,4 0 0 1 4,4 v93.9 z" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 1000 VUs: 21,3%&lt;/title&gt;&lt;/path&gt;
&lt;line x1="364.0" y1="236" x2="382.0" y2="236" stroke="var(--c-g3)" stroke-width="2"/&gt;
&lt;line x1="392.0" y1="236" x2="410.0" y2="236" stroke="var(--c-pt)" stroke-width="2"/&gt;
&lt;line x1="420.0" y1="236" x2="438.0" y2="236" stroke="var(--c-pl)" stroke-width="2"/&gt;
&lt;text x="373.0" y="254.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;1000 VUs&lt;/text&gt;
&lt;path d="M523.0,236.0 v-66.0 a4,4 0 0 1 4,-4 h16.0 a4,4 0 0 1 4,4 v66.0 z" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x — 1200 VUs: 15,2%&lt;/title&gt;&lt;/path&gt;
&lt;path d="M551.0,236.0 v-155.4 a4,4 0 0 1 4,-4 h16.0 a4,4 0 0 1 4,4 v155.4 z" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 1200 VUs: 34,6%&lt;/title&gt;&lt;/path&gt;
&lt;line x1="582.0" y1="236" x2="600.0" y2="236" stroke="var(--c-g3)" stroke-width="2"/&gt;
&lt;line x1="610.0" y1="236" x2="628.0" y2="236" stroke="var(--c-pt)" stroke-width="2"/&gt;
&lt;line x1="638.0" y1="236" x2="656.0" y2="236" stroke="var(--c-pl)" stroke-width="2"/&gt;
&lt;text x="591.0" y="254.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;1200 VUs&lt;/text&gt;
&lt;text x="99.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="127.0" y="228.8" fill="var(--fg)" font-size="11" text-anchor="middle" font-weight="600"&gt;0,09&lt;/text&gt;
&lt;text x="155.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="183.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="211.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="317.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;&amp;lt; 0,01&lt;/text&gt;
&lt;text x="345.0" y="132.1" fill="var(--fg)" font-size="11" text-anchor="middle" font-weight="600"&gt;21,3&lt;/text&gt;
&lt;text x="373.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="401.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="429.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="535.0" y="160.0" fill="var(--fg)" font-size="11" text-anchor="middle" font-weight="600"&gt;15,2&lt;/text&gt;
&lt;text x="563.0" y="70.6" fill="var(--fg)" font-size="11" text-anchor="middle" font-weight="600"&gt;34,6&lt;/text&gt;
&lt;text x="591.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="619.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="647.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;rect x="46.0" y="271" width="9" height="9" rx="2" fill="var(--c-g4)"/&gt;
&lt;text x="60.0" y="280.0" fill="var(--fg)" font-size="11" text-anchor="start"&gt;GameAP 4.x&lt;/text&gt;
&lt;rect x="166.0" y="271" width="9" height="9" rx="2" fill="var(--c-pp)"/&gt;
&lt;text x="180.0" y="280.0" fill="var(--fg)" font-size="11" text-anchor="start"&gt;PufferPanel&lt;/text&gt;
&lt;rect x="294.0" y="271" width="9" height="9" rx="2" fill="var(--c-g3)"/&gt;
&lt;text x="308.0" y="280.0" fill="var(--fg)" font-size="11" text-anchor="start"&gt;GameAP 3.x&lt;/text&gt;
&lt;rect x="414.0" y="271" width="9" height="9" rx="2" fill="var(--c-pt)"/&gt;
&lt;text x="428.0" y="280.0" fill="var(--fg)" font-size="11" text-anchor="start"&gt;Pterodactyl&lt;/text&gt;
&lt;rect x="542.0" y="271" width="9" height="9" rx="2" fill="var(--c-pl)"/&gt;
&lt;text x="556.0" y="280.0" fill="var(--fg)" font-size="11" text-anchor="start"&gt;Pelican&lt;/text&gt;
&lt;/svg&gt;
&lt;p&gt;Fehlgeschlagene Anfragen (HTTP ≥ 400), % aller Anfragen im Profil:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Profil&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;load (bis 100 VUs)&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress (bis 800 VUs)&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0,09&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1000&lt;/td&gt;
					&lt;td&gt;&amp;lt; 0,01&lt;/td&gt;
					&lt;td&gt;21,3&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1200&lt;/td&gt;
					&lt;td&gt;15,2&lt;/td&gt;
					&lt;td&gt;34,6&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Die Bruchpunkte diesen Daten zufolge: PufferPanel liefert als Erstes Fehler: vereinzelte (0,08–0,12 %) bereits bei 800 VUs, 21 % bei 1000, 35 % bei 1200 (bis zu 40 % bei der Listen-Anfrage). GameAP 4 besteht 1000 VUs nahezu fehlerfrei (Median — null Fehler; 0,011 % in einem der drei Durchläufe) und gibt bei 1200 VUs 14,3–15,5 % Fehler zurück. Die PHP-Panels geben überhaupt keine Fehler zurück — in keinem Profil.&lt;/p&gt;
&lt;p&gt;Aber „0 % Fehler“ bedeutet hier nicht „das Panel funktioniert“. Bei stress-1200 liegt der p95 von GameAP 3 bei 2,1 s, der von Pterodactyl bei 14,1 s, der von Pelican bei 17,5 s. Formal bekommt jede Anfrage irgendwann ein 200 (k6 wartet bis zu 60 s); praktisch ist ein Panel, das in 10–17 Sekunden antwortet, unbrauchbar. Das sind zwei verschiedene Degradationsmodi, nicht „PHP hält durch und Go nicht“:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Go-Panels — Fail-Fast&lt;/strong&gt;: Ein Teil der Anfragen endet schnell mit einem Fehler, der Rest wird mit akzeptabler Latenz bedient (der Median von GameAP 4 bei 1200 VUs liegt bei 25 ms, der von PufferPanel bei 97 ms). Der Client weiß sofort, dass der Server kämpft.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PHP-Panels — eine Warteschlange&lt;/strong&gt;: PHP-FPM reiht die Anfragen in eine Queue ein, es gibt keine Fehler, aber die Antwortzeit wächst grenzenlos. Der Client wartet, ohne zu wissen, ob eine Antwort kommt.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Welcher Modus der „richtige“ ist, ist eine Frage der Anforderungen, nicht des Benchmarks. Die praktische Konsequenz ist eindeutig: Die Überlast eines PHP-Panels taucht im Fehler-Monitoring nicht auf — nur in der Latenz.&lt;/p&gt;
&lt;p&gt;Erreichte RPS in den Stress-Profilen:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Profil&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;stress (bis 800 VUs)&lt;/td&gt;
					&lt;td&gt;259&lt;/td&gt;
					&lt;td&gt;257&lt;/td&gt;
					&lt;td&gt;210&lt;/td&gt;
					&lt;td&gt;82&lt;/td&gt;
					&lt;td&gt;68&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1000&lt;/td&gt;
					&lt;td&gt;716&lt;/td&gt;
					&lt;td&gt;615&lt;/td&gt;
					&lt;td&gt;341&lt;/td&gt;
					&lt;td&gt;90&lt;/td&gt;
					&lt;td&gt;73&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1200&lt;/td&gt;
					&lt;td&gt;764&lt;/td&gt;
					&lt;td&gt;699&lt;/td&gt;
					&lt;td&gt;349&lt;/td&gt;
					&lt;td&gt;90&lt;/td&gt;
					&lt;td&gt;74&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Diese Tabelle bitte genau lesen: Wegen der Think-Time-Pausen und der allmählichen VU-Rampe kann das Stress-Profil physikalisch nicht mehr als ~260 Anfragen/s liefern (die zeitgemittelte Zahl aktiver VUs beträgt ≈ 268, bei ~3,1 s Pausen pro Drei-Anfragen-Iteration). GameAP 4 und PufferPanel stoßen an die Grenze des Profils, nicht an ihre eigene: 259 und 257. GameAP 3 schafft 210. Pterodactyl und Pelican hingegen liefern in jedem Stress-Profil ungefähr ihren max-throughput (82–90 bzw. 68–74 Anfragen/s gegenüber Grenzen von 93 und 76) — das Panel bedient, was es kann, der Rest staut sich in der Warteschlange.&lt;/p&gt;
&lt;h3 id="ressourcen-und-engpässe"&gt;Ressourcen und Engpässe &lt;a class="hanchor" href="#ressourcen-und-engp%c3%a4sse" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;CPU-Spitzenwert der Panel-VM, %:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Profil&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;smoke (1 VU)&lt;/td&gt;
					&lt;td&gt;0,4&lt;/td&gt;
					&lt;td&gt;0,6&lt;/td&gt;
					&lt;td&gt;3,2&lt;/td&gt;
					&lt;td&gt;2,3&lt;/td&gt;
					&lt;td&gt;2,9&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;baseline (10 VUs)&lt;/td&gt;
					&lt;td&gt;0,7&lt;/td&gt;
					&lt;td&gt;0,9&lt;/td&gt;
					&lt;td&gt;4,8&lt;/td&gt;
					&lt;td&gt;8,9&lt;/td&gt;
					&lt;td&gt;10,9&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;load (bis 100 VUs)&lt;/td&gt;
					&lt;td&gt;2,4&lt;/td&gt;
					&lt;td&gt;3,8&lt;/td&gt;
					&lt;td&gt;25,7&lt;/td&gt;
					&lt;td&gt;81,2&lt;/td&gt;
					&lt;td&gt;96,8&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress (bis 800 VUs)&lt;/td&gt;
					&lt;td&gt;20,4&lt;/td&gt;
					&lt;td&gt;65,3&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1000&lt;/td&gt;
					&lt;td&gt;40,0&lt;/td&gt;
					&lt;td&gt;95,6&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1200&lt;/td&gt;
					&lt;td&gt;87,7&lt;/td&gt;
					&lt;td&gt;96,1&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;max-throughput&lt;/td&gt;
					&lt;td&gt;96,1&lt;/td&gt;
					&lt;td&gt;95,3&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Die Schlüsselzeile ist load: Die „Arbeitslast“ von 100 gleichzeitigen Nutzern, die jedes Panel mit null Fehlern besteht, kostet GameAP 4 und PufferPanel 2–4 % CPU, GameAP 3 — 26 %, Pterodactyl — 81 %, Pelican — 97 %. Pterodactyl und Pelican laufen in diesem Profil bereits am Rand der Sättigung — für Lastspitzen bleibt ihnen kein Puffer.&lt;/p&gt;
&lt;p&gt;Wohin die CPU unter Überlast fließt — Prozesse im Stress-Profil (800 VUs), Spitzenwert über das Fenster, Mittelwert der Durchläufe 2–3:&lt;/p&gt;
&lt;svg class="bench-chart" viewBox="0 0 720 330" role="img" aria-label="CPU pro Prozess im Stress-Profil (800 VUs). Bei Pterodactyl und Pelican beansprucht MySQL etwa einen ganzen Kern" style="max-width:100%;height:auto;font-family:var(--mono);font-size:12px"&gt;
&lt;text x="8.0" y="16.0" fill="var(--fg)" font-size="13" text-anchor="start" font-weight="600"&gt;CPU pro Prozess im Stress-Profil (800 VUs)&lt;/text&gt;
&lt;text x="712.0" y="16.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;niedriger ist besser&lt;/text&gt;
&lt;text x="8.0" y="32.0" fill="var(--muted)" font-size="11" text-anchor="start"&gt;Spitzenwert im Profilfenster · 400% = 4 vCPU · Mittelwert der Durchläufe 2–3&lt;/text&gt;
&lt;line x1="118.0" y1="48" x2="118.0" y2="258" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="118.0" y="272.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;0%&lt;/text&gt;
&lt;line x1="248.5" y1="48" x2="248.5" y2="258" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="248.5" y="272.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;100%&lt;/text&gt;
&lt;line x1="379.0" y1="48" x2="379.0" y2="258" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="379.0" y="272.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;200%&lt;/text&gt;
&lt;line x1="509.5" y1="48" x2="509.5" y2="258" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="509.5" y="272.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;300%&lt;/text&gt;
&lt;line x1="640.0" y1="48" x2="640.0" y2="258" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="640.0" y="272.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;400%&lt;/text&gt;
&lt;text x="110.0" y="73.5" fill="var(--fg)" font-size="12" text-anchor="end"&gt;GameAP 4.x&lt;/text&gt;
&lt;path d="M118.0,56.5 h38.0 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-38.0 z" fill="var(--c-app)"&gt;&lt;title&gt;GameAP 4.x — gameap: 31,5% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="165.0" y="68.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;31,5&lt;/text&gt;
&lt;path d="M118.0,74.5 h1.9 a1.8744545454545474,1.8744545454545474 0 0 1 1.8744545454545474,1.8744545454545474 v11.3 a1.8744545454545474,1.8744545454545474 0 0 1 -1.8744545454545474,1.8744545454545474 h-1.9 z" fill="var(--c-db)"&gt;&lt;title&gt;GameAP 4.x — postgresql: 2,9% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="127.7" y="86.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;2,9&lt;/text&gt;
&lt;text x="110.0" y="115.5" fill="var(--fg)" font-size="12" text-anchor="end"&gt;PufferPanel&lt;/text&gt;
&lt;path d="M118.0,98.5 h92.4 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-92.4 z" fill="var(--c-app)"&gt;&lt;title&gt;PufferPanel — pufferpanel: 73,1% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="219.4" y="110.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;73,1&lt;/text&gt;
&lt;path d="M118.0,116.5 h9.4 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-9.4 z" fill="var(--c-db)"&gt;&lt;title&gt;PufferPanel — postgresql: 9,5% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="136.4" y="128.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;9,5&lt;/text&gt;
&lt;text x="110.0" y="157.5" fill="var(--fg)" font-size="12" text-anchor="end"&gt;GameAP 3.x&lt;/text&gt;
&lt;path d="M118.0,140.5 h412.1 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-412.1 z" fill="var(--c-app)"&gt;&lt;title&gt;GameAP 3.x — php-fpm: 318% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="539.1" y="152.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;318&lt;/text&gt;
&lt;path d="M118.0,158.5 h38.0 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-38.0 z" fill="var(--c-db)"&gt;&lt;title&gt;GameAP 3.x — mysqld: 31,4% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="165.0" y="170.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;31,4&lt;/text&gt;
&lt;text x="110.0" y="199.5" fill="var(--fg)" font-size="12" text-anchor="end"&gt;Pterodactyl&lt;/text&gt;
&lt;path d="M118.0,182.5 h313.7 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-313.7 z" fill="var(--c-app)"&gt;&lt;title&gt;Pterodactyl — php-fpm: 243% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="440.7" y="194.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;243&lt;/text&gt;
&lt;path d="M118.0,200.5 h138.8 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-138.8 z" fill="var(--c-db)"&gt;&lt;title&gt;Pterodactyl — mysqld: 109% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="265.8" y="212.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;109&lt;/text&gt;
&lt;text x="110.0" y="241.5" fill="var(--fg)" font-size="12" text-anchor="end"&gt;Pelican&lt;/text&gt;
&lt;path d="M118.0,224.5 h336.2 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-336.2 z" fill="var(--c-app)"&gt;&lt;title&gt;Pelican — php-fpm: 260% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="463.2" y="236.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;260&lt;/text&gt;
&lt;path d="M118.0,242.5 h120.0 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-120.0 z" fill="var(--c-db)"&gt;&lt;title&gt;Pelican — mysqld: 94,3% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="247.0" y="254.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;94,3&lt;/text&gt;
&lt;rect x="118" y="285" width="9" height="9" rx="2" fill="var(--c-app)"/&gt;
&lt;text x="132.0" y="294.0" fill="var(--fg)" font-size="11" text-anchor="start"&gt;Anwendung (Go / php-fpm)&lt;/text&gt;
&lt;rect x="358" y="285" width="9" height="9" rx="2" fill="var(--c-db)"/&gt;
&lt;text x="372.0" y="294.0" fill="var(--fg)" font-size="11" text-anchor="start"&gt;Datenbank (PostgreSQL / MySQL)&lt;/text&gt;
&lt;/svg&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Prozess&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Anwendung (Go / php-fpm)&lt;/td&gt;
					&lt;td&gt;31,5&lt;/td&gt;
					&lt;td&gt;73,1&lt;/td&gt;
					&lt;td&gt;318&lt;/td&gt;
					&lt;td&gt;243&lt;/td&gt;
					&lt;td&gt;260&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Datenbank (PostgreSQL / MySQL)&lt;/td&gt;
					&lt;td&gt;2,9&lt;/td&gt;
					&lt;td&gt;9,5&lt;/td&gt;
					&lt;td&gt;31,4&lt;/td&gt;
					&lt;td&gt;109&lt;/td&gt;
					&lt;td&gt;94,3&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;100 % = ein Kern, insgesamt 4 vCPU. Nginx blieb in jedem Durchlauf ≤ 3,2 %; Redis, wo process_exporter es sah, ≤ 5,1 % (die Monitoring-Abdeckung des Redis-Prozesses erwies sich als lückenhaft — in manchen Durchläufen verfolgte process_exporter ihn nicht; das ändert nichts am Gesamtbild, aber er bleibt aus der Tabelle ausgenommen).&lt;/p&gt;
&lt;p&gt;Die interessanteste Zeile ist die der Datenbank. Bei Pterodactyl und Pelican verbraucht MySQL 94–109 % CPU — nahezu einen ganzen Kern — und bedient dabei 68–82 Anfragen pro Sekunde. Bei GameAP 3 ist dasselbe MySQL 8.0 mit denselben Einstellungen zu 31 % ausgelastet — bei 210 Anfragen pro Sekunde. Pro Anfrage verbrennen Pterodactyl und Pelican etwa neunmal mehr Datenbank-CPU-Zeit als GameAP 3. Offenbar ist der Engpass dieser Panels nicht PHP als solches, sondern ihre Datenbank-Workload. Die Ursache wurde nicht profiliert und bleibt eine offene Frage; ein &lt;code&gt;EXPLAIN&lt;/code&gt;-Durchgang über die Abfragen der Listen-Endpunkte liegt nahe.&lt;/p&gt;
&lt;p&gt;RAM-Spitzenwert der VM, MB:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Profil&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;smoke (1 VU)&lt;/td&gt;
					&lt;td&gt;449&lt;/td&gt;
					&lt;td&gt;462&lt;/td&gt;
					&lt;td&gt;1 049&lt;/td&gt;
					&lt;td&gt;1 096&lt;/td&gt;
					&lt;td&gt;1 177&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress (bis 800 VUs)&lt;/td&gt;
					&lt;td&gt;480&lt;/td&gt;
					&lt;td&gt;539&lt;/td&gt;
					&lt;td&gt;1 288&lt;/td&gt;
					&lt;td&gt;1 463&lt;/td&gt;
					&lt;td&gt;1 606&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1200&lt;/td&gt;
					&lt;td&gt;701&lt;/td&gt;
					&lt;td&gt;744&lt;/td&gt;
					&lt;td&gt;1 354&lt;/td&gt;
					&lt;td&gt;1 469&lt;/td&gt;
					&lt;td&gt;1 610&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;max-throughput&lt;/td&gt;
					&lt;td&gt;641&lt;/td&gt;
					&lt;td&gt;672&lt;/td&gt;
					&lt;td&gt;1 342&lt;/td&gt;
					&lt;td&gt;1 445&lt;/td&gt;
					&lt;td&gt;1 556&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Prozess-RSS bei stress-800 (Mittelwert der Durchläufe 2–3): die Anwendung — 65 MB bei GameAP 4 und 107 MB bei PufferPanel gegenüber 2,7–4,2 GB Gesamt-RSS über fünfzig php-fpm-Worker; die Datenbank — 107 MB PostgreSQL bei GameAP 4 gegenüber ~613–641 MB MySQL. Zwei Vorbehalte: Der RSS der php-fpm-Worker zählt Shared Memory mehrfach (der reale Verbrauch der VM steht in der Tabelle oben), und PufferPanels PostgreSQL-RSS schwankte spürbar zwischen den Durchläufen (721 MB im ersten, ~440 MB im zweiten und dritten).&lt;/p&gt;
&lt;p&gt;Und eine Anomalie, die ehrlicherweise unerklärt bleibt: PufferPanel ist das einzige Panel, das unter Last aktiv auf die Festplatte schreibt — Spitzen von 140–150 Schreib-IOPS gegenüber 4 bei GameAP 4 und 21–24 bei den übrigen. Die Ursache (Logs? Auditing? Besonderheiten der PostgreSQL-Nutzung?) wurde nicht untersucht.&lt;/p&gt;
&lt;h3 id="was-die-einzelnen-endpunkte-zeigen"&gt;Was die einzelnen Endpunkte zeigen &lt;a class="hanchor" href="#was-die-einzelnen-endpunkte-zeigen" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Median-Latenz pro Endpunkt im load-Profil, ms:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Endpunkt&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;list_servers&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0,87&lt;/td&gt;
					&lt;td&gt;1,41&lt;/td&gt;
					&lt;td&gt;11,1&lt;/td&gt;
					&lt;td&gt;87,3&lt;/td&gt;
					&lt;td&gt;141&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;server_details&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0,58&lt;/td&gt;
					&lt;td&gt;0,74&lt;/td&gt;
					&lt;td&gt;8,34&lt;/td&gt;
					&lt;td&gt;12,7&lt;/td&gt;
					&lt;td&gt;25,6&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;server_status&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0,38&lt;/td&gt;
					&lt;td&gt;1,49&lt;/td&gt;
					&lt;td&gt;8,34&lt;/td&gt;
					&lt;td&gt;11,5&lt;/td&gt;
					&lt;td&gt;20,9&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Die Serverliste ist die schwerste Anfrage bei jedem Panel, aber bei Pterodactyl und Pelican ist die Kluft dramatisch: Die Liste ist 7–8-mal langsamer als die Details-Anfrage (87 und 141 ms gegenüber 13 und 26 ms). Es ist die Listen-Anfrage, die unter Last als Erstes degradiert.&lt;/p&gt;
&lt;p&gt;Zur Erinnerung an den Vorbehalt aus der Methodik: Die Größe der Listen-Antwort unterscheidet sich zwischen den Panels (102 Datensätze bei GameAP, 50 bei Pterodactyl/Pelican, 20 bei PufferPanel), daher ist ein Vergleich der &lt;code&gt;list_servers&lt;/code&gt;-Zeile &lt;strong&gt;zwischen&lt;/strong&gt; den Panels nicht fair. Was man aus dieser Tabelle ablesen kann, ist das Verhältnis zwischen den Endpunkten innerhalb eines Panels — und die Tatsache, dass GameAP 4 seine vollständige Liste von 102 Datensätzen (~13 KB) schneller liefert, als irgendein PHP-Panel seine erste Seite liefert.&lt;/p&gt;
&lt;h3 id="die-drei-direktvergleiche"&gt;Die drei Direktvergleiche &lt;a class="hanchor" href="#die-drei-direktvergleiche" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;GameAP 3 → GameAP 4.&lt;/strong&gt; Dafür wurde neu geschrieben: Der baseline-Median ist 9,24 gegenüber 0,82 ms (11×), der load-Median 8,78 gegenüber 0,59 ms (15×), die Durchsatzgrenze 394 gegenüber 1126 Anfragen/s (2,9×), der Speicher der gesamten VM 1,0–1,4 GB gegenüber 0,45–0,70 GB, die CPU im load-Profil 26 % gegenüber 2,4 %.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GameAP 4 vs. PufferPanel.&lt;/strong&gt; Beide sind Go + PostgreSQL, und beide sind eine Größenordnung schneller als die PHP-Gruppe. Zwischen den beiden: GameAP 4 ist nach Median in baseline/load 1,9–2,3× schneller und nach Durchsatzgrenze 1,6× (1126 gegenüber 696), bricht unter Überlast später ein (15 % Fehler bei 1200 VUs gegenüber PufferPanels 21 % bereits bei 1000 und ersten vereinzelten Fehlern bei 800) und rührt die Festplatte kaum an. Beachten Sie jedoch, dass PufferPanel in diesem Szenario eine Größenordnung weniger Daten pro Listen-Anfrage liefert (20 Datensätze, ~1,6 KB gegenüber 102 Datensätzen, ~13 KB) — der Abstand wurde bei einer für PufferPanel leichteren Arbeit gemessen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pterodactyl vs. Pelican.&lt;/strong&gt; Der Fork erwies sich in jedem Profil als langsamer als das Original: Im load-Profil ist der Median 54,5 gegenüber 20,7 ms, p95 — 473 gegenüber 154 ms, die Grenze — 76 gegenüber 93 Anfragen/s, und die CPU-Sättigung tritt früher ein (97 % bereits bei load gegenüber 81 %). Prozessbezogen ist Pelicans php-fpm stärker ausgelastet (260 gegenüber 243 %) und sein MySQL weniger (94 gegenüber 109 %). Die Ursachen der Unterschiede wurden nicht untersucht; zum Testzeitpunkt war Pelican ein junger Fork (1.0.x), und sein Performance-Profil kann sich noch ändern.&lt;/p&gt;
&lt;h2 id="einschränkungen"&gt;Einschränkungen &lt;a class="hanchor" href="#einschr%c3%a4nkungen" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Eine Aufstellung dessen, was die Schlussfolgerungen dieses Tests begrenzt.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Unterschiedliche Datenbanken zwischen den Gruppen.&lt;/strong&gt; Die Go-Panels liefen auf PostgreSQL, die PHP-Panels auf MySQL 8.0 (in beiden Fällen die von den Entwicklern der Panels empfohlenen Konfigurationen). Jeder „Go vs. PHP“-Vergleich hier bedeutet in Wirklichkeit „Go+PostgreSQL vs. PHP+MySQL“ — dieser Test trennt den Beitrag der Datenbank nicht von dem der Sprache und der Architektur. Innerhalb jeder Gruppe sind die Datenbanken identisch.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unterschiedliche Antwortgrößen bei &lt;code&gt;list_servers&lt;/code&gt;.&lt;/strong&gt; Jede Datenbank enthält 100 Server, aber GameAP liefert die ganze Liste (102 Datensätze), Pterodactyl/Pelican die erste Seite von 50, PufferPanel die erste Seite von 20; die Antwortgrößen reichen von 1,6 bis 16 KB. Der Test hat die Paginierung nicht auf eine gemeinsame Seitengröße normalisiert. Direkte panelübergreifende Listen-Latenzvergleiche sind daher verzerrt; zugunsten wessen, hängt vom Paar ab (die Verzerrung macht PufferPanels Arbeit leichter und die von GameAP schwerer).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GameAP 3 hat keinen Status-Endpunkt&lt;/strong&gt;: Sein &lt;code&gt;server_status&lt;/code&gt; ist eine Wiederholung der Details-Anfrage, sodass ein Drittel des Szenarios bei GameAP 3 nicht äquivalent zu den anderen Panels ist.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nur lesend, nur API.&lt;/strong&gt; Keine Schreibzugriffe, kein WebSocket, keine UI; die Mock-Server wurden nie installiert oder gestartet, und die Daemons auf den benachbarten VMs waren praktisch untätig. Dies ist ein Test der HTTP/API-Schicht der Panels, nicht der Panels als Ganzes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Das Closed-Loop-Modell von k6&lt;/strong&gt; (&lt;a href="#das-closed-loop-lastmodell"&gt;siehe Methodik&lt;/a&gt;): Die degradierten Panels erhielten automatisch weniger Last, daher sind ihre Stress-Zahlen eine optimistische Schätzung. Das k6-Anfragen-Timeout beträgt 60 s.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Aufwärmphase.&lt;/strong&gt; Ein smoke-Aufwärmdurchlauf (30 s) vor der Profilserie und ein Dienst-Neustart vor jedem Profil. Bei den Panels, die nicht CPU-limitiert sind (GameAP 3/4, PufferPanel), ist die durchschnittliche Latenz bei baseline höher als im schwereren load-Profil (0,85 → 0,66 ms; 1,49 → 1,27; 10,9 → 9,7) — ein Teil des baseline-Fensters ist offenbar noch Aufwärmphase. Das ändert nichts an den Schlussfolgerungen, aber die absoluten baseline-Zahlen sind leicht aufgebläht.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Neustart-Asymmetrie.&lt;/strong&gt; Vor jedem Profil wurden bei den PHP-Panels php-fpm, nginx und MySQL neu gestartet (Buffer Pool und Caches geleert; bei GameAP 3 auch Redis), bei PufferPanel die Anwendung (PostgreSQL lief weiter), und bei GameAP 4 nur nginx (die Anwendung und PostgreSQL nicht). Die PHP-Panels starteten jedes Profil „kälter“. Die Rampenphasen der Profile kompensieren das teilweise, aber die Asymmetrie wurde nicht vollständig beseitigt.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Versionen auf Major-Ebene erfasst&lt;/strong&gt; (GameAP 4.x / 3.x, Pterodactyl 1.11.x, Pelican 1.0.x, PufferPanel 3.x, April 2026). GameAP 4 ist funktional jünger und einfacher als die übrigen — weniger Arbeit pro Anfrage zu leisten kann Teil seines Vorteils sein; das wurde nicht quantifiziert.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Veränderte Limits.&lt;/strong&gt; Bei Pterodactyl und Pelican wurden die Rate-Limits auf 10 000 Anfragen/min angehoben — eine Standardinstallation hätte die Last früher abgeschnitten.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitoring.&lt;/strong&gt; CPU und RAM sind VM-weite Metriken im 15-s-Schritt (kurze Spitzen können geglättet werden); Prozessmetriken haben einen 30-s-Schritt, und die Abdeckung des Redis-Prozesses ist über die Durchläufe lückenhaft; PufferPanels smoke-Statistiken enthalten die OAuth-Anfrage aus &lt;code&gt;setup()&lt;/code&gt;. Eine Hardware-Konfiguration, ein VM-Layout, 100 Server in der Datenbank — auf anderer Hardware und bei anderen Datenmengen werden die absoluten Zahlen anders ausfallen.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="fazit"&gt;Fazit &lt;a class="hanchor" href="#fazit" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Zurück zu den drei Fragen aus den Zielen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wie unterschiedlich sind die Panels bei normaler Last?&lt;/strong&gt; Im load-Profil (bis zu 100 gleichzeitige Nutzer) arbeiten alle fünf Panels mit null Fehlern, und die Latenz unterscheidet sich um eine Größenordnung oder mehr: 0,6–1,4 ms Median bei den Go-Panels, ~9 ms bei GameAP 3, 21–55 ms bei Pterodactyl/Pelican. Sagen wir es unverblümt: Für einen Menschen im Browser sind selbst 55 ms schnell. Wenn Sie ein Panel, ein Dutzend Server und keine Automatisierung betreiben, wird sich jeder der Kandidaten instantan anfühlen. Der Unterschied wird praktisch bei Integrationen und Automatisierung, bei Massenoperationen, auf billiger Hardware — und beim Preis dieser Geschwindigkeit: Dieselben 100 VUs kosten Pelican 97 % CPU und GameAP 4 — 2,4 %.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wo liegt der Bruchpunkt und wie bricht ein Panel?&lt;/strong&gt; Nach Durchsatzgrenze: 1126 (GameAP 4) → 696 (PufferPanel) → 394 (GameAP 3) → 93 (Pterodactyl) → 76 (Pelican) Anfragen/s. Unter Überlast gibt es zwei Modi: Die Go-Panels scheitern schnell mit Fehlern (PufferPanel ab 800–1000 VUs, GameAP 4 ab 1200), die PHP-Panels geben keine Fehler zurück, antworten aber in Sekunden bis Dutzenden von Sekunden. Die praktische Lehre für das Monitoring: Die Überlast eines PHP-Panels ist nur in der Latenz sichtbar — Fehler-Alarme wird es nicht geben.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Was ist der Engpass?&lt;/strong&gt; Bei GameAP 4 — die eigene CPU der Anwendung (die Datenbank ist kaum ausgelastet). Bei PufferPanel — die Anwendung plus nennenswerte Festplattenschreibzugriffe, deren Ursache nicht untersucht wurde. Bei GameAP 3 — php-fpm (318 % CPU bei MySQL mit 31 %). Bei Pterodactyl und Pelican sieht das Bild anders aus: Neben php-fpm frisst MySQL nahezu einen ganzen Kern — pro Anfrage ist das etwa neunmal mehr Datenbank-CPU-Zeit, als GameAP 3 auf dasselbe MySQL verwendet. Das ist das interessanteste Ergebnis des Tests, und es verdient eine eigene Untersuchung mit Query-Profiling.&lt;/p&gt;
&lt;p&gt;Dieser Test misst einen einzigen Ausschnitt — die Lesegeschwindigkeit der HTTP/API-Schicht. Er sagt nichts über Funktionsumfang, Bedienbarkeit, Sicherheit oder Ökosystem aus, und die Wahl eines Panels hängt auch davon ab. GameAP 4 hat diesen Benchmark gewonnen, ist aber auch der jüngste Kandidat; Pterodactyl hat nach Zahlen verloren — und bleibt dennoch das verbreitetste Panel mit dem größten Ökosystem. Was Sie mit diesen Fakten anfangen, bleibt Ihnen überlassen.&lt;/p&gt;
&lt;h3 id="wie-es-weitergeht"&gt;Wie es weitergeht &lt;a class="hanchor" href="#wie-es-weitergeht" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Phase 2 — Gameserver-Verwaltung&lt;/strong&gt;: Massenstart/-stopp von N Servern, stationärer Zustand mit laufenden Servern, parallele WebSocket-Konsolen, Server-Erstellung über die API. Dafür wird ein Fake-Gameserver vorbereitet — eine Binärdatei, die einen echten Gameserver nachahmt.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skalierung nach Datenvolumen&lt;/strong&gt;: Durchläufe mit 1 / 100 / 1000 Servern in der Datenbank, um zu messen, wie die Latenz der Listen-Endpunkte von der Datenbankgröße abhängt.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Offene Fragen&lt;/strong&gt; aus dieser Phase: PufferPanels Festplattenschreibzugriffe, Profiling der MySQL-Abfragen von Pterodactyl/Pelican, der Unterschied zwischen Pelican und Pterodactyl.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Die Skripte, Konfigurationen und Rohdaten aller Durchläufe liegen im Repository &lt;a href="https://github.com/et-nik/game-panels-benchmark" target="_blank" rel="noopener"&gt;game-panels-benchmark&lt;/a&gt;. Wenn Sie einen Fehler in der Methodik oder der Interpretation finden — öffnen Sie ein Issue: Er wird erneut geprüft und eine Korrektur veröffentlicht.&lt;/p&gt;</content:encoded></item><item><title>Der GameAP-Blog ist zurück</title><link>https://blog.gameap.com/de/news/blog-relaunch/</link><pubDate>Sun, 02 Aug 2026 12:00:00 +0300</pubDate><guid>https://blog.gameap.com/de/news/blog-relaunch/</guid><description>Der GameAP-Blog wurde neu aufgelegt: Projektneuigkeiten, Release-Ankündigungen und Anleitungen für Gameserver.</description><content:encoded>&lt;p&gt;Der GameAP-Blog ist zurück. Die alte Version war jahrelang unverändert geblieben und deutlich in die Jahre gekommen. Statt sie wiederzubeleben, haben wir den Blog daher von Grund auf neu aufgebaut — auf einer neuen Plattform und unter neuen Adressen.&lt;/p&gt;
&lt;h2 id="neue-adressen"&gt;Neue Adressen &lt;a class="hanchor" href="#neue-adressen" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Der Blog lief früher unter einer einzigen Domain, &lt;code&gt;gameap.blog&lt;/code&gt;, auf der die Sprachen über ein Pfadpräfix unterschieden wurden: &lt;code&gt;gameap.blog/en/&lt;/code&gt; und &lt;code&gt;gameap.blog/ru/&lt;/code&gt;. Die englische und die russische Version haben jetzt ihre eigene Domain, die spanische und die deutsche sind über ein Pfadpräfix auf &lt;code&gt;blog.gameap.com&lt;/code&gt; erreichbar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.gameap.com/"&gt;blog.gameap.com&lt;/a&gt; — englische Version;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.gameap.ru/" target="_blank" rel="noopener"&gt;blog.gameap.ru&lt;/a&gt; — russische Version;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.gameap.com/es/"&gt;blog.gameap.com/es/&lt;/a&gt; — spanische Version;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.gameap.com/de/"&gt;blog.gameap.com/de/&lt;/a&gt; — deutsche Version.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Damit fügt sich der Blog in den Rest des Projekts ein: Die englischsprachigen Ressourcen finden sich unter &lt;code&gt;gameap.com&lt;/code&gt; (&lt;a href="https://gameap.com/" target="_blank" rel="noopener"&gt;Website&lt;/a&gt;, &lt;a href="https://docs.gameap.com/" target="_blank" rel="noopener"&gt;Dokumentation&lt;/a&gt;), die russischsprachigen unter &lt;code&gt;gameap.ru&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Links auf die alte Domain &lt;code&gt;gameap.blog&lt;/code&gt; funktionieren weiterhin — sie führen zu den neuen Adressen.&lt;/p&gt;
&lt;p&gt;Jeder Artikel erscheint in allen vier Sprachen. Der Sprachumschalter im Seitenkopf führt zum selben Artikel in der anderen Sprache, nicht zur Startseite.&lt;/p&gt;
&lt;h2 id="was-sie-erwartet"&gt;Was Sie erwartet &lt;a class="hanchor" href="#was-sie-erwartet" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Projektneuigkeiten&lt;/strong&gt; — Ankündigungen neuer GameAP-Releases, Änderungen am Panel und am Daemon, Neues aus dem Plugin-Ökosystem.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Anleitungen&lt;/strong&gt; — praxisnahe Artikel zum Einrichten von GameAP und zum Betrieb von Gameservern: von der Installation des Panels bis zum Feintuning.&lt;/li&gt;
&lt;li&gt;Vergleiche, Benchmarks und ausführliche Analysen — alles, was nicht in die Dokumentation passt.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="nützliche-links"&gt;Nützliche Links &lt;a class="hanchor" href="#n%c3%bctzliche-links" aria-label="Link zu dieser Überschrift"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gameap.com/" target="_blank" rel="noopener"&gt;GameAP-Website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.gameap.com/" target="_blank" rel="noopener"&gt;Dokumentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gameap" target="_blank" rel="noopener"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Der erste große Artikel ist bereits in Arbeit — ein Lasttest der beliebtesten Control Panels für Gameserver.&lt;/p&gt;</content:encoded></item><item><title>Willkommen</title><link>https://blog.gameap.com/de/news/welcome/</link><pubDate>Fri, 24 Apr 2020 00:00:00 +0300</pubDate><guid>https://blog.gameap.com/de/news/welcome/</guid><description>Willkommen im GameAP-Blog. Hier veröffentlichen wir Informationen zu GameAP-Releases, Anleitungen, Informationen zu Modulen und mehr.</description><content:encoded>&lt;p&gt;Willkommen im GameAP-Blog. Hier werden Informationen zu GameAP-Releases, Anleitungen, Informationen zu Modulen usw. veröffentlicht.&lt;/p&gt;</content:encoded></item></channel></rss>