Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / Need Help making a non-blocking wait command

Author
Message
SquareMan
14
Years of Service
User Offline
Joined: 26th Dec 2011
Location:
Posted: 27th Dec 2011 06:43
so I'm making a Tetris like game in DBPro and I ran into a problem, I need to find a way to make a wait command that does not block the flow of the program so i can control when to make the block automatically fall to the next block level without blocking the player from moving the block left and right and rotating it. Any help will be appreciated.
Daniel TGC
Retired Moderator
19
Years of Service
User Offline
Joined: 19th Feb 2007
Location: TGC
Posted: 28th Dec 2011 15:46 Edited at: 28th Dec 2011 15:46
Just just need a timer.

Start timer, when it expires allow and event to happen, reset the timer and repeat. It won't prevent anything else from happening unless you tell it too.

for example

time = timer() + 1000
if timer() => time then (trigger event)

This code basically makes the game wait 1 second before doing something, while keeping any game loops running.
MrValentine
AGK Backer
15
Years of Service
User Offline
Joined: 5th Dec 2010
Playing: FFVII
Posted: 28th Dec 2011 17:21
I thought you could use the sleep command... I was thinking about this a week ago...

Millenium7
21
Years of Service
User Offline
Joined: 13th Dec 2004
Location:
Posted: 28th Dec 2011 17:57
'always' better to write your own code when it comes to timing and pauses. And it's always better to write movement in distance over time rather than distance per loop. Master these 2 principles and you have a quality product

Oh and the timer() command is not 100% reliable, it's a hell of a lot better than not using it, but preferably get matrix1util's and use the hitimer() command. The reason is timer() is linked to [insert something that is related to the program itself] whereas hitimer() calls the cpu and will remain accurate all the time. Timer() can be out by a few ms every second
Mobiius
Valued Member
23
Years of Service
User Offline
Joined: 27th Feb 2003
Location: The Cold North
Posted: 29th Dec 2011 08:35
Quote: "I thought you could use the sleep command"

Sleep pauses execution, so no further code would be executed until the sleep was over. (Same goes for wait)

Quote: "Oh and the timer() command is not 100% reliable"

It's reliable enough. Who's going to notice a few ms here and there? I know I don't.

I'd do what Daniel suggests. It's simple and works. But I believe IanM has some sort of trigger command in one of his many plugins. You can setup a trigger event to call a function every x milliseconds.

Just don't ask me what it is... (Paging IanM! lol)

My signature is NOT a moderator plaything! Stop changing it!
Millenium7
21
Years of Service
User Offline
Joined: 13th Dec 2004
Location:
Posted: 29th Dec 2011 12:51
Quote: "It's reliable enough. Who's going to notice a few ms here and there? I know I don't"


you would notice it in multiplayer, or if you payed any sort of attention to variance in framerate. Anything you control with timer() will run 'faster' at a lower fps. The difference is quite profound when comparing say 10fps to 120fps, and noticable when there are dips in your framerate. If you are controlling player movement via timer() then each and every call means its out just a bit further each time, thus why you'll move slower at a higher framerate.

Depending on your netcode this can cause fairly obvious problems in a multiplayer environment. First of all each players movement speed is different, but if you use server side prediction to smooth out movement and/or prevent cheating, your client's will begin jumping back n forth due to the difference in FPS on machines
Daniel TGC
Retired Moderator
19
Years of Service
User Offline
Joined: 19th Feb 2007
Location: TGC
Posted: 30th Dec 2011 12:48
Given the ping times in the average death match I think lag would cause more time delays then a simple timer sequence. Over thinking this isn't a great idea. Use the simple timer code. If later on you discover a reason why it can't be used I'd love to hear it. But all of my experiments and projects over the last four years have never suffered because of it.
Dr Tank
17
Years of Service
User Offline
Joined: 1st Apr 2009
Location: Southampton, UK
Posted: 30th Dec 2011 20:16
Quote: "
for example

time = timer() + 1000
if timer() => time then (trigger event)"

I thought that would fail when the timer rolls over but it doesn't! Seems inequalities work different to how i expected with dwords, so it totally works!
MrValentine
AGK Backer
15
Years of Service
User Offline
Joined: 5th Dec 2010
Playing: FFVII
Posted: 30th Dec 2011 20:31
yeah but timer is in my opinion not accurate as it does not exactly go 1 2 3 4 5 6 it goes 1 5 9 14 25 36

if you get me... but perhaps an extra line to check if timer = timer + timeelapsed = timer + 1000 or well basically you check if the timer recorded + 1000 and then check if current timer is above this number... if you get me...

but just my experience with it...

Agent
21
Years of Service
User Offline
Joined: 7th Sep 2004
Location: Sydney, Australia
Posted: 1st Jan 2012 07:37
You're right, TIMER() is not precisely accurate, but it doesn't have to be. When you trigger your movement, you multiply the movement amount by the difference in the current timer from the last timer. That means that even if its out by a few milliseconds, your movement distance will be compensated appropriately.

In other words, if the timer is a few milliseconds late, you move your character slightly further than you would if it were correct, so his overall speed remains constant.

If you have a need to be precisely accurate with your timings, you'll need matrix hitimer(), but I'm with Dan; I can't think of any case where you'd need that sort of accuracy, even in a multiplayer game.

Millenium7
21
Years of Service
User Offline
Joined: 13th Dec 2004
Location:
Posted: 1st Jan 2012 09:54
Quote: "You're right, TIMER() is not precisely accurate, but it doesn't have to be. When you trigger your movement, you multiply the movement amount by the difference in the current timer from the last timer. That means that even if its out by a few milliseconds, your movement distance will be compensated appropriately."


the timer() itself lags behind, not just the calling of it, it will not catch up
please see attached code (requires matrix1utils for use of hitimer command)



maybe it's just me, but a variance of an additional ~7% in movement after a mere 5 seconds is not exactly what i'd call 'professional'

And lets not keep in mind this is not even a recode, this is quite possible the simplest 'fix' you could ever do to any piece of code. Simply go to view-replace and replace all instances of timer() with hitimer(). Done
Grog Grueslayer
Valued Member
21
Years of Service
User Offline
Joined: 30th May 2005
Playing: Green Hell
Posted: 1st Jan 2012 18:11
I seriously doubt anybody will play a game with a stopwatch in hand to make sure everything is timed just right. That's why we always check time the time is equal to or more than the delay we want... if it goes beyond the delay it'll still trigger the event. There are many more factors that may cause a delay other than the TIMER() command itself so why worry?

Burning Feet Man
18
Years of Service
User Offline
Joined: 4th Jan 2008
Location: Sydney, Australia
Posted: 1st Jan 2012 23:19
I know that I'd like to use a sharp knife over a blunt one, if I have the option.

Help build an online DarkBASIC Professional help archive.
DarkBasic Help Wikia
Agent
21
Years of Service
User Offline
Joined: 7th Sep 2004
Location: Sydney, Australia
Posted: 2nd Jan 2012 06:20
It doesn't have to catch up if you compensate for the lag by increasing the move distance based on the discrepancy. This is a basic precept of timer based movement and I'm quite surprised we're talking about this at all.

Millenium7
21
Years of Service
User Offline
Joined: 13th Dec 2004
Location:
Posted: 2nd Jan 2012 15:39 Edited at: 2nd Jan 2012 15:42
Quote: "It doesn't have to catch up if you compensate for the lag by increasing the move distance based on the discrepancy. This is a basic precept of timer based movement and I'm quite surprised we're talking about this at all."

and how are you going to know what the discrepency is? please reread what I wrote, and run the provided code if necessary. The only way you are going to know how far the timer() command is out by, is by using a more accurate timer in the first place!

the code I provided shows 2 spheres moving at a distance based on time elapsed per loop, is framerate independent and theoretically will move exactly the same amount per second. However 1 is controlled by timer() and the other controlled by hitimer(), you'll see the timer() sphere moves at a slightly different speed and is not as consistent or accurate as the hitimer() sphere, especially at varying framerates
Benjamin
23
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 2nd Jan 2012 20:51 Edited at: 2nd Jan 2012 21:58
Just a word of reference: sleep and wait use a technique called busy waiting, whereby the application runs a loop until the specific time has elapsed. This means it will increase the application's primary core (or whole CPU if it's that of a single-core) usage to maximum, wasting system resources, battery power (if using one), and increasing heat. If you need simple blocking functionality call kernel32's Sleep function instead.

Quote: "Timer() can be out by a few ms every second"


In my experience the inaccuracy is not really noticeable enough to be of any concern. As long as you're not losing time (which you aren't) there should be no problem. Of course some cases may require a specific accuracy, but I'm speaking generally.

@Millenium7: Your code is wrong, it samples the timers twice within the same loop, which will result in a loss of time. A properly written routine keeps time just fine:



I see about ~1ms (a small discrepancy caused by the order of sampling, nothing more) difference after 10 seconds. I get the same result after running for a whole minute.



Support a charitable indie game project!
Chris Tate
DBPro Master
17
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 2nd Jan 2012 21:15 Edited at: 2nd Jan 2012 21:20
Three reasonable methods that spring to my mind:

Method 1: As was stated, use the timer function and move according to the amount of lag using the framerate:



Method 2: Use a Matrix1 ticker for each block, and move according to the amount of lag.



Method 3: Deduct the frames passed from a variable countdown.


These vaguely spring to mind and need some work but they should do the trick.

Is lag really likely to disrupt a game of Tetris on a computer in todays multi-core home PC technology age?

Login to post a reply

Server time is: 2026-07-10 03:09:14
Your offset time is: 2026-07-10 03:09:14