Time Travel

for Game Development

with Elm

11th of June 2015 - Functional Programming eXchange - London

@doppioslash

+ClaudiaDoppioslash

blog.doppioslash.com

About me

LamdaCat screencast

@lambda_cat

lambdacat.com

What I do

What is the single most soul destroying thing in game development?

What is the single most soul destroying thing in game development?

C++?

What is the single most soul destroying thing in game development?

Having to achieve a 10 moves combo to check if you have fixed an inconvenient bug?

What is the single most soul destroying thing in game development?

Projects getting canned?

Slow Iteration times

What is the single most soul destroying thing in game development?

Example Common Game Development Workflow

(starring Unity)

Make a change and test on PC

Example Common Game Development Workflow (starring Unity)

Example Common Game Development Workflow (starring Unity)

All works

Make a change and test on Device

Example Common Game Development Workflow (starring Unity)

Make a change and test on Device

Start build

Make a change and test on Device

20 minutes later

(if your build times are still sane)

Make a change and test on Device

Get the build file, load it on device

Make a change and test on Device

Find new and exciting bugs

Slow Iteration times

Say bye to Flow

Those 45m that took you to load the problem in your brain? Lost.

Slow Iteration times

you forgot what you started a build for

Slow Iteration times

Error prone forest of build settings

Slow Iteration times

Deadline panic 10x increase

(suffering together at late hours might be team-building but surely we don't need this :P)

What can fix this?

What can help?

Jenkins churning builds out in background

What can help?

Type system to catch bugs before running

What can help?

Unit testing

If you could have the ideal workflow what would you want it to be like?

(outside of having a magic 'Make game' button)

Inventing on Principle

As seen on LambdaCat:

Inventing on Principle

Hot reload: reload changes to the code without stopping the game

Inventing on Principle

Time Travel:

being able to scrub to any point in the session

Inventing on Principle

Omniscience: see all the state during the entire session

Is that even possible?

Which language makes it all possible RIGHT NOW?

Elm

(I'm sure no one saw this coming)

(Elm debug demo)

What sort of language is Elm?

What sort of language is Elm?

Purely Functional

Functional Reactive

What sort of language is Elm?

Eager

What sort of language is Elm?

Static Type System

What sort of language is Elm?

Compiles to Javascript, HTML, CSS

What sort of language is Elm?

Interoperates with Javascript while still being type safe

What sort of language is Elm?

Small

What sort of language is Elm?

Invented by Evan Czaplicki for his thesis

What sort of language is Elm?

Meant to be approachable and practical

What sort of language is Elm?

Meant to be approachable and practical

No 'scary' terms like Monad

Elm Reactor

Elm Reactor

Inspired by Inventing on Principle

Elm Reactor

Also solves the 'debug mouse movements conundrum'

Elm Reactor

Fundamentals made in a few days by Laszlo

Elm Reactor

Because Elm's language design was 'compatible'

Elm Architecture

Elm Architecture

Imports

Elm Architecture

import Graphics.Element exposing (..)

​import Time

import Window

Elm Architecture

Model

Model

type alias UserInput = {}

userInput : Signal UserInput

userInput Signal.constant {}

type alias Input =

    { timeDelta : Float

​    , userInput : UserInput

    }

Model

type alias UserInput = {}

userInput : Signal UserInput

userInput Signal.constant {}

type alias Input =

    { timeDelta : Float

​    , userInput : UserInput

    }

Type signature

Model

type alias UserInput = {}

userInput : Signal UserInput

userInput Signal.constant {}

type alias Input =

    { timeDelta : Float

​    , userInput : UserInput

    }

A record

Type alias

Signal

Model

type alias GameState = {}

defaultGame : GameState

defaultGame {}

Elm Architecture

Display

Display

display : (Int,Int) -> GameState -> Element

display (w,h) gameState show gameState

Display

display : (Int,Int) -> GameState -> Element

display (w,h) gameState show gameState

Type signature

Elm Architecture

Update

Update

stepGame : Input -> GameState -> GameState

stepGame {timeDelta,userInput} gameState 

                    gameState

Elm Architecture

Signals

Signals

delta : Signal Float

delta Time.fps 30

input : Signal Input

input Signal.sampleOn delta    

     (Signal.map2 Input delta userInput)

sampleOn

Signals

delta : Signal Float

delta Time.fps 30

input : Signal Input

input Signal.sampleOn delta    

     (Signal.map2 Input delta userInput)

map2

Signals

gameState : Signal GameState

gameState Signal.foldp stepGame

           defaultGame input

Signals

gameState : Signal GameState

gameState Signal.foldp stepGame

           defaultGame input

foldp

Main

Elm Architecture

Main

main : Signal Element

main Signal.map2 display

       Window.dimensions gameState

Main

main : Signal Element

main Signal.map2 display

       Window.dimensions gameState

Signal of Element values

What are Signals?

Stream of values

What are Signals?

What are Signals?

What are Signals?

a different way of thinking about variables

What are Signals?

an explicit model of variable mutation in time

What are Signals?

non-awkward way of structuring callbacks

What are Signals?

they are wired in signal graphs (directed acyclic graphs)

What are Signals?

What kind of functions can we apply on signals?

What kind of functions can we apply on signals?

merge : Signal a -> 

Signal a -> Signal a

What kind of functions can we apply on signals?

 

filter : (a -> Bool) -> a -> 

Signal a -> Signal a

What kind of functions can we apply on signals?

map : (a -> result) -> Signal a -> Signal result

apply a function on a signal

returns another, transformed, signal

What kind of functions can we apply on signals?

map2 : (a -> b -> result) -> 

Signal a -> Signal b -> 

Signal result

apply a function on two signals

What kind of functions can we apply on signals?

make a signal that depends on the past values of a signal

foldp : (a -> state -> state) -> state -> Signal a -> 

Signal state

What is this foldp thing?

What is this foldp thing?

Fold from the past

What is this foldp thing?

foldp takes (a -> state -> state) 

a function

What is this foldp thing?

... -> state -> ...

a default state

What is this foldp thing?

... -> Signal a -> ...

an input signal

What is this foldp thing?

... -> Signal state

returns a signal (next state of the program, after applying update)

What is this foldp thing?

rules out having signals of signals

How Elm Reactor works

Record Inputs

How Elm Reactor works

Reapplies functions to inputs

How Elm Reactor works

combines the previous state and old inputs to make the current state. 

How Elm Reactor works

snapshotting for performance

How Elm Reactor works

How Elm Reactor works

changes to types will break hot swapping

if a change doesn't compile

How Elm Reactor works

What about Elm makes it a good fit for a Time Travelling Debugger

Why Elm Reactor works

Applying the same inputs will return the same output

Why Elm Reactor works

No side effects so safe to replay code

Why Elm Reactor works

All mutable state is stored in the foldp

Static signal graph

Why Elm Reactor works

But, can it scale?

Castle of Elm

But, can it scale?

Game Jam game

Castle of Elm

Roguelike

Castle of Elm

Made in a couple of days

Castle of Elm

From scratch, only with Elm apis

Castle of Elm

Still slightly more than toy game

Castle of Elm

Flexible tile sistem

Castle of Elm

Character collisions

Castle of Elm

Demo

Castle of Elm

Ok, it can't be all good

Out of memory

Ok, it can't be all good

schroedinger hot swapping

Ok, it can't be all good

Ok, it can't be all good

But you can help!

It's OSS

Why it's worth to use statically typed pure Functional languages in Game Development

Why it's worth to use new language research in Game Development

No runtime exceptions

Why it's worth to use new language research in Game Development

No race conditions

Why it's worth to use new language research in Game Development

Better tools

Why it's worth to use new language research in Game Development

Less code

Why it's worth to use new language research in Game Development

Ease of parallelisations

Time Travel in Game Development with Elm at FPX 2015

By Claudia Doppioslash

Time Travel in Game Development with Elm at FPX 2015

  • 3,579