 : scaled-velocity ( player -- velocity )
     [ velocity>> ] [ velocity-modifier>> ] bi v* ;
 
-: tick-player ( world player -- )
+: save-history ( world player -- )
+    clone swap history>> push ;
+
+:: tick-player-reverse ( world player -- )
+    player reverse-time>> :> reverse-time
+    world history>> :> history
+    history length 0 > [
+        history length reverse-time 1 - - 1 max history set-length
+        history pop world (>>player)
+    ] when ;
+
+: tick-player-forward ( world player -- )
+    2dup save-history
     [ apply-friction apply-gravity ] change-velocity
     dup scaled-velocity [ v+ [ terrain-segment>> ] dip collide ] curry with change-location
     drop ;
+
+: tick-player ( world player -- )
+    dup reverse-time>> [
+        tick-player-reverse
+    ] [
+        tick-player-forward
+    ] if ;
 
 M: terrain-world tick*
     [ dup focused?>> [ handle-input ] [ drop ] if ]

CONSTANT: terrain-vertex-row-length $[ 512 1 + 2 * ]

TUPLE: player
    location yaw pitch velocity velocity-modifier ;

TUPLE: terrain-world < game-world
    player
    sky-image sky-texture sky-program
    terrain terrain-segment terrain-texture terrain-program
    terrain-vertex-buffer ;

M: terrain-world tick-length
    drop 1000 30 /i ;

:: handle-input ( world -- )
    world player>> :> player
    read-keyboard keys>> :> keys

    key-left-shift keys nth
    VELOCITY-MODIFIER-FAST VELOCITY-MODIFIER-NORMAL ? player (>>velocity-modifier)

    {
        [ key-1 keys nth 1  f ? ]
        [ key-2 keys nth 2  f ? ]
        [ key-3 keys nth 3  f ? ]
        [ key-4 keys nth 4  f ? ]
        [ key-5 keys nth 10000 f ? ]
    } 0|| player (>>reverse-time)

    key-w keys nth [ player walk-forward ] when 
    key-s keys nth [ player walk-backward ] when 
