Moving is just adding
Bewegen ist nur Zusammenzählen
To the computer, the hero is just a few numbers: where it is, and how fast it is going.
Für den Computer ist der Held nur ein paar Zahlen: wo er ist und wie schnell er sich bewegt.
- Position: where the hero is.
xis east-west,zis north-south,yis up-down. - Position: wo der Held ist.
xist Ost-West,zist Nord-Süd,yist oben-unten. - Velocity: how fast it moves in each direction, in cells per second.
- Geschwindigkeit: wie schnell er sich in jede Richtung bewegt, in Zellen pro Sekunde.
Every frame, the game does a tiny bit of adding:
In jedem Bild rechnet das Spiel ein bisschen zusammen:
position = position + velocity × dtPosition = Position + Geschwindigkeit × dt
And gravity is just as simple. Every frame, it pulls the up-down speed down a bit:
Und die Schwerkraft ist genauso einfach. In jedem Bild zieht sie die Auf-und-ab-Geschwindigkeit ein Stück nach unten:
velocity.y = velocity.y - 22 × dtGeschwindigkeit.y = Geschwindigkeit.y - 22 × dt
That is all you need for a jump: set the up-speed to a big number, and gravity bends it back down into a nice curve.
Mehr braucht man nicht für einen Sprung: Setz die Aufwärts-Geschwindigkeit auf eine große Zahl, und die Schwerkraft biegt sie zu einer schönen Kurve zurück.
The game's own measurements
Die Maße des Spiels
| one celleine Zelle | 1 unit wideEinheit breit |
| one terrain leveleine Geländestufe | 0.5 units highEinheiten hoch |
| the heroder Held | 0.85 units tallEinheiten groß |
| runningrennen | 2.8 units per secondEinheiten pro Sekunde |
| walking (hold Ctrl)gehen (Strg halten) | 1.9 units per secondEinheiten pro Sekunde |
| gravitySchwerkraft | 22 units per second, every secondEinheiten pro Sekunde, jede Sekunde |
| jump speedSprungtempo | 6.27 units per second up: about 0.9 units highEinheiten pro Sekunde nach oben: etwa 0,9 Einheiten hoch |
All in src/core/constants.js. Change them, and the whole game feels different.
Alles in src/core/constants.js. Ändere sie, und das ganze Spiel fühlt sich anders an.
Try it: run and jump
Probier es: rennen und springen
Click the picture, then run with ← → and jump with Space. Can you leap over the water? Can you get onto the high block? Then play with gravity and the jump speed: try moon gravity!
Klick ins Bild, dann renn mit ← → und spring mit der Leertaste. Schaffst du den Sprung über das Wasser? Kommst du auf den hohen Block? Dann spiel mit Schwerkraft und Sprungtempo: Probier Mond-Schwerkraft!
Tricks that make it feel good
Tricks, damit es sich gut anfühlt
Real physics is not always fun. Game makers cheat a little, on purpose, so the controls feel fair:
Echte Physik macht nicht immer Spaß. Spielemacher schummeln absichtlich ein bisschen, damit sich die Steuerung fair anfühlt:
Coyote time
Kojotenzeit
Like the cartoon coyote who runs off a cliff and only falls when he looks down: for 0.12 seconds after you walk off an edge, you can still jump. Without it, you would often press jump "just too late" and fall, and it would feel unfair.
Wie der Kojote im Zeichentrick, der über eine Klippe rennt und erst fällt, wenn er nach unten schaut: 0,12 Sekunden nachdem du über eine Kante gelaufen bist, kannst du noch springen. Ohne das würdest du oft "gerade zu spät" springen und fallen, und es würde sich unfair anfühlen.
Try it in the demo: switch coyote time off and jump very late at the edge of the water.
Probier es in der Demo: Schalte die Kojotenzeit aus und spring ganz spät am Rand des Wassers.
Jump buffer
Sprungpuffer
If you press jump a tiny moment before you land (up to 0.15 seconds), the game remembers it and jumps as soon as your feet touch the ground.
Wenn du die Sprungtaste einen winzigen Moment bevor du landest drückst (bis zu 0,15 Sekunden), merkt sich das Spiel das und springt, sobald deine Füße den Boden berühren.
Speed ramp
Anlaufen
You don't reach full speed instantly: it takes 0.25 seconds. But stopping is fast (about 0.1 seconds). Short taps stay precise, and you never slide past where you wanted to stop.
Du erreichst die volle Geschwindigkeit nicht sofort: Es dauert 0,25 Sekunden. Aber Anhalten geht schnell (etwa 0,1 Sekunden). So bleiben kurze Tipper genau, und du rutschst nie über die Stelle hinaus, an der du stehen wolltest.
The leap
Der Weitsprung
Jumping while running gives you a little push forward: just enough to get over a gap of one cell. The world builder knows this number too, and only plans jumps you can really make!
Springen beim Rennen gibt dir einen kleinen Schubs nach vorn: genau genug, um über eine Lücke von einer Zelle zu kommen. Der Weltbauer kennt diese Zahl auch und plant nur Sprünge, die du wirklich schaffen kannst!
Bumping into things
Gegen Dinge stoßen
Sliding along walls. Walk diagonally into a wall: you don't stop dead, you slide along it. The trick: the game moves you east-west first and checks for a wall, then north-south and checks again. If only one direction is blocked, the other one still works.
An Wänden entlangrutschen. Lauf schräg gegen eine Wand: Du bleibst nicht stecken, sondern rutschst an ihr entlang. Der Trick: Das Spiel bewegt dich zuerst Ost-West und prüft auf eine Wand, dann Nord-Süd und prüft nochmal. Ist nur eine Richtung versperrt, geht die andere trotzdem.
Little steps. A ledge up to 0.3 units high is walked up without jumping. Higher than that, you need to jump.
Kleine Stufen. Eine Kante bis 0,3 Einheiten Höhe gehst du ohne Springen hoch. Ist sie höher, musst du springen.
Walking downhill. Without help, you would fly off every little slope like off a ramp. So when you are on the ground, the game sticks you to the floor if it is less than 0.25 units below you.
Bergab gehen. Ohne Hilfe würdest du von jedem kleinen Hang abheben wie von einer Rampe. Darum klebt dich das Spiel am Boden fest, wenn du am Boden bist und der Boden weniger als 0,25 Einheiten unter dir ist.
Slopes. Walking uphill is slower. Slopes that are too steep make you slide down.
Hänge. Bergauf gehen ist langsamer. Zu steile Hänge lassen dich runterrutschen.
Ceilings. Jump under a bridge, and you bump your head: your upward speed is set to zero.
Decken. Spring unter einer Brücke, und du stößt dir den Kopf: Deine Aufwärts-Geschwindigkeit wird auf null gesetzt.
Fluids. Water, lava and acid are deadly. When you walk towards their edge, the game stops you. But a jump, a knockback or a fall can still carry you in. So be careful!
Flüssigkeiten. Wasser, Lava und Säure sind tödlich. Wenn du auf ihren Rand zu gehst, hält das Spiel dich an. Aber ein Sprung, ein Rückstoß oder ein Sturz kann dich trotzdem hineintragen. Also Vorsicht!
Hard landings
Harte Landungen
When you land, the game looks at how fast you were falling:
Wenn du landest, schaut das Spiel, wie schnell du gefallen bist:
| FALLING SPEED | FALLTEMPO | WHAT HAPPENS | WAS PASSIERT |
|---|---|---|---|
| up tobis 10 | a normal landing | eine normale Landung | |
| more thanmehr als 10 | you land on your bottom and are dizzy for a moment | du landest auf dem Hintern und bist kurz benommen | |
| more thanmehr als 14 | you tumble over as a ragdoll, and it hurts: up to 60 damage | du kippst als Ragdoll um, und es tut weh: bis zu 60 Schaden |
Falling speed grows the longer you fall, so this is really about how high you fell. Try the drop buttons in the jump demo!
Das Falltempo wächst, je länger du fällst. Eigentlich geht es also darum, wie hoch du gefallen bist. Probier die Fall-Knöpfe in der Sprung-Demo!
Falling into the cube below
In den Würfel darunter fallen
Some cubes have holes, open to the depth below. Fall in, and you slide down into the cube below... but the landing costs the full 60 damage, and puts you back in the cube you fell from, at the last safe spot. No shortcuts!
Manche Würfel haben Löcher, offen zur Tiefe darunter. Fällst du hinein, rutschst du in den Würfel darunter... aber die Landung kostet die vollen 60 Schaden und setzt dich zurück in den Würfel, aus dem du gefallen bist, an die letzte sichere Stelle. Keine Abkürzungen!
The holes line up with the world: there is only a hole where the cube below really exists.
Die Löcher passen zur Welt: Es gibt nur ein Loch, wo der Würfel darunter wirklich existiert.
Floppy! The ragdoll
Schlabberig! Die Ragdoll
When the hero gets knocked over, the animation stops, and a ragdoll takes over: the body flops around by physics, like a puppet with cut strings. It's made of just dots and sticks. Knock it over, kick it, or grab a dot and throw it!
Wenn der Held umgestoßen wird, hört die Animation auf, und eine Ragdoll (Stoffpuppe) übernimmt: Der Körper schlackert durch Physik herum wie eine Marionette mit durchgeschnittenen Fäden. Sie besteht nur aus Punkten und Stäben. Stoß sie um, tritt sie, oder pack einen Punkt und wirf ihn!
This is the game's ragdoll, flattened into a side view. The game's version works the same way in 3D.
Das ist die Ragdoll des Spiels, platt gemacht zu einer Seitenansicht. Die Version im Spiel funktioniert genauso, nur in 3D.
How a ragdoll works
Wie eine Ragdoll funktioniert
The ragdoll has 16 dots, one at each joint: pelvis, chest, neck, head, shoulders, elbows, hands, hips, knees and feet.
Die Ragdoll hat 16 Punkte, einen an jedem Gelenk: Becken, Brust, Hals, Kopf, Schultern, Ellbogen, Hände, Hüften, Knie und Füße.
- Move every dot as if it were alone. Its speed? Where it is now, minus where it was one step ago. (This trick is called Verlet.) Add gravity.
- Jeden Punkt bewegen, als wäre er allein. Seine Geschwindigkeit? Wo er jetzt ist, minus wo er einen Schritt vorher war. (Dieser Trick heißt Verlet.) Schwerkraft dazu.
- Fix the sticks. Some sticks are now too long or too short. Push both ends towards the right length.
- Die Stäbe reparieren. Manche Stäbe sind jetzt zu lang oder zu kurz. Schieb beide Enden in Richtung der richtigen Länge.
- Fixing one stick breaks another a bit... so fix them all 6 times. Close enough!
- Einen Stab zu reparieren macht einen anderen ein bisschen kaputt... also repariere alle 6-mal. Nah genug!
- Floor: a dot below the floor is put back on top, and slowed down (friction).
- Boden: Ein Punkt unter dem Boden wird wieder obendrauf gesetzt und abgebremst (Reibung).
That runs 120 times a second, more often than the picture, so it stays stable.
Das läuft 120-mal pro Sekunde, öfter als das Bild, damit es stabil bleibt.
Getting up again
Wieder aufstehen
When the dots stop moving, the game checks: is the body lying face down or on its back? Then it plays the matching "get up" animation.
Wenn die Punkte still liegen, prüft das Spiel: Liegt der Körper auf dem Bauch oder auf dem Rücken? Dann spielt es die passende "Aufstehen"-Animation.
The tricky part: the animation was made for a body lying in one exact pose, but the ragdoll lies in a random heap. So the game smoothly morphs the ragdoll's pose into the first frames of the get-up animation, and turns the hero to match. The feet stay planted, so nothing slides.
Das Knifflige: Die Animation wurde für einen Körper in einer ganz bestimmten Lage gemacht, aber die Ragdoll liegt als zufälliger Haufen da. Darum verwandelt das Spiel die Haltung der Ragdoll sanft in die ersten Bilder der Aufsteh-Animation und dreht den Helden passend. Die Füße bleiben stehen, damit nichts rutscht.
src/game/ragdoll.js and src/render/animator.js
src/game/ragdoll.js und src/render/animator.js
The real code: jumping
Der echte Code: springen
p.coyote is a timer. On the ground it is always reset to 0.12. In the air it counts down by dt every frame.
p.coyote ist ein Zeitmesser. Am Boden wird er immer wieder auf 0,12 gesetzt. In der Luft zählt er in jedem Bild um dt herunter.
p.jumpBuf is a timer too: pressing jump sets it to 0.15, then it counts down.
p.jumpBuf ist auch ein Zeitmesser: Die Sprungtaste setzt ihn auf 0,15, dann zählt er herunter.
The jump only happens if both timers are still above zero. That's the whole trick: two countdowns!
Der Sprung passiert nur, wenn beide Zeitmesser noch über null sind. Das ist der ganze Trick: zwei Countdowns!
In water, the same code makes you paddle up out of the water, a bit slower (4.8).
Im Wasser lässt dich derselbe Code aus dem Wasser hochpaddeln, etwas langsamer (4,8).
Math.hypot(vx, vz) is the speed along the ground (Pythagoras!).
Math.hypot(vx, vz) ist das Tempo über den Boden (Pythagoras!).
The real code: one ragdoll step
Der echte Code: ein Ragdoll-Schritt
p is where each dot is, o where it was ("old"). Their difference is the speed. 0.998 loses a tiny bit each step, like air slowing it down.
p ist, wo jeder Punkt ist, o, wo er war ("old" heißt alt). Der Unterschied ist das Tempo. 0.998 verliert in jedem Schritt ein winziges bisschen, als würde die Luft bremsen.
solve measures a stick (d), compares it with its length (len) and moves both ends half of the difference (* 0.5) towards each other or apart.
solve misst einen Stab (d), vergleicht ihn mit seiner Länge (len) und schiebt beide Enden um die Hälfte des Unterschieds (* 0.5) aufeinander zu oder auseinander.
"Apart" sticks only push, never pull: they just stop a knee from folding all the way into the hip.
"Abstands"-Stäbe drücken nur, ziehen nie: Sie verhindern bloß, dass ein Knie ganz in die Hüfte klappt.