RE: [Haskell] Making 'Super Nario Bros.' in Haskell

That’s great -- easy to follow, even though I can’t read the comments. ^^ It’s not possible for actors to ‘watch’ each other in this system, correct? For instance, if one actor holds a reference to another, it will keep that old version of the actor alive, but it won’t see when the actor moves. This game doesn’t seem to need actors that watch each other, but it’s very common in games. I’ve been using IORefs for that purpose, but I like how pure the Mario game is. Is there a better way than IORefs? ________________________________ From: haskell-bounces@haskell.org [mailto:haskell-bounces@haskell.org] On Behalf Of Korcan Hussein Sent: Wednesday, October 29, 2008 4:57 PM To: haskell@haskell.org Subject: [Haskell] Making 'Super Nario Bros.' in Haskell Hi I haven't seen this posted any where so I'm sorry in advance if this has been mentioned already but I came across this recent video on youtube: http://uk.youtube.com/watch?v=gVLFGQGRsDw it's a mario clone written in haskell with a link to source code repository (http://svn.coderepos.org/share/lang/haskell/nario/). I thought that it maybe useful to some people. Trustworthiness: Vendor reliability: Privacy: Child safety: ________________________________ For the best free wallpapers from MSN Click here! http://wallpapers.msn.com/?ocid=%5bB001MSN42A0716B%5d

"Eli Ford"
Is there a better way than IORefs
Without looking at the code: The state Monad. Imperative implementations of games are usually[1] modelled as finite automata, there's no reason to do it any different in a functional language. Add a bit of glue to translate input events into input symbols and output symbols into graphics, sound and general joyful multimedia goodness and some strings to tell your automata that it's supposed to switch to a new state each frame and you're set. [1] That is, I know of no counterexamples, except broken automata where clueless code monkeys update the game state while drawing onto the screen and similar atrocities. -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited.

Is there a better way than IORefs
The state Monad.
Do you mean one state shared among all actors, like this? type MGame = State GameState newtype GameState = GameState { <shared state> } That gets part of the way, but I'm thinking of a situation where each instance of a particular type of actor can have its own reference to some other actor: newtype Watcher = Watcher { otherActor :: IORef ActorWrapper } (Here, ActorWrapper is an existential type that hides a specific actor type.) I started writing a game using IORefs that way, allowing actors to see and cause changes in each other, but in the back of my mind I wonder if this is a symptom of a C++ background.

"Eli Ford"
Is there a better way than IORefs
The state Monad.
Do you mean one state shared among all actors, like this?
type MGame = State GameState newtype GameState = GameState { <shared state> }
That gets part of the way, but I'm thinking of a situation where each instance of a particular type of actor can have its own reference to some other actor:
newtype Watcher = Watcher { otherActor :: IORef ActorWrapper }
(Here, ActorWrapper is an existential type that hides a specific actor type.)
I started writing a game using IORefs that way, allowing actors to see and cause changes in each other, but in the back of my mind I wonder if this is a symptom of a C++ background.
As a general rule, if you're thinking IORef's you aren't thinking Haskell. You shouldn't think of a global state Monad as state being shared between all actors, but capturing the state of many actors at a particular instance of time: The state Monad, by itself, encapsulates time, not data. The data encapsulation is done by the type of the state, something like MyState = MyState { actors::(Map UKey Actor), ... } where UKey is unique for the whole run-time of the game, that is, if you store e.g. a reference to a door in the state of a switch, you can make the switch explode (either in the frame-global update or when triggered) if Mario happened to jump on the door and thus destroyed it. (Please don't take this as an example of good game design) If you look at the source of MonadState, you'll notice that it doesn't care about what you put into it, at all. It's merely pure imperative sugar that allows you to pretend not to be programming in a functional language. My model, of course, doesn't really differ from yours except that it can't blow up that badly as eg. you can't ever modify your game state from inside draw or mess with gl in update. As a general rule, always try hard to restrict usage of the IO Monad to the main function. It doesn't mean that you can't code imperatively and side-effect full in the rest of your program, it just means that you can't launch nuclear missiles and cause major side effects outside of your program. Nothing is stopping you from further restricting side-effects by using the state Monad on two different types to eg. seperate the GUI state from the game state, so that you can't ever select a menu item when Mario collects a mushroom or similar insanities. Decide for yourself how much granularity you want. One of the strangest features of Haskell is that, despite and because of being an uttermost functional language, it actually promotes imperative programming in the guise of monadic programming. -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited.
participants (2)
-
Achim Schneider
-
Eli Ford