30

Frame based simulations will experience errors when updates fail to compensate for non-linear rates of change. For example consider an object starting with position and velocity values of zero experiencing a constant acceleration of one. If we apply this update logic: velocity += acceleration * elapsedTime position += velocity * elapsedTime We can expect ...


19

Your main problem is likely this: final int skipTicks = 1000 / ticksPerSecond; Dividing an int by an int returns an int (the value is rounded down if needed), so skipTicks evaluates to 16. 1000 / 16 is 62.5 so you get around this many ticks per second. To solve this the easiest solution would be to use a millisecondsPerTick variable (what you are calling ...


9

You could restart your time value every 2pi: if(time > 2*pi) time -= 2*pi; If is still okay to increase your time variable infinitely but the input for the sine is to large, just use fmod(time, 2*pi).


7

Alex's answer seems sufficient, but you say you want more detail, so here goes. First, why does the gameloop from http://www.koonsolo.com/news/dewitters-gameloop/ deliver its desired frame rate while your version doesn't? Because their integer division works out exactly: const int FRAMES_PER_SECOND = 25; const int SKIP_TICKS = 1000 / FRAMES_PER_SECOND; ...


6

Get rid of the Sleep call. Sleep is fine for reducing CPU usage, but it is not fine for controlling framerate, and these two are not the same thing. Sleep can have poor precision, in the order of ~16 milliseconds. Sleep guarantees that the thread will resume at some arbitrary time after the Sleep interval has elapsed, not at the exact Sleep interval. ...


6

It depends on where you're calling your step from. If you're calling it from Update, your movement will indeed be framerate independent if you scale with Time.deltaTime, but if you're calling it from FixedUpdate, you need to scale with Time.fixedDeltaTime. I figure you're calling your step from FixedUpdate, but scaling with Time.deltaTime, which would result ...


6

Yes, you need to keep Time.deltaTime into account when you use Input.GetAxis, because the values it returns are also deltaTime-adjusted. You can read this in the documentation: This is frame-rate independent; you do not need to be concerned about varying frame-rates when using this value. The example code in the documentation makes it clear that ...


5

I've done some tests simulating low framerate conditions, and empirically confirmed that the deltaTime value for each FixedUpdate step does indeed stay consistent. For example, using the default Fixed TimeStep of 0.02 (50 Hz) and Maximum Allowed Timestep of 0.3333333 (as set in Edit -> Project Settings -> Time)... At 60 fps we get 0-1 physics & ...


4

You will unfortunately never get a behaviour that is 100% consistent across framerates, but it’s worth trying to approximate. Here is my suggested solution and the explanation of the maths behind it. Consider what happens to distance after your update: it becomes distance * (1 - factor) since the camera moved by distance * factor. If the player wasn’t ...


4

I think you need to rethink what you're trying to do. Look at the last lines in your example move forward code var scalar = //**IDK what goes here something that considers the fps**// player.position.x += units * scalar; Now look at the normal movement scaled by time code player.position.x += 1 * dt Notice the similarity? I understand that you have ...


4

I'd go with something like this (pseudo-code): spawnProbability = 0.001 // Your original probability at fixed timestep spawnAtThisFrequency = 1/30 // The original fixed timestep dt dtAcc = 0 // An accumulator that will accumulate the variable dt update( dt ) { dtAcc += dt; // Accumulate while( dtAcc >= spawnAtThisFrequency ) ...


4

On some platforms the game actually starts running before the splash screen is gone. So this may give the illusion of a defective timer if you test it right at the start. Another issue on slow devices is that your first frame of timer activation may have a very large deltaTime if other things happen at the same time. For example if it takes 2 seconds to ...


4

Your lerps and slerps are backwards: lerp(current, previous, alpha) should be lerp(previous, current, alpha) ie. increasing alpha (more time accumulated since the last update) should move us toward the future, not toward the past. This could account for at least some of the choppiness you perceive. There could be additional judder coming from the player ...


4

Games inherited this term from animation, film, and video. There, a "frame" is one still image in the sequence. By playing lots of frames in rapid succession, we create the illusion of motion. See this strip of 35 mm film from the Museum of Obsolete Media. In it, we can see three consecutive frames of a Spider-Man movie. The framerate of a piece ...


3

I assume GetTicks() is standard SDL. In which case when I look at the documentation is says "Get the number of milliseconds since the SDL library initialization." However all your calculations seems to be in seconds. So if you treat the output from GetTicks() as being seconds you are gonna effectively be running 1000 times faster. Or you would if it weren't ...


3

If my assumption that you want your speed to lose 2% of its value every second, then this is a perfect opportunity to use the exponential rate of decay expression, which looks like this: A=Pe^(rt) A is the final amount you want (so, after 1 second, .98(vx)) and P is the initial amount. t is just time, so since you want the velocity to only be 98% of its ...


3

So I have struggled to get this right and this is what I currently use. The point is to have a friction value that is dependent on time and therefor works on low and hi end devices similarly. //*** Set friction value friction = 5f; //*** Calculate Fiction decay xRatio = 1 / (1 + (Time.deltaTime * friction)); //*** Decay velocity velocity *= xRatio; //*** ...


3

Ok, think I got an answer for you. The short version: compute the friction force F = friction * velocity before you start the loop and apply it in do Physics() like this: v -= F * deltaTime. Long version: the assumption you're making that it should work independent of frame time only works with constant acceleration, like the one you're applying in ...


3

It’s because, in general, jumping involves applying an impulse instead of a force. You apply forces when the interaction is expected to last for at least some time. For instance, gravity is a force: it lasts more or less forever. Pushing a door is applying a force, too: you keep pushing while the door opens. You apply impulses when the interaction should ...


3

Simply put, you need to send a time-stamp with each snapshot from the server, and with each input from the client. On both ends you need a process to "fill in" any frames where packets are not received. In my game (a fast-paced action game - yours may be different), on the server, I discard any "older" (out-of-order) input, and simply guess that if no new ...


3

I share the skepticism @Estharon expresses about whether players will enjoy a 30-minute non-interactive battle, but I'll answer as if it's a given that these will be interesting events. Unless there's a compelling reason for this to take exactly 30 minutes, I would make a sequence of smaller fixed or randomized decisions (balanced around a target duration) ...


3

Expanding on Stormwind's lead, I'd be curious whether your application needs a windowed average with equal weights per unit of time, or if an exponential moving average may suffice. The latter is very simple to implement, and can be adapted to a variable framerate like so: float weight = 1 - pow(1 - responsiveness, dT * referenceFPS); smoothedValue += (...


3

JavaScript On the browser For code running in the browser, I would strongly advice to use requestAnimationFrame as game loop. See availability. Example: function update(timestamp) { // ... window.requestAnimationFrame(update); } window.requestAnimationFrame(update); requestAnimationFrame takes a callback that will be called once per frame, ...


2

Where's deltaMouse coming from? If the API you're using is giving you translation units like pixels or centimeters, you shouldn't scale by deltaTime. Moving your mouse 1 cm should rotate the camera by, say, 15 degrees, regardless of how many frames or how long it took to move that 1 cm.


2

deltaTime = (float)(currentTime - previousTick) / 1000000.f It's a simple floating point bug. When you divide an integer by another integer it returns an integer. This truncates all your decimal detail.


2

The fix is simple, integrate position in the middle of integrating velocity. (As in, add half of the force, update, then add the other half.) Here is a more in-depth explanation: http://www.niksula.hut.fi/~hkankaan/Homepages/gravity.html


2

I would still use GameTime to track the passage of time (no sense reinventing that wheel), but I would not bother storing it in your MyTime object and you certainly shouldn't try to subclass GameTime. Just create your own type with whatever fields you want and then use the GameTime provided to the Game class to update your instance however you want, applying ...


2

As Sean says you are really just using the accumulator to enforce a fixed time step, this is likely to look very jumpy in comparison with the rest of your game. This would be one approach that applies movement on each update: class Camera { const float factor = /* low values for "tight" movement */; void update (float timeElapsed) { ...


2

Why do you want another way? The one you describe is what you'd use in any kind of game development, whether or not you use DirectX. The problem is this: In (most) games you have a main loop. This loop runs as fast as the hardware allows. However, people use different hardware, so on some computers, this will be faster than on others. So in order to make an ...


Only top voted, non community-wiki answers of a minimum length are eligible