Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm using C#/XNA and have been told quite a few times not to mix update code with draw code -- and I'm certain I'm not! But could anyone please describe what exactly is 'logic code'?

As seen here: http://blogs.msdn.com/b/shawnhar/archive/2007/07/25/understanding-gametime.aspx

[...] make sure you put all your game logic inside the Update method (not in Draw!) and everything will run at a nice constant speed.

I'm asking this since my game's speed is fluctuating relative to the FPS. Slow FPS equals slow-moving objects and visa versa. And yes, I am including the expected position += speed * (float)gt.ElapsedGameTime.TotalSeconds; code.

This is probably a big rookie question, but I just want to be absolutely clear on the definition of this.

share|improve this question
    
I think you meant position = speed * ...TotalSeconds. Notice it's = not +=. If it were += just as you typed, then your position would fly off the screen almost instantaneously. – DrZ214 Jan 27 at 0:47
    
I have code that looks like 'position += direction * speed * ...TotalSeconds' and that works very well. I may have mistyped something, but position = speed would assign it every update. Your way may work, but I have my code working like this. (Note that direction is normalized) – Shyy Guy Jan 27 at 0:57
    
I thought gt.ElapsedGameTime.TotalSeconds is the number of seconds elapsed from starting the program (game). If you're multiplying your speed by that, then after 5 seconds of playing, your speed will be 5 times faster (except the special case where speed is set to 0). Not sure what else you could have that would make that untrue, but I'm intrigued. – DrZ214 Jan 27 at 1:03
1  
Aha, it's since the last update. gamedev.stackexchange.com/questions/67968/… – Shyy Guy Jan 27 at 1:05
2  
Fascinating I never would have guessed that. Never had any need for such a thing in seconds, because I personally use my own variable called iii that i manually increment every update, because I don't want it in seconds, i want steps or frames. I can see that your way is a valid way of soft-coding things though. – DrZ214 Jan 27 at 1:09
up vote 97 down vote accepted

Does it change the state of your game world? It's logic code.

Does it display the state of the game world? It's rendering code.

share|improve this answer
    
I'll glance through my code to be 100% certain. Good explanation, thanks. – Shyy Guy Jan 25 at 17:57
37  
Does it handle input? Its controller code. Separate control from logic, so that you can use the same logic with different types of controls. E.g. a FPSInputController + CharacterMotor vs. AIInputController + CharacterMotor vs NetworkInputController (e.g. other players in a multiplayer instance) + CharacterMotor. The motor (logic code) doesn't care how it gets the instructions it does, only that they're supplied (this kind of decoupling allows for easy transition from player to AI bot (think Left 4 Dead and idle players) and back, among other things). – Draco18s Jan 25 at 18:11
9  
Draco brings up a good point. There are many many different divisions that you can put into the code. Nils' division is what I'd consider the archetypal division between logic and rendering, but there are many other layers that you'll see. The real reason to separate them out into layers is that each layer consists of similar actions which require a similar style of code with similar requirements. For example, in many games, you can get away with game logic taking 2 or 3 frames to complete, but if you don't do rendering each frame, the user's eye will notice quickly. – Cort Ammon Jan 25 at 19:39
    
Keeping them distinct will help you manage your requirements when they start to become a source of strain. – Cort Ammon Jan 25 at 19:40
6  
And remember that if you throw too much MVC at it it can slow down to a crawl, so always strive for a balance between maintainability and optimization. But don't optimize too early, unless you're absolutely sure what you're doing. And remember you can always refactor. And... Uh, make many games and learn from your mistakes. – Maurycy Jan 26 at 13:09

Your separation is correct if:

  • Calling Draw() multiple times in a row without any interspersed calls to Update() would never result in any visible changes between the calls.
  • Calling Update() multiple times in a row without an interspersed call to Draw() would be like playing the game with the screen turned off: everything moves along perfectly and consistently, you just can't see it.
share|improve this answer
4  
Properly written Draw() may draw different pictures as the time passes. For example, frames of animated sprites may continue to change. Also, objects may continue to visually move forward if rendering code uses a common trick and adds velocity * time since last update / period of update to visible position of objects (while their real position remains unchanged). – HolyBlackCat Jan 26 at 16:05
2  
iff meaning if-and-only-if? – BalinKingOfMoria Jan 26 at 21:57
3  
@HolyBlackCat: that's arguable. What if I want to pause graphics? What if the frames of animation affect the game (attack animations corresponding to hitboxes, etc.) ? Visual interpolation still implies that "time" (as in the game's delta time) is passing, but if time is passing and you're not Updateing then what else is getting out of sync? Player inputs being missed, network events not being processed, etc? The game should be driven off of a single clock, with fixed "ticks" for game logic or physics derived from that clock, and derived graphics state also driven by that same clock. – Sean Middleditch Jan 26 at 23:02
    
@SeanMiddleditch I agree, almost always you can write Draw() in a such way so it always draws same picture when called several times in a row. One should do that if possible. But there are cases when you don't know at what frequency Draw() will be called. For example, if you want full support (actual 120 FPS) for new 120hz monitors and you turn vsync on. What if I want to pause graphics? Then you pass 0 instead of actual delta time to the Draw(). – HolyBlackCat Jan 27 at 10:40
2  
@HolyBlackCat: Nothing I was getting at would preclude use of 120hz rendering. I absolutely was not recommending a fixed draw rate; that's just amateurish. There should be one global game clock whose delta is measured in terms of render frames that feeds into the accumulation value for the fixed-rate game logic tick. That global clock drives graphics, including interpolation. You can pause graphics by setting the clock scale to 0. You can have hierarchical clocks so e.g. UI still runs and animates while character interpolation stops, too, very very easily. – Sean Middleditch Jan 27 at 21:12

The point here is separation of Model things that are not the model.

The Game Logic is the Model as referred to in

These are all different, related, software architecture patterns. But in all case the Model is the same thing it's the real logic and the real state.

It is the when making business software it is sometimes called business logic, and encoded some of the businesses policies. Eg if your are coding something for a bank, to calculate credit card bills, then the functionality to cause someone to not have to pay interest if they clear their debt in less than 30 days, is part of the business logic, it lives in the model. It does not for example live on one of the displaying layers. The code for printing a bill, does not for example, edit the text based on their actions. This example perhaps highlights why you might want to organise your code that way.

Similar goes for game logic.

Imagine that at some point your game was ported to another console. It might help to imagine something really different to your current target. Eg if you are targeting somehting with a gamepad/controller, Imagine your game being ported to a touchscreen tablet. The game logic is the part of the code that does not change when you port it.

If your game were something like a military strategy game, imagine it being converted to the worlds most complex boardgame. The game logic is the sections of code, that directly correspond to lines in the rule book. (Not all the lines in the rule book, not the ones about moving pieces, but some.).

The game logic is the thing that never changes, no matter the form.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.