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...@haskell.org [mailto:haskell...@haskell.org] On Behalf Of Korcan Hussein
Sent: Wednesday, October 29, 2008 4:57 PM
To: has...@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>
> 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.
_______________________________________________
Haskell-Cafe mailing list
Haskel...@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
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.
> > > 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.
_______________________________________________