Functional Reactive Programming in...
Transcript of Functional Reactive Programming in...
![Page 1: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/1.jpg)
![Page 2: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/2.jpg)
Functional Reactive Programming in Games
Elise Huard - CodeMesh 2015
![Page 3: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/3.jpg)
What
![Page 4: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/4.jpg)
![Page 5: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/5.jpg)
FRP
![Page 6: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/6.jpg)
Elerea https://github.com/cobbpg/elerea
data Signal a Monad, Applicative, Functor
data SignalGen a Monad, Applicative, Functor, MonadFix
t
![Page 7: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/7.jpg)
![Page 8: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/8.jpg)
The Salespitch
![Page 9: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/9.jpg)
![Page 10: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/10.jpg)
game :: RandomGen t => Signal (Bool, Bool, Bool, Bool) -> t -> SignalGen (IO ())game directionKey randomGenerator = mdo randomNumber <- stateful (undefined, randomGenerator) nextRandom player <- transfer2 initialPlayer (movePlayer 10) directionKey gameOver' monster <- transfer3 initialMonster wanderOrHunt player randomNumber gameOver' gameOver <- memo (playerEaten <$> player <*> monster) gameOver' <- delay False gameOver return $ renderFrame win glossState <$> player <*> monster <*> gameOver
![Page 11: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/11.jpg)
start :: SignalGen (Signal a) -> IO (IO a)
network <- start $ game directionKey randomGeneratorfix $ \loop -> do readInput win directionKeySink join network threadDelay 20000 esc <- exitKeyPressed win unless esc loop
![Page 12: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/12.jpg)
(directionKey, directionKeySink) <- external (False, False, False, False)
(l,r,u,d) <- (,,,) <$> keyIsPressed window Key'Left <*> keyIsPressed window Key'Right <*> keyIsPressed window Key'Up <*> keyIsPressed window Key'DowndirectionKeySink (l, r, u, d)
![Page 13: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/13.jpg)
simpleSignal <- stateful 2 (+3)
randomNumber <- stateful (undefined, randomGenerator) nextRandom
![Page 14: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/14.jpg)
player <- transfer2 initialPlayer movePlayer directionKey gameOver’
monster <- transfer3 initialMonster wanderOrHunt player randomNumber gameOver’
![Page 15: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/15.jpg)
gameState = GameState <$> renderState <*> soundState
![Page 16: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/16.jpg)
![Page 17: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/17.jpg)
game :: RandomGen t => Signal (Bool, Bool, Bool, Bool) -> t -> SignalGen (IO ())game directionKey randomGenerator = mdo player <- transfer2 initialPlayer (movePlayer 10) directionKey gameOver' randomNumber <- stateful (undefined, randomGenerator) nextRandom monster <- transfer3 initialMonster wanderOrHunt player randomNumber gameOver' gameOver <- memo (playerEaten <$> player <*> monster) gameOver' <- delay False gameOver return $ renderFrame win glossState <$> player <*> monster <*> gameOver
![Page 18: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/18.jpg)
Subnetworks
![Page 19: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/19.jpg)
generator :: Signal (SignalGen a) -> SignalGen (Signal a)
playLevel :: Signal (Bool, Bool, Bool, Bool) -- event signals -> LevelNumber -- pattern match on level number -> Score -> Health -> SignalGen (Signal GameState, Signal Bool)
-- in playGame main function(gameState, levelTrigger) <- switcher $ playLevel directionKey <$> levelCount' <*> score' <*> lives'
![Page 20: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/20.jpg)
![Page 21: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/21.jpg)
dynamic networks
![Page 22: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/22.jpg)
Signal [Bolt]
bolts <- transfer2 [] manageBolts shootKey player
![Page 23: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/23.jpg)
SignalGen [Signal Bolt]
let bolt direction range startPosition = stateful (Bolt startPosition direction range False) moveBolt mkShot shot currentPlayer = if hasAny shot then (:[]) <$> bolt (dirFrom shot) boltRange (position currentPlayer) else return []newBolts <- generator (mkShot <$> shoot <*> player)bolts <- collection newBolts (boltIsAlive worldDimensions <$> monsters)
![Page 24: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/24.jpg)
collection :: (Signal [Signal Bolt]) -> Signal (Bolt -> Bool) -> SignalGen (Signal [Bolt])collection source isAlive = mdo boltSignals <- delay [] (map snd <$> boltsAndSignals') -- add new bolt signals bolts <- memo (liftA2 (++) source boltSignals) let boltsAndSignals = zip <$> (sequence =<< bolts) <*> bolts -- filter out dead ones boltsAndSignals' <- memo (filter <$> ((.fst) <$> isAlive) <*> boltsAndSignals) return $ map fst <$> boltsAndSignals'
![Page 25: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/25.jpg)
physics
![Page 26: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/26.jpg)
![Page 27: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/27.jpg)
execute :: IO a -> SignalGen a
effectful :: IO a -> SignalGen (Signal a)
![Page 28: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/28.jpg)
Round-up
![Page 29: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/29.jpg)
Cons
![Page 30: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/30.jpg)
![Page 31: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/31.jpg)
Some added complexity in handling infrastructure
![Page 32: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/32.jpg)
performance?
![Page 33: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/33.jpg)
Pros
![Page 34: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/34.jpg)
Conceptually simpler (smaller units)
![Page 35: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/35.jpg)
Testability
![Page 36: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/36.jpg)
prop_insideLimits move player@(Player (x,y) _ _) = (x > ((-worldWidth) `quot` 2 + playerSize `quot` 2)) && (x < (worldWidth `quot` 2 - playerSize `quot` 2)) && (y > ((-worldHeight) `quot` 2 + playerSize `quot` 2)) && (y < (worldHeight `quot` 2 - playerSize `quot` 2)) ==> not $ (\p -> outsideOfLimits (worldWidth, worldHeight) p playerSize) $ position $ movePlayer playerSpeed (worldWidth, worldHeight) move Nothing (False, False, False, False) Nothing player
![Page 37: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/37.jpg)
![Page 38: Functional Reactive Programming in Gamesgotocon.com/.../slides/EliseHuard_FRPAndFunctionalGameProgram… · start :: SignalGen (Signal a)-> IO (IO a) network](https://reader034.fdocuments.net/reader034/viewer/2022042400/5f0f67707e708231d443fde1/html5/thumbnails/38.jpg)