Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (806)
Games in Android Showcase (239)
games submitted by our members
Games in WIP (868)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  About separating game logic from rendering  (Read 5350 times)
0 Members and 1 Guest are viewing this topic.
Offline cuprite

Junior Newbie





« Posted 2015-08-26 05:02:24 »

Hey guys, I'm new to game development. Anyway, I was reading stuff on how you're supposed to completely separate game logic from rendering. So does that mean you shouldn't use logic statements at all during the rendering portion of the code to determine whether to draw an object or not?

for example:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
gameloop(){
     //Update
     stateTime += delta time;
     movementInput();
     if(player is at a certain position)
        atPosition = true;

     //Render
     if(stateTime > 5 && atPosition)
        draw(something);
     else
        draw(someOtherThing);
}


If so, what's a better way of controlling which things to draw to the screen?
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #1 - Posted 2015-08-26 05:43:38 »

It means that ideally you should be able to express your code something like this:

1  
2  
3  
4  
5  
gameLoop:
    processUserInput()     // kind of separate from game logic, but could include in processGameLogic
    processGameLogic()     // produces the current game state from last frame's state
    renderCurrentState()   // does nothing to change game state, only renders it
    sleep(remainingTime)


The game state doesn't have to be a single object (although it could be), it is comprised of whatever datastructures you use to store e.g. the currently loaded level, it's map, the entity list, the player's position, inventory, score, etc.

Rendering of course can (and probably will, depending on how you define it) use 'logic' during it's step, but that program logic should be separate in that it has no effect on what the current game state is. It is local to and contained by the rendering phase. render()'s only job is to read and display the state.

User input can/should also be it's own step, which can be a sub-step in the logic phase if you like, I described a single method using queues here:
http://www.java-gaming.org/topics/i-get-a-java-lang-nullpointerexception-i-cant-fix/36564/msg/347415/view.html#msg347415
Offline KevinWorkman

« JGO Plugged Duke »


Medals: 288
Projects: 12
Exp: 12 years


HappyCoding.io - Coding Tutorials!


« Reply #2 - Posted 2015-08-26 11:55:05 »

So does that mean you shouldn't use logic statements at all during the rendering portion of the code to determine whether to draw an object or not?

No.

The "you should separate game logic and rendering" rule might be better restated as "your rendering code should not change your game state" instead.

It's completely fine (and expected) to poll your game logic (determining player position, etc) from your rendering code. But your game's model should be able to run completely independently of the renderer.

In other words, I should be able to write a renderer for your game, and I should be able to swap it in to your code with a one-line change (call my renderer instead of yours) without requiring any changes to the underlying game model.

This becomes useful for porting your game over to multiple systems. Oftentimes your game model will remain mostly the same, but only your rendering code will change. If you keep the two separate, that becomes pretty easy.

HappyCoding.io - Coding Tutorials!
Happy Coding forum - Come say hello!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #3 - Posted 2015-08-26 12:07:26 »

Take into consideration that this should be considered a guideline, not a holy grail. When you develop your game, you will most likely suck at it at some level, and the code will be a complete mess. This is okay, as long as you learned something developing these small games. People who get stuff done, tend to be less uncomfortable with crappy code.

So don't start refactoring just yet - developing and finishing a game is - at this point - the goal. Keep general guidelines in mind, but by all means don't try to make the renderer swappable. Such things are incredibly hard for developers with a decade of experience under their belt. Ask yourself this: will you port your game to another platform any time soon? If not, don't bother, just get your game playable, that is hard enough as it is, when you're new to the game.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline KevinWorkman

« JGO Plugged Duke »


Medals: 288
Projects: 12
Exp: 12 years


HappyCoding.io - Coding Tutorials!


« Reply #4 - Posted 2015-08-26 13:11:25 »

I absolutely agree with Riven: especially if you're just starting out, any code you write is going to seem terrible in 6 months. This is a sign that you're improving. But it also means that spending a lot of time trying to refactor your code to be perfect gives you vastly diminished returns as compared to just finishing something that works and moving on to the next project.

It's nice to keep in mind the general guidelines of game development while you work, but I wouldn't become overly worried about strictly adhering to them. They'll become more natural to you over time.

HappyCoding.io - Coding Tutorials!
Happy Coding forum - Come say hello!
Offline CommanderKeith
« Reply #5 - Posted 2015-08-26 13:24:45 »

Making the rendering code swappable is an interesting idea, nice one KevinWorkman.
But then in some respects, keeping the render method as a part of the game object being rendered also has an elegance to it. After all, the game object would know best how it should be rendered and any refactoring or improvement made to the game object state can be easily updated in the rendering code in that game object class, rather than finding the renderer class and updating it there.

Reminds me of argument over using classes versus entity component systems like artemis.

Offline KevinWorkman

« JGO Plugged Duke »


Medals: 288
Projects: 12
Exp: 12 years


HappyCoding.io - Coding Tutorials!


« Reply #6 - Posted 2015-08-26 13:43:03 »

Making the rendering code swappable is an interesting idea, nice one KevinWorkman.

Thanks. To be fair it's not really my idea, it's just the application of MVC logic to game development. Your model shouldn't care about your view or controller, to the point that you should be able to swap out your view and controller and have your model still function.

In my experience, the ability to swap out your view/renderer is more of a "best case scenario" goal to shoot for than it is something that actually happens very often. Most people probably don't care about literally being able to swap out a renderer, but separating your code as if you did care about it will make your life easier in other departments as well.

But then in some respects, keeping the render method as a part of the game object being rendered also has an elegance to it. After all, the game object would know best how it should be rendered and any refactoring or improvement made to the game object state can be easily updated in the rendering code in that game object class, rather than finding the renderer class and updating it there.

I agree, and that's how I code my own games. That being said, I generally do keep my model code in a step() function, and then my render code in a draw() function. It wouldn't be too hard to move my draw() function to a rendering class, and then swap out different rendering classes. If you keep your rendering code separate from your modeling code like that, you're still semantically obeying the guideline of swappability.

HappyCoding.io - Coding Tutorials!
Happy Coding forum - Come say hello!
Offline CommanderKeith
« Reply #7 - Posted 2015-08-26 14:04:32 »

But then in some respects, keeping the render method as a part of the game object being rendered also has an elegance to it. After all, the game object would know best how it should be rendered and any refactoring or improvement made to the game object state can be easily updated in the rendering code in that game object class, rather than finding the renderer class and updating it there.

I agree, and that's how I code my own games. That being said, I generally do keep my model code in a step() function, and then my render code in a draw() function. It wouldn't be too hard to move my draw() function to a rendering class, and then swap out different rendering classes. If you keep your rendering code separate from your modeling code like that, you're still semantically obeying the guideline of swappability.

Yes i do the same thing too. The alternative entity component system approach is interesting and it would be nice to try it one day.

Offline cuprite

Junior Newbie





« Reply #8 - Posted 2015-08-26 15:17:24 »

Thanks for all the replies! Ridiculously helpful!
Offline DavidBVal
« Reply #9 - Posted 2015-08-27 13:08:19 »

Wise words from Riven. When you get your hands dirty, you have to compromise. Sometimes as he mentions, it is a matter of choosing between refactoring to perfection, or actually finishing the damn thing. And sometimes it is "intentional" bad design because of optimization, making your code uglier and less structured, but more efficient. In the end, coding is a means, not an end. The end is, your game finished, working and published.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline gouessej
« Reply #10 - Posted 2015-08-27 14:05:14 »

Actually, when you mix the game logic with the rendering, there is no way to update the former less often than the latter. Do you really need to check if there are some collisions 60 times per second? Imagine that the end user disables the v-sync, should your game really run those checks as much time as possible? A physics engine can create lots of short-lived objects, running it only when it is necessary can be helpful to reduce the memory and CPU footprint of your game, especially on machines with a limited autonomy (laptops, mobile phones, ...).

It depends on the kind of game that you create but maybe you'll need to avoid mixing together not only to ease the port to other platforms. In my humble opinion, writing dirty code is a bad idea on long term projects (working with it will become increasingly discouraging as time goes by) and writing an independent renderer can be helpful if you need to switch to another library.

If you use a "good" framework or a "good" engine, you don't have to worry about it as this separation is already done, just don't mix everything in your own code.

Julien Gouesse | Personal blog | Website | Jogamp
Offline KaiHH

JGO Kernel


Medals: 798



« Reply #11 - Posted 2015-08-27 14:21:53 »

Regardless of the specific domain of an application (game or something else), whether design is bad or not is determined by how and in which ways you see the need for change in the future and how well that change can be realized while still satisfying all functional and non-functional (performance, memory-footprint, etc.) requirements of the application.

If you see change in trying to port to another platform: Well, then you've got to have a design that supports that.
If you see change in trying to use another renderer (Direct3D?): Well, then you know what your design ought to support.

In the classic IEEE article "Who Needs An Architect", written by Martin Fowler, Ralph Johnson was cited with, that it is simple to make one thing easy to change in a software system. But we cannot make everything easy to change, as that would make the whole system very complex.
So, yes, it is always about compromises and architecture is really just the design decisions that make further anticipated changes easy to do.

There is also no such thing as "good" or "bad" design per se. Sure, there are loads of books about basic design principles out there. But those are meant to help design your application in a way that it is easier to adapt to common and recurring changes.

But in my opinion, the "quality" measure of design is defined by how well that design supports anticipated change.
You can write the crappiest code for an application/game; if the application/game works, and given it will never change again, it was by definition not bad design.

Design always "becomes" bad when you see change that is not easy to incorporate.
Pages: [1]
  ignore  |  Print  
 
 

 
Riven (587 views)
2019-09-04 15:33:17

hadezbladez (5529 views)
2018-11-16 13:46:03

hadezbladez (2410 views)
2018-11-16 13:41:33

hadezbladez (5790 views)
2018-11-16 13:35:35

hadezbladez (1233 views)
2018-11-16 13:32:03

EgonOlsen (4669 views)
2018-06-10 19:43:48

EgonOlsen (5688 views)
2018-06-10 19:43:44

EgonOlsen (3205 views)
2018-06-10 19:43:20

DesertCoockie (4104 views)
2018-05-13 18:23:11

nelsongames (5125 views)
2018-04-24 18:15:36
A NON-ideal modular configuration for Eclipse with JavaFX
by philfrei
2019-12-19 19:35:12

Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!