Awards
The developers of the issue are: Relminator and Oz
Unjustly omitted in previous issues, I wish to awards these two individuals, as much for their past efforts, also equally for their valuable contributions in the past two months.
Oz (Alex Barry) developed sometime ago and continues to diligently maintain FB headers for Chipmunk, a popular 2D physics engine. He also provides examples, demos and documentation. Great work overall and a wonderful asset for the FB game developing community. Keep it up!
Official Chipmunk FreeBASIC webpage: https://github.com/mrozbarry/Chipmunk-Physics/
Official forum thread: http://www.freebasic.net/forum/viewtopic.php?f=14&t=16476
Local download of the latest version (6.x): Chipmunk-Physics-master.zip (492 KB)
In late October Oz also wrapped ENet for FreeBASIC, a game networking library (network communication layer on top of UDP). He also provided a simple server example with a client. Thank you, Oz!
Official webpage: https://github.com/mrozbarry/enet
Local download of the latest version : enet-master.zip (84 KB)
Relminator (Richard Eric M. Lope) continues to maintain his superb OpenGL 2D rendering engine for FreeBASIC, Easy GL2D. Besides maintaining this library he takes the time to write wonderful and lengthy game dev tutorials on various topics (last and this issue of BASIC Gaming), as well as to develop an exciting new game - Convex Wars FB. What is there more to say? A community member we can all wish for! Thank you for all your hard work so far, Richard.
Easy GL2D webpage: http://rel.phatcode.net/junk.php?id=115
Download the latest version (v.0.7) of Easy GL2D here: LibFBGL2D7.zip (1072 KB)
Download Convex Wars FB here: ConvexWarsFB.zip (956 KB)
Reusable code is organized code is easy code
Written by Joe King (November, 2012)
Make your code reusable, you often read. There are many benefits to this. You can use it later for another project. You can share it. Others might use it. You can easily port it to other languages and systems.
This idea sounds great, but in practice I found it challenging. It's a skill that takes practice.
My old games consisted of a few files with code gone awry everywhere. The code was hard to maintain and easy to forget. Now, I am completely lost when I come back to it. This is because I organized the code in my head and not in the code itself. And when that organization is forgotten, I see the code for what it is, an unsightly mess.
On the contrary, reusable is organized code. It's easy to build upon and maintain. You can leave it for awhile and come back and pick up where you left off. So even if you don't plan to use your code in the future, make it reusable. It'll be easier to work with.
To make your code reusable is to separate different categories of code like you would organize clothes as you put them away or organize books in a library. Everything has a spot. You know where to look for something because it has a place; it is all organized according to a system. All the books aren't piled in one spot.
So what are the different categories of code? There's graphics code. For keyboard and game controllers, there's input code. There's game logic code -- for how the objects in your game behave. The list goes on. It's up to you on how you want to categorize, but there are a few fundamental categories -- just like fiction and non-fiction. These are data, presentation, and game logic: the data that composes the game, what you hear and see on the screen (how the data is presented), and the code that connects them and makes it all work.
From there you can break it up further. For example: output code can be graphics, sound, or whatever else the user will experience. Data can be image files, binary files, game scripts, and so on -- this is also the code that manages loading the data and handling resources. Game logic can be broken up into AI, player movement, physics, etc.
You want to separate these three basic categories. You don't want game data or game logic in your rendering code. Your rendering code should just be that: rendering code. Keep it only for drawing lines, sprites, whatever. Don't have it access any game data or logic. This part can be tricky, but do your best. You'll get better with practice.
A good place to start is to organize your code into files. Have a file convention for where things are stored. Maybe put your graphics code in a file called "graphics". It should hold all the graphics methods that you use for your game. If the file ever becomes big and cumbersome, split it into two files (based on another category, like fonts and other graphics), and throw them in a folder called "graphics". This is just an example. Use whatever makes sense for you.
On the other end of the spectrum you have the data end. A map manager is an example -- code that loads the levels and sets everything up. This can be more complicated, particularly the "set everything up" part. For example, I create a method named Map::load(). This method will load the map into memory, create the game objects (enemies, items, etc.), and set up defaults (like the player starting position), and reset values like the HP and score. But the values are somewhere else in the code. Should the map code directly access these values? Should Map::load() have access to the score variable? If the map code starts directly modifying globals like these then it becomes less reusable.
This already sounds like a headache. This is way too complicated. The map code should not be responsible for handling all of this. It should only load the map and allow me to access properties of the map, such as tile data. The setup code can be put either before or after the call to Map::load(). If you still need the method to access the outside values, use callback functions. I would like to go into more detail on callback functions, but that is for another article. In the meantime, read up on them.
As you make your code reusable, ask yourself if the code can run on its own or whether it depends on some other code. Some code needs to depend on other code. Critical parts of your game need to use graphics and sound code. But the graphics and sound code shouldn't need your game code to work. If you find otherwise, pull your game code out and put it where it belongs.
Here's a good test. Write a test file that only uses the graphics module (or map module, or whatever). Can you use it without providing excessive data? Can you load and draw a sprite without telling the graphics module about how much HP that sprite has? Can you load a map without first having to setup global score and object variables? Do you need to modify the module to make it work for your simple test? If you answer yes to any of these questions, then you may need to break some things out. The goal of your module should be something simple: to draw sprites, to load and manage map data, to load and play sounds, whatever. Make your module as simple as possible to use. Write method names that are intuitive, something you could guess if you forget. Your module should work with providing as little data as possible.
As you do this, I predict that your project will be more fun to work on. You'll be less stressed and frustrated. You'll be more motivated. When things are easy, it's easy to be motivated. When your code is well structured good things happen. Things make more sense. Bugs are easier to track down. You win the lottery. You know, awesome stuff.
An article written by Joe King
Platform Games 101 - A Jump and Run Game Article for the 6 Year Old in All of Us - Part 3
Written by Richard Eric M. Lope (November, 2012)
III. A digression in Framerate Independence aka "Delta-Time"
Introduction
The first time I've heard the word "delta" was when I was a little tot
watching a movie called "Delta Force" (Hell yeah! Chuck Norris FTW!).
The second time was my physics class (which I didn't really care about
since I was busy chasing girls at that time. :*) ). But I do remember
that "delta" means "change in quantity". ie. DeltaV is Change in Velocity.
The third time was when I started coding demos (Mono and Disco comes to
mind ). Demos in general don't need controls like a game does and you'd
want to pump as many frames per second as you can when coding them. But
because demos tend to be calculation and GFX heavy, some computers won't
run them at at full speed. So we do what you call [i]"frame-skipping"[/i]
which involves delta-time.
Before you send me an email telling me that I'm writing an article for
platform games, I should give you a preamble that this is still part
of the platforming series. I'm writing about delta timing because this
concept would be integral to our game engine later on.
So why the dt article? Because without some form frame control, any frame
dependent game can run from like 10 FPS on a slow computer or 1000 FPS on a
fast one and that would make your game unplayable unless you're on the right
computer.
Gone are the days of DOS where we could limit the FPS (Frames Per Second)
of our games at a nice 60 FPS by calling WAIT 3DAh, 8h. We now have computers
that will never wait for vertical retrace no matter how you try to coerce
the card to force vsych. My two laptops won't accept OpenGL code to force
synching no matter what I do. I tried it from GLFW, FB to SDL without success.
So I just limit my frames to 60 FPS by calling this code:
do : loop until (timer - time_start) >= (1/60.0)
time_start = timer
It worked. However, there are two big issues with this technique.
-
Unless you put a "sleep" in between the loop, you're looking at 100% CPU
usage for your game. If, however you put a "sleep" inside the loop,
your game would likely run below 60 FPS.
-
Your game wastes a lot of cycles doing nothing on a fast enough computer.
In the essence, this system is just not elegant and a bad the way to
control frames in modern game programming.
The Dt System
The most important concept in framerate independence is the [i]"dt system"[/i]. Dt
means "delta-time" or the "change in time" (in seconds). Dt is the time elapsed
between two frames. ie:
Complete code (means that you can cut and paste, compile then run):
dim as single dt
dim as single LastTime = Timer
dim as single CurrentTime = Timer
dim as single SecondsElapsed = 0
dim as single StartTime = Timer
do
CurrentTime = Timer
dt = CurrentTime - LastTime
LastTime = CurrentTime
SecondsElapsed += dt
Locate 1,1
Print "CurrentTime = " & CurrentTime
Print "dt = " & dt
Print "Seconds Elapsed via dt = " & SecondsElapsed
Print "Seconds Elapsed via Timer = " & CurrentTime - StartTime
loop until Inkey <> ""
The sharp minded among you would notice that dt is added to SecondsElapsed
and that SecondsElapsed is equal to the total time (in seconds) our nifty little
demo ran. This is the basis of delta-timing. You see, the faster our loop runs
the smaller the dt (speed is inversely proportional to dt). So no matter how
fast our loop executes dt would compensate by becoming smaller and smaller.
The number of seconds elapsed in a fast or a slow computer would always be the
same. You can say that the above code is "framerate independent".
So how do we use dt to make our games run at the same speed on different
computers then? First, I want to give you a game situation.
Say your game runs at a sloooooooow 10 FPS (simple example).
A 10 FPS game runs at 1/10th of a second per frame. Therefore, your game loop
completes 10 cycles every 1 second. Since Dt is the change in time the loop
completes, our dt value would be 1/10 or 0.1 second. At 1 second, our total dt
values add up to 0.1 * 10 which is equal to 1. Some numbers...
FPS Loop TIME DT
10 FPS -> 1/10s -> 0.1 ( 1/10.0 ) -> 0.1 * 10 = 1
50 FPS -> 1/50s -> 0.02 ( 1/50.0 ) -> 0.02 * 50 = 1
60 FPS -> 1/60s -> 0.0167 ( 1/60.0 ) -> 0.0167 * 60 = 1
100 FPS -> 1/60s -> 0.01 ( 1/100.0) -> 0.01 * 100 = 1
See the relationship yet? Tip: "Sum of dt per second is equal to 1" ;*)
Using Dt to Move Objects
With frame-limited games we were used to fixed units. So, an object with a speed of 1 will move 1 pixel per frame and with 60 FPS an object with a
speed of 1 would move 60 units per second.
With delta-timing we base our units in pixels per second. That is, if we
want to move an object 60 units a second no matter how much FPS we get, we will
give it a speed of 60.
At Speed = 60
FPS dt FPS * dt * Speed Distance moved in Pixels
10 -> 0.1 -> 10 * 0.1 * 60 = 60
50 -> 0.02 -> 50 * 0.02 * 60 = 60
60 -> 0.0167 -> 60 * 0.0167 * 60 = 60
100 -> 0.01 -> 100 * 0.01 * 60 = 60
I believe the above table says it all. "Same speed regardless of framerate".
Try this little demo:
Deltatime.zip
Did you try the on-screen instructions? I bet you did and noticed that when we drag
the window, the simulation skips by a large amount relative to time. This is one of
the biggest problems with simple delta-time, the larger the timestep (dt), which
means your engine runs slower than expected, the less accurate the simulation. By
dragging the window in our simulation, you force the timestep to "accumulate" in
some big value and you will see the result as "jumping" of positions and collision
breakdown. This is actually how "frame-skipping" in emulators work.
So how do we "fix" it? Easy, just limit your dt to a maximum value equal to your fixed
timestep (1/60 for 60 FPS).
CurrentTime = Timer
dt = CurrentTime - LastTime
LastTime = CurrentTime
if( dt > FIXED_TIME_STEP ) then dt = FIXED_TIME_STEP '' This is the fix
So if your 60 FPS game for some reason (like a sloooow computer) runs at 30 FPS, your dt
would be capped at 1/60. The effect of this is slowdown in your game when the FPS drops
below 60, but I'd rather have slowdowns instead of simulation breakdown.
Now that we know how delta-timing works, it's time for a little example:
Linear movement:
DeltatimeDtCapped.zip
constructor Ball()
x = rnd * SCREEN_WIDTH
y = rnd * SCREEN_HEIGHT
dim as single a = (rnd * 360) * PI / 180
Speed = 80 + rnd * 180
Dx = cos(a) * Speed
Dy = sin(a) * Speed
End Constructor
sub Ball.Update( byval dt as single )
X += Dx * dt '' scale our movement by how much time
Y += Dy * dt '' has elapsed since last update
'' bounce around if we hit a wall
if( X < 0 ) then Dx = -Dx
if( X > SCREEN_WIDTH ) then Dx = -Dx
if( Y < 0 ) then Dy = -Dy
if( Y > SCREEN_HEIGHT ) then Dy = -Dy
End Sub
As you can see, we just pass our dt value to our update function and do the
dt calculations as usual.
X += Dx * dt '' scale our movement by how much time
Y += Dy * dt '' has elapsed since last update
Accelerated movement:
DeltatimeAcceleration.zip
constructor Ball()
x = rnd * SCREEN_WIDTH
y = rnd * SCREEN_HEIGHT
dim as single a = (rnd * 360) * PI / 180
Speed = 0
DirX = cos(a) '' save direction
DirY = sin(a)
End Constructor
sub Ball.Update( byval dt as single )
Speed += ACCELERATION * dt '' accelerate by dt amount every frame
if Speed > 180 then Speed = 180 '' limit speed or we go waaay fast
Dx = DirX * Speed '' Calculate direction
Dy = DirY * Speed '' No need to do dt here
X += Dx * dt '' scale our movement by how much time
Y += Dy * dt '' has elapsed since last update
'' bounce around if we hit a wall
if( X < 0 ) then Dirx = -Dirx
if( X > SCREEN_WIDTH ) then Dirx = -Dirx
if( Y < 0 ) then Diry = -Diry
if( Y > SCREEN_HEIGHT ) then Diry = -Diry
End Sub
With acceleration, our dt calculation is a little but complicated. Instead of
multiplying speed (Dx and Dy) by dt, we multiply Acceleration by dt and add it to Speed.
It may be a little hard to visualize, but try to think about it and it would
eventually make sense. One rule I always employ is: "if you have to add or subtract,
chances are, you need to use dt".
Rotations can be done the same way as the linear or accelerated movement.
Angle += RotationSpeed * dt
Okay, so we have a system that would run at a constant speed on any framerate and we have a great
way to do our game or physics simulation right? Wrong! I kinda lied about dt being the fix-all-
system regarding framerate independence. It may work just fine with simple games, but some
calculation-heavy games tend to breakdown on large dt values and sometimes even on small dt values.
I've experienced on this when writing a delta-time based platform engine that worked quite well on FPS
below 400. But when I tried it on a very fast machine at my wife's workplace, the collision
didn't work quite well (very jittery). Fortunately, the guy who made TinyPTC came to the rescue.
Enter the Gaffer (Fix your darn timestep!)
This system is based on this article made by Gaffer (so I won't explain all the details of the technique):
http://gafferongames.com/game-physics/fix-your-timestep/
The gist of the article is about "decoupling" your game physics from your display by using a timestep
"accumulator". This means that your game logic and physics run at a different speed than your display.
So your display may run at an absurdly fast ~1000 FPS, but your physics logic would always run on a
set timestep. By making your physics run at a fixed timestep, say 60 FPS, you will have more control
over your physics and can predict the outcome of your logic. Your display rate could vary as low or as
high as it want, but the logic would still run at a constant speed. Now this is what I call true framerate
independence!
OT: Whoaa! I just felt an Earthquake!
Iloilo, Philippines, (11/14/12), 1:23 PM while watching Cinema Klasika on GMAnews TV.
Deltatiming using Accumulator: DeltatimeAccumulator.zip
The accumulator system is fine, but why stop there?
Deltatiming using Accumulator with Interpolaton: DeltatimeAccumulatorInterpolation.zip
You may have noticed the fact that I did not limit my dt when its value is greater than FIXED_TIME_STEP.
This is because the system Gaffer thought of is so good it could undersample or oversample depending on
the speed of the simulation. Of course it would still jitter on really slow machines so you may want to
implement a dt limiter if you want. It really depends what you want as a bitter pill, "jumping" (no dt limit)
or "slowdowns" (dt is limited to FIXED_TIME_STEP) when FPS gets below FIXED_TIME_STEP. I personally use
the dt limiter since my games tend to be arcade games and I'd rather have slowdowns than position jumps.
Getting your player object get hit by a bullet that miraculously teleports from one point to another in a
single frame is a lot more frustrating than getting it hit by a slowing down bullet.
However, if you still see jitters when using the interpolated version of the dt system on a fast enough
computer, chances are that's a rounding off error. You can easily fix that by using doubles instead of
singles (floats) in your delta-time calculations.
Now for something you would never expect in a delta-time article...
The Union (Combining Deltatiming with Frame Limited Physics)
Yes, you read it right. I've developed a way to use timestepping in Frame limited games. This system allows
you to code in a frame-based system while using delta timing. This is a good system to port games that
run on a frame-limited basis (Nintendo DS games are still frame-limited). How do we do it then?
First let's look at how the Gaffer system works (without the interpolation part):
FIXED_TIME_STEP = 1/60.0
CurrentTime = Timer
dt = CurrentTime - LastTime
LastTime = CurrentTime
Accumulator += dt '' Add accumulator
'' As long as accumulator gets above or equal 1/60 we update by dt = 1/60
while( Accumulator >= FIXED_TIME_STEP )
for i as integer = 0 to ubound(balls)
Balls(i).Update( FIXED_TIME_STEP ) '' Update ball at fixed timesetep (1/60)
next
Accumulator -= FIXED_TIME_STEP '' decrease accumulator
Wend
Do you see the fact that Balls(i).Update( FIXED_TIME_STEP ) updates at a constant timestep value (FIXED_TIME_STEP)?
Do you also see that at 60 FPS, a ball having a velocity of 1 would move 1 unit in 1 second if dt = FIXED_TIME_STEP?
ie: 60 * 1 * 1/60 = 1.
Do you also see that at 60 FPS, a ball having a velocity of 1 would move 60 units in 1 second if dt = 1?
ie: 60 * 1 * 1 = 60
I bet you already see the relationship and could make the code to marry frame limited games with delta timing.
However in case you still don't...
Assume we run at 60 FPS (like if we forced vsynch at 60 Hz) so at 1 second with a speed of 1 we move 60 units:
Complete code:
cls
const as single FIXED_TIME_STEP = 1/60.0
const as single DeltaTimeSpeed = 60.0 '' 1 second speed for 1 unit per frame
const as single FrameLimitedSpeed = 1.0
dim as integer Frame = 0
dim as single XFrameLimited = 0
dim as single XFixedTimeStep = 0
Do
Frame += 1
XFixedTimeStep += DeltaTimeSpeed * FIXED_TIME_STEP
XFrameLimited += FrameLimitedSpeed
locate 1,1
print "XFixedTimeStep = " & XFixedTimeStep
print "XFrameLimited = " & XFrameLimited
sleep 10,1
Loop until Frame >= 200
sleep
There it is. I hope that the above code explains it well.
And Since...
XFixedTimeStep += DeltaTimeSpeed * FIXED_TIME_STEP
XFrameLimited += FrameLimitedSpeed
Are virtually the same, we could substitute one for the other. Here's our ball demo
With the new "united" system:
DeltatimeFrameBased.zip
This works very well and you get your physics free of dt. In fact, you can also do
"interpolation" with this system if you really want it.
When to use this system is up to you. Most of my games are SHMUPS (Shoot Em Up/Space Shooter)
where "replays" are almost always a must. Since the way I save replays are framebased, you could
only imagine how large the replay file would eat memory at 500 FPS instead of 60.
Every 10 Minute of play at 4 bytes a frame:
60 FPS * 60 Sec/Min * 10 MinutesPlayed * 4 Bytes = 144000 bytes
500 FPS * 60 Sec/Min * 10 MinutesPlayed * 4 Bytes = 1200000 bytes
So you can just imagine how big our replay file when you play for for 30 minutes.
Here are some of my games with a replay system:
Frantic Journey RX: http://rel.phatcode.net/index.php?action=contents&item=FJ-RX
Space Impakto DS (This is in C++, but the replay system only use 1 byte per frame): http://rel.phatcode.net/index.php?action=contents&item=Space-Impakto-DS
Then again, there's nothing stopping you from doing your game physics with the interpolated system
while doing your replays frame-based. In fact, you can use any of the dt systems along with each other.
Imagine this: Your player object use an interpolated system, your bullets use the simple dt system
and your replay system use the framebased system in one single engine. But that would
be kind of mental.
Here's an example of using all the different systems in one gameploop. As you can see they all update
with the same timestep, so you can use any system you like or of all of them at once.
DeltatimeComparison.zip
Cool Things You Can Do With Timestepping
There are some nice things you can do with delta time. With the way the dt system works, it's very easy
to implement these game and physics related things:
1. Pause
Setting your dt to 0 pauses everything.
CurrentTime = Timer
dt = CurrentTime - LastTime
LastTime = CurrentTime
dt = 0
2. Slowdowns
Dividing your dt by a value slows down everything (aka Matrix Bullet-Time).
The code below makes the objects move at 1/2 speed.
CurrentTime = Timer
dt = CurrentTime - LastTime
LastTime = CurrentTime
dt /= 2
3. Speedup
As with slowing down, scaling your dt by a value
speeds up everything (Vampire movement in Twilight).
The code below makes the objects move at 2x speed.
CurrentTime = Timer
dt = CurrentTime - LastTime
LastTime = CurrentTime
dt *= 2
Sample here: DeltaTimeLaser.zip
Note that I'm using Easy GL2D's special function to return the dt which makes
things much more readable. I'll also use Framebased delta timing for our
Platforming tutorial from now on so that it would be easy to understand.
A good exercise would be to code a demo with different objects running on different
timesteps simultaneously. I'll let you do that yourself. :*)
Thanks:
Michael H4tt3n Nissen for the circle code and the tip for using doubles
Fotoncat for some proofreading
Copyright
Richard Eric M. Lope (http://rel.phatcode.net)
11/15/2012