How do I speed a game up as it progresses?

BlitzMax Forums/BlitzMax Beginners Area/How do I speed a game up as it progresses?

brian70(Posted 2016) [#1]
I'm currently dabbling with BlitzMax (used Blitz Plus when I had Windows, now have the free BM for Linux).

Starting with a simple scroller (player moves left/right and tries to avoid obstacles, see how long they last).

I'd like it to get faster as it goes along. I thought originally of changing the increment in pixels that obstacles move, or having a routine that increments a counter each frame and update the obstacles every certain number of frames (ie, start by moving them every 10 frames then every 8 until it gets quicker).

Is there a more well used or proper way to increase the speed of a game as it progresses? This would also apply to space invader type game where they get quicker as more aliens are destroyed.

Thanks in advance


H&K(Posted 2016) [#2]
Stupid as this may sound you are coming at this the wrong way, Program first the "fastest" you want it to be. Then figure out how to make it slower.


Derron(Posted 2016) [#3]
- update logic at a constant speed (eg. with 120 hertz)
- render your game at the speed you wish (eg. at screen refresh rate)
- have a fixed entity velocity
- modify the velocity by a gameSpeedFactor (eg. 1.0 for "default speed")

Within update-logic:
- check for "inbetween steps": so for the steps of a movement within "lastUpdateX" and "currentUpdateX" (so you do not miss "hits")

Within render:
- render at "inbetween steps" (you know when your next render-frame will come, when the last was - and at which percentage of "inbetween" you are at the current render frame) - so you might have "lastX + progress * (dX)"


Short: the speed increase is then done by a "gameSpeedFactor" - which is some kind of "global" for all entities in the game scene (of course GUI/interface elements are excluded - same for effects or other realtime thingies).


bye
Ron


dw817(Posted 2016) [#4]
Hi Brian. Sometimes examining and tweaking source code is the best way to see a solution to a problem. Here is a quick game I made with you in mind and what you asked for - you wanted a game to go faster and faster the longer it played.

The easiest way to do this would be to control FLIP(). Sure you can increase the speed of the moving objects and stuff, but as you want EVERYTHING in the game to increase speed, you could do it a lot easier simply by controlling how often FLIP() is called in your program.

Here is the code, just under 100-lines.






Derron(Posted 2016) [#5]
dw817:
The easiest way to do this would be to control FLIP(). Sure you can increase the speed of the moving objects and stuff, but as you want EVERYTHING in the game to increase speed, you could do it a lot easier simply by controlling how often FLIP() is called in your program.


Are you seriously suggesting to render more frames per second to have a faster game "world"?

Hope I just understood your suggestion in a wrong way...



bye
Ron


Bobysait(Posted 2016) [#6]
@Derron

fl:-10 ' tricky FLIP, the higher LV is, the less often it is called
If fl<0 ' thus, less calls to FLIP mean a faster running game
Flip
fl=lv/100
EndIf



I think you understood exactly what it is about.

There is no need to draw images that are not rendered on the loop, tou're just asking the CPU to burn for nothing.

Keep the flip synchronized, the only thing you need to control the scrolling is a global velocity factor applied on objects and background.

One good thing to use is delta timing to update objects according to the time elapsed between current time and last loop time.
Then apply the factor to the time and you'll get a global coef for anything that moves.

// Init before the loop
int st = millisecs()-20;
int mt = 0;
int lt = 0;
float dt = 0.0f;
float coef = 1.0f;

float Inc_Velocity = 0.01f;
float Cur_Velocity = 1.0f;

while(!Exit_Condition)
{    
    // Update the time based movement.
    lt = mt; // last loop time
    mt = millisecs()-st; // current time
    dt = (float)(mt-lt); // elapsed time (Delta Time = time between two loops)
    coef = 60.0f * dt /1000.0f; // loop coeficient (based on a 60 FPS rate so the coef at 60 fps is 1.0)
    
    // increase velocity Time Based
    Cur_Velocity += Inc_Velocity * coef;
    
    // move your Scrolling stuff according to realtime velocity
    BackGroundStuffDir += Cur_Velocity * coef;
    
    /* [...] */
    
}




dw817(Posted 2016) [#7]
Derron, decreasing Flip() is one way to speed up everything. I don't do this in my professional code outside of debugging as it's too jerky for what I want.

Instead I use real numbers and percentages to increase all graphic elements and information around. I was just pointing out this is a quick and dirty way to get a program to run faster over a period of time, which is exactly what Brian asked for.

Also useful if your code runs too slow for some reason even at maximum speed. You can cut down on Flip() usage and that will greatly speed everything up.

I used this method back on S2 because my computer was pretty slow then. I called it Rapid Rabbit and you could tell PEEKEVENT() (the equivalent of Flip() ) was being skipped every other frame because a small running rabbit appeared in the top-right-hand corner for reference.

You invoked it by hitting NUM-LOCK PLUS and again to disable it.

While my main engine today is under 20% CPU usage, I will leave Rapid Rabbit available in there if someone wants to activate it, if nothing else to easily blur past everything when they are debugging their world code.


Derron(Posted 2016) [#8]
Dunno why you are talking about "professional code" ... relying on the render capability of a computer to have a certain "game world speed" is ... ahh ... I would call it "lacking on far-sight".

Like I described in #3 already - which is similar to what Bobysait in #6 suggested, you just adjust the velocity of the objects.

If you want to keep the velocity constant, you could also increase the frequency of physical/logical world updates (I would prefer the "gameSpeedFactor"-approach). Of course you need to decouple Logic and rendering first (which makes it independend of potential "flip"-limitations).

Just check the various "delta timing" discussions here on the board.


Loop (until GameExit / Key_Escape / ...):
- UpdateWorld() as much as needed for that "cycle"
- If enough cycle-time available: RenderWorld() 1x for that cycle
- delay()/sleep for the rest of the cycle-time
(in my game I adjusted it to have physic and render calls limited - so eg 60 PhysicUpdates/s and 30 Render/s - keeps CPU usage low)


UpdateWorld() is there to move objects, to check for colliding entities, to adjust gamestates, send network packets, handle input ...

RenderWorld() is doing nothing than representing the current state of the world ... no (logical) movement or other things are done.
Now the exception: you _could_ do some kind of movement: if you render more often than "UpdateWorld()" is called (because your computer is faster and power consumption is of no matter for you) you have to adjust offset entities: lastX + (x-lastX) * cycleProgress. So the nearer the "next update" is, the lower the distance of the entity to the "x"-value of the update call.


While Bobysait now suggested to use some kind of "gameSpeedFactor" (in his case the velocity).
Per Update your entity moves then:

x :+ dx * deltaTime * gameSpeedFactor
x ... position on x
dx ... speed on x axis (the scalar value/magnitude of "velocity" - so no "direction" described within)
deltaTime ... fraction of a second
gameSpeedFactor ... world speed modifier

If you eg. define your world to update 50 times per second, your deltaTime will be 1.0/50 seconds (20ms -> 0.02s).
You then define your "dx" no longer "frame depending" (2px per frame) but in "px per second". (or you even get more flexible by defining it in "% of screenwidth" or something more independent).

To avoid "jittering" (sometimes it is updated 19ms later, sometimes 21ms because of some inaccuracies or hickups) you then offset the entities in your render-call by the amount of time passed then ...



So another hint: before you are now replying with "short example code so people could easily try out":

shortening
local a:int = 5, b:int = 5
print (a+b)


with
print 10

is - while having a similar result - not some code others benefit of.



Seriously: _if_ you really persist on using your "flip" : check at the begin of your loop if you are doing a "flip" in this cycle, and if not, do not do "DrawText" or other things. They wont be seen so save the processing. And like told in another thread: depending on the graphics engine (DX, OGL) the heavy load is done by flip() - or already the Draw-Commands.

BTW: I am going partially d'accord with one of your phrases: that skipping Flips() helps on slower computers.
Maybe your code would look more "physics / render separating" when not doing the Draw-things regardless of skipped flips or not (because I am assuming, that you mean the right thing, but your code is expressing/first-glance-showing the opposite). Nonetheless your code is adding constant values to the entities - regardless of potential cpu hickups ...



bye
Ron


dw817(Posted 2016) [#9]
It works and my main code works with percentiles. There are no hiccups, I'm good with that, Ron.


Bobysait(Posted 2016) [#10]
Nobody ask you to use a different technic, you're free to make what you want, but as this topic is not your's, let us explain to others (and essentially to brian70 who asked for it) why your solution is not that reliable, or at least, far from the easiest and robust way to do it.
And working or not, it's kind of a leak to draw stuff that are not rendered or used.

At lest, insert this before on top on your loop
local enableDraw:byte = ((fl-10)<0);


And add a simple test before drawing calls
if enableDraw then DrawImage [...]
if enableDraw then DrawText [...]


Then it will start to look like something almost good.
At least you wont use CPU usage for nothing.


Kryzon(Posted 2016) [#11]
But he's a professional


Bobysait(Posted 2016) [#12]
brian10 :

Is there a more well used or proper way to increase the speed of a game as it progresses



dw817 :

I was just pointing out this is a quick and dirty way to get a program to run faster over a period of time, which is exactly what Brian asked for.



"more well used or proper way" Vs "quick and dirty way" ...

I think someone, somewhere, maybe missed something.
But yeah, we are wrong when we want to make things clear.

This guy ... tsss ... you know ...


dw817(Posted 2016) [#13]
Brian, as they mentioned, you can use differential speeds for your elements. I can recode this if you like using that method. No-one else seems to be submitting full source examples here.

And yes, Brian, I know about that guy. But you shouldn't. Let's keep judgement of personal characters out of the conversation. Already had one topic locked for being derailed.

Focus instead on a game engine that speeds up over time - the author's request.


Bobysait(Posted 2016) [#14]
Sometimes it's just missing a private message section to answer this kind of post.



No-one else seems to be submitting full source examples here.



For large sources, there is the code archive section. it's more accessible to users so they don't need to search the forum for a lost code at some random section.
Regarding the technical aspect of brian's question, it has been answered without the needs for full sources, so, if brian feels the need to get a more complete explained stuff, he'll ask it himself. Then it's up to you to stop judging the way the forum and its members work. You want to feed sources, "just do it", we won't blame you for that, but don't judge us in return.
You don't need to mention it on each topic and you probably don't see it this way, but :
- Every time you let suppose you're the only one who post stuff, you're being disrespectul to us.
We, old members, posted lots of full source codes along the years. You could at least stop saying (if not thinking) "you" post source code, while we don't (because actually, we do ! A lot !).

Then, most of the last questions posted those days have been answered long time ago by members who also posted full documented sources included. Most of the time, it's just a matter of "Searching the forum" before posting, but as long as they didn't post it in code archive, it's almost the same that if it was lost in the abyss.
There is a huge archive database all along the forum, it has been built by members along the years (like me, and many, many, many other members) and it answers so many questions that when you post something we already posted and say you post sources, we just want to bash you ... we also want to slap you ... sometimes.

So, you, for sure, don't see yourself as a bad guy (so don't we), but you really answer many times like you think we are stupid.
I just say it while thinking it's not intended, and give you the benefit of doubt.
Try to consider this ... and just imagine we can't all be wrong while we are more and more to think you're not behaving very well on the forum.
Whatever it probably is not very clear but, we don't want to fight with you or show you you're useless or something else ... it's just that you probably don't see that you're a bit
passive aggressive / sarcastic on your posts and that's what make things go worse and worse. (we are just humans ... we almost always answers with some kind of "an eye for an eye" law)


dw817(Posted 2016) [#15]
If all sources for all questions were posted, there would be no questions. As questions do crop up and appear, I can't help but post a good working example to explain the mechanics.

I'm human too. and yes - I see you guys out there. Sometimes you do just throw out a gnawed on bone and wonder why the person asking a question doesn't return with THANK YOU - no, they just vanish, and you never see them again. Discouraged I imagine.

I will always answer questions with sourcecode if I can, that's my nature. And - not now, but an hour from now, I'll go to repost the above using percentiles to increase speed.

It will be smoother animation that way, and the code can be examined to see how it's done. Copy it, tweak it, learn from it.


dw817(Posted 2016) [#16]
Hmm ... Ok, here is the new code as promised. And yes, Bobysait. It is very smooth motion. Uses about 2% of my CPU here so it's good tight coding.



Brian, once you transfer this code to BlitzMAX, press CTRL-F and FIND all occurrences of "lv#" (el vee pound) Abbreviation for LEVEL. See how they are used. So if you use a real variable (one that can contain a decimal point) like this which increases a tiny bit over time, everything it is associated with will neatly start to accelerate.

Hope This Helps !


Matty(Posted 2016) [#17]
If you use delta timing all you need to do is increase the value for delta when you want to increase the speed.

Delta timing involves multiplying the speed objects move by a floating point value.

Eg.

X = X + speed

Becomes

X = X + speed * delta

Do this for all motion in the game and controlling speed becomes dead easy.


Derron(Posted 2016) [#18]
@matty

Delza is a value describing the change of a aspect... so dx = x2-x1.

That is why a thing adjusting game world physics (speed, maybe gravity,...) should be called gameSpeedFactor (or similar) but not delta...as delta already describes the change from "then to now" ...it is...an absolute value, not a relative percentage (you call this maybe an delta factor then ... or frameProgress).

Dw's sample is still a crude mix of draw and logic...which makes the code maybe shorter...but harder to understand (in terms of logic-flow).


There is no need to post sample code...as the forum search for deltatime already offers answers (the principle of adjusting values with some kind of modificator - you just add the "game speed"-modificator next to the deltaTimeFactor). It is up to the OP to accept deltatiming (and the multiplied speedAdjustmentFactor) as potential answer and to research a bit further on its own. If not...you end up answering very individual questions ("how to move a spaceship in a curvy way" vs "how to move an object on a curve path"... the second one might lead to algorithms containing bezier-curves with some tracking/control points).


Nonetheless...we already described a working "logic"... and the OP should request "code" if he really needed code then... this helps keeping threads clean and the content easy to follow. You know have multiple "samples" posted...and the OP even did not respond...and I doubt that this is based on "so many replies, so few working example codes". People who really want to code...enjoy being included in an discussion rather than copy pasting others work. And I would prefer helping people interested in coding.


Back to delta: why is this useful?
It allows to have a constantly and "smooth" increasement of the worldSpeed-Factor (if you want to increase in "x per second"). If you increase per "each run 100 meters" you of course do it differently and wont need deltaTime(Factor).


Bye
Ron


brian70(Posted 2016) [#19]
Thank you all for the replies.
There was a lot to read through and try to understand (hence the delay in replying).

Regarding a search for detlatime - I didn't know that was the term I was looking for, and had spent some time trying to just search for variations on "speed up a game".

I didn't know I specifically needed to ask for code example. I appreciate for people who know BM/game programming well it is probably enough to say "you just need to do x, y and z" but I haven't quite reached that stage yet.

That was also the reason I posted in the beginners area, as I've only just started using BlitzMax and needed some pointers to get off the ground.

@dw817, thanks for the great example, I will be going through the code and seeing how that works.


Thanks again


dw817(Posted 2016) [#20]
You are very welcome Brian. *Grin* I learned to code from examples myself, mostly David H Ahl a video game pioneer. Sometimes explanations like the guys above - well, don't work for =ME= And maybe there's something wrong with me if that is the case.

It's like someone giving me verbal commands to do some housework. I was never very good with following spoken instructions and I often told them I didn't understand what they wanted, and could they show me, please ?

So then the same person picks up a broom and sweeps for a few seconds to show me how it's done, and then goes to the other items and demonstrates - for just a few seconds - what needs to be done.

Then I have a much better idea rather than verbal commands. The same is true with programming for me.