Author Topic: Separating render and logic  (Read 8679 times)

mike3

  • Rogueliker
  • ***
  • Posts: 125
  • Karma: +0/-0
    • View Profile
    • Email
Separating render and logic
« on: July 07, 2013, 09:15:26 AM »
Hi.

In a roguelike (or perhaps, any other kind of game) game loop, we may have:

input
logic
render

in that order. These should be separate. But suppose we need to print a message, which happens during the logic. Or show an explosion, or a magic, or an animation of a projectile firing, and so forth. These should all be handled in the "render" phase, yet the logic dictates if one does or doesn't happen. What's the best way to handle this? I was going to try a system where the render system is simply passed different things that happen which affect the display during the logic, which go on a queue, and then at render time for this turn it goes through the queue and handles each one, rendering it in the same sequence as they happened. So the actual rendering doesn't take place during the logic, only notification of the render system with what needs to be rendered. Would this be "correct"?

Trystan

  • Rogueliker
  • ***
  • Posts: 164
  • Karma: +0/-0
    • View Profile
    • my blog
Re: Separating render and logic
« Reply #1 on: July 07, 2013, 07:47:31 PM »
This is something I've been experimenting with a lot lately. In my latest work, the main loop is the same but the details depend on whether there are animations or not. If there's animations queued up, then any input is ignored or queued up, the "logic" just updates the animations, the animations are rendered, and it automatically repeats. Once the animations are all done, any queued up input is handled, the "logic" updates the game world, it renders normally, and waits for the next input.

I think many of the older roguelikes written in C didn't really separate the three clearly and any code could render some text, block until a key was pressed, then handle it immediately.

What's "best" depends on what your language supports and what you're trying to do. I need multiple animations to happen at once because I have dozens or hundreds of traps getting animated each turn. I'm also relying on an event driven framework so I can't really block on user input or do any low-level tricks the C programmers rely on.

I think you should make a very small prototype that has just the things you care about - maybe with teams of archers shooting at each other. Try a few different architectures and see what you like and don't like.

mike3

  • Rogueliker
  • ***
  • Posts: 125
  • Karma: +0/-0
    • View Profile
    • Email
Re: Separating render and logic
« Reply #2 on: July 07, 2013, 09:38:42 PM »
This is something I've been experimenting with a lot lately. In my latest work, the main loop is the same but the details depend on whether there are animations or not. If there's animations queued up, then any input is ignored or queued up, the "logic" just updates the animations, the animations are rendered, and it automatically repeats. Once the animations are all done, any queued up input is handled, the "logic" updates the game world, it renders normally, and waits for the next input.

I think many of the older roguelikes written in C didn't really separate the three clearly and any code could render some text, block until a key was pressed, then handle it immediately.

What's "best" depends on what your language supports and what you're trying to do. I need multiple animations to happen at once because I have dozens or hundreds of traps getting animated each turn. I'm also relying on an event driven framework so I can't really block on user input or do any low-level tricks the C programmers rely on.

I think you should make a very small prototype that has just the things you care about - maybe with teams of archers shooting at each other. Try a few different architectures and see what you like and don't like.

Well, this system doesn't have animations, it's just a text-based program right now. But I'd like it to be possible to extend to animations in the future.

So then am I right in thinking that your system is a little bit similar to what I mentioned in my post? That the animations are queued up during the logic for the turn, and then the actual rendering happens afterwards, like how in the system mentioned in my post, things to "happen on the display" (which could include animations in a future version) are queued up?

Also, does the system I mention in the original post keep them "separate" enough?
« Last Edit: July 07, 2013, 10:13:09 PM by mike3 »

Trystan

  • Rogueliker
  • ***
  • Posts: 164
  • Karma: +0/-0
    • View Profile
    • my blog
Re: Separating render and logic
« Reply #3 on: July 07, 2013, 10:18:31 PM »
That the animations are queued up during the logic for the turn, and then the actual rendering happens afterwards, like how in the system mentioned in my post, things to "happen on the display" (which could include animations in a future version) are queued up?

Yup.

I've found it best to do queued up animations after updating each creature. There are other ways of dealing with this but I haven't found one that I'm 100% happy with.

Anvilfolk

  • Rogueliker
  • ***
  • Posts: 374
  • Karma: +0/-0
    • View Profile
Re: Separating render and logic
« Reply #4 on: July 08, 2013, 01:18:01 AM »
This issue goes beyond RL development, and can actually be discussed at the level of game development in general.

I've been interested in gamedev for a while and have read quite a bit, but it turns out that most tutorials and books out there will essentially teach you an API, but never really tell you how your code should be organised. It's like all that matters is that you can render things.

Fortunately, I came across a review of a book that said the book was more about how to organise code than how to render specific things. I've been reading through it and it led me to completely rework the RL I'm currently developing.

The book is called Game Coding Complete (4th ed.), and I can heartily recommend it if you already have some programming experience. It's for C++ and DirectX, whereas I want Python and SFML, but it is entirely possible to ignore the technical aspects and focus on the organisational ones.

They essentially espouse the MVC pattern (model-view-controller), where the model is the game itself (no graphics involved), the view can the the user-interface/rendering for the human, or a network interface for a remote player, or for an AI, and the controller deals with inputs (for the player) and possibly AI decisions.

I highly recommend you just find the book somewhere and give a read to chapters 1-3,5-7,10,11, but the two main things related to your question are the following:

Have an EventManager. The model is doing its own thing, with time passing, actors moving, etc etc. Whenever anything of interest happens, send the EventManager an Event reporting it. If an actor moved, if an actor was created, if an attack occurred, etc etc etc. The EventManager is going to distribute these events to whoever is interested in them. Your game classes tell the EventManager what events they are interested in, and what function to call back once an Event is triggered.

For example, your rendering system is attached to the player's View. The View is interested in all events of the type Move (which it uses to update the locations of its sprites), of type Create (so it can add another visual representation for the object), of type Attack (so it can write "you do 5 damage") to the screen, etc etc.


For animations, you're likely to need something else, which changes the main loop. The authors of the book suggest using a ProcessManager, for anything that takes more than one "frame" or update to process. This can include things like AI routines that stop executing after a little bit so they don't hog a processor, or animations. Suppose an actor throws a grenade and it explodes. The model will deal damage to everything within a given radius, and then will generate an Explosion event. The Human View (which previously registered for Explosion events) will receive the event, and create a new Process whose sole purpose is to draw an explosion animation at the given location (by choosing frame after frame after frame as time passes). Once the explosion is complete, the process kills itself off.


So that's how the authors do it... at least in my interpretation of what they explained, but to be honest I did more of a quick perusal than a deep study, so I might be wrong. But conceptually this seems to make a lot of sense, and to be generalisable to many gamedev scenarios.

Hope this helps!
"Get it hot! Hit it harder!!!"
 - The tutor warcry

One of They Who Are Too Busy

JollyRoger

  • Newcomer
  • Posts: 26
  • Karma: +0/-0
    • View Profile
    • Fallen
Re: Separating render and logic
« Reply #5 on: July 08, 2013, 04:21:55 AM »
I can't understand whats the problem?
Render doesn't magically draw everything when when it happens.
You make calculations for turn, then render draws it.
If you want some sort of animation, we stay on the same place.
We have a bunch of data, that represents game world, current situation etc
Calculation routines changing it, but data still exists. Render routines uses this data to draw required part for player.
If calculation doesn't changed anything, so render will draw the same. 
Our Roguelike project - Fallen: http://ffhtr.blogspot.ru/.