Action Script 3. How to prevent lag bugs issues in flash games? - sql

How to prevent lag bugs issues in flash games? For example If game have countdown timer 1 minute and player have to catch that much items that possible.
Here are following lag bugs issues:
If items moving (don't have static position) - that higher lag player
have, that slower items move;
Timer starting count slowly when player have lags (CPU usage 90-100%).
So for example If player without lags can get 100 points, player with slow / bad computer can get 4-6x more, like 400-600.
I think that because It's on client side, but how to move It to server side? Should I insert (and update) countdown time to database? But how to update It on every millisecond?
And how about items position solution? If player have big lags, items moving very very slowly, so easy to click on that, have you any ideas?

Moving the functionality to the server side doesn't solve the problem.
Now if there are many players connected to the server, the server will lag and give those players more time to react.
To make your logic independent from lag, do not base it on the screen update.
Because this assumes a constant time between screen updates (or frames)
Instead, make your logic based on the actual time that passed between frames.
Use getTimer to measure how much time passed between the current and the last frame.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/package.html
Of course, your logic should include calculations for what happens in between frames.

In order to mostly fix speed issues on the client you need to make all your speed related code based on actual time, not frames. For example:
Here is a fairly typical example code used to move an object based on frames:
// speed = pixels per frame
var xSpeed:Number = 5;
var ySpeed:Number = 5;
addEventListener(Event.ENTER_FRAME, update);
function update(e:Event):void {
player.x += xSpeed;
player.y += ySpeed;
}
While this code is simple and good enough for a single client, it is very dependent on the frame rate, and as you know the frame rate is very "elastic" and actual frame rate is heavily influenced by the client CPU speed.
Instead, here is an example where the movement is based on actual elapsed time:
// speed = pixels per second
var xSpeed:Number = 5 * stage.frameRate;
var ySpeed:Number = 5 * stage.frameRate;
var lastTime:int = getTimer();
addEventListener(Event.ENTER_FRAME, update);
function update(e:Event):void {
var currentTime:int = getTimer();
var elapsedSeconds:Number = (currentTime - lastTime) / 1000;
player.x += xSpeed * elapsedSeconds;
player.y += ySpeed * elapsedSeconds;
lastTime = currentTime;
}
The crucial part here is that the current time is tracked using getTimer(), and each update moves the player based on the actual elapsed time, not a fixed amount. I set the xSpeed and ySpeed to 5 * stage.frameRate to illustrate how it can be equivelent to the other example, but you don't have to do it that way. The end result is that the second example would have consistent speed of movement regardless of the actual frame rate.

Related

How can you make the updates/second constant?

As far as I know, love.update and love.draw is called every frame. You can turn vsync off (unlimited calls to love.update) or leave it on (fixed to refresh rate). Since different computers have different refresh rates, you need to be able to support different ups's, otherwise the game will run at different speeds for different computers.
There are 2 solutions I can think of:
Cap UPS.
Run at an arbitrary UPS.
There were a few issues with 2, so I think a constant UPS might be better. My computer's refresh rate is 57Hz so I used that in the code.
function love.update(dt)
t = t + dt
while t >= 1/57 do
t = t - 1/57
--stuff
end
end
The game runs fine if I turn vsync on, but if it's off, then it's slightly jittery and I think it would probably be like that regardless of vsync on other PC's. Is there a way to cap the UPS better or should I just use solution 2?
you need to use the dt in update function,
let's say you have a sprite moving 1 pixel every frame
function love.update(dt)
sprite.x = sprite.x + 1
end
for you with a refresh rate of 57 fps the sprite will move of 57 pixel per second, but others would see it move at say 60 pixel per second
function love.update(dt)
sprite.x = sprite.x + 60*dt
end
now at 57 fps, you call 57 time update in one second and your sprite would move exactly 60 pixel (60*(1/57)*57), and others running at 60fps would also see it moving of 60 pixels (60*(1/60)*60)
using dt you are doing computation time relative, not frame relative discarding the problem altogether
It seems like you know how to set vsync, but here's the code I'm using in love.load() to set it:
love.window.setMode(1, 1, {vsync = false, fullscreen = true})
At the start of my update loop I have the following code:
self.t1 = love.timer.getTime()
This grabs the time at the beginning of the loop and is paired with the following code at the end end of the loop:
self.delta = love.timer.getTime() - self.t1
if self.delta < self.fps then
-- sleep to maintain 60fps
love.timer.sleep(self.fps - self.delta)
end
-- calculate frame rate
self.delta = love.timer.getTime() - self.t1
self.frameRate = 1 / self.delta
If your computer is able to run the update at faster than 60FPS then the game will sleep at the end of the update loop to enforce a constant frame rate. Unfortunately this only caps the frame rate (solution 1 in your post). That being said, this method runs with no jitters (I have tested on multiple Windows machines).
I believe I got this method from this link.
Be careful with vsync since some computer screens can run at different frame-rate (like 60fps, 120fps...). And even with computer screens that run at the same frame-rate, enabling vsync in love2d is a setting that can be overridden by the graphic card settings. So you should always consider using the delta-time (dt). Refer to #nepta answer to know how the delta-time should be used.

Repeating a short sound very fast with CreateJS

Goal
I am trying to create a fast ticking sound in a Cordova app using Createjs.
The ticking sound speed changes based on user settings. At the moment the timing is erratic
Setup
I have an mp3 audio file of a single tick sound that is 50ms long.
A target speed of repetition could be as fast as 10 times per second.
Question
How can I get the sound to play evenly and consistently at that speed?
More Technical Detail
createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED;
createjs.Ticker.framerate = 30;
Cheers for any help
This should be pretty straightforward. I set up a quick fiddle to play a sound a specific amount of times per second. It seems pretty reliable, even when playing at 60fps.
https://jsfiddle.net/lannymcnie/ghjejvq9/
The approach is to just check every Ticker.tick if the amount of time has passed since the last tick sound. The duration is derived by 1000/ticksPerSecond.
// Every tick
var d = new Date().getTime();
if (d > lastTick + 1000/ticksPerSecond) {
createjs.Sound.play("tick");
lastTick = d;
}

Confusion with writing a game loop

I'm working on a 2D video game framework, and I've never written a game loop before. Most frameworks I've ever looked in to seem to implement both a draw and update methods.
For my project I implemented a loop that calls these 2 methods. I noticed with other frameworks, these methods don't always get called alternating. Some frameworks will have update run way more than draw does. Also, most of these types of frameworks will run at 60FPS. I figure I'll need some sort of sleep in here.
My question is, what is the best method for implementing this type of loop? Do I call draw then update, or vice versa? In my case, I'm writing a wrapper around SDL2, so maybe that library requires something to be setup in a certain way?
Here's some "pseudo" code I'm thinking of for the implementation.
loop do
clear_screen
draw
update
sleep(16.milliseconds)
break if window_is_closed
end
Though my project is being written in Crystal-Lang, I'm more looking for a general concept that could be applied to any language.
It depends what you want to achieve. Some games prefer the game logic to run more frequently than the frame rate (I believe Source games do this), for some games you may want the game logic to run less frequently (the only example of this I can think of is the servers of some multiplayer games, quite famously Overwatch).
It's important to consider as well that this is a question of resolution, not speed. A game with logic rate 120 and frame rate 60 is not necessarily running at x2 speed, any time critical operations within the game logic should be done relative to the clock*, not the tic rate, or your game will literally go into slow motion if the frames take too long to render.
I would recommend writing a loop like this:
loop do
time_until_update = (update_interval + time_of_last_update) - current_time
time_until_draw = (draw_interval + time_of_last_draw) - current_time
work_done = false
# Update the game if it's been enough time
if time_until_update <= 0
update
time_of_last_update = current_time
work_done = true
end
# Draw the screen if it's been enough time
if time_until_draw <= 0
clear_screen
draw
time_of_last_draw = current_time
work_done = true
end
# Nothing to do, sleep for the smallest period
if work_done == false
smaller = time_until_update
if time_until_draw < smaller
smaller = time_until_draw
end
sleep_for(smaller)
end
# Leave, maybe
break if window_is_closed
end
You don't want to wait for 16ms every frame otherwise you might end up over-waiting if the frame takes a non-trivial amount of time to complete. The work_done variable is so that we know whether or not the intervals we calculated at the start of the loop are still valid, we may have done 5ms of work, which would throw our sleeping completely off so in that scenario we go back around and calculate fresh values.
* You may want to abstractify the clock, using the clock directly can have some weird effects, for example if you save the game and you save the last time you used a magical power as a clock time, it will instantly come off cooldown when you load the save, as that is now minutes, hours or even days in the past. Similar issues exist with the process being suspended by the operating system.

best way to create a timer for a game

I have a time limiter for a game I am doing, what I am doing right now is using an initial value and deducting one value per frame update. here is the code :
- (void) gameTime {
fullTime = fullTime - 1;
NSLog(#"%i", fullTime);
float xScale = 10 * fullTime / 4000;
//_game.timerGraphic.scaleX = 10;
//[_game.timerGraphic setScaleX:10];
[_game.timerGraphic setScaleX:xScale];
}
now the problem is that timerGraphic is a CCSprite, and when I update the ScaleX it doesnt work unless its a absolute value, is there anyway i can make this smoother and resize the "timer" in a smoother way?
The problem with this sort of approach is that is makes the timer in your app dependent on the frame rate. Cocos2D has some built in mechanisms for dealing with these sorts of issues. In particular, the idea is that each time you load a new frame, you update animation values based on the amount of time elapsed between the previous and current frame. Look at the "Making Things Move" section in this Cocos2D tutorial. It explains how to schedule a selector (i.e., create a timer to fire the -nextFrame: method). This method get passed a dt (delta time) argument that can be used for creating smooth animations.

Bouncing ball not conforming to Conservation of Energy Rule

I am currently busy on writing a small ball physics engine for my programming course in Win32 API and c++. I have finished the GDI backbuffer renderer and the whole GUI (couple of more things to adjust) but i am very near to completion. The only big obstacles that last are ball to ball collision (but i can fix this on my own) but the biggest problem of them all is the bouncing of the balls. What happens is that i throw a ball and it really falls, but once it bounces it will bounce higher than the point were i released it??? the funny thing is, it only happens if below a certain height. This part is the physics code:
(If you need any more code or explanation, please ask, but i would greatly appreciate it if you guys could have a look at my code.)
#void RunPhysics(OPTIONS &o, vector<BALL*> &b)
{
UINT simspeed = o.iSimSpeed;
DOUBLE DT; //Delta T
BOOL bounce; //for playing sound
DT= 1/o.REFRESH;
for(UINT i=0; i<b.size(); i++)
{
for(UINT k=0; k<simspeed; k++)
{
bounce=false;
//handle the X bounce
if( b.at(i)->rBall.left <= 0 && b.at(i)->dVelocityX < 0 ) //ball bounces against the left wall
{
b.at(i)->dVelocityX = b.at(i)->dVelocityX * -1 * b.at(i)->dBounceCof;
bounce=true;
}
else if( b.at(i)->rBall.right >= SCREEN_WIDTH && b.at(i)->dVelocityX > 0) //ball bounces against the right wall
{
b.at(i)->dVelocityX = b.at(i)->dVelocityX * -1 * b.at(i)->dBounceCof;
bounce=true;
}
//handle the Y bounce
if( b.at(i)->rBall.bottom >= SCREEN_HEIGHT && b.at(i)->dVelocityY > 0 ) //ball bounces against the left wall
{
//damping of the ball
if(b.at(i)->dVelocityY < 2+o.dGravity/o.REFRESH)
{
b.at(i)->dVelocityY = 0;
}
//decrease the Velocity of the ball according to the bouncecof
b.at(i)->dVelocityY = b.at(i)->dVelocityY * -1*b.at(i)->dBounceCof;
b.at(i)->dVelocityX = b.at(i)->dVelocityX * b.at(i)->dBounceCof;
bounce=true;
}
//gravity
b.at(i)->dVelocityY += (o.dGravity)/o.REFRESH;
b.at(i)->pOrigin.y += b.at(i)->dVelocityY + (1/2)*o.dGravity/o.REFRESH*DT*METER;
//METER IS DEFINED GLOBALLY AS 100 which is the amount of pixels in a meter
b.at(i)->pOrigin.x += b.at(i)->dVelocityX/o.REFRESH*METER;
b.at(i)->UpdateRect();
}
}
return;
}
You are using the Euler method of integration. It is possible that your time step (DT) is too large. Also there seems to be a mistake on the row that updates the Y coordinate:
b.at(i)->pOrigin.y += b.at(i)->dVelocityY + (1/2)*o.dGravity/o.REFRESH*DT*METER;
You have already added the gravity to the velocity, so you don't need to add it to the position and you are not multiplying the velocity by DT. It should be like this:
b.at(i)->pOrigin.y += b.at(i)->dVelocityY * DT;
Furthermore there appears to be some confusion regarding the units (the way METER is used).
Okay, a few things here.
You have differing code paths for bounce against left wall and against right wall, but the code is the same. Combine those code paths, since the code is the same.
As to your basic problem: I suspect that your problem stems from the fact that you apply the gravity after you apply any damping forces / bounce forces.
When do you call RunPhysics? In a timer loop? This code is just an approximation and no exact calculation. In the short interval of delta t, the ball has already changed his position and velocity a litte bit which isn't considered in your algorithm and produces little mistakes. You'll have to compute the time until the ball hits the ground and predict the changes.
And the gravity is already included in the velocity, so don't add it twice here:
b.at(i)->pOrigin.y += b.at(i)->dVelocityY + (1/2)*o.dGravity/o.REFRESH*DT*METER;
By the way: Save b.at(i) in a temporary variable, so you don't have to recompute it in every line.
Ball* CurrentBall = b.at(i);
ANSWER!!ANSWER!!ANSWER!! but i forgot my other account so i can't flag it :-(
Thanks for all the great replies, it really helped me alot! The answers that you gave were indeed correct, a couple of my formulas were wrong and some code optimisation could be done, but none was really a solution to the problem. So i just sat down with a piece of paper and started calculation every value i got from my program by hand, took me like two hours :O But i did find the solution to my problem:
The problem is that as i update my velocity (whith corrected code) i get a decimal value, no problem at all. Later i increase the position in Y by adding the velocity times the Delta T, which is a verry small value. The result is a verry small value that needs to be added. The problem is now that if you draw a Elipse() in Win32 the point is a LONG and so all the decimal values are lost. That means that only after a verry long period, when the values velocity starts to come out of the decimal values something happens, and that alongside with that, the higher you drop the ball the better the results (one of my symptons) The solution to this problem was really simple, ad an extra DOUBLE value to my Ball class which contained the true position (including decimals) of my ball. During the RenderFrame() you just take the floor or ceiling value of the double to draw the elipse but for all the calculations you use the Double value. Once again thanks alot for all your replies, STACKOVERFLOW PEOPLE ROCK!!!
If your dBounceCof is > 1 then, yes your ball will bounce higher.
We do not have all the values to be able to reply to your question.
I don't think your equation for position is right:
b.at(i)->dVelocityY += (o.dGravity)/o.REFRESH;
This is v=v0+gt - that seems fine, although I'd write dGravity*DT instead of dGravity/REFRESH_FREQ.
b.at(i)->pOrigin.y += b.at(i)->dVelocityY + (1/2)*o.dGravity/o.REFRESH*DT*METER;
But this seems off: It is eqivalent to p = p0+v + 1/2gt^2.
You ought to multiply velocity * time to get the units right
You are scaling the gravity term by pixels/meter, but not the velocity term. So that ought to be multiplied by METER also
You have already accounted for the effect of gravity when you updated velocity, so you don't need to add the gravity term again.
Thanks for the quick replies!!! Sorry, i should have been more clear, the RunPhysics is beiing run after a PeekMessage. I have also added a frame limiter which makes sure that no more calculations are done per second than the refresh rate of the monitor. My dleta t is therefore 1 second devided by the refresh rate. Maybe my DT is actually too small to calculate, although it's a double value??? My cof of restitution is adjustable but starts at 0.9
You need to recompute your position on bounce, to make sure you bounce from the correct place on the wall.
I.e. resolve the exact point in time when the bounce occured, and calculate new velocity/position based on that direction change (partially into a "frame" of calculation) to make sure your ball does not move "beyond" the walls, more and more on each bounce.
W.r.t. time step, you might want to check out my answer here.
In a rigid body simulation, you need to run the integration up to the instant of collision, then adjust the velocities to avoid penetration at the collision, and then resume the integration. It's sort of an instantaneous kludge to cover the fact that rigid bodies are an approximation. (A real ball deforms during a collision. That's hard to model, and it's unnecessary for most purposes.)
You're combining these two steps (integrating the forces and resolving the collisions). For a simple simulation like you've shown, it's probably enough to skip the gravity bit on any iteration where you've handled a vertical bounce.
In a more advanced simulation, you'd split any interval (dt) that contains a collision at the actual instance of collision. Integrate up to the collision, then resolve the collision (by adjusting the velocity), and then integrate for the rest of the interval. But this looks like overkill for your situation.