Game-Design 101
How do you build a game that is fun? Here you build it step by step, like following a furniture assembly plan. At every step you see straight away what changes, and which invisible parts do the work behind it.
English version coming soon. The chapters below are in German for now.
Five decisions in this order before building. The chapters below go through them step by step.
The chapters are in German for now. This overview is already in both languages.
Die Kunst des Game Designs
Warum wir spielen, und was Game Design ausmacht.
Teileliste: was du in diesem Kapitel brauchst
- 1. Der Spieltrieb: Warum wir spielen (Homo Ludens)
- 2. Die Spielwiesen des modernen Game Designs
- 3. Deine Rolle als Game Designer
Die Kunst des Game Designs
„Wir hören nicht auf zu spielen, weil wir alt werden. Wir werden alt, weil wir aufhören zu spielen.“
Das Spielen begleitet uns ein Leben lang: Von den ersten neugierigen Schritten im Kindesalter bis hin zu komplexen digitalen Welten, taktischen Brettspielen oder fesselnden Rollenspielen. Aber warum fasziniert uns das Spielen seit Jahrtausenden? Und was macht ein richtig gutes Spiel aus?
1. Der Spieltrieb: Warum wir spielen (Homo Ludens)
Spielen ist weit mehr als nur Zeitvertreib – es ist ein menschliches Grundbedürfnis. In der Spielforschung (Ludologie) gilt der Mensch als Homo Ludens (der spielende Mensch). Im geschützten Raum eines Spiels lernen wir:
- Regeln auszutesten, ohne echte Konsequenzen befürchten zu müssen.
- Gemeinschaft zu erleben und soziale Bindungen zu stärken.
- In neue Rollen zu schlüpfen und eigene Grenzen auszuloten.
Schon historische Klassiker wie Mensch ärgere dich nicht (inspiriert vom altindischen Pachisi) zeigten: Spiele sind ein Spiegel des Lebens – voller Hoffnung, kleiner Krisen und dem Glück des gemeinsamen Gewinnens (oder Verlierens).
2. Die Spielwiesen des modernen Game Designs
Als Game Designer gestaltest du Welten, die ganz unterschiedliche menschliche Bedürfnisse ansprechen. Die moderne Spiellandschaft teilt sich dabei in drei grosse Hauptbereiche auf:
| Bereich | Charakteristik | Was es im Spielenden auslöst |
|---|---|---|
| Brett- & Gesellschaftsspiele | Analoge Runden am Tisch, oft prämiert durch Auszeichnungen wie Spiel des Jahres. | Verbindung & Entschleunigung: Fördert echte soziale Interaktion, Haptik und das Miteinander im Kreis von Familie und Freunden. |
| Videospiele & eSport | Interaktive digitale Welten – von kreativen Sandboxen wie Minecraft bis zu hochkompetitiven Ligen. | Immersion & Leistung: Bietet packende Storys, maximale Gestaltungsfreiheit, fordert aber auch Skill, Reaktion und Verantwortungsbewusstsein. |
| Rollenspiele & Cosplay | Aktives Verkörpern fremder Charaktere (Pen & Paper, LARP, digitale RPGs). | Identität & Gemeinschaft: Erlaubt kreativen Selbstausdruck, das Ausleben fantastischer Welten und das Wachsen von starken Communitys. |
3. Deine Rolle als Game Designer
Hier kommt die Magie ins Spiel: Game Design ist die Kunst, Regeln, Mechaniken und Welten so miteinander zu verweben, dass aus einfachem Code oder Pappe ein unvergessliches Erlebnis wird.
Ob du ein kleines Tool für zwischendurch baust oder ein komplexes System entwirfst – du erschaffst den Rahmen, in dem Menschen Freude, Spannung und Gemeinschaft erleben.
Start: Game heisst Spiel
Bevor du baust: Woher kommt das Wort «Game», warum entscheidest du zuerst das Genre, und wie sieht der Plan aus, mit dem aus einer Idee ein Spiel wird?
Teileliste: was du in diesem Kapitel brauchst
- Das Wort: «Game» ist Englisch und heisst Spiel
- Die Genres: sehr viele, auch solche mit ernstem Hintergrund
- Das Konzept: zuerst das Genre entscheiden, planen und festhalten
- Die Roadmap: Genre → Spielmechanik → Design → Setting → Techstack
- Danach: Storytelling (Kapitel ★ Story)
Game heisst Spiel
Das Wort «Game» kommt aus dem Englischen und heisst Spiel. Das solltest du nicht vergessen.
Egal wie gross dein Projekt wird und wie viel Technik dahintersteckt: Am Ende baust du ein Spiel, also etwas, das man spielen will.
Neu im Code nur diese Zeilen kommen dazu
S.bild = 'spiel';if (S.bild === 'spiel') {
text('GAME', 82, 62, '#4de1ff', 30, 'center');
text('=', 160, 62, '#ffffff', 30, 'center');
text('SPIEL', 238, 62, '#ffe36b', 30, 'center');
text('Nicht vergessen!', 160, 92, '#ffffff', 13, 'center');
const hoch = Math.abs(Math.sin(t * 3)) * 34; // ein hüpfender Ball
circle(160, GROUND - 8 - hoch, 8, '#ff9f43');
rect(0, GROUND, W, H - GROUND, '#2a3a55');
}Viele Genres, auch ernste: zuerst das Genre entscheiden
Es gibt sehr viele Genres: Jump-and-Run, Rätsel, Strategie, Rennspiel, Abenteuer und viele mehr. Und es gibt auch Genres mit einem sehr ernsten Hintergrund, zum Beispiel Spiele über Krieg, Flucht oder eine Naturkatastrophe.
Darum gilt beim Konzept: Zuerst entscheidest du, welches Genre du machen willst. Dann planst du es und hältst es im Konzept fest. Erst danach geht es weiter:
- Genre entscheiden, planen, im Konzept festhalten
- die Roadmap: Genre → Spielmechanik → Design → Setting → Techstack
- das Storytelling
Neu im Code nur diese Zeilen kommen dazu
S.bild = 'ernst';if (S.bild === 'ernst') {
const karten = [['1 · Genre', 'entscheiden, planen, festhalten', '#4de1ff'], ['2 · Roadmap', 'Genre bis Techstack', '#ff9f43'], ['3 · Story', 'Storytelling', '#ffd24a']];
karten.forEach((k, i) => {
const x = 12 + i * 102;
rect(x, 40, 92, 96, '#162544');
rect(x, 40, 92, 5, k[2]);
text(k[0], x + 46, 72, k[2], 12, 'center');
text(k[1], x + 46, 100, '#ffffff', 7, 'center');
});
text('Das Konzept: in dieser Reihenfolge', 160, 26, '#ffffff', 12, 'center');
}Die Roadmap: so sieht der Plan aus
Eine Roadmap ist dein Fahrplan: Welche Entscheidung kommt zuerst, welche danach? Für ein Spiel gehst du in dieser Reihenfolge vor:
Genre → Spielmechanik → Design → Setting → Techstack
Jede Station baut auf der vorherigen auf. Nach der Roadmap kommt das Storytelling (Kapitel ★ Story). In den nächsten fünf Schritten schauen wir jede kurz an, immer mit einem Mini-Beispiel: Ship Ahoi!!!, der Seeschlacht aus dem Lab.
Neu im Code nur diese Zeilen kommen dazu
S.bild = 'karte';
S.hl = 0; // 0 = alle Stationen der Reihe nach zeigen
S.namen = ['Genre', 'Mechanik', 'Design', 'Setting', 'Techstack'];
S.bsp = ['Strategie, Seeschlacht', 'Feld antippen: Platsch!', 'Comic-Meer, grosse Knöpfe', 'Käpt\'n Krawall jagt Meerjungfrauen', 'HTML + JavaScript, offline'];if (S.bild === 'karte') {
const h = S.hl || 1 + Math.floor(t / 1.5) % 5; // welche Station leuchtet
for (let i = 0; i < 5; i++) {
const x = 6 + i * 63, an = i + 1 === h;
rect(x, 52, 56, 40, an ? '#ff4d4d' : '#162544');
text(i + 1, x + 28, 68, '#ffffff', 11, 'center');
text(S.namen[i], x + 28, 84, '#ffffff', 9, 'center');
if (i < 4) text('→', x + 59, 76, '#8aa0c8', 10, 'center');
}
text('Roadmap', 160, 32, '#ffe36b', 15, 'center');
text('Beispiel: ' + S.bsp[h - 1], 160, 122, '#ffffff', 11, 'center');
}1 · Genre: Welche Art Spiel?
Das Genre ist die Art des Spiels: Jump-and-Run, Rätsel, Strategie, Rennspiel, Abenteuer, Simulation. Du hast es schon im Konzept entschieden; in der Roadmap ist es die erste Station, auf der alles andere aufbaut. Es sagt den Spielern schon vor dem ersten Klick, was sie ungefähr erwartet.
Mini-Beispiel: Ship Ahoi!!! ist ein Strategiespiel, genauer eine Seeschlacht wie «Schiffe versenken». Man denkt nach, statt schnell zu reagieren.
Neu im Code nur diese Zeilen kommen dazu
S.hl = 1;2 · Spielmechanik: Was tust du?
Die Spielmechanik ist das, was der Spieler immer wieder tut, und was danach passiert. Mehr dazu in Kapitel 2.
Mini-Beispiel: Bei Ship Ahoi!!! tippst du ein Feld im fremden Meer an. Dann kommt «Platsch!» (daneben) oder «BOING!» (Treffer). Wer ein Schiff verliert, fährt bei einer anderen Crew mit: «Niemand bleibt zurück».
Neu im Code nur diese Zeilen kommen dazu
S.hl = 2;3 · Design: Wie sieht es aus, wie fühlt es sich an?
Beim Design entscheidest du, wie das Spiel aussieht, klingt und sich bedient: Farben, Figuren, Knöpfe, Töne, wie schwer es ist.
Mini-Beispiel: Ship Ahoi!!! hat ein buntes Comic-Meer, laute Effekte wie «BOING!» und grosse Knöpfe, die man auch auf dem Handy gut trifft.
Neu im Code nur diese Zeilen kommen dazu
S.hl = 3;4 · Setting: Wo und wann spielt es?
Das Setting ist die Welt des Spiels: der Ort, die Zeit, die Figuren. Es gibt der Mechanik einen Sinn.
Mini-Beispiel: Ship Ahoi!!! spielt auf hoher See. Der fiese Käpt'n Krawall jagt die Meerjungfrauen, und die Crews halten zusammen. Wie das Setting zur Geschichte wird, zeigt das Kapitel ★ Story.
Neu im Code nur diese Zeilen kommen dazu
S.hl = 4;5 · Techstack: Womit baust du es?
Der Techstack sind deine Werkzeuge: Programmiersprache, Programme, wo das Spiel läuft (Browser, Handy, Konsole). Ganz am Schluss, denn die Technik muss zum Spiel passen, nicht umgekehrt.
Mini-Beispiel: Ship Ahoi!!! ist mit HTML und JavaScript gebaut, läuft im Browser und sogar offline. Mehrere Geräte verbinden sich ohne Internet über einen QR-Code.
Neu im Code nur diese Zeilen kommen dazu
S.hl = 5;Das nimmst du mit
- Game heisst Spiel. Das solltest du nicht vergessen.
- Es gibt sehr viele Genres, auch solche mit sehr ernstem Hintergrund. Beim Konzept entscheidest du zuerst das Genre, planst es und hältst es im Konzept fest.
- Danach die Roadmap: Genre → Spielmechanik → Design → Setting → Techstack. Erst die Idee, ganz am Schluss die Technik.
- Dann das Storytelling: Kapitel ★ Story.
Neu im Code nur diese Zeilen kommen dazu
S.hl = 0;Storytelling: Geschichten, die packen
Warum spielt man ein Spiel lieber, wenn es eine Geschichte hat, auch wenn sie ganz einfach ist? Wir nehmen ein kleines Spiel, «Fang das Licht», und geben ihm eine Story.
Teileliste: was du in diesem Kapitel brauchst
- Figur: jemand, mit dem man mitfiebert
- Wunsch: was die Figur will oder braucht
- Hindernis: was im Weg steht
- Gefühl: Freude, Spannung, Erleichterung
- Ende: wie es ausgeht, auch wenn es knapp nicht reicht
- Steuerung: Pfeiltasten oder die Knöpfe ◀ ▶ unter der Vorschau
Viele Spiele haben kaum Story
Viele Spiele sind zum schnellen Konsumieren gemacht: kurz spielen, Punkte holen, weg. Eine Geschichte gibt es dort kaum oder gar nicht.
Hier siehst du ein kleines Spiel: «Fang das Licht». Du steuerst die blaue Figur mit den Pfeiltasten oder den Knöpfen ◀ ▶ nach links und rechts. Berührst du ein gelbes Licht, gibt es einen Punkt und es springt woanders hin. Das orange Licht gibt 3 Punkte, verschwindet aber bald wieder. Du hast 20 Sekunden Zeit, danach startet Tippen eine neue Runde. In Kapitel 1 baust du genau dieses Spiel später selbst, Schritt für Schritt.
Es funktioniert. Aber warum sammelst du die Lichter eigentlich?
Eine Story packt dich
Eine Geschichte soll den Spieler packen, auch in einem schnellen Spiel. Dafür reicht ein einziger Satz: Wer braucht Hilfe, und warum?
Jetzt ist es Leuchtturm Lux, der nicht mehr leuchtet. Jedes Licht, das du fängst, macht ihn heller. Gleiche Regeln, gleiche Steuerung, aber plötzlich hat jedes Licht einen Sinn. Genau das macht ein Spiel viel wertvoller.
Neu im Code nur diese Zeilen kommen dazu
S.ziel = 10; // so viele Lichter braucht Luxconst hell = Math.min(1, S.score / S.ziel); // 0 = aus, 1 = ganz hell
if (hell > 0) { ctx.globalAlpha = hell * 0.5; circle(160, 50, 26, '#ffe36b'); ctx.globalAlpha = 1; }
rect(154, 58, 12, 50, '#e8e8f0'); // der Turm
rect(154, 70, 12, 7, '#ff4d4d');
rect(154, 90, 12, 7, '#ff4d4d');
circle(160, 52, 6, hell >= 1 ? '#ffe36b' : '#555c70'); // die Lampe
text('Lux ist aus! Sammle ' + S.ziel + ' Lichter.', 160, 30, '#ffe36b', 11, 'center');Ein gutes Ende, auch wenn es knapp ist
Eine Geschichte braucht ein Ende. Schaffst du die 10 Lichter, leuchtet Lux und die Schiffe finden heim. Schaffst du es nicht, ist das kein «Verloren!», sondern ein freundliches «Fast! Nochmal?».
So bleibt man dran: Man will die Geschichte gut ausgehen sehen.
Neu im Code nur diese Zeilen kommen dazu
if (S.score >= S.ziel && !S.gerettet) {
S.gerettet = true;
beep(880, 0.2); // Lux leuchtet!
}if (S.time <= 0) {
rect(0, 60, W, 56, '#0f1a33');
if (S.gerettet) text('Lux leuchtet! Die Schiffe finden heim.', 160, 86, '#ffe36b', 12, 'center');
else text('Fast! Noch ' + (S.ziel - S.score) + ' Lichter. Nochmal?', 160, 86, '#ffffff', 12, 'center');
text('Tippen = neue Runde', 160, 104, '#8aa0c8', 10, 'center');
}Beispiel: Ship Ahoi!!!
Ein echtes Beispiel aus dem Lab: Ship Ahoi!!! und Ship Ahoi!!! 2... x3. Die Geschichte ist super einfach:
- Käpt'n Krawall ist der Fiesling, der die Meerjungfrauen jagt.
- Die Meerjungfrau Valeria flieht und bittet die Crews um Hilfe.
- Moritz die Muräne versteckt sich in Felshöhlen: «Blubb! Mich findet ihr nie!»
- Bruno Barracuda ist schnell wie der Blitz und schiesst zwei Mal.
Mehr ist es nicht. Und trotzdem spielen Kinder das gern, weil es Emotionen weckt: Man will Valeria retten, man lacht über Moritz, man freut sich, wenn Krawall im Gummiboot davonpaddelt.
Spielen und dabei denken
Das Schönste: Weil die Geschichte packt, bleiben die Kinder dran, und sind dabei produktiv. Sie überlegen sich Strategien: Wo versteckt sich Moritz als Nächstes? Wie verteilen wir die Schüsse? Wer hilft wem?
Die Story ist also nicht nur Dekoration. Sie ist der Grund, warum man sich anstrengt, nachdenkt und gemeinsam Lösungen findet.
Das nimmst du mit
- Viele Spiele haben kaum Story. Das geht, aber man verschenkt viel.
- Schon ein Satz packt: Wer braucht Hilfe, und warum?
- Verbinde Story und Mechanik: Fortschritt im Spiel = Fortschritt in der Geschichte.
- Ein gutes Ende ist freundlich, auch wenn es knapp nicht gereicht hat.
- Einfache Figuren mit einer Eigenschaft reichen, siehe Käpt'n Krawall, Valeria, Moritz und Bruno.
- Story weckt Emotionen, und wer mitfiebert, denkt mit und entwickelt Strategien.
Was ist ein Spiel?
Was macht aus einem Ding ein Spiel? Wir bauen «Fang das Licht» und sehen, was dazukommt.
Teileliste: was du in diesem Kapitel brauchst
- Ziel: was man erreichen will
- Regel: was erlaubt ist und was passiert
- Rückmeldung: wie das Spiel zeigt, was man getan hat
- Entscheidung: eine Wahl, die etwas kostet
- Steuerung: Pfeiltasten oder die Knöpfe unter der Vorschau
Die leere Bühne
Eine gängige Beschreibung: Ein Spiel ist eine freiwillige Aufgabe mit Regeln, einem Ziel und Rückmeldung. Fehlt etwas davon, ist es Spielzeug oder Film. Wir bauen alle vier Zutaten nacheinander ein.
Jetzt gibt es nur die Bühne: einen Boden. Man kann nichts tun, nichts erreichen, nichts verlieren.
Neu im Code nur diese Zeilen kommen dazu
rect(0, GROUND, W, H - GROUND, '#2a3a55'); // BodenEin Ziel
Zuerst das Ziel: ein Licht auf dem Boden. Es gibt jetzt etwas, das man haben will, auch wenn man noch nichts tun kann.
Ohne Ziel fragt sich der Spieler: «Und jetzt?»
Neu im Code nur diese Zeilen kommen dazu
S.star = { x: 250 };circle(S.star.x, GROUND - 14, 7, '#ffe36b'); // das Lichtsetup läuft einmal beim Start.Eine Aktion
Jetzt braucht der Spieler eine Aktion: eine kleine Figur, die du nach links und rechts bewegst. Die Eingabe (Pfeiltasten, Knöpfe) wird in input gelesen.
Neu im Code nur diese Zeilen kommen dazu
S.p = { x: 40 };S.p.x = clamp(S.p.x + input.dir * P.SPEED, 8, W - 8);circle(S.p.x, GROUND - 8, 8, '#4de1ff'); // die FigurP.SPEED = 2.4; // Tempo, Bereich 0.5 bis 5Eine Regel
Die Regel verbindet Aktion und Ziel: Wenn die Figur beim Licht ist, dann bekommt man einen Punkt, und das Licht springt woanders hin.
Das Spiel prüft das in update, 60 Mal pro Sekunde.
Neu im Code nur diese Zeilen kommen dazu
S.score = 0;if (Math.abs(S.p.x - S.star.x) < 14) {
S.score++;
S.star.x = rnd(30, 290);
}Rückmeldung
Rückmeldung sagt dem Spieler: «Das hast du gerade geschafft.» Ein Ton, ein Blitz und ein Zähler machen aus der unsichtbaren Regel ein spürbares Erlebnis.
Das Spiel erkennt, dass sich der Punktestand geändert hat, und reagiert darauf.
Neu im Code nur diese Zeilen kommen dazu
S.lastScore = 0;
S.flash = 0;if (S.score !== S.lastScore) {
S.lastScore = S.score;
S.flash = 1;
beep(660);
}
S.flash = Math.max(0, S.flash - 0.06);if (S.flash > 0) {
ctx.globalAlpha = S.flash * 0.35;
rect(0, 0, W, H, '#ffffff');
ctx.globalAlpha = 1;
}
text('Licht: ' + S.score, 8, 16, '#ffffff', 13);Eine Herausforderung
Jetzt gibt es Druck: 20 Sekunden Zeit. Das Spiel kann enden, das Ergebnis ist eine Zahl. Erst jetzt will man es besser machen.
Nach dem Ende friert das Spiel ein (stop), nur immer läuft weiter, damit ein Tippen neu startet.
Neu im Code nur diese Zeilen kommen dazu
S.time = 20;if (S.time <= 0 && input.tap) restart();S.time -= dt;text('Zeit: ' + Math.ceil(Math.max(S.time, 0)), W - 8, 16, '#ffffff', 13, 'right');
if (S.time <= 0) {
rect(0, 60, W, 56, 'rgba(0,0,0,0.6)');
text('Zeit um! ' + S.score + ' Licht', W / 2, 94, '#ffe36b', 20, 'center');
text('Tippen für Neustart', W / 2, 110, '#ffffff', 11, 'center');
}S.time <= 0Eine Entscheidung
Bisher gab es nur einen Weg. Eine Entscheidung entsteht, wenn zwei Dinge etwas kosten: Das orange Licht gibt 3 Punkte, steht aber meist weiter weg und verschwindet nach 4 Sekunden.
Lohnt sich der Weg? Das entscheidest du.
Neu im Code nur diese Zeilen kommen dazu
S.big = { x: 280, life: 4 };S.big.life -= dt;
if (S.big.life <= 0) {
S.big.x = rnd(30, 290);
S.big.life = 4;
}
if (Math.abs(S.p.x - S.big.x) < 18) {
S.score += 3;
S.big.x = rnd(30, 290);
S.big.life = 4;
}circle(S.big.x, GROUND - 20, 12, '#ff9d3b');
text('3', S.big.x, GROUND - 16, '#5a2d00', 12, 'center');Das nimmst du mit
Ein Spiel besteht aus kleinen Teilen, die sich gegenseitig brauchen:
- Ziel gibt der Aktion einen Sinn.
- Regel verbindet Aktion und Ziel.
- Rückmeldung macht die Regel spürbar.
- Herausforderung (hier Zeit) gibt dem Ergebnis Gewicht.
- Entscheidung macht aus Reagieren ein Denken.
In unseren Spielen findest du dasselbe: bei Ship Ahoi!!! ist das Ziel, alle Schiffe zu finden, die Regel «Treffer bringt einen zweiten Schuss» und die Rückmeldung «Blubb!» oder «BOING».
Spielmechanik
Aktion, Folge, Rückmeldung: was ist ein Kernloop? Wir bauen den «Sternensammler».
Teileliste: was du in diesem Kapitel brauchst
- Mechanik: eine Handlung, die das Spiel versteht (springen, einsammeln)
- Kernloop: die kleine Schleife, die man immer wieder spielt
- Eingabe, Physik, Regel: die drei Hooks
input,physics,update - Steuerung: Pfeiltasten und Leertaste oder die Knöpfe
Die Figur
Eine Mechanik ist eine Handlung, die das Spiel versteht und beantwortet. Wir bauen einen Sternensammler aus fünf Mechaniken: bewegen, fallen, springen, landen, einsammeln.
Zuerst die Figur. Ihre Position y sind die Füsse, das macht die Landung später einfacher.
Neu im Code nur diese Zeilen kommen dazu
S.p = { x: 40, y: GROUND, vy: 0, onGround: true };rect(0, GROUND, W, H - GROUND, '#2a3a55'); // Boden
circle(S.p.x, S.p.y - 8, 8, '#ffd24a'); // Figur (y = Füsse)Bewegen
Die erste Mechanik: Eingabe wird Bewegung. input liest, S.p.x ändert sich.
Neu im Code nur diese Zeilen kommen dazu
S.p.x += input.dir * P.SPEED;
S.p.x = clamp(S.p.x, 8, W - 8);P.SPEED = 2.2; // Tempo, Bereich 0.5 bis 5Schwerkraft
Jetzt fällt die Figur. Die Geschwindigkeit vy wächst mit jedem Bild um die Schwerkraft, die Position folgt der Geschwindigkeit. Am Boden bleibt sie stehen.
Die Figur startet in der Luft, damit du den Fall siehst. Neustart zeigt ihn nochmal.
Neu im Code nur diese Zeilen kommen dazu
S.p.y = 70;
S.p.onGround = false;S.p.vy += P.GRAV;
S.p.y += S.p.vy;
S.p.onGround = false;
if (S.p.y >= GROUND) {
S.p.y = GROUND;
S.p.vy = 0;
S.p.onGround = true;
}P.GRAV = 0.25; // Schwerkraft, Bereich 0.05 bis 0.8Springen
Eine Mechanik, die Schwerkraft braucht: der Sprung. Er gibt der Figur einen Schub nach oben, aber nur, wenn sie am Boden steht. Sonst könnte man in der Luft endlos weiterspringen.
Neu im Code nur diese Zeilen kommen dazu
if (input.jump && S.p.onGround) {
S.p.vy = -P.JUMP;
beep(440);
}P.JUMP = 6; // Sprungkraft, Bereich 3 bis 9Landen auf Plattformen
Eine Plattform ist ein zweiter Boden, aber nur von oben begehbar. Die Figur landet, wenn sie im letzten Bild über der Plattform war und jetzt darauf oder darunter ist, und sie nach unten fällt.
Neu im Code nur diese Zeilen kommen dazu
S.plat = { x: 130, y: 108, w: 70 };if (S.p.vy >= 0 && S.p.x > S.plat.x - 4 && S.p.x < S.plat.x + S.plat.w + 4) {
const vorher = S.p.y - S.p.vy; // wo waren die Füsse im letzten Bild?
if (vorher <= S.plat.y && S.p.y >= S.plat.y) {
S.p.y = S.plat.y;
S.p.vy = 0;
S.p.onGround = true;
}
}rect(S.plat.x, S.plat.y, S.plat.w, 6, '#6fa8ff');Einsammeln: der Kernloop
Jetzt schliesst sich der Kreis: springen, sammeln, Punkt, weiter. Das ist der Kernloop, die kleine Schleife, die man immer wieder spielt. Sie muss schon allein Spass machen.
Ein Ring zeigt die Folge: Der Stern erscheint nach dem Einsammeln an einem neuen Ort, entweder auf der Plattform oder am Boden.
Neu im Code nur diese Zeilen kommen dazu
S.star = { x: 165, y: 92 };
S.score = 0;
S.ring = null;if (Math.abs(S.p.x - S.star.x) < 12 && Math.abs((S.p.y - 8) - S.star.y) < 14) {
S.score++;
beep(660);
S.ring = { x: S.star.x, y: S.star.y, r: 4 };
S.star.x = rnd(30, 290);
S.star.y = (S.star.x > S.plat.x && S.star.x < S.plat.x + S.plat.w) ? 92 : 136;
}
if (S.ring) { S.ring.r += 1.2; if (S.ring.r > 26) S.ring = null; }circle(S.star.x, S.star.y, 6, '#ffe36b');
if (S.ring) { ctx.strokeStyle = '#ffffff'; ctx.lineWidth = 2; ctx.beginPath(); ctx.arc(S.ring.x, S.ring.y, S.ring.r, 0, 6.2832); ctx.stroke(); }
text('Sterne: ' + S.score, 8, 16, '#ffffff', 13);Das nimmst du mit
Fünf Mechaniken, ein Kernloop. Das Muster ist immer dasselbe: Aktion → Folge → Rückmeldung.
- Aktion: Pfeil oder Sprung
- Folge: Figur bewegt sich, fällt, landet, sammelt
- Rückmeldung: Ton, Ring, Zähler
Im Lab siehst du dasselbe bei Eis löscht Feuer: Der Ritter läuft, springt, und jede Berührung bringt eine Folge.
Logik und Regeln
Wenn dies, dann das: Wie entscheidet das Spiel, was passiert? Wir erweitern den Sternensammler mit Gefahren.
Teileliste: was du in diesem Kapitel brauchst
- Bedingung: eine Frage, die wahr oder falsch ist
- Zustand: in welcher Phase das Spiel gerade ist (Menü, Spiel, Ende)
- Zufall und Können: was das Glück macht und was der Spieler
- Kollision: wenn sich zwei Dinge berühren
- Basis: der fertige Sternensammler aus Kapitel 2 (Code unter «Ganzer Code bis hier»)
Wenn, dann: der Sumpf
Eine Regel hat die Form «wenn Bedingung, dann Folge». Ein Beispiel: Im Sumpf (rechts am Boden) wird die Figur langsamer.
Der Ausdruck S.hit ist wahr oder falsch. Das Spiel fragt in jedem Bild neu.
Neu im Code nur diese Zeilen kommen dazu
S.zone = { x: 230, w: 60 };S.hit = S.p.x > S.zone.x && S.p.x < S.zone.x + S.zone.w && S.p.y >= GROUND - 1;
if (S.hit) S.p.x -= input.dir * P.SPEED * 0.6;rect(S.zone.x, GROUND - 4, S.zone.w, 4, S.hit ? '#e0b030' : '#6a5a2a');Zustände: Menü, Spiel
Ein Spiel hat Phasen. Das Spiel merkt sich in S.state, in welcher es ist. Im Menü steht alles still, nach einem Tippen beginnt das Spiel.
Neu im Code nur diese Zeilen kommen dazu
S.state = 'menu';if (S.state === 'menu' && (input.tap || input.jump)) S.state = 'play';if (S.state === 'menu') {
rect(0, 50, W, 70, 'rgba(0,0,0,0.65)');
text('Sternensammler', W / 2, 82, '#ffe36b', 20, 'center');
text('Tippen zum Start', W / 2, 104, '#ffffff', 12, 'center');
}S.state !== 'play'Zufall gegen Können
Rote Gegner erscheinen zufällig am rechten Rand und rollen nach links. Zufall bestimmt, wann sie kommen, Können bestimmt, ob du ihnen ausweichst (springen).
Ein gutes Spiel mischt beides: nur Zufall frustriert, nur Können wird berechenbar.
Neu im Code nur diese Zeilen kommen dazu
S.gegner = [];if (Math.random() < P.SPAWN * dt) S.gegner.push({ x: W + 10 });
for (const g of S.gegner) g.x -= P.GTEMPO;
S.gegner = S.gegner.filter(g => g.x > -10);for (const g of S.gegner) rect(g.x - 6, GROUND - 12, 12, 12, '#ff5b5b');P.SPAWN = 0.6; // Gegner pro Sekunde, Bereich 0 bis 2
P.GTEMPO = 1.6; // Tempo der Gegner, Bereich 0.5 bis 5Kollision: Treffer
Jetzt treffen die Gegner. Eine Kollision ist eine einfache Frage: Sind die beiden nah genug beieinander? Wir messen den Abstand in x und prüfen, ob die Figur am Boden ist (also nicht gesprungen).
Ein Treffer kostet ein Leben.
Neu im Code nur diese Zeilen kommen dazu
S.leben = 3;for (const g of S.gegner) {
if (Math.abs(g.x - S.p.x) < P.HIT && S.p.y > GROUND - 12) {
g.x = -99; // der Gegner verschwindet
S.leben--;
beep(160);
}
}text('Leben: ' + S.leben, W - 8, 16, '#ff8f8f', 13, 'right');P.HIT = 11; // Trefferbereich, Bereich 4 bis 20Zustand: das Ende
Wenn die Leben aufgebraucht sind, wechselt das Spiel in den Zustand «Ende»: Alles friert ein, eine Meldung erscheint, ein Tippen startet neu.
Wir erweitern einfach stop: Es hält jetzt auch bei 0 Leben an.
Neu im Code nur diese Zeilen kommen dazu
if (S.leben <= 0 && input.tap) restart();if (S.leben <= 0) {
rect(0, 56, W, 64, 'rgba(0,0,0,0.65)');
text('Geschafft: ' + S.score + ' Sterne', W / 2, 88, '#ffe36b', 18, 'center');
text('Tippen für Neustart', W / 2, 108, '#ffffff', 11, 'center');
}S.leben <= 0Treffer sichtbar machen
Regeln, die man nicht merkt, fühlen sich zufällig an. Wenn man ein Leben verliert, soll das Bild kurz rot aufblitzen. Wie bei der Rückmeldung in Kapitel 1 erkennt das Spiel die Änderung von S.leben.
Neu im Code nur diese Zeilen kommen dazu
S.letzteLeben = 3;
S.blink = 0;if (S.leben !== S.letzteLeben) {
S.letzteLeben = S.leben;
S.blink = 1;
}
S.blink = Math.max(0, S.blink - 0.05);if (S.blink > 0) {
ctx.globalAlpha = S.blink * 0.4;
rect(0, 0, W, H, '#ff0000');
ctx.globalAlpha = 1;
}Das nimmst du mit
Regeln sind meist Wenn-dann-Sätze, die das Spiel 60 Mal pro Sekunde prüft. Dazu kommen:
- Zustände für die Phasen (
menu,play, Ende) - Zufall für Überraschung, Können für Verdienst
- Kollision als Abstandsfrage
- Rückmeldung für jede Regel, die der Spieler spüren soll
In Ship Ahoi!!! 2 gilt etwa: «Wenn die Crew ihr letztes Schiff verliert, fährt sie bei einer anderen mit.» Das ist eine Regel im Wenn-dann-Format.
Was macht Spass?
Wann fühlt sich ein Spiel gut an: nicht langweilig, nicht frustrierend? Wir drehen an den Reglern.
Teileliste: was du in diesem Kapitel brauchst
- Herausforderung gegen Können: der Kern von «Flow» (gängiger Fachbegriff: ein Zustand, in dem man in einer Aufgabe aufgeht)
- Fairness: Fehler soll man als eigene Fehler erleben
- Belohnung und «Juice» (Fachwort für kleine Effekte, die Treffer gut anfühlen lassen)
- Basis: der Sternensammler mit Gefahren aus Kapitel 3
Zu leicht: Langeweile
Wenn kaum Gefahr kommt und alles gelingt, wird es langweilig. Hier gibt es fast keine Gegner. Fühlt sich das nach Spass an?
Meinung statt Beweis: Fast alle Spielregeln über «Spass» sind Erfahrungswerte, keine Gesetze. Probier selbst.
Neu im Code nur diese Zeilen kommen dazu
P.SPAWN = 0.12; // Gegner pro Sekunde, Bereich 0 bis 2
P.GTEMPO = 1.2; // Tempo der Gegner, Bereich 0.5 bis 5Zu schwer: Frust
Jetzt das Gegenteil: viele, schnelle Gegner. Wer ständig verliert, ohne zu verstehen warum, gibt auf.
Neu im Code nur diese Zeilen kommen dazu
P.SPAWN = 1.8; // Gegner pro Sekunde, Bereich 0 bis 2
P.GTEMPO = 4.2; // Tempo der Gegner, Bereich 0.5 bis 5Die Kurve: leicht, dann schwerer
Gute Spiele beginnen leicht und werden schwerer, so wie der Spieler besser wird. Das hält zwischen Langeweile und Frust. Hier steigt alle 8 Sekunden die Stufe: mehr und schnellere Gegner.
Neu im Code nur diese Zeilen kommen dazu
S.zeit = 0;
S.level = 1;S.zeit += dt;
S.level = 1 + Math.floor(S.zeit / 8);
if (Math.random() < S.level * 0.1 * dt) S.gegner.push({ x: W + 10 });
for (const g of S.gegner) g.x -= S.level * 0.2;text('Stufe ' + S.level, W / 2, 16, '#9fb4d8', 12, 'center');P.SPAWN = 0.3; // Gegner pro Sekunde, Bereich 0 bis 2
P.GTEMPO = 1.3; // Tempo der Gegner, Bereich 0.5 bis 5Fairness: der Trefferbereich
Spieler ertragen Niederlagen, wenn sie sie selbst verschuldet glauben. Sie ertragen es nicht, wenn sie «eigentlich vorbei» waren. Darum ist der Trefferbereich meist etwas kleiner als das Bild der Figur.
Der weisse Rahmen zeigt deinen wirklichen Trefferbereich.
Neu im Code nur diese Zeilen kommen dazu
ctx.strokeStyle = 'rgba(255,255,255,0.6)';
ctx.lineWidth = 1;
ctx.strokeRect(S.p.x - P.HIT, S.p.y - 16, P.HIT * 2, 16);P.HIT = 7; // Trefferbereich, Bereich 3 bis 18Belohnung und «Juice»
Dieselbe Regel fühlt sich grossartig oder lahm an, je nachdem, wie das Spiel sie feiert. Kleine Effekte («Juice») wie Funken machen aus einem Punkt ein Erlebnis.
Sammle einen Stern: Funken sprühen.
Neu im Code nur diese Zeilen kommen dazu
S.teile = [];
S.letztePunkte = 0;if (S.score !== S.letztePunkte) {
S.letztePunkte = S.score;
for (let i = 0; i < 12; i++) S.teile.push({ x: S.p.x, y: S.p.y - 8, vx: rnd(-2, 2), vy: rnd(-3, -0.5), l: 1 });
}
for (const q of S.teile) { q.x += q.vx; q.y += q.vy; q.vy += 0.1; q.l -= 0.03; }
S.teile = S.teile.filter(q => q.l > 0);for (const q of S.teile) {
ctx.globalAlpha = q.l;
circle(q.x, q.y, 2.5, '#ffe36b');
}
ctx.globalAlpha = 1;Dein Regler-Set
Jetzt gehört dir die ganze Werkstatt: Tempo, Gegner, Schwerkraft, Trefferbereich. Stelle das Spiel so ein, dass es dir Spass macht.
Es gibt dabei keine richtige Einstellung. Aber es gibt Fragen, die du dir stellen kannst: Weiss ich immer, warum ich verloren habe? Will ich nochmal?
Neu im Code nur diese Zeilen kommen dazu
P.SPEED = 2.2; // Tempo der Figur, Bereich 0.5 bis 5
P.GRAV = 0.25; // Schwerkraft, Bereich 0.05 bis 0.8
P.JUMP = 6; // Sprungkraft, Bereich 3 bis 9
P.SPAWN = 0.5; // Gegner pro Sekunde, Bereich 0 bis 2
P.GTEMPO = 1.5; // Tempo der Gegner, Bereich 0.5 bis 5
P.HIT = 8; // Trefferbereich, Bereich 3 bis 18Das nimmst du mit
Spass ist keine einzelne Zutat, sondern ein Gleichgewicht:
- Nicht zu leicht (Langeweile), nicht zu schwer (Frust): Die Schwierigkeit wächst mit dem Können.
- Fairness: Fehler sollen eigene Fehler sein.
- Rückmeldung und «Juice» feiern jeden Erfolg.
- Spielgefühl entsteht aus wenigen Zahlen, die man in kleinen Schritten einstellt und selbst ausprobiert.
Das ist Erfahrungswissen von Spieleentwicklern, kein Naturgesetz. Dein eigenes Spielen und das von Kindern ist die beste Messung.
Denken und Strategie
Wie bringt man Spieler zum Nachdenken? Wir bauen eine kleine Expedition ohne Reflexe, nur mit Entscheidungen.
Teileliste: was du in diesem Kapitel brauchst
- Karten: Wahlmöglichkeiten, die man vergleichen kann
- Ressourcen: Dinge, die knapp sind (Gold, Proviant, Runden)
- Risiko und Erwartungswert: was im Durchschnitt herauskommt
- Information: Wissen, das etwas kostet
- Steuerung: Tasten 1 bis 3 oder die Zahlenknöpfe
Drei Karten
Hier gibt es keine Figur und kein Tempo. Das Spiel zeigt drei Karten, du wählst eine. Alle Spannung entsteht aus dem Nachdenken, nicht aus der Reaktion.
Die Karten stehen als Liste im Zustand, nicht fest im Zeichencode. So kannst du später leicht Karten ändern.
Neu im Code nur diese Zeilen kommen dazu
S.karten = [
{ n: '1 Weitergehen', t: 'Gold suchen' },
{ n: '2 Rasten', t: 'Proviant holen' },
{ n: '3 Spähen', t: 'Vorschau' }
];
S.sel = 0;
S.msg = '';if (input.pick >= 1 && input.pick <= 3) {
S.sel = input.pick;
beep(400 + input.pick * 100);
}S.karten.forEach(function (k, i) {
const x = 12 + i * 102;
rect(x, 64, 94, 76, S.sel === i + 1 ? '#3b6bb0' : '#223049');
text(k.n, x + 47, 94, '#ffffff', 12, 'center');
text(k.t, x + 47, 116, '#9fb4d8', 10, 'center');
});
text('Wähle 1, 2 oder 3', W / 2, 40, '#ffe36b', 13, 'center');Wahl hat Folgen
Jetzt hat jede Karte eine Folge: Weitergehen bringt 2 Gold und kostet 1 Proviant. Rasten gibt 2 Proviant. Jede Wahl ist ein Zug, danach kommt die nächste Runde.
Die Folgen stehen als Funktionen in S.aktionen. Die Eingabe ruft einfach die passende auf.
Neu im Code nur diese Zeilen kommen dazu
S.gold = 0;
S.prov = 7;
S.runde = 1;
S.aktionen = {
1: function () { S.gold += 2; S.prov -= 1; S.msg = 'Weitergegangen: +2 Gold, -1 Proviant'; },
2: function () { S.prov += 2; S.msg = 'Gerastet: +2 Proviant'; },
3: function () { S.msg = 'Gespäht: noch ohne Wirkung'; }
};if (S.aktionen[input.pick]) {
S.aktionen[input.pick]();
S.runde++;
}text('Gold ' + S.gold + ' Proviant ' + S.prov + ' Runde ' + S.runde, 8, 16, '#ffffff', 12);
text(S.msg, W / 2, 172, '#ffe36b', 11, 'center');Ziel und knappe Mittel
Jetzt braucht es ein Ziel und eine Grenze: 12 Gold in höchstens 8 Runden, und der Proviant darf nicht ausgehen. Aus «Weitergehen» wird eine echte Abwägung, weil alles knapp ist.
Neu im Code nur diese Zeilen kommen dazu
if ((S.prov <= 0 || S.runde > 8 || S.gold >= 12) && (input.tap || input.pick)) restart();rect(0, 56, W, 64, 'rgba(0,0,0,0.65)');
if (S.gold >= 12) {
text('Geschafft! ' + S.gold + ' Gold', W / 2, 94, '#9bff9b', 18, 'center');
} else if (S.prov <= 0 || S.runde > 8) {
text('Ziel verfehlt: ' + S.gold + ' Gold', W / 2, 94, '#ff9d9d', 18, 'center');
}
S.prov <= 0 || S.runde > 8 || S.gold >= 12Risiko und Durchschnitt
Jetzt wird «Weitergehen» unsicher: Mit einer Chance findest du viel Gold, sonst verlierst du Proviant. Der Durchschnitt (Erwartungswert) bleibt etwa gleich, aber das Ergebnis schwankt stark.
Mit den Reglern findest du heraus, wann sich das Wagnis lohnt.
Neu im Code nur diese Zeilen kommen dazu
S.aktionen[1] = function () {
if (Math.random() < P.CHANCE) { S.gold += P.GEWINN; S.msg = 'Fund! +' + P.GEWINN + ' Gold'; }
else { S.prov -= P.VERLUST; S.msg = 'Nichts gefunden, -' + P.VERLUST + ' Proviant'; }
S.prov -= 1;
};text('Ø Gold pro Weitergehen: ' + (P.CHANCE * P.GEWINN).toFixed(1), 8, 32, '#9fb4d8', 10);P.CHANCE = 0.5; // Chance auf Fund, Bereich 0 bis 1
P.GEWINN = 4; // Gold bei Fund, Bereich 1 bis 8
P.VERLUST = 1; // Proviantverlust ohne Fund, Bereich 0 bis 4Information hat einen Preis
Jetzt bekommt die dritte Karte einen Sinn: Spähen kostet 1 Proviant und verrät, ob der nächste Zug ein Fund wird. Wissen gegen Ressource: eine der schönsten Entscheidungen im Spieldesign.
Dafür wird der Wurf vorab gemacht und im Zustand gespeichert.
Neu im Code nur diese Zeilen kommen dazu
S.naechste = Math.random() < P.CHANCE;
S.weiss = false;
S.aktionen[1] = function () {
if (S.naechste) { S.gold += P.GEWINN; S.msg = 'Fund! +' + P.GEWINN + ' Gold'; }
else { S.prov -= P.VERLUST; S.msg = 'Nichts gefunden, -' + P.VERLUST + ' Proviant'; }
S.prov -= 1;
S.naechste = Math.random() < P.CHANCE;
S.weiss = false;
};
S.aktionen[3] = function () {
S.prov -= 1;
S.weiss = true;
S.msg = 'Späher: der nächste Zug ' + (S.naechste ? 'lohnt sich' : 'ist leer');
};if (S.weiss) text(S.naechste ? '★ Fund sicher' : '✖ leer', W / 2, 56, S.naechste ? '#9bff9b' : '#ff9d9d', 14, 'center');Vorausdenken
Gute Strategie heisst: nicht nur den nächsten Zug sehen, sondern den Weg zum Ziel. Das Spiel kann helfen, indem es das Ziel in eine Zahl übersetzt: Wie viel Gold musst du ab jetzt pro Runde schaffen?
Neu im Code nur diese Zeilen kommen dazu
if (S.gold < 12 && S.runde <= 8) {
text('Nötig: ' + ((12 - S.gold) / Math.max(1, 9 - S.runde)).toFixed(1) + ' Gold pro Runde', W / 2, 52 + (S.weiss ? 18 : 0), '#9fb4d8', 11, 'center');
}Das nimmst du mit
Denkspiele entstehen aus:
- Wahl mit Folgen, die sich unterscheiden (keine Karte ist immer die beste)
- Knappheit: Ressourcen, Runden, Zeit
- Risiko: gleicher Durchschnitt, anderes Gefühl
- Information gegen Ressource
- Ein Ziel, das Vorausplanen belohnt
Im Lab findest du dasselbe bei Map und Mythen und im Hafen von Ship Ahoi!!!: wo setze ich meine nächste Aktion?
Lernen und Produktivität
Wie baut man ein Spiel, in dem man nebenbei etwas lernt, ohne dass es nach Schule riecht? Wir bauen die «Zahlenbrücke».
Teileliste: was du in diesem Kapitel brauchst
- Aufgabe: eine Frage mit einer klaren Antwort
- Rückmeldung: warum falsch oder richtig
- Passende Schwierigkeit: nicht zu leicht, nicht zu schwer
- Wiederholung: Fehler kommen wieder
- Produktivität: kommt am Ende etwas heraus?
- Steuerung: Tasten 1 bis 3 oder die Zahlenknöpfe
Eine Aufgabe, drei Antworten
Die Grundform jedes Lernspiels: eine Frage, mehrere Antworten, eine ist richtig. Hier eine Rechenaufgabe mit drei Karten.
Neu im Code nur diese Zeilen kommen dazu
S.baue = function (a, b) {
S.a = a;
S.b = b;
const r = a + b;
S.opt = [r, r + 1, r - 1].sort(function () { return Math.random() - 0.5; });
S.richtig = S.opt.indexOf(r) + 1;
S.fehler = 0;
};
S.neu = function () { S.baue(Math.floor(rnd(2, 9)), Math.floor(rnd(2, 9))); };
S.pruefe = function (n) {
if (n === S.richtig) { beep(660); S.neu(); } else { beep(180); }
};
S.neu();if (input.pick) S.pruefe(input.pick);text(S.a + ' + ' + S.b + ' = ?', W / 2, 52, '#ffffff', 26, 'center');
S.opt.forEach(function (o, i) {
rect(14 + i * 102, 84, 92, 50, '#223049');
text((i + 1) + ': ' + o, 60 + i * 102, 116, '#ffffff', 16, 'center');
});Rückmeldung mit Erklärung
«Falsch» sagt wenig. Besser: zeigen, was richtig gewesen wäre. Das Spiel schreibt die Lösung hin. Fehler werden so zur Lernchance.
Neu im Code nur diese Zeilen kommen dazu
S.msg = 'Wähle 1, 2 oder 3';
S.ok = 0;
S.nok = 0;
S.pruefe = function (n) {
if (n === S.richtig) {
S.ok++; S.msg = 'Richtig!'; beep(660); S.neu();
} else {
S.nok++; S.msg = 'Nicht ganz. ' + S.a + ' + ' + S.b + ' = ' + (S.a + S.b); beep(180);
}
};text(S.msg, W / 2, 172, '#ffe36b', 11, 'center');Hilfe zur rechten Zeit
Wer zweimal an derselben Aufgabe scheitert, braucht einen Anstoss. Das Spiel zählt die Fehler dieser Aufgabe und färbt nach dem zweiten die richtige Karte gelb.
Neu im Code nur diese Zeilen kommen dazu
S.pruefe = function (n) {
if (n === S.richtig) { S.ok++; S.msg = 'Richtig!'; beep(660); S.neu(); }
else { S.nok++; S.fehler++; S.msg = S.fehler >= 2 ? 'Tipp: die gelbe Karte' : 'Nicht ganz, versuch es nochmal'; beep(180); }
};if (S.fehler >= 2) {
rect(14 + (S.richtig - 1) * 102, 84, 92, 50, 'rgba(255,227,107,0.4)');
}Fortschritt sichtbar machen
Lernen ist unsichtbar. Ein Spiel macht den Fortschritt sichtbar: Jede richtige Antwort legt eine Brückenplatte. Bei acht Platten ist die Brücke fertig. Fehler kosten nichts, sie bremsen nur.
Neu im Code nur diese Zeilen kommen dazu
S.platten = 0;
S.pruefe = function (n) {
if (n === S.richtig) { S.ok++; S.platten++; S.msg = 'Richtig!'; beep(660); S.neu(); }
else { S.nok++; S.fehler++; S.msg = S.fehler >= 2 ? 'Tipp: die gelbe Karte' : 'Nicht ganz, versuch es nochmal'; beep(180); }
};if (S.platten >= 8 && (input.tap || input.pick)) restart();for (let i = 0; i < 8; i++) rect(24 + i * 34, 146, 30, 8, i < S.platten ? '#c9a062' : '#33415c');
text('Brücke: ' + S.platten + ' / 8', 8, 16, '#ffffff', 12);
if (S.platten >= 8) {
rect(0, 56, W, 64, 'rgba(0,0,0,0.65)');
text('Brücke fertig!', W / 2, 94, '#9bff9b', 20, 'center');
}S.platten >= 8Passende Schwierigkeit
Wer immer dasselbe löst, lernt nichts mehr. Wer nur scheitert, gibt auf. Das Spiel passt die Zahlen an: Nach drei richtigen Antworten in Folge steigt die Stufe, nach zwei Fehlern bei einer Aufgabe sinkt sie.
Neu im Code nur diese Zeilen kommen dazu
S.stufe = 1;
S.serie = 0;
S.neu = function () {
const m = 3 + S.stufe * 4;
S.baue(Math.floor(rnd(2, m)), Math.floor(rnd(2, m)));
};
S.neu();
S.pruefe = function (n) {
if (n === S.richtig) {
S.ok++; S.platten++; S.serie++; S.msg = 'Richtig!'; beep(660);
if (S.serie >= 3 && S.stufe < 4) { S.stufe++; S.serie = 0; S.msg = 'Stufe hoch!'; }
S.neu();
} else {
S.nok++; S.fehler++; S.serie = 0;
if (S.fehler === 2 && S.stufe > 1) S.stufe--;
S.msg = S.fehler >= 2 ? 'Tipp: die gelbe Karte' : 'Nicht ganz, versuch es nochmal'; beep(180);
}
};text('Stufe ' + S.stufe, W - 8, 16, '#9fb4d8', 12, 'right');Wiederholung
Wer einen Fehler macht, soll dieselbe Aufgabe später nochmal sehen. Das Gehirn lernt am besten, wenn Schwieriges wiederkommt. Das Spiel merkt sich die verpassten Aufgaben und mischt sie unter die neuen.
Neu im Code nur diese Zeilen kommen dazu
S.wieder = [];
S.neu = function () {
if (S.wieder.length && Math.random() < 0.4) {
const t = S.wieder.shift();
S.baue(t.a, t.b);
} else {
const m = 3 + S.stufe * 4;
S.baue(Math.floor(rnd(2, m)), Math.floor(rnd(2, m)));
}
};
S.pruefeBasis = S.pruefe;
S.pruefe = function (n) {
if (n !== S.richtig && S.fehler === 0) S.wieder.push({ a: S.a, b: S.b });
S.pruefeBasis(n);
};text('Zum Wiederholen: ' + S.wieder.length, 8, 32, '#ff9d8a', 10);Lernstand zeigen
Am Ende zählt, ob etwas hängen geblieben ist. Zeige Spielern, wie gut sie sind, und zwar ehrlich: Richtige und falsche Antworten. Das ist die Messung, die jedes Lernspiel braucht.
Neu im Code nur diese Zeilen kommen dazu
text('Richtig ' + S.ok + ' · Fehler ' + S.nok + (S.ok + S.nok > 0 ? ' · ' + Math.round(100 * S.ok / (S.ok + S.nok)) + ' %' : ''), W / 2, 172 - 0, '#9fb4d8', 10, 'center');Das nimmst du mit
Wann wird ein Lernspiel gut, und wann wird es Arbeit mit Verpackung?
- Spiel: Ich will weiter, weil es sich gut anfühlt, besser zu werden.
- Arbeit: Ich mache weiter, weil ich muss oder weil Belohnungen locken, die nichts mit der Sache zu tun haben.
Hilfreich sind: sofortige Rückmeldung, passende Schwierigkeit, Wiederholung, sichtbarer Fortschritt und keine Angst vor Fehlern.
Produktiv ist ein Spiel, wenn am Ende etwas herauskommt: ein Können, eine Brücke, ein Ergebnis. Prüfe es mit der Quote.
Zusammen spielen
Was ändert sich, wenn jemand mitspielt? Wir setzen eine «Möwe» als Mitspielerin zum Licht-Spiel.
Teileliste: was du in diesem Kapitel brauchst
- Mitspieler: eine zweite Figur mit eigenen Zielen
- Wettbewerb gegen Zusammenspiel: dieselbe Welt, anderes Gefühl
- Gummiband: Hilfe für den, der hinten liegt
- Signale: sich ohne Worte verständigen
- Basis: «Fang das Licht» aus Kapitel 1 bis Schritt 5
Eine zweite Figur
Wir nehmen das Spiel aus Kapitel 1 und setzen eine Möwe dazu. Zuerst steht sie nur da. Eine zweite Figur verändert ein Spiel noch nicht, erst das, was sie tut.
Neu im Code nur diese Zeilen kommen dazu
S.bot = { x: 280, score: 0 };rect(S.bot.x - 8, GROUND - 14, 16, 14, '#ff9d8a');Die Möwe sammelt mit
Jetzt handelt die Möwe: Sie fliegt zum Licht und sammelt es, wenn sie schneller ist als du. Sofort entsteht Spannung, denn jedes Licht kann ihr gehören.
Neu im Code nur diese Zeilen kommen dazu
S.botZiel = function () { return S.star.x; };const d = S.botZiel() - S.bot.x;
S.bot.x += sign(d) * Math.min(P.BTEMPO * (S.bremse || 1), Math.abs(d));
if (Math.abs(S.bot.x - S.star.x) < 14) {
S.bot.score++;
S.star.x = rnd(30, 290);
}text('Möwe: ' + S.bot.score, W - 8, 16, '#ff9d8a', 13, 'right');P.BTEMPO = 1.8; // Tempo der Möwe, Bereich 0.5 bis 4Gegeneinander oder zusammen?
Das ist die wichtigste Entscheidung eines Mehrspielerspiels: Gegeneinander oder zusammen? Dieselbe Welt, dieselben Lichter, aber ein ganz anderes Gefühl. Wähle unten eine Variante und probiere beide.
Neu im Code nur diese Zeilen kommen dazu
if (Math.max(S.score, S.bot.score) >= 10 && (input.tap || input.jump)) restart();if (S.score > S.bot.score) text('♛ du führst', W / 2, 16, '#ffe36b', 11, 'center');
if (S.score < S.bot.score) text('♛ Möwe führt', W / 2, 16, '#ff9d8a', 11, 'center');
if (Math.max(S.score, S.bot.score) >= 10) {
rect(0, 56, W, 64, 'rgba(0,0,0,0.65)');
text(S.score > S.bot.score ? 'Du gewinnst!' : 'Die Möwe gewinnt', W / 2, 94, S.score > S.bot.score ? '#9bff9b' : '#ff9d9d', 20, 'center');
}Math.max(S.score, S.bot.score) >= 10Das Gummiband
Wer weit hinten liegt, verliert die Lust. Ein Gummiband hilft: Liegt die Möwe mehr als ein paar Lichter vorn, bremst sie. Liegt sie zurück, gibt sie Gas. Das Spiel bleibt bis zum Schluss offen.
Neu im Code nur diese Zeilen kommen dazu
const d = S.bot.score - S.score;
S.bremse = d > P.BAND ? 0.4 : (d < -P.BAND ? 1.5 : 1);if (S.bremse !== 1) text(S.bremse < 1 ? 'Möwe bremst' : 'Möwe gibt Gas', W - 8, 30, '#ff9d8a', 10, 'right');P.BAND = 3; // Abstand fürs Gummiband, Bereich 1 bis 8Signale ohne Worte
Wer zusammenspielt, muss sich verständigen. Oft nicht mit Text, sondern mit kleinen Zeichen. Hier: Tippe ins Bild, und die Möwe fliegt dorthin. Im Zusammenspiel wird das zu einem Teamwerkzeug.
Neu im Code nur diese Zeilen kommen dazu
S.ping = null;
S.botZiel = function () { return S.ping ? S.ping.x : S.star.x; };if (input.tap) S.ping = { x: input.tap.x, t: 1.5 };
if (S.ping) {
S.ping.t -= dt;
if (S.ping.t <= 0) S.ping = null;
}if (S.ping) {
circle(S.ping.x, GROUND - 20, 6, 'rgba(255,157,138,0.6)');
text('hierher!', S.ping.x, GROUND - 30, '#ffd0c4', 10, 'center');
}Das nimmst du mit
Mehrspieler heisst: andere Menschen entscheiden. Das verändert alles:
- Ziele bestimmen das Gefühl: Wettbewerb oder Team.
- Fairness hilft (Gummiband), kann aber auch nerven.
- Verständigung braucht einfache Zeichen.
In Ship Ahoi!!! 2 sollen zwei Handys ohne Netz über Hotspot und QR-Codes zusammenspielen. Das ist noch nicht auf zwei Geräten getestet; der Test steht aus.
Vom Einfall zum Prototyp
Wie wird aus einer Idee ein Spiel, das du anderen zeigen kannst? Du füllst dein eigenes Ideenblatt aus.
Teileliste: was du in diesem Kapitel brauchst
- Einfall: ein Satz genügt
- Prototyp: die kleinste Version, die man spielen kann
- Kernloop: der Teil, der Spass machen muss
- Test: anderen zuschauen, ohne zu erklären
- Die Eingaben bleiben in deinem Browser (
localStorage), nichts wird gesendet
Der Einfall in einem Satz
Jedes Spiel beginnt mit einem Satz. Wenn du ihn nicht in einem Satz sagen kannst, ist die Idee noch zu gross. Schreibe deinen Einfall ins Feld.
So sieht es aus Beispiel, nicht deine Antwort
Idee: Ein kleiner Vogel muss Sterne aus dem Wald holen, bevor die Nacht kommt.Das Ziel
Was will der Spieler erreichen? Ein klares Ziel in einer Zeile. Fehlt es, fehlt der Grund zum Weiterspielen (Kapitel 1).
So sieht es aus Beispiel, nicht deine Antwort
Ziel: Zehn Sterne sammeln, bevor die Sonne untergeht.Die Regeln
Zwei bis drei Regeln genügen. Mehr ist für einen ersten Prototyp zu viel (Kapitel 3: Wenn dies, dann das).
So sieht es aus Beispiel, nicht deine Antwort
Regeln: Pfeile bewegen, Sprung auf Äste. Dornen werfen mich zurück zum Start.Die Rückmeldung
Wie merkt der Spieler, dass er etwas richtig oder falsch gemacht hat? Ton, Licht, Bewegung, Zahl (Kapitel 1 und 4).
So sieht es aus Beispiel, nicht deine Antwort
Rückmeldung: Ton und Funken bei jedem Stern, der Himmel wird dunkler.Der Kernloop
Was macht man im Spiel immer wieder? Das ist der Teil, der allein Spass machen muss (Kapitel 2). Baue und teste zuerst nur diesen.
So sieht es aus Beispiel, nicht deine Antwort
Kernloop: Springen, zum Stern fliegen, einsammeln, neues Ziel.Der Testplan
Zeige den Prototyp anderen. Erkläre nichts, sage nichts, schau zu. Wo zögern sie, wo lachen sie, wo geben sie auf? Das sind deine besten Hinweise.
So sieht es aus Beispiel, nicht deine Antwort
Test: Drei Personen je fünf Minuten spielen lassen, nichts erklären, nur zuschauen.Dein Blatt
Hier ist dein ganzes Ideenblatt. Kopiere es und speichere es dort, wo du deine Ideen sammelst (Notizen, Chat, Mail an dich selbst). Das Blatt bleibt zusätzlich in diesem Browser.
Der nächste Schritt gehört dir: bauen, testen, ändern. Erst nach dem Test weisst du, was wirklich wichtig ist.
Übung und Glossar
Jetzt baust du selbst: Wähle Ziel, Hindernis und Rückmeldung und siehst sofort das Ergebnis.
Teileliste: was du in diesem Kapitel brauchst
- Baukasten: wähle pro Schritt eine Variante
- Beurteilung: eine Checkliste für dein Spiel
- Glossar: alle Fachwörter zum Nachschlagen
- Basis: die Figur aus Kapitel 2 (laufen, fallen, springen)
Wähle ein Ziel
Du hast eine Figur, die läuft und springt (Kapitel 2). Was soll sie erreichen? Wähle unten. Das Ziel gibt allem anderen den Sinn.
Neu im Code nur diese Zeilen kommen dazu
S.score = 0;
S.ev = 0;
S.star = { x: 250, y: 136 };if (S.score >= 8 && (input.tap || input.jump)) restart();if (Math.abs(S.p.x - S.star.x) < 14 / (P.SCHWER || 1) && Math.abs((S.p.y - 8) - S.star.y) < 16) {
S.score++;
S.ev = 1;
S.star.x = rnd(30, 290);
S.star.y = Math.random() < 0.5 ? 136 : 100;
}circle(S.star.x, S.star.y, 6, '#ffe36b');
text('Sterne: ' + S.score + ' / 8', 8, 16, '#ffffff', 12);
if (S.score >= 8) {
rect(0, 56, W, 64, 'rgba(0,0,0,0.65)');
text('Geschafft!', W / 2, 94, '#9bff9b', 20, 'center');
}S.score >= 8Wähle ein Hindernis
Eine Zone auf dem Boden macht den Weg interessant. Drei Arten, drei Gefühle: Sumpf bremst, Dornen werfen zurück, ein Trampolin hilft. Alle sind eine Regel «wenn in der Zone, dann …».
Neu im Code nur diese Zeilen kommen dazu
if (S.p.x > 130 && S.p.x < 190 && S.p.y >= GROUND - 1) S.p.x -= input.dir * P.SPEED * 0.6;rect(130, GROUND - 4, 60, 4, '#7a6a2a');Wähle die Rückmeldung
Das Ereignis aus Schritt 1 ist da, aber das Spiel schweigt. Wähle, wie es das feiert. Vergleiche besonders «Keine» mit den anderen.
Neu im Code nur diese Zeilen kommen dazu
if (S.ev) beep(660);
S.ev = 0;Stelle die Schwierigkeit ein
Ein einziger Regler wirkt auf dein Spiel: Beim Sterne-Spiel wird die Berührzone kleiner, beim Überleben fallen mehr Steine, beim Wettlauf bleibt weniger Zeit. Starte nach dem Verstellen neu (⟲), damit alle Werte gelten.
Neu im Code nur diese Zeilen kommen dazu
text('Schwierigkeit ×' + P.SCHWER, W / 2, 172, '#9fb4d8', 10, 'center');P.SCHWER = 1; // Schwierigkeit, Bereich 0.5 bis 1.8Die Checkliste
Prüfe dein Spiel mit sechs Fragen:
- Ziel: Weiss ich in fünf Sekunden, was ich tun soll?
- Regeln: Sind sie klar und halten sie, was sie versprechen?
- Rückmeldung: Merke ich jeden Erfolg und jeden Fehler?
- Entscheidung: Gibt es eine Wahl, bei der keine Antwort immer die beste ist?
- Herausforderung: Ist es weder zu leicht noch zu schwer?
- Fairness: Verliere ich durch eigene Fehler?
Drei Fragen mit «Ja» genügen für einen ersten Prototyp. Alles andere kommt mit dem Test (Kapitel 8).
Glossar
Alle Fachwörter aus dem Tutorial zum Nachschlagen. Tippe in die Suche, um zu filtern.
New on mykeyz.ch, not yet tested on real phones. The content is general game design knowledge; technical terms are common terms. Code: own code, MIT, © Michaelangelo Zünd.