concurrency-wise, you might find useful Rich Hickey's ants simulation

https://github.com/juliangamble/clojure-ants-simulation/
the relevant video where he explains it:
https://www.youtube.com/watch?v=dGVqrGmwOAw
(if you want the slides too, see in the comments: someone suggested google
for "Must watch: Clojure concurrency")



On Mon, May 20, 2013 at 4:02 AM, Daniel P. Wright <d...@dpwright.com> wrote:

> Hello,
>
> I am trying to structure the game loop for a simple game in clojure,
> trying to keep things pure as far as possible to get a feel for how this
> would work in a functional environment.  Currently, I am working with
> a message-based system, whereby various events create "messages" which I
> then act on to change state.  For example:
>
>   1. Read keypresses, generate a message for each keypress and add to
>      the queue.
>   2. Read from the network; add any incoming messages to the queue.
>   3. Add an "update" message to the queue which can be used for generic
>      update processing: AI, physics, whatever
>   4. Go through the entities in my world delivering these messages as
>      appropriate.  Keypress and update messages will be processed by any
>      entity that implements a handler for them; network messages may be
>      "directed" so that they only get sent to a specific entity.
>     (The return value of the functions processing these messages is
>      itself a vector of messages, such as "update-state" to replace the
>      current state of an entity (position, etc) with a new state, or
>      perhaps a message to send information over the network.)
>   5. Send any outgoing network messages, perform any state updates, etc.
>   6. Draw the screen, return to 1 and begin the next game loop.
>
> The issue I'm having is that this system results in rather a lot of
> looping through every entity in the world.  There are two full loops,
> delivering the messages in step 4 and updating the state in step 5.
> Originally I had the message handlers in step 4 return a new state
> rather than new messages, so I just updated the entities in-place during
> the first loop, but I found sometimes I wanted to do other things than
> just update state -- for example send messages over the network, or to
> another entity in the world.  So it seemed more flexible to return
> messages, even if some of those messages are directed toward the entity
> sending it.
>
> My other issue is that with messages intended to be processed by a
> particular entity, I can either check that while looping through the
> whole list of entities (which means for every entity it's not intended
> for I'm running a wasteful check on the id of a message), or I can put
> the entities in a map instead of a vector and look them up by some id
> instead (in which case I'm doing a search for every directed message, on
> top of the loop I'm already doing through all the entities).
>
> I've come from a mostly C++ background, so my sense of when I'm doing
> something really bad isn't very well-tuned in functional languages at
> the moment.  I write something that "feels" nice and looks pretty, and
> then I step back and think about what it's actually *doing* and I can't
> help but think "in C++ this would be unforgivably vile."
>
> It seems the more I try to push function purity the more I have to loop
> through some monolithic data structure holding all of my state, since I
> can't just pass references around and modify them in-place.  Writing the
> code for the entities themselves is going quite well -- I am keeping
> their functions pure, not referring to anything outside of the
> parameters they're passed in, and thus always returning the same result
> given the same input, and limiting their input to the information they
> need without giving them access to the entire state of everything -- all
> of which is great for testing, parallelisation, and all the rest.  It's
> at the higher level of managing the collection of these entities and
> their relationships that I wonder whether I am working along the right
> lines or whether I am in some sense "doing it wrong".
>
> As an aside, right now I am avoiding storing entity state as atoms and
> having the update functions modify those atoms because although clojure
> helps update their values safely it still means the function has side
> effects, and I'm trying to keep functions as "pure" as possible at least
> until I can understand the limitations of doing that and see the
> necessity for using global constructs.
>
> I have a feeling this is only going to get more complex as I start
> wanting to make smaller sub-lists that refer to the same entities.  For
> example my entities may be stored in some tree format in the world
> state, but I might want to have a list of "all enemies within a certain
> radius" or whatever just as a convenience for quick access to those
> entities I'm interested in.  Right now if I updated an entity in this
> list it would remain not updated in the global state tree... I'm
> guessing there's no way around holding an atom or similar in both lists
> and updating that, but here I may be missing something also.
>
> Sorry for the slightly rambling mail; thoughts/guidance appreciated!
>
> -Dani.
>
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to