Zum Inhalt springen
klyogames

Was möchtest du hinzufügen?

Ein Konto für Spieler und Entwickler. Beiträge und Clips landen in der Community, Spiele nach einer Prüfung im Katalog.

Spiel (ZIP-Paket)Eigene Adresse und Statistiken, dazu ein Anteil an den Werbeeinnahmen, sobald wir Werbung einschalten. Online nach der automatischen Prüfung. Clip aus einem SpielNimm im Studio mit einem Klick 15–30 Sekunden aus deinem Spiel auf. Beitrag für die CommunityText, Fotos oder ein Video bis 30 s: eine Frage, ein Aufruf zum Testen, ein Release.

Dokumentation

klyo SDK für HTML5-Spiele

Eine Datei in dein Spiel, und schon kann es mit der Seite sprechen, auf der es läuft: Es schickt Punkte an die Bestenliste, speichert den Fortschritt auf unserem Server, fragt nach einer Werbepause und lässt den Spieler einen Clip aufnehmen. Das Spiel bekommt keinen Zugriff auf die Seite, die Werbung oder den Server. Es fragt, und die Seite entscheidet.

So fügst du das SDK in dein Spiel ein

Eine Zeile in der index.html, vor deinem eigenen Skript. Das klappt auch, wenn jemand das Spiel außerhalb des Katalogs öffnet: Die Aufrufe brechen nicht ab, sie antworten sofort. Die polnischen Namen aus früheren Versionen (klyo.gotowa, klyo.wynik, klyo.postep, klyo.tablica, klyo.zapis, klyo.przerwa, klyo.nagroda, klyo.pelnyEkran, klyo.obraz) funktionieren weiter, denn es sind dieselben Funktionen.

<script src="https://games.klyo.pl/sdk/klyo-gry-sdk.js"></script>

So meldest du, dass das Spiel spielbereit ist

Ruf das auf, sobald das Spiel geladen ist und gespielt werden kann. Die Seite blendet dann den Ladebildschirm aus und stoppt das Ladesymbol.

klyo.ready();

So schickst du Punkte an die Bestenliste

Nach jeder beendeten Partie. Die Punkte landen in der Bestenliste auf dem Server und in den Rekorden des Spielers, mit Konto auch auf einem zweiten Gerät. Die Antwort enthält alles für den Endbildschirm: die heutige Platzierung samt Sprung, die der Woche, die ewige Bestenliste und den Spieler direkt davor.

klyo.score(1200, (o) => {
  // o.todayRank, o.previousTodayRank (jump),
  // o.weekRank, o.allTimeRank,
  // o.above = { name, score }  → "320 to OpenGamers"
  showEndScreen(o);
});

So gibst du dem Spieler während der Partie ein Ziel

Ruf es bei jeder Punkteänderung auf; das Kit drosselt sich selbst (höchstens 4-mal pro Sekunde). Die Seite zeigt unter dem Spiel ein Abzeichen: „#14 · 320 bis OpenGamers“ und beim Überholen „↑ #13, du überholst …“. Ohne diesen Aufruf gibt es kein Abzeichen; nichts geht ins Netz, es ist nur ein Gespräch mit der Seite.

klyo.progress(points);

So zeigst du die zwanzig besten Ergebnisse

Drei Zeiträume: Tag, Woche, gesamt. Die Antwort enthält die Spielernamen, dieselben, die auch die Community anzeigt.

klyo.leaderboard.get("day", (t) => {
  showBoard(t.entries);
});

Teams, Karten und Einladungen per Link

Du übergibst der Lobby Teams und Karten, und der Raum auf dem Server merkt sie sich: Die Lobby des Portals zeigt Teamspalten mit freien Plätzen (der Spieler wählt, ein volles Team lehnt ab) und Kartenkacheln (der Gastgeber wählt). Ein Einladungslink bringt einen Freund direkt in den Raum und ins Team der Person, die ihn geschickt hat, so spielt ihr zusammen. Am Computer reicht es, den Link zu öffnen, am Handy genügt ein Tipp auf die Einladungskarte. Die Schnellsuche wählt nach Karte und Team, und mit dropIn setzt sie Spieler direkt in eine laufende Partie. Lege Seiten und Karte nur über room().players[i].team und room().map fest, nie über eine lokale Auswahl im Menü deines Spiels: So landen zwei Spieler, die beide Angriff gewählt haben, garantiert im selben Team.

klyo.online.onInvite(() => playOnline()); // player from a link
function playOnline() {
  klyo.online.lobby({ players: 10, mode: "realtime", dropIn: true,
    teams: [{ id: "attack", name: "Attack" }, { id: "defense", name: "Defense" }],
    maps: [{ id: "port", name: "Port", image: "maps/port.webp" }] }, (o) => {
    if (!o.ok) return;
    const me = o.room.players.find((p) => p.who === o.room.me);
    startMatch(o.room.map, me.team, o.room.players);
  });
}

So überwacht der Server die Spielregeln einer Partie

Die Spielregeln einer Partie schreibst du in eine Datei klyo-rules.json in deinem Paket: wie oft pro Sekunde ein Spieler schießen darf, wie viele Schuss ein Magazin fasst, was es auffüllt und wie lange das Nachladen dauert, wie schnell sich eine Figur bewegt und wie hoch der Schaden maximal ist. Wir lesen die Datei bei der Veröffentlichung, ein Spieler kann sie also nicht im Browser ändern. Der Spielserver prüft jede Aktion, bevor andere Spieler sie sehen, auch über die Ersatzverbindung. Eine Aktion gegen die Regeln erreicht niemanden, und dein Spiel bekommt onReject mit dem Grund. Treffer und Punkte übernimmst du nur aus Nachrichten, die eine Aktion enthalten.

klyo.online.act("shoot", { damage: 36, hit: target });
klyo.online.pos(x, y, z);
klyo.online.onReject((r) => {
  // r.reason: "burst-empty", "locked", "too-fast", "too-far"
  fixAmmo(r);
});
// klyo-rules.json:
// { "online": { "actions": { "shoot": { "perSecond": 10, "burst": 30, "refill": "reload" },
//   "reload": { "lockMs": 2500 } }, "position": { "maxSpeed": 7.5 } } }

So zeigst du das Wochenturnier

Jedes Spiel mit dem SDK bekommt automatisch ein Turnier: Montag bis Sonntag, ohne Geldpreise, das Podium erhält XP (100, 60 und 30), wenn mindestens drei Spieler mitgemacht haben. In die Tabelle kommen nur Ergebnisse, die die Fairnessprüfung bestanden haben. Die Antwort enthält das Ende der Runde, die Top 50, deinen Platz und die Gewinner der letzten Wochen.

klyo.tournament.get((t) => {
  // t.endsAt, t.entries, t.me = { rank, score },
  // t.winners = [{ edition, name, score }]
  showTournament(t);
});

So speicherst du den Fortschritt geräteübergreifend

Bis zu 64 KB pro Spieler und Spiel, gespeichert auf dem Server. Lade beim Start, speichere nach wichtigen Änderungen, nicht in jedem Frame.

klyo.save.set({ level: 4, gold: 120 });
klyo.save.get((z) => {
  if (z.ok && z.data) loadState(z.data);
});

So setzt du eine Werbepause an die richtige Stelle

Den Zeitpunkt wählst du, nicht wir. Gut passen das Ende eines Levels und der Bildschirm nach einer Niederlage, schlecht die Mitte eines Kampfes. Das Spiel wartet auf den callback, bevor es weitergeht.

klyo.adBreak("between-levels", () => {
  resumeGame();
});

So baust du eine Belohnungswerbung ein

Der Spieler startet sie selbst per Knopf: ansehen und Bonus kassieren. Gib die Belohnung NUR, wenn in der Antwort ok auf true steht. false heißt: Es gab keine Werbung, sie lief nicht zu Ende oder der Spieler hat sie geschlossen.

bonusButton.onclick = () => {
  klyo.rewardedAd((o) => {
    if (o.ok) giveBonus(500);
    else say("Bonus next time.");
  });
};

So forderst du den Vollbildmodus an

Browser erlauben den Vollbildmodus nur als Reaktion auf einen Klick des Spielers, also ruf das aus einem Klick-Handler auf, nicht nach dem Laden des Spiels.

klyo.fullscreen();

So können Spieler einen Clip von deinem Spiel aufnehmen

Eine Zeile, und der Spieler hat auf der Seite einen funktionierenden Aufnahmeknopf. Die Frames verlassen nie das Fenster: Das Spiel kodiert sie selbst und übergibt fertige Bytes. Deshalb klappt das auch auf Handys, wo Browser keine Bildschirmaufnahme haben.

klyo.canvas(myCanvas);

So reagierst du, wenn die Seite um Ruhe bittet

Ein Spieler lässt das Spiel am Schreibtisch in einem kleinen Fenster laufen und schaltet das Portal stumm. Die Seite kann dein Spiel nicht von außen stummschalten (das verbietet der Browser), also sagt sie es dir, und du entscheidest: Mixer stumm, Musik aus. Ohne diesen Aufruf passiert nichts und nichts geht kaputt.

klyo.onSound((on) => {
  mixer.mute = !on;
});

So passt du die Steuerung an das Gerät an

Touch oder Tastatur, wie viele Pixel, ohne Raten anhand der Bildschirmbreite. Die Antwort: { touch, width, height }.

const d = klyo.device();
if (d.touch) showOnScreenButtons();

So spielst du online mit mehreren Leuten

Ein Raum mit einem 6-stelligen Code für deine Freunde oder eine Schnellsuche innerhalb des Spiels. Der Server hält die Zugreihenfolge fest und speichert die Züge, das Spiel prüft die Spielregeln. Ein Zug oder eine Nachricht darf bis zu 1 KB groß sein, ein rundenbasierter Raum fasst bis zu 64 Personen, ein Live-Raum bis zu 16. Eine Partie endet mit move und result.winner, das fließt in die Siegesrangliste (klyo.online.ranking) ein, und die Schnellsuche bringt Spieler mit ähnlicher Bilanz zusammen. In einem Live-Raum (mode: 'realtime') laufen send und onMessage über einen UDP-Kanal zum Spielserver von klyo, bis zu 120 Nachrichten pro Sekunde. send verschickt Bytes (Uint8Array), einen String oder ein Objekt bis etwa 1 KB, und der Empfänger bekommt denselben Typ. Eine send-Nachricht kann wie jedes UDP-Paket unterwegs verloren gehen, nutze sie also für Zustände, die sich ohnehin erneuern. Für ein Ereignis, das ankommen muss (ein Schuss, ein Treffer, ein aufgesammelter Gegenstand), nimm klyo.online.act, auch in einem Spiel ohne Regeln: Das SDK schickt es dreimal, und der Empfänger erhält es einmal. klyo.online.net() verrät dir die Verbindungsart und den Ping. Kommt UDP nicht durch, nutzen dieselben Aufrufe eine Ersatzverbindung (20 pro Sekunde). Antwortfelder: room.code, room.me, room.host, room.turn, room.players.

klyo.online.quick((o) => {
  if (o.ok) showCode(o.room.code);
});
klyo.online.onStart((r) => begin(r.players, r.turn));
klyo.online.onMove((m) => apply(m.who, m.move));
// when klyo.online.room().turn === klyo.online.room().me:
klyo.online.move({ from: 12, to: 16 });

So bekommen Spieler eine Lobby, ohne dass du eine schreibst

Das Fenster „Online spielen“ (Schnellsuche mit einem Spieler ähnlicher Bilanz, eigener Raum mit Code, Link für einen Freund, Liste wartender Räume, Top-Spieler und dein Rekord) zeichnet das Portal, nicht das Spiel. Das Spiel macht einen Aufruf und bekommt die Antwort, sobald die Partie beginnt. Ein Link mit Code (?pokoj=CODE) öffnet die Spielseite und tritt von selbst bei. Nach einem Neuladen der Seite bringt resume dich mit der Liste der Züge zurück in die Partie.

klyo.online.lobby({ players: 2 }, (o) => {
  if (o.ok) begin(o.room);
});

So teilst du einen Spielerpool mit deiner eigenen Website oder einem anderen Portal

Dieselben Räume funktionieren auch außerhalb von klyo. Lade auf deiner eigenen Seite oder einem anderen Portal für Browserspiele unsere Raumbrücke vor dem SDK: Dann tritt das Spiel klyo Räumen als Gast bei, und seine Spieler treffen klyo Spieler in denselben Echtzeiträumen. Die Brücke deckt Echtzeiträume ab (Schnellspiel, Beitreten, Start, Nachrichten, Spielkanal, Teams und Karten); rundenbasierte Räume bleiben auf klyo Seiten. Ein Gast hat keinen Zugriff auf ein klyo Konto, Zahlungen oder das Panel. Punkte, Spielstände und Aufnahmen funktionieren nur auf klyo Seiten. Deine Domain muss vorher auf unserer Liste stehen: Schick uns die Adresse deiner Seite, und wir schalten sie frei.

<script src="https://games.klyo.pl/sdk/klw-mini.js"></script>
<script src="https://games.klyo.pl/sdk/pokoj-most.js"></script>
<script>
  window.klyoMostPokoi = klyoPokojMost({ slug: "your-game", nick: () => playerName });
</script>
<script src="https://games.klyo.pl/sdk/klyo-gry-sdk.js"></script>

Multiplayer-Spiel mit eigenem Match-Server

Du hast schon einen Server (Photon, Colyseus, eigener WebSocket) und das Spiel auf deiner eigenen Website? Du musst nichts umziehen: Die klyo-Version verbindet sich mit demselben Server, deshalb spielen Spieler auf klyo und auf deiner Website in denselben Partien. Bei CrazyGames läuft es genauso: Dort liegen die Spieldateien, und der Entwickler betreibt den Server für die Partien. Im Entwicklerstudio gibst du im letzten Schritt des Assistenten, „Inhalt“, die Serveradresse und die Datenschutzerklärung des Spiels an. Jemand von klyo gibt beides frei, meist innerhalb eines Tages. Bis dahin kommt ein Paket, das sich mit diesem Server verbindet, nicht in den Katalog. Wir erlauben nur diese eine Adresse und nur in deinem Spiel. Die Bedingungen: Ein Spieler auf klyo spielt als Gast (keine Anmeldung bei deinen Konten und keine Zahlungen im Spiel), und das Spiel bindet unser SDK ein (klyo.ready und Punkte). Die Spielseite sagt den Spielern, dass die Partien auf deinem Server laufen, und verlinkt deine Datenschutzerklärung. Ein Spiel mit eigenem Server läuft im Browser. In die klyo-App fürs Handy kommt es vorerst nicht.

// no change in the game code: the same address as on your site
const ws = new WebSocket("wss://eu1.your-game.com/ws");
klyo.ready();
// after a match:
klyo.score(points);

Komplettes Beispiel: Tic Tac Toe online (ganze Datei)

In die index.html einfügen, SDK dazu, veröffentlichen. Der Gastgeber spielt X, der Server weiß, wer am Zug ist, und das Brett ist nach dem Neuladen wieder da.

<!doctype html>
<meta charset="utf-8">
<script src="https://games.klyo.pl/sdk/klyo-gry-sdk.js"></script>
<div id="board"></div><p id="status"></p>
<script>
var B = document.getElementById("board"), S = document.getElementById("status");
var cells = ["", "", "", "", "", "", "", "", ""], mark = "";
function me() { var r = klyo.online.room(); return r ? r.me : ""; }
function draw() { var h = ""; for (var i = 0; i < 9; i++) h += '<button data-i="' + i + '">' + (cells[i] || "\u00b7") + "</button>"; B.innerHTML = h; }
function won() { var L = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];
  return L.some(function (l) { return cells[l[0]] && cells[l[0]] === cells[l[1]] && cells[l[0]] === cells[l[2]]; }); }
B.addEventListener("click", function (e) {
  var i = e.target.getAttribute("data-i"), r = klyo.online.room();
  if (i === null || cells[i] || !r || r.turn !== r.me) return;      // the server keeps whose turn it is; the game checks the rules
  cells[i] = mark; draw();
  klyo.online.move({ i: +i }, won() ? { end: true, result: { winner: r.me } } : null);
});
klyo.online.onStart(function (r) { mark = r.host === me() ? "X" : "O"; cells = ["", "", "", "", "", "", "", "", ""]; draw(); S.textContent = "Playing! You: " + mark; });
klyo.online.onMove(function (m) { if (m.who !== me()) { cells[m.move.i] = mark === "X" ? "O" : "X"; draw(); } S.textContent = m.turn === me() ? "Your move" : "Opponent's move"; });
klyo.online.onEnd(function (z) { S.textContent = z.result && z.result.winner === me() ? "You win!" : "Match over"; });
klyo.ready();
klyo.online.resume(function (r) {                                   // return after a refresh or from a ?pokoj=CODE link
  if (r.ok) { r.moves.forEach(function (m) { cells[m.move.i] = m.who === r.room.host ? "X" : "O"; }); draw(); return; }
  klyo.online.lobby({ players: 2 }, function (o) { if (!o.ok) S.textContent = "Play when you are ready."; });
});
</script>

So siehst du, warum Spieler abspringen

Ganz ohne Code erfasst das klyo-Kit sechs Schritte jeder Sitzung: Besuch der Spielseite, Spielen, Laden (klyo.ready), erster Zug, 30 Sekunden Spielzeit und Punktestand, getrennt nach Handy und Computer, dazu eine Klickkarte. Im Studio unter „Ergebnisse und Bewertungen“ siehst du, bei welchem Schritt die Leute abspringen und wie lange das Spiel lädt. Zwei Zeilen bringen dir mehr: klyo.level(3, "complete") zeigt, bei welchem Level sie aussteigen, und klyo.event("coins", 50) zählt deine eigenen Ereignisse. Dein KI-Assistent bekommt dasselbe über das MCP-Werkzeug klyo_game_analytics, samt Aufgaben: was du verbessern solltest und warum. Beim Server kommen nur Zahlen an, keine persönlichen Daten.

klyo.level(3, "start");     // level 3 started
klyo.level(3, "complete");  // cleared
klyo.level(3, "fail");      // lost
klyo.event("shop_open");
klyo.event("coins", 50);

So markierst du einen Moment, der einen Clip wert ist

Das Spiel weiß am besten, wann etwas Sehenswertes passiert: eine Kombo, eine Explosion, ein geschafftes Level, eine knappe Niederlage. Ein Aufruf setzt eine Markierung auf die Zeitleiste der Aufnahme. Der Clip-Editor wählt den Abschnitt um die letzte Markierung von selbst aus, damit der Spieler den Moment nicht Sekunde für Sekunde suchen muss. Ein Rekord aus klyo.wynik hat Vorrang. Die Art ist ein kurzes Wort ohne Leerzeichen, die Daten ein kleines Objekt für die Bildunterschrift des Clips. Nichts geht ins Netz; ohne Aufnahme verfällt die Markierung einfach.

klyo.moment("combo", { streak: 12 });

Gemeinsamer Wochenwettbewerb: API 1.2.0

Die Runde wechselt automatisch am Montag um 0:0 UTC. Der Server berechnet die Punkte aus den Zügen und speichert den besten abgeschlossenen Versuch. Normale Spielrekorde bleiben davon getrennt.

Der Inhaber muss für das Spiel zuerst ein installiertes Regelmodul aktivieren. Derzeit verfügbar: blockfall-weekly-v1. Für ein anderes Spiel braucht es ein eigenes Regelmodul auf dem Server.

klyo.league.standings({scope: 'week'}, showBoard);
klyo.league.start(crypto.randomUUID(), resumeRun);
// Keep run and base; retry identical moves after a lost acknowledgement.
klyo.league.moves(run, base, [column], acceptServerState);
klyo.league.finish(run, moveCount, showConfirmedScore);

Normale Rekorde: standings({scope:"classic"}). Diese Werte meldet der Client selbst, sie werden nicht anhand einer Aufzeichnung geprüft. record({}) liefert ein Profil und requiredConsent. Eine ausdrückliche Veröffentlichung erfordert {score, gameRank, publish:true, consentVersion:requiredConsent, eligible16:true}. Setze die Einwilligung nie automatisch. record({score,gameRank}) aktualisiert nur einen bestehenden öffentlichen Eintrag. record({publish:false}) zieht die Veröffentlichung zurück, ohne den privaten Spielstand zu ändern. data und erase gelten für beide Bestenlisten.

SDKRPC v1Argumente
klyo.league.standingsgry.liga.tablica.v1options, callback
klyo.league.startgry.liga.start.v1requestId string or {requestId, gameRank?}, callback
klyo.league.movesgry.liga.ruchy.v1run, base, columns, callback
klyo.league.finishgry.liga.koniec.v1run, moves, callback
klyo.league.datagry.liga.dane.v1options, callback
klyo.league.erasegry.liga.usun.v1confirm, callback
klyo.league.recordgry.liga.rekord.v1options, callback

Die Identität stammt vom angemeldeten klyo Host oder aus einem geprüften Facebook-Nachweis. Konten verschiedener Anbieter werden nicht automatisch verknüpft. Künftige klyo games Apps können dieselbe SDK-Brücke nutzen; diese Version enthält noch keinen nativen mobilen Host.

Der Datenexport kommt seitenweise, je 10 Durchgänge (Cursor next). Zum Löschen ist confirm: "DELETE" nötig. Gespeichert werden Durchgänge 90 Tage, Wochenausgaben 52 Wochen und das beste Wettbewerbsergebnis aller Zeiten bis zur Löschung. Bei SERVER_BUSY versuchst du es nach einer Pause mit derselben Vorgangskennung erneut.

So baust du ein Spiel für die Rekordseite

Was das Spiel kostenlos bekommt. Eine Kachel auf der Rekordseite (games.klyo.pl/records/) mit ewigem Rekord und Podium, einen Platz im Medaillenspiegel des Tages (Gold, Silber, Bronze für die Plätze 1–3 in jedem Spiel), einen Eintrag im Live-Band „Neueste Rekorde“, ein Abzeichen „Heute vorn: X“ auf der Katalogkachel und für Spieler mit Konto die Meldung „X hat dich überholt“. Einzige Bedingung: Das Spiel ruft klyo.wynik auf.

Drei Aufrufe, fertig. Beim Start klyo.ready(), während der Partie klyo.progress(points) (das Abzeichen „#14 · 320 bis X“ unter dem Spiel), am Ende klyo.score(points, cb), und die Antwort enthält alles für den Endbildschirm: die heutige Platzierung samt Sprung, die der Woche, die ewige Bestenliste und den Spieler direkt davor. Pro Gerät und Tag zählt ein bestes Ergebnis: Zehn Partien hintereinander belegen nicht zehn Plätze.

Punktegrenze. Stell im Studio in der Zeile des Spiels die höchste Punktzahl ein, die das Spiel erreichen kann. Die Kachel bekommt das Zeichen „Grenze ✓“, und jedes Ergebnis darüber wird sofort abgelehnt. Ohne Grenze funktioniert die Bestenliste trotzdem, aber auf der Kachel steht „keine Grenze“, und ein Ergebnis, das mehr als zehnmal so hoch ist wie das nächste (bei mindestens zehn Einträgen), steht „in Prüfung“. Einträge kannst du in der Spielkarte entfernen.

Mit einem KI-Assistenten (MCP). Verbinde klyo mit deinem Assistenten und sag: „Füge diesem Spiel die klyo Bestenliste hinzu“. Das Werkzeug klyo_game_sdk gibt ihm dieselbe Beschreibung wie diese Seite: die Aufrufe, das Muster start → progress → score, die Grenze. klyo_update_game lädt das neue Paket hoch.

Schritt für Schritt: So bekommt dein HTML5-Spiel eine Bestenliste

Was das SDK nicht macht und was du nicht hochladen darfst

Dein Spiel darf keine eigene Werbung enthalten. Kein fremdes Werbenetzwerk: AdMob, AdSense, Unity Ads, AppLovin, ironSource, Poki, CrazyGames oder Ähnliches. Die Prüfung beim Hochladen lehnt so ein Paket ab und nennt das gefundene Netzwerk.

Warum. Die Werbung spielt unsere Seite rund um den Spielrahmen aus. So gibt es ein Publisher-Konto, eine Abrechnung und einen Anteil, den du nachprüfen kannst. Zwei Publisher auf einer Seite sind für Google ungültiger Traffic, und darauf steht die Sperrung des Kontos: unseres und damit indirekt auch deines.

Das Spiel kommt weder an die Seite noch an den Server. Keine Cookies, kein Spielerkonto, keine Daten aus anderen Spielen: Es läuft unter einer eigenen Adresse und spricht mit der Seite nur über diese Aufrufe. Deshalb können wir fremde Spiele annehmen, ohne ihren Code Zeile für Zeile zu lesen.

Testbar vor der ersten Werbung. Werbepausen und Belohnungswerbung funktionieren in der Vorschau und im Portal auch dann, wenn für einen Spieler keine Werbung verfügbar ist: Statt echter Werbung zeigt die Seite kurz einen Platzhalterbildschirm und antwortet danach genau so wie bei echter Werbung. So baust und testest du die ganze Bonusmechanik, bevor der erste Cent fließt.

Was passiert, wenn jemand das Spiel außerhalb von klyo öffnet

Nichts geht kaputt. Eine Werbepause kehrt sofort zurück, Punkte und Spielstände bleiben im Browser, und ein Clip hat einfach kein Ziel. Du kannst einen Build für alles verwenden; ein eigenes Paket für uns brauchst du nicht.

Klyo Kit: ein Spielgerüst in Studioqualität

Zwei script-Tags und ein Aufruf. Das Kit liefert, was jedes Studio braucht: Menü, Pause, Endbildschirm mit Rekord und Platz in der Bestenliste, Einstellungen (Ton, helles oder dunkles Design, Sprache), Berührung, Maus, Tastatur und Gamepad als ein einziges Ereignis, ein Canvas für jeden Bildschirm samt den sicheren Bereichen des iPhone, synthetischer Klang ohne Audiodateien (setzt nach dem Hintergrund wieder ein), „Juice“ (Übergänge, Wackeln, Partikel, Aufblitzen), Speicherstand über alle Geräte und die Modi allein, am selben Gerät (Handy weitergeben) und online per Link. Du schreibst nur das eigentliche Spiel.

&lt;script src=&quot;https://games.klyo.pl/sdk/klyo-gry-sdk.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://games.klyo.pl/sdk/klyo-kit.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
var gra = klyoKit.start({ nazwa: &quot;My game&quot;, tryby: [&quot;solo&quot;, &quot;hotseat&quot;, &quot;online&quot;], uklad: &quot;oba&quot;,
  naStart: function (tryb) { newRound(); } });
var c = gra.plotno(), g = c.getContext(&quot;2d&quot;);           // full screen, DPR, resize
gra.on(&quot;tap&quot;, function (d) { /* touch and mouse together */ gra.dzwiek.graj(&quot;zbior&quot;); gra.juice.czastki(d.x, d.y); });
gra.koniec({ wygrana: true, wynik: 120 });              // end screen + leaderboard + best
&lt;/script&gt;
  • Referenzspiel mit dem Kit: Schiffe versenken (Solo, ein Gerät, online per Link, ~200 Zeilen). gra.ai.minimax gibt rundenbasierten Spielen einen Gegner, und gra.wskazniki verarbeitet mehrere Finger auf einem Bildschirm. Den Rest erledigt das Kit.
  • Über einen Assistenten: klyo_game_scaffold liefert Startdateien und die komplette API; der Assistent schreibt Menü, Pause oder Audio nie doppelt.
  • Keine externen Stylesheets oder Schriften: Spiel-Hosts haben style-src 'self', deshalb bettet das Kit sein CSS ein, nutzt die Systemschrift, und die Farben kommen aus gra.motyw.paleta.

Das Spiel auf jedem Bildschirm: was wir verlangen und was wir messen

Dein Spiel bekommt die ganze Szenenfläche und im Vollbild den ganzen Gerätebildschirm: Auf dem Handy öffnet „Spielen“ den Vollbildmodus in derselben Geste, ein Querformatspiel auf einem hochkant gehaltenen Handy bekommt einen um 90° gedrehten Rahmen, und keine Geste geht an den Browser. Das Spiel muss sich also an jedes Seitenverhältnis anpassen, von 390×844 bis 2400×1560.

  • Layout für jedes Seitenverhältnis. Hör auf resize und skaliere das Canvas auf innerWidth × innerHeight; kein festes 1280×720 mit Balken.
  • Touchsteuerung. pointerdown/pointermove oder touchstart/touchmove mit { passive: false } und preventDefault() auf dem canvas, dazu touch-action: none. Gesteuert wird per Tippen und Ziehen. Auf dem Handy gibt es kein Hover, Zielen „beim Bewegen ohne Taste“ gibt es dort also nicht. Ein Spiel ohne Touch-Events bekommt im Entwicklerstudio die Aufgabe „nur am Computer“.
  • Lesbarkeit. Kleinster Text ≥ 10 px CSS bei 390 px Breite und devicePixelRatio 1.
  • Ausrichtung bei der Veröffentlichung. Gib Querformat, Hochformat oder beides an. Das Portal bittet dann ums Drehen und dreht den Rahmen. Sperr die Ausrichtung nicht im Spiel selbst.
  • Audio. Starte den Ton erst nach der ersten Geste des Spielers. Nach der Rückkehr aus dem Hintergrund (iPhone) setzt du den AudioContext innerhalb einer Geste fort.
  • Größe und Ladezeit. Erster Download auf Handys ≤ 20 MB, erstes Bild des Spiels ≤ 20 s, relative Pfade.
  • Prüf dein Spiel vor dem Hochladen auf deinem Rechner. node klyo-test.mjs http://localhost:8080/ my-game ./klyo-test --uklad=pion. Die Datei /sdk/klyo-test.mjs misst genau das, was wir bei der Veröffentlichung messen, mit denselben Grenzwerten (Node.js 22 + Chrome/Chromium). --uklad ist die Ausrichtung, die du bei der Veröffentlichung angibst (pion | poziom | oba). Vor einer Veröffentlichung hängst du --slaby-telefon --jezyki an: ein günstiges Handy (viermal langsamerer Prozessor, schwaches Netz) und dasselbe Spiel auf Polnisch und auf Englisch, mit einem Vorschaubild pro Sprache.

Bei der Veröffentlichung öffnen wir das Spiel auf vier Bildschirmen (Handy hochkant und quer mit Touch, Tablet, Computer) und messen: Scrollen innerhalb des Rahmens, den Anteil des Bildschirms, den das Spiel ausfüllt, den kleinsten Text, die Listener für Berührungen, die Größe des ersten Downloads und die Ladezeit. Das Ergebnis siehst du mit Vorschaubildern in der Spielkarte im Entwicklerstudio, dein Assistent sieht es in klyo_game_diagnostics. Wir raten nicht: Genau das sieht der Spieler.

Was das Paket mitbringen muss

  • Eine Datei index.html im Hauptverzeichnis der ZIP. Dort startet das Spiel.
  • Das Spiel muss ohne Download und ohne Anmeldung im Browser laufen, auch auf Handys.
  • Bis 350 MB. Die Prüfung schaut auf Größe, fehlende Dateien, fremde Werbenetzwerke und Spuren von Schadcode und dauert etwa zehn bis zwanzig Sekunden.
  • Aus dem Altersfragebogen, den du beim Hochladen ausfüllst, entsteht die Alterskennzeichnung. Sie entscheidet über die Sichtbarkeit und die Aufnahme in die Store-Apps.