Dear Game Developers, Stop Messing This Up!

  Рет қаралды 668,531

Jonas Tyroller

Jonas Tyroller

Күн бұрын

DeltaTime. This video is all about that mysterious variable that oh so many game developers seem to struggle with. How to use DeltaTime correclty? I got the answers and hope this video will help to deepen your understanding about how to make frame rate independent video games.
0:00 - Intro
0:34 - Creating The Illusion of Motion
1:11 - Simple Linear Movement
3:25 - But What is DeltaTime Exactly?
5:42 - Fixed Updates
8:22 - Movement While Changing Speed
10:41 - Integrals And Why You Might Need Them
13:17 - Approximations And Why They Are Fine
14:30 - Movement Formulas
15:03 - The Unforgivable Mistake
16:54 - How to Lerp Correctly
20:43 - Test Your Game!
21:31 - Get Your Grade Here!
My Games:
➤ Play Thronefall on Steam: store.steampowered.com/app/22...
➤ Join the Thronefall Discord: / discord
➤ Play Will You Snail on Steam: store.steampowered.com/app/11...
➤ Join the Will You Snail Discord: / discord
For the game developers among you:
➤ Join our creative game dev community on Discord: / discord
Hope you enjoy. :)
#gamedev #indiedev

Пікірлер: 1 600
@JonasTyroller
@JonasTyroller 10 ай бұрын
Small corrections (I learn some things from you as well, how nice, haha): - Using Time.deltaTime in Fixed Update is actually fine in Unity cause it automatically returns Time.fixedDeltaTime depending on where it is called from. - Using Delta Time in fixed update still makes sense for various reasons (it keeps speed to units/second and helps when inaccuracies in the fixed update intervals occur) That means 10 free points to you if your read this, haha. Will keep updating this in case I got anything else wrong. :P
@Robyamdam
@Robyamdam 10 ай бұрын
Can you do more of these please?, Maybe an episode on debugging or finding code related problems that don't seem to have an answer
@blockify
@blockify 10 ай бұрын
dont these 2 corrections contradict eachother? or am I being dumb xD If deltaTime returns fixedDeltaTime while in the Fixed Update, then how can it keep speed to units/second and help inaccuracies?
@aksimilumaspvp7278
@aksimilumaspvp7278 10 ай бұрын
@@blockify no because fixedDeltatime takes the inaccuraties and inconsistencies in fixedupdate into account, and deltaTime gives rhat fixedDeltatime. Point is in fixedUpdate fixedDeltatime==DeltaTime. There is no difference using one or another. Still, using either one can be helpful to get around inaccuraties(which can happen in fixedupdate if u use neither)
@wayfarergames
@wayfarergames 10 ай бұрын
​@@blockifyif it helps, you can think of multiplying by deltaTime or fixedDeltaTime as a sort of "per frame -> per second" conversion in unity! (You can also convert the other way by dividing by deltaTime, e.g. if you want to get the amount an object has moved in a single frame, you'd divide its velocity by deltaTime since in Unity velocities are usually per second)
@CyberAngel67
@CyberAngel67 10 ай бұрын
It doesn't return fixedDelta time. If we go back to what I said in another comment, the correct answer is not A in fact non of the truly was the right answer. delta time is the time it took to process the last frame, the documentation backs this up. So when you run that in FixedUpdate, that means the normal delta and the fixed delta will be the same value, but one does not simply return the other. Physics is a fixed step, therefore both are going to equal the same value!
@leffeup8117
@leffeup8117 10 ай бұрын
As someone who litteraly had a math test earlier today on the subject of integrals, this was a great ego boost
@nobody.of.importance
@nobody.of.importance 10 ай бұрын
I recall when I got into Math 251 Differential Calculus, I thought it was going to be some pretty insane shit, but it turns out we use it all the time without even realizing it. It's just so much more powerful if you know the fancy tricks. I cannot recommend enough that those who don't know at least differential calculus to learn it. You will not regret it.
@gogauze
@gogauze 10 ай бұрын
​@@nobody.of.importance*sigh* FINE. I'll go learn differental calculus this month.
@Nidhsa
@Nidhsa 10 ай бұрын
@@gogauze im learning it in the fall
@nobody.of.importance
@nobody.of.importance 10 ай бұрын
@@gogauze Knowledge is power! Good luck! Same for you Nidhsa c:
@juxyper
@juxyper 10 ай бұрын
this is not only integrals, this is discrete integrals!
@tommysedin
@tommysedin 10 ай бұрын
6:50 I would say that it's not pointless to multiply by fixedDeltaTime; Makes it easier to code consistent units (say if you're trying to follow SI units strictly, or if you have calculations in both Update and FixedUpdate that should follow the same unit). Also, if you ever end up changing the frame rate of the FixedUpdate, you'll have to change every single calculation.
@JonasTyroller
@JonasTyroller 10 ай бұрын
Fair! :)
@zelos666
@zelos666 10 ай бұрын
The physics will actually break if you change Time.timeScale and don't multiply by fixedDeltaTime, because fixedDeltaTime will change with the timeScale. Meaning it's actually not always the same value, if you have any kind of speedup or slowdown with timeScale in your game.
@ThePhoenix107
@ThePhoenix107 10 ай бұрын
Just want to add that the code example did not need to be changed at all to be called for FixedUpdate. And that is because Time.deltaTime actually returns Time.fixedDeltaTime when called from within FixedUpdate.
@mrcreepypl
@mrcreepypl 10 ай бұрын
@@ThePhoenix107 Cool to know, but I'll still stick with fixedDeltaTime for consistency and clarity.
@rhysvanderwaerden5518
@rhysvanderwaerden5518 10 ай бұрын
​@@zelos666it actually is the other way. The fixed delta time stays the same, but anything running in fixed time will become more granular in real time because fewer fixed steps will occur between frames. This is why you might need to reduce your fixed time step for slow motion. If you are modifying your fixed delta time for this purpose then you definitely need multiply by it in fixed update.
@grbrigsted
@grbrigsted 10 ай бұрын
If you're not using fixed updates, you might end up clipping through walls from lag spikes, unless you're using rays to assert if the player has moved through a wall between the previous frame and the current.
@i_makegames
@i_makegames 10 ай бұрын
correct me if im wrong but, this will only happen if you use a rigid body controller, not for example the player controller asset, also you dont need to code a ray check as you can just set the rigid body to 'continuous' or 'continuous dynamic'
@JonelKingas
@JonelKingas 9 ай бұрын
im literally so new at game dev, im just pretty much using everything in fixedupdate, and what needs to execute fast for example key pressed in update, idk if its fine but it works fine, example in my game this: void Update() { if (Input.GetMouseButtonDown(0)) { isShooting = true; CalculateShootDirection(); } else if (Input.GetMouseButtonUp(0)) { isShooting = false; } if (isShooting) { CalculateShootDirection(); } } void FixedUpdate() { if (isShooting) { shootTimer += Time.fixedDeltaTime; if (shootTimer >= shootingDelay) { Vector3 bulletVelocity = bulletSpeed * shootDirection; GameObject bullet1 = Instantiate(bulletPrefab, bulletSpawnPoint1.position, Quaternion.identity); bullet1.GetComponent().velocity = bulletVelocity; GameObject bullet2 = Instantiate(bulletPrefab, bulletSpawnPoint2.position, Quaternion.identity); bullet2.GetComponent().velocity = bulletVelocity; float rotationAngle = Mathf.Atan2(shootDirection.y, shootDirection.x) * Mathf.Rad2Deg; bullet1.transform.rotation = Quaternion.Euler(0f, 0f, rotationAngle); bullet1.transform.Rotate(Vector3.forward, 90f); bullet2.transform.rotation = Quaternion.Euler(0f, 0f, rotationAngle); bullet2.transform.Rotate(Vector3.forward, 90f); shootTimer = 0f; } } } private void CalculateShootDirection() { // Calculate the shoot direction based on the player's transform shootDirection = bulletSpawnMainPoint.up; // Assuming the player's forward direction is along the X-axis shootDirection.Normalize(); }
@hexagon_
@hexagon_ 9 ай бұрын
Orange grenade lifestyle
@grbrigsted
@grbrigsted 9 ай бұрын
Neutral Milk Hotel
@notChocoMilk
@notChocoMilk 9 ай бұрын
so that’s how i fix that.. too bad i’m already making a new player controller
@metalstarver642
@metalstarver642 10 ай бұрын
Actually things get 100x more complicated if you have non-constant forces, you need to lookup numerical integration (initial value problem). Your recommended way is called Leapfrog integration. It can work really far from accurate if you have spring forces (with springs you need tiny timestep or other more sophisticated methods which usually are not suitable for real-time).
@astecheee1519
@astecheee1519 9 ай бұрын
I feel like springs are better expressed with approximations in games.
@drstrangecoin6050
@drstrangecoin6050 9 ай бұрын
Is a second order taylor series the wrong thing to do here?
@metalstarver642
@metalstarver642 9 ай бұрын
@@drstrangecoin6050 It depends. For springs or gravity (N-body sim) to get stable results Taylor series won't be enough. You would need implicit methods for accurate and stable results (too slow for real-time). But for games springs could be done without forces in more stable way (e.g XPBD). Stability of gravity forces usually not an issue unless you're doing Solar system simulations or the like (in which case parametrized elliptical orbits may be better option for game). For a game maybe first check implicit Euler and then XPBD if it fails, otherwise start faking it.
@ckjdinnj
@ckjdinnj 8 ай бұрын
Implicit is used all the time in games. In fact they showed a common example in the video … velocity = velocity + acceleration * deltaTime position = position + velocity * deltaTime 2nd order Taylor series is fine for most use-cases. If you have to support some wildly stiff springs or need a high degree of accuracy then you could try rk4. p0=initialPos r=restingPos v0=initialVelocity k=springStiffness dt=deltaTime m=mass f1=k*(r-p0) // force v1=dt*f1/m+v0 p1=0.5*dt*v1+p0 f2=k*(r-p1) v2=0.5*dt*f2/m+v0 p2=0.5*dt*v2+p0 f3=k*(r-p2) v3=0.5*dt*f3/m+v0 p3=dt*v3+p0 f4=k*(r-p3) v4=dt*f4/m+v0 v_final=v0+(f1+2*f2+2*f3+f4)*(dt/m)/6 p_final=p0+(v1+2*v2+2*v3+v4)*dt/6
@ckjdinnj
@ckjdinnj 8 ай бұрын
Performance cost is relative as well. It’s all about scale of use. If you wanted a 3rd person spring arm camera and it needed to be super stiff/snappy one use of rk4 would be fine. However if you are setting up a dense foliage section where foliage physically interacts with the player then you’d probably just use a simple implicit approach with v_final=v0+dt*k*(r-p)/m p_final=v_final*dt+p0
@Ochros
@Ochros 10 ай бұрын
21:50 From your testing scheme, it's actually possible to get everything wrong and also the -10 points, leaving you with a grading that is undefined according to your evaluation :P (if I didn't miss anything)
@Aeroxima
@Aeroxima 10 ай бұрын
Negative F!
@Cynadyde
@Cynadyde 10 ай бұрын
being undefined, there's every chance we hit a negative integer overflow and land on a grade no less than 150
@madmax404
@madmax404 10 ай бұрын
In this case I think you can just give yourself 4294967285 points
@EmersonPeters
@EmersonPeters 10 ай бұрын
Spoken like a true game tester!
@Jonskipvp
@Jonskipvp 8 ай бұрын
@@madmax404 the only winning move is not to play
@Randy14512
@Randy14512 10 ай бұрын
I don't code, but I am a physics nerd and saw delta time and it peaked my interest. Was not disappointed to see the explanations of calculating changes in distance as a function of time when not accelerating, when accelerating, and with a changing acceleration value. With the questions that were math based and not definition based other then syntax i am happy to say I got the idea right lol.
@superscatboy
@superscatboy 10 ай бұрын
For future reference: It *piqued* your interest.
@oisyn-
@oisyn- 10 ай бұрын
@@superscatboy Maybe his interest curve reached a local maximum, so it really did peak his interest.
@superscatboy
@superscatboy 10 ай бұрын
@@oisyn- Or maybe that's just a load of old bollocks 🤷‍♂️
@baitposter
@baitposter 10 ай бұрын
​@@superscatboy Well, my interest definitely *peaked* when seeing the title of this video
@nathangamble125
@nathangamble125 10 ай бұрын
@@baitposter So your interest decreased when actually watching the video?
@klikkolee
@klikkolee 10 ай бұрын
I'm going to contest question 2 based on the wording. The presentation of a frame can be conceptualized as happening at specific instant of time, but the game logic of a frame takes meaningful time to happen. If I just see phrases like "the current frame" and "the last frame" in reference to timing and without further indication, I will interpret that as referring to those spans of time. In the context of timing, frames have a start and an end, and that end is before the frame's presentation. Since each operation can be conceptualized as contributing to a specific frame, the end of a frame is the same as the start of the next. You don't know when the current frame will finish or when it will present, but you do know when it started. A game engine is going to use the most recent frame-time estimate it can, and that would be the time between the start of the current frame and the start of the previous frame. This is more consistent with the wording of option B than the wording of option A, and it is consistent with the wording in the Unity script reference for Time.deltaTime: "The interval in seconds from the last frame to the current one"
@rumbleball542
@rumbleball542 2 ай бұрын
Thank you.
@Julianiolo
@Julianiolo Ай бұрын
wtf this is exactly what I just wrote lol. With a lot more fancy words sprinkled in though
@MrWolfheat
@MrWolfheat 10 ай бұрын
I think that in the latest unity versions using deltaTime in fixedUpdate will automatically use the fixedDeltaTime internally so you do not need to change this. Unity implicitly understand which one to use by the context it is used in.
@CyberAngel67
@CyberAngel67 10 ай бұрын
it won't auto use the fixed delta time, the timing will just be identical.
@1vader
@1vader 10 ай бұрын
It's not only in the latest Unity version. I recall hearing about this behavior at least several years ago.
@delphicdescant
@delphicdescant 10 ай бұрын
Wow that's kind of terrible API design. Would be a lot better if using deltaTime in fixedUpdate were an error. Implicit/hidden behavior is an evil that you might expect to see in the realm of web dev frontend nonsense, but not in applications programming.
@DiThi
@DiThi 10 ай бұрын
In my opinion, the best API design would be to have the delta time as argument to the update functions, that way it's impossible to mess it up.
@milanstevic8424
@milanstevic8424 10 ай бұрын
Unity's API design choices are notoriously bad. Thankfully once you learn all the shitty things and minefields it's full of, you can safely ignore it and build up your own software more robustly. But be warned, Unity is a hell to learn.
@sammtavv
@sammtavv 10 ай бұрын
I didn't know i always wanted a video from Jonas directly to the developers. Gotta love these videos!
@tcatdev
@tcatdev 10 ай бұрын
When people misuse lerp you can really feel it in the gameplay. I did a little different than you though. I recorded the start position and start time, then I use the elapsed time to calculate the lerp factor in each frame. I also like using cosine instead of sqrt, because it gives a more natural feel. The formula is (1 - cos(x * PI)) / 2, where x is the elapsed time.
@bastian_5975
@bastian_5975 10 ай бұрын
Are you saying you did position = lerp(startingPosition, endingPosition, 1-cos(x*pi)/2)? Because that would cause it to go back and forth between the start and end, not approach but never reach the end.
@gajbooks
@gajbooks 10 ай бұрын
@@bastian_5975 It should probably be cos(1/(x+2)*PI), which is really just a differently smoothed version of 1 - (1/(x+1)), where x is elapsed time in both scenarios. (There's an absolute ton of "sigmoid" functions you can use to infinitely approach a number.) The delta-time lerp works though, just it makes a little less sense logically because instead of lerping between two fixed points, you end up lerping between the destination and the previous location.
@bastian_5975
@bastian_5975 10 ай бұрын
@@gajbooks at first I thought you meant cos(1/(pi*(x+2))), but cos(pi/(x+2)) looks so much better that I think you mean that. And are you saying that the function you defined was a sigmoid function or that sigmoid functions are a class of functions that also achieve that effect?
@cyzaine
@cyzaine 10 ай бұрын
As a Godot user, I love that this just explains the concepts. Doesn't matter what the engine is! I felt I kinda knew all this, but it's presented so well I feel I learned something anyway.
@lukkkasz323
@lukkkasz323 10 ай бұрын
yeah, btw for those that don't know, the equivalent of FixedUpdate() in Godot is _physics_process().
@DevDoge_
@DevDoge_ 10 ай бұрын
​@@lukkkasz323isnt it _physics_process(Delta)
@nobody.of.importance
@nobody.of.importance 10 ай бұрын
Yeah, thankfully stuff like this is pretty engine agnostic. Once you know how one engine works, a lot of it is easy to carry over to others, at least from a technical perspective.
@anyapeanutlover
@anyapeanutlover 10 ай бұрын
I'm also a Godot user, and I know that Update() is "_process(delta)", and FixedUpdate() is "_physics_process(delta)"
@RADkate
@RADkate 10 ай бұрын
ive also never seen someone mult everything by delta time in a godot tutorial
@Random-kj1go
@Random-kj1go 10 ай бұрын
please we need more of thisss this is the exact technical info no one talks about and it even has a visualisation very good video 10/10
@Ombarus
@Ombarus 10 ай бұрын
Very impressed, you've covered many of the pitfalls. Just two remark: Fixed Update is useful to avoid costly exponent which are very common in Physics calculation because if you have a constant delta time then the linear approximation is good enough (so the "bad" lerp in a FixedUpdate would work just fine). The big drawback with FixedUpdate is that you'll usually notice "jerking" as one frame you'll update 3 times, but then the next frame only 1, then the next 2. Usually to fix this you need to extrapolate the difference between the current frame's deltatime and the FixedDeltaTime.
@nathanielguggenheim5522
@nathanielguggenheim5522 10 ай бұрын
Or avoid FixedUpdate() altogether and call Physics.Simulate() by yourself in Update() after disabling automatic PhysX Update. Actually the only method I know to avoid Unity's microstuttering.
@madmax404
@madmax404 10 ай бұрын
Thanks for the Lerp fix! This is something I pretty much gave up on after I realized the solution would be a easy to mess up, and almost completely just changed to using spring-damp systems, though partially because they're also often just better. Though I'd say that the "simple" solution to calculating per-frame movement deltas is not ok 9/10 time but probably closer to 99/99.9% of the time. I've never actually brushed against it but have had a lot of pain due to different update rates simply ending up with different results, and inconsistent amounts of FixedUpdates causing frame pacing issues. For the Xbox One port of Thief of Thief for example, I ended up doing a hack that connects Update and FixedUpdate rates as long as they don't want to be too far from each other and managed to remove almost all frame pacing issues (which were bad otherwise) from the game. I've had to do this only once, but I had a sprint-joint system smoothly controlling the camera in Among The Trolls. If the framerate got REALLY bad, the system went completely out of whack. So for that I implemented custom sub-stepping where the calculation was always calculated with an almost non-changing deltatime but just repeated enough times during a frame if the framerate was bad. This is how FixedUpdate also works in essence, but with FixedUpdate this can cause those cursed problems where the frames get longer because FixedUpdate is called more, if FixedUpdate gets even slightly expensive. Closest solution I have to syncing 2 clients with different frame times (in absolute time) was a server-time synchronized RPC where, I decided to trigger the event on the slower-updating client even if the trigger time wasn't yet reached as long as if the estimated time of the next frame would be even more off. Of course this also used the last frame's frametime though but made some events seem almost magically in-sync as long as I could schedule the event far enough in the past (like 300ms).
@XoIoRouge
@XoIoRouge 7 ай бұрын
I love the presentation of this video, with an actual test. The whole "YOU WILL BE GRADED JOKE" actually motivated me to do well on this test that no one will see. I've seen many youtubers educate with information, by just telling us the right answer, showing it in examples, with great animations to help visualize. That process works, but I think many content creators forgot how effective it is to challenge our knowledge. At 3:41, despite me using deltaTime in many places, I realize that... I'm not EXACTLY sure which of these four are true. Thank you for challenging my knowledge, and because of that, you've stuck out as a memorable youtube educator. I've subscribed and I look forward to learning more from you.
@enreeper
@enreeper 10 ай бұрын
Way back before I even knew about delta time I used to have my games code run at 120fps and didn't noticed any weird behaviour, but as soon as other players with 60hz displays played the game everything was in slow motion running at half the speed, they often commented the game feels slow and me and my friend playing at 120 allways wondered what do they mean until I realised this issue.
@DOSRetroGamer
@DOSRetroGamer 10 ай бұрын
Lol
@JonasTyroller
@JonasTyroller 10 ай бұрын
Haha. Oh, no. :D
@blockify
@blockify 10 ай бұрын
haha i too didn't realise for ages because since I never did anything big scale the fps stayed relatively consistent
@inkedalien
@inkedalien 10 ай бұрын
same with us lol tested it out by racing each other in different refresh rates haha
@APaleDot
@APaleDot 10 ай бұрын
For those confused about the lerp section, I have a really easy way to think about it intuitively: If your "lerpSpeed" is 1, then the base of the exponent (the number on the bottom) is the portion of the distance you want to cover in one second. So in the video this number is 0.5 which means the character covers 1/2 the distance to the goal every second. The reason this works is because when you do this multiple times in a row, the distance decreases exponentially. So, if you imagine your frame rate is 4 frames per second, then in the first frame the character covers 0.5 ^ 0.25 of the distance (because deltaTime is 0.25), and the next frame the distance will be less but they will still cover another 0.5 ^ 0.25 of _that_ distance. So the total distance covered will be (0.5 ^ 0.25)(0.5 ^ 0.25), which if you remember your exponent rules is equal to 0.5 ^ 0.5. In other words when you exponentiate like this, the deltaTime in the exponent adds linearly every time you lerp. In this example, if you lerp every frame for one second (that is 4 frames) then the exponent adds up to 0.5 ^ 1. In other words, you cover half the distance in one second, regardless of your deltaTime, as I stated in the beginning. EDIT: as explained in the replies, the base of the exponent actually represents the portion _remaining_ after 1 second, not the portion covered after 1 second, because you start at t = 0 which would give a blend value of 1, so we use 1 - 0.5^t instead (or Jonas puts the current position in the second parameter of lerp, which is equivalent)
@NXTangl
@NXTangl 10 ай бұрын
For this reason, I would use Math.Exp(-lerpSpeed * deltaTime).
@pixelz3040
@pixelz3040 10 ай бұрын
Just want to point something out here, cause this kinda bothered me. You are correct in that the reason for the deltaTime being in the exponent is so that they add to 1, but the total distance covered is NOT just the product of the blends. You can easily see this if you use a base other than 0.5. Assuming you have the function laid out like Jonas did, where the target position occurs when the blend is 0, then the position of the snail after n frames is going to be (target_position)(1 - (product of all the blends)). You can deduce this through induction with the lerp function. Lets say that our blend is 0.1 ^ 0.25, where the 0.25 is our deltaTime, just like in your example. Initially, the snail's position is 0. After 4 frames, or 1 second, the snail's position will be (target_position)(1 - (0.1 ^ 0.25) ^ 4) = (target_position)(1 - 0.1) = 0.9(target_position). After 4 frames, the snail moves 90% of the distance, not 10% as you implied. Fundamentally, what you're saying is helpful, but I saw the comment and got caught up on that snag for a while, and it kept me from truly understanding what was going on. Also, I agree with @NXTangl, using the built in exponential function is nice because then you don't have that arbitrary base and the speed is more directly controlled by lerpSpeed.
@feha92
@feha92 10 ай бұрын
> So in the video this number (lerpspeed) is 0.5 which means the character covers 1/2 the distance to the goal every second No, in the video you cover 0.3 of the distance every second because of that number (lerpspeed) being 0.5.
@APaleDot
@APaleDot 10 ай бұрын
@@feha92 No, "this number" refers to the base of the exponent, which is 0.5 in the video. I also say that I'm setting lerpSpeed to 1 for simplicity. lerpSpeed is also 1 in the video IIRC, so I'm not sure how you mixed that up. Edit: actually, lerpSpeed is 0.5 in the video, so it makes sense you got mixed up. But I still said "if lerpSpeed is 1".
@APaleDot
@APaleDot 10 ай бұрын
@@pixelz3040 You're right, the base of the exponent is the portion _remaining_ after one second, not the portion covered. Those two numbers just happen to be the same when the base is 0.5, my bad. I personally still like to use the arbitrary base because the meaning of the base is clear when the exponent is 1, and I don't want to think about a base of 1 / 2.718. lerpSpeed controls the speed the same way in either case.
@IvanLeben
@IvanLeben 10 ай бұрын
There is actually another layer of complexity here, which even experienced games developers often miss: regardless of how much time has passed between your consecutive update calls, the monitor typically can only present images spaced at a fixed interval from each other - the refresh rate of the monitor. The only exception here would be if you are using a variable-refresh monitor with a GSync or FreeSync technology. If you are updating your game with variable deltaTimes, but presenting those frames on the screen at a fixed rate, you will create what we call "microstuttering". The animation will overall keep correct pace with the wall clock, but it will appear jerky, unsmooth. Unless you are using GSync, you should only ever update your game in increments that are a multiple of the monitor refresh rate and then tell the rendering system to present these frames at the correct time in the future - if you are updating the game for X milliseconds, then the frame you've generated should be presented exactly X milliseconds from when the previous frame was presented. This technique is callled "frame pacing" and fixes microstuttering. Note that modern game-engines like Unity and Unreal might automate frame-pacing for you behind the scenes, by feeding you deltaTimes and presenting the frames as appropriate (support might also depend on the platform you are shipping the game on).
@wakannnai1
@wakannnai1 6 ай бұрын
If your engine is developed properly, DeltaTime should be tied directly to the update of a frame. Most modern engines (Unreal Engine, Unity, and most AAA Engines) tie DeltaTime directly to the update of every frame. This by definition means that each tick is tied to the update of a frame. In the scenario you presented this is not what happens. If your actual frame update is not in sync with your refresh rate on your monitor, you'll typically see frame tearing (since almost all engines will queue at least a frame in advance in the back buffer and update the screen on each refresh). Screen tearing happens since the new frame that was in the process of rendering in the back buffer is being pushed to the screen in an incomplete state. Microstuttering really happens when you're close to the target refresh rate. Since there's some variability in each frames workload (both on the CPU and GPU), frame completion may not fall exactly on the expected interval to update (ie 1 frame may have taken 17ms rather than 16.5ms to complete rendering). In order to avoid this, a lot of devs will try to exceed performance from the target enough to minimize Microstuttering. It has nothing to do with updating your game with variable DeltaTimes. It has more to do with frame consistency.
@BicycleName
@BicycleName 10 ай бұрын
For anyone interested in learning more about numerical integration, there's a whole range of other schemes you can apply which have different stability properties based on the deltaTime and the equations of motion of the players. Here at 8:22, if I can recall properly, he first uses Euler Forward then Euler Backward and after that, Crank-Nicolson. If you had a more complicated movement, you could as well switch to a spicier scheme (like Runge-Kutta) but it's propably over-engineering the task you're trying to achieve.
@Puukiuuki
@Puukiuuki 10 ай бұрын
True, although this makes the difference between explicit (forward Euler) and implicit methods (backward E, C-N) appear very similar, since there is only a time dependence here. Normally you will need to solve a system of equations, which makes the thing inherently stable. A good example is the exponential speed case, where an explicit method can easily overshoot.
@Zicrus
@Zicrus 10 ай бұрын
3:48 This could actually be A or B depending on your definitions. I picked B, because it's the time between when the current frame started being processed and when the previous frame started being processed. If your definition for the time of a frame is when it is done processing, then A is the correct answer. I view the start of the frame as the true time, since that is also when inputs are registered, so the actual frame that is being displayed is slightly behind, not the other way around.
@mcarr87
@mcarr87 10 ай бұрын
Just to add on to your comment, the video is wrong here as per reasonable definitions. The term 'current frame' always refers to the one you're currently processing. 'deltaTime' is calculated at the start of the processing of the current frame by comparing the time to the time the previous frame began processing. deltaTime is essentially how long the last frame took to process from start to end (where 'end' is the start of the current frame). "Time elapsed between the last frame and the one preceeding it" is a not a good definition of deltaTime because the frame before the last one has no relevance. The current frame's deltaTime value is calculated in the current frame and not at the end of the previous one. As per Unity's own documentation for Time.deltaTime it says it's "The interval in seconds from the last frame to the current one". I believe the error is largely due to representing frames as a point in a timeline when something is rendered on the screen. At some time, typically very shortly after that rendered frame point on the timeline, the deltaTime value will be calculated. The only relevant frames in the calculation is the previous frame and the current frame. Carrying on from this the video then describes deltaTime having a "1 frame delay" which is also stated and described confusingly. Obviously deltaTime is not going to be related to how slow the current frame is because it can't predict the future. So the best value it actually could be: the previous frame's calculation time, is essentially what it actually is. Describing that as a "1 frame delay" doesn't really make sense. Obviously here the video is referring to deltaTime in relation to something moving on screen and pointing to how the object moves only a little bit on screen on the frame that took a long time and then has the larger jump on the next frame. Saying that "deltaTime always has a 1 frame delay" because of this particular example is not reasonable. deltaTime is not delayed, it is the correct value for when it was calculated. Nothing prevents a programmer from calculating their own deltaTime equivalent value and moving objects with that right before rendering. Time.deltaTime is not delayed, you have just chosen to use it in a way that gives a result that you refer to as having a delay. If anyone was confused by the 1 frame delay part of the video and curious, the way the deltaTime value would work after a slow frame is is: If a game was running at 60FPS on Frame A, Frame B's deltaTime would be ~0.0166s. That's how long it was from the start of Frame A to the start of Frame B. If Frame B was then slow and took 0.1s (10FPS) to complete, Frame C's deltaTime value would be 0.1s Basically the frame after the slow frame would see the larger deltaTime value. Not a bad video otherwise, but that section in particular I think would be very confusing to programmers trying to learn about deltaTime. I believe conceptually it's essentially correct, but by representing frames in relation to deltaTime in that way and slightly misrepresenting when deltaTime is calculated it makes something fairly simple much more confusing.
@technorazor976
@technorazor976 10 ай бұрын
I understood it that way too, thanks for confirming! +10 points to me!
@mcarr87
@mcarr87 10 ай бұрын
And I just want to say that I don't like leaving some big comment like that, I just needed to write that much to explain everything. Obviously Jonas seems to be great at what he does and has made an excellent video. I know I'd hate making videos like this because it'd be very had to not make errors or poorly represent some things even if you know them well yourself in reality. I'd not want to have to see comments like mine above, but know that it's only left in the interest of helping clarify those elements from the video for anyone confused or off-put by them. I'm sure you (Jonas) understand what I've explained yourself and just (in my opinion) didn't express them adequately in that small part of the video.
@Gamesaucer
@Gamesaucer 10 ай бұрын
@@mcarr87 Your comment is far more confusing than the video is. There are a few reasons for this. Firstly, there are two entirely contradictory definitions of a "current frame" at play here, which you don't seem to realise. On their own, both definitions are valid, but the one you present here has some issues in its broader context. You seem to define a "frame" as the routine that runs to produce it. In that sense, the current frame is indeed the one you're processing. But then a frame is a process and not a point in time. This contradicts with the definition of deltaTime in the Unity documentation you quoted, "The interval in seconds from the last frame to the current one". That one notably _does_ define a "frame" as being a point in time, as evidenced by it not saying "from the _start_ of the last frame". One important problem with your definition is that updating the game state is not linked to visuals whatsoever. A game could poll for inputs twice as often as it renders a new frame. These are still two game updates, but there is only one frame rendered. If you define a frame as a process, you'd have to exclude the time spent updating the game state, and only include the rendering time. But that's demonstrably not the value that deltaTime contains. The other definition of a frame is "the image being shown on the screen". This is a far more intuitive definition, and how most people understand such terms as "fps". There are 60 images being shown to me per second. And whatever is being shown to me at any given time, is the "current" frame. This frame is shown to me all at once and does not change afterwards until the next frame arrives. Thus, the moment it appears on my screen is a single point in time and not a process. Reading the definition of deltaTime again, this makes a lot more sense. Because the "current frame" is what you just finished. And deltaTime is indeed the space between those points in time by all definitions. You say that the way this definition is worded in the video is inaccurate, but that is simply not true. "Time elapsed between the last frame and the one preceding it" is a perfectly valid way of describing it, so long as you take "last" to mean "most recent" over "previous". The current frame is the most recent frame, and therefore the current frame can also be described as the last frame. This is not a strange way to use English, and should not be confusing for someone who speaks the language well enough to watch English videos on KZfaq and writes English comments. Additionally, I strongly disagree with that a "1 frame delay" is a bad way to describe what happens. Of course, the variable itself isn't delayed. Because it's defined with that delay already built-in. If I told you what I ate yesterday, my statement isn't delayed by one day. But that doesn't mean that your knowledge of what I ate isn't! The latter is the "delay" the video refers to. The example is clear about this as well: the frame shown after the lagspike does not take the lagspike into account exactly because that frame is being calculated as if it will render in the same amount of time that the last frame did. Regardless of what you're actually building, it is theoretically impossible to react within 1 frame to the time it takes to render just by reading the deltaTime variable. In short, it takes exactly one frame before you can react to how long a frame takes to render. I'd like to ask what you would describe this effect as, if not a "1 frame delay." This description has nothing to do with motion; it's a factual description of what you observe when you look at the game frame by frame. It takes one frame to adjust to a frame taking longer to render. You cannot adjust immediately. This is the definition of a delay. Don't get me wrong, I agree that there are ways in which the video could have been clearer. I just don't think that the things you take issue with are the problem, and that the alternatives you provide make things less clear rather than more clear. What the video really needed is not a change in definitions, but a more precise and consistent use of language. "Last" and "current" typically have the same meaning, but it'd be clearer if you stuck to one. It'd also be helpful to distinguish a "frame" as what's being shown, from an "update" as being the process to create it. And possibly a few other similar things. The content and presentation itself is fine and doesn't need to be changed, the script for the video really just needed one more editing pass.
@mcarr87
@mcarr87 10 ай бұрын
@@Gamesaucer I appreciate your arguments and while I don't disagree that much of this depends on your particular definition, I don't agree that in this context of programming the definition of 'current frame' would only refer to the frame most recently output to the GPU. While not used too commonly as a direct term in the Unity docs and variables, you'll only find "current frame" referring to the one currently being processed that would next render (e.g. OnDemandRendering.willCurrentFrameRender) unless referencing something selected in a timeline like in the Profiler. Also I was directly referring to where the video's uses the phrase "the frame currently being processed". I 100% agree that a frame can and often does refer simply to the image presented to the screen, and the duration of that image on the screen in a standard, single buffered game would be determined by how long the following frame takes to update and render. That's not in question. But you bring up a great point that I didn't bother with because I'd already written too much before, and that is how a game could have multiple Updates without rendering a frame if it wanted. Alternatively you could have things like double or triple buffering that could delay the rendering of a frame until after other queued frames had rendered. To me, both of these are great arguments for my point. First, going off your concept, lets say you're in Unity with a disabled Camera object and you manually called Render() every 3rd frame. Here you have 3 Updates over 3 frames (as per Unity's definition of a frame. See e.g.: "Update[()] is called every frame") where only 1 of them is something drawn to the screen. You also have 3 different deltaTime values across those frames, 2 of which can't be said to have any relevance to what was drawn on screen last. You could also run your game's multiplayer server without rendering anything ever and it still has deltaTime and what most refer to as a frame rate (including Profilers, etc). You could argue that without rendering anything there is no 'frame rate' if you wanted, but that only diminishes your arguments because deltaTime still exists and is still calculated in the way I said it was without any relevance to what was drawn or if anything was drawn at all. The same type of example can be given for multiple buffering of frames where the deltaTime does not relate to what was last drawn on screen. I don't think in the context of programming your point "the moment it appears on my screen is a single point in time and not a process" has much validity. For one, saying a frame is a point in time doesn't really relate to the concept being discussed which is to do with the duration of a frame. Secondly even if you were to try to talk about it as a singular moment in time, what moment is that? When the LCD monitor draws the first line or the CRT's electron gun starts emitting or when the end of the image is finally displayed? What if the frame rate is faster than the monitor and it never finishes? I know that's overly pedantic, but it's just to illustrate that that is not a consistent or really even well definable thing and doesn't actually relate to actual programming and deltaTime. I don't really want to continue, but I'll quickly address your points on "1 frame delay" which I also find a bit odd. Saying what you ate yesterday is completely different from deltaTime. When deltaTime is calculated by Unity when a new frame begins processing, that is not a value telling you about something from the past. That is an immediate, current time difference between right now and back then. If it's referred to on the next line it's extremely current and relevant. You could say it's less 'current' later in the frame processing, but that depends entirely on how it's used. This is why I mentioned how you could use your own delta time calculation for rendering if you really wanted something more current for the frame you're processing than deltaTime. To say it has a delay is to proscribe a very weird definition to it. It is what it says it is and it does not give a delayed value at any point after its value is set. It's always 100% accurate as per what it is defined as being the value of. You know immediately at the start of processing a frame what the time the last frame took, there's no delay. That's the point of the value. To say it has a delay would be to give it the definition of "this is how long this frame will take, but you won't know until next frame because it has a 1 frame delay". I feel like this sort of discussion comes across as antagonistic and I apologise if it comes across that way. I also expect this could be one of those things where it's an ongoing back and forth, but I don't want to do that. I will freely admit that there's validity to the video's way of putting it and taken with certain definitions it's not wrong. This is what I said in my original post. I just don't believe in the context of programming, which this is, it was stated in the most valid and coherent way.
@Pontypants
@Pontypants 10 ай бұрын
I am one of those. I know everything. No need for pen and paper. I already know. Even what I don't know I know... And then some..
@Bobsteperous
@Bobsteperous 9 ай бұрын
Now THIS is the kind of tutorial i need, ive had enough of people just telling me what to put in to get my desired output, and i need that perfect level between talked to like a baby, and expecting im Einstein. You hit that nail right on the head.
@charlesmayberry2825
@charlesmayberry2825 5 ай бұрын
I'm glad you pointed out the issues with update and fixed update, The thing is, some things need to be calculated before you should continue, in which case, fixed update is the answer, however those need to be lightweight because you need them for function quickly, in some games the physics may not need high accuracy, in which case, it's fine for them to happen whenever. However games that are heavily reliant on the physics (like an FPS) you really need those collisions calculated before continuing.
@RobLang
@RobLang 10 ай бұрын
*screams in multiplayer* Love this video, Jonas. Beautifully explained. Would love to see more like it!
@magnusm4
@magnusm4 10 ай бұрын
Please elaborate. I've wanted to implement multiplayer in the future so any hiccups or things to consider is really useful.
@aleksapetrovic7088
@aleksapetrovic7088 10 ай бұрын
.
@IONProd
@IONProd 10 ай бұрын
@@magnusm4 multiplayer you can't just use deltatime for each pc because everything needs to be synced. So you need a main computer (which could be a player too) that does the calculations, and the players' pcs need to display that information. But frames can't be involved in the calculations of the variables, otherwise things would move really weirdly. You need the numbers sent to the pcs, and the pcs to render that information using deltatime, because you need to get the correct number for that point of time based on when the individual player's frame renders. And the rendering calculations are gonna need to be precise otherwise objects are going to appear in the wrong spot because if the calculation is off the number on the server is still correct, but it's displayed incorrectly on the player pc.
@Kenjuudo
@Kenjuudo 8 ай бұрын
​@@IONProdAnd this is the reason why so many beautiful indy games lack multiplayer support. It's really hard to do properly.
@JustinBieshaar
@JustinBieshaar 9 ай бұрын
This was truly such a treat to watch! As an experienced game developer myself, I am definitely sharing this with aspiring and junior devs around me as this is such an informative and fun way to understand the use of deltaTime. Big ups and don't mind making more of these videos! 😉
@LethalChicken77
@LethalChicken77 10 ай бұрын
You actually do want to multiply by fixedDeltaTime in FixedUpdate a lot of the time, to ensure that your speeds are in units per second and the numbers in the inspector actually have meaning. It's also needed for more advanced custom physics, used in the integrations.
@routeone4790
@routeone4790 10 ай бұрын
This needs to be turned into a series to help new people to understand more on coding.
@battalll
@battalll 9 ай бұрын
i dont think this has to do anything with coding. more like high school physics and how delta time on game engines work with a very very simple explanation.
@afriendlyfox
@afriendlyfox 8 ай бұрын
@@Fix-- Why did you get scared away? If you didn't understand anything, I want to say that it's completely normal for a newbie to not understand like 70% of the video. To be able to take something from this video, you need to have basic knowledge of C# (at least be able to write a quadratic equation solver), basic knowledge of Unity (at least what GameObject is, what MonoBehaviour class and its methods are and a rough idea of how physics work in Unity), a good school level math and some calculus knowledge. Besides, you have to have tried to make a character move to encounter the problems Jonas is talking about.
@Strong256
@Strong256 9 ай бұрын
Mans violated my last braincell after clapping for nobody at 12:50
@runrajrun
@runrajrun 10 ай бұрын
Really entertaining video, the pacing is great! I'd love move videos like this in the future
@RyanCamaratta
@RyanCamaratta 4 ай бұрын
Subscribed, i really like your fun way of explaining things Most people try this and imo wind up compromising the quality of the video/explanation/etc but not here, this was great!
@JonasTyroller
@JonasTyroller 10 ай бұрын
Which grade did you get? :D
@Alithegamer99
@Alithegamer99 10 ай бұрын
Please when is thronefall dropping on PS4
@ngoclangthi7442
@ngoclangthi7442 10 ай бұрын
I got grade c! (Being a beginner programmer that can't even make a simple player movement script lol)
@jpratt8676
@jpratt8676 10 ай бұрын
F, because I didn't write down my points. I did okay but it counts for nothing :P
@Pixel-fish
@Pixel-fish 9 ай бұрын
F i got 10 in the second question and ten in another and then lost ten
@veritas7010
@veritas7010 8 ай бұрын
Grades are of no importance
@TheShelfman
@TheShelfman 10 ай бұрын
Thank you for your service professor Jonas😎
@JonasTyroller
@JonasTyroller 10 ай бұрын
Always.
@richardericlope3341
@richardericlope3341 10 ай бұрын
Awesome vid! I've always been partial to fixed timestep. It's just a few vars and a singgle function you call everyframe. Less calculations as well when compared to variable timesteps. Slowdowns are better than frame jumps. Collisions get crazy unless you do some swept tests in variable timesteps. Online games though is where variable timesteps shine. I once made an article about it that shows how to use variable, fixed, fixed + accumulator(Gaffer's technique) , etc. alongside each other. Seeing them simultaneously run was nice.
@simoncodrington
@simoncodrington 10 ай бұрын
Outstanding video mate, great work trying to demystify this. Be keen to see more content like this
@mathijsfrank9268
@mathijsfrank9268 10 ай бұрын
It is called FixedUpdate, but that doesn't mean it is actually 100% fixed. It tries to run in fixed intervals. However this will never be exactly right, either because of cpu cycles or if a fixed update exceeds its time budget. This will most likely be insignificant in most cases, but there is still a reason to use fixedDeltaTime for this. For example if you run physics in this fixed update and it always takes just a tiny bit longer than expected, the error can add up over time and without fixedDeltaTime it might explode your physics.
@JonasTyroller
@JonasTyroller 10 ай бұрын
That's a useful addition. Good to know.
@chocolate_maned_wolf
@chocolate_maned_wolf 9 ай бұрын
@@JonasTyrollerthis comment should be pinned tbh
@allenhalsted4895
@allenhalsted4895 10 ай бұрын
I have been developing games since the 1980s and have built several game engines from scratch. So I didn't really learn anything today, but I think that Jonas did an excellent job of explaining the concept. Keep up the good work!
@LePeppino
@LePeppino 10 ай бұрын
That was great! As a newbie in game dev I was really proud to get some questions right, hehe. And your examples and explanations were really good and useful, would love to see more like this. Subbed!
@MarissaFarmer
@MarissaFarmer 10 ай бұрын
This was a really great video. I don't see a lot of in-depth discussions to this detail, so I really liked it. I hope you do more!
@L1Q
@L1Q 10 ай бұрын
I expected a tip related to doing visual calculations exactly at render time by accounting for extrapolation in the shader. Game logic can still run 100% correct and lag by a frame, but image is always as fresh as it can possibly be. Great use for this is e.g. rotating camera with mouse/joystick movement. Another approach could be to use absolute time. Absolute is way better for most functions that can have a definite starting point. The last task is such a case. No way accumulate error over time. Just subtract start time from current time and plug the function result into lerp. And for bonus points: do both in the shader :D
@SpaceMushroomAdventures
@SpaceMushroomAdventures 10 ай бұрын
The amount of work put into this video is insane! I am not even interested in deltaTime, but I am still watching
@bradley1995
@bradley1995 10 ай бұрын
Stumbled onto this video. The information is clear, the illustrations are all over, it's funny and witty, and has thought me something while maintaining my attention. I've been a dev for sometime but this video has by far explained this topic better than any other. You have gained a sub from me! Can't wait to check out your other content!
@emiroguy
@emiroguy 10 ай бұрын
Cool video, good explanations with good humor! I just subbed, looking forward to watching your other videos!
@ThiagoJaqueta
@ThiagoJaqueta 10 ай бұрын
The reason why fixedDeltaTime exists, is that you'll be able to change the rate of fixed updates per second. By default unity uses 50hz, but you might wanna increase or decrease this value depending on your project. If you don't multiply your values by the delta, changing the rate in [Edit > Settings > Time > Fixed Timestep] will result in the physics running faster or slower than intended.
@Pixelhurricane
@Pixelhurricane 10 ай бұрын
yep absolutely, once was having issues with the precision of physics collisions in a project I was working on so I had to bump up the fixed update rate to help solve it. I use fixedDeltaTime in my workflow for exactly cases like that, I might have had to rewrite weeks of code otherwise
@rhysvanderwaerden5518
@rhysvanderwaerden5518 10 ай бұрын
You can even modify fixedDeltaTime at runtime.
@simaopereira9416
@simaopereira9416 10 ай бұрын
Wow, I'm honestly quite impressed by the quality of this video. It's very entertaining and informative at the same time, I hope you do more videos like this ;)
@baralike8206
@baralike8206 10 ай бұрын
I think this is a great subject and something that many lack a good understanding of, but in my opinion this video too shows a lack of understanding of deltaTime. My biggest problem with this video's explanation of deltaTime arises in the explanation of why alternative b) is wrong in the first question (around 4:18). This video seems to present the idea that a frame should represent what the state of the program is when the frame is presented, while in reality, a frame represents what the state of the program was when the frame's update function began (when deltaTime was measured, to be precise). This means we're not using "the last frame's deltaTime as an approximation for the current one's," we are instead rightfully using deltaTime as the time between the last update call and the current one, because that gives us the state of the program at the time of updating. This also means that deltaTime does not "always have a 1 frame delay" (5:34) as an explanation for why lag spikes are 1 frame off. Instead, the state of the program that a frame is presenting is always at a 1 frame delay from the current state of the program. There is no special feature of deltaTime making it 1 frame behind. Furthermore, in any well-designed double-buffer renderer, the previous frame should be drawn on the gpu while the current frame is updating on the cpu. Once updating has completed, the previous frame is presented as the current frame, making the presented frame TWO frames behind the current state of the program. (+1 for every additional frame buffer) Other than that, I think this video explains things well and was fun to watch. A quick point to make is that for the explanation of the last question, the idea is presented that an exponential function is essential to achieve the desired result, while any function beginning at 0 and approaching 1 would work, such as 1 - 1/(1 + deltaTime * lerpSpeed), removing the need of Math.Pow. I guess I'll come across as another know-it-all, but I just wanted to share my understanding of the topic and I'll be happy to discuss it further!
@xNothing2Lose
@xNothing2Lose 2 ай бұрын
Ty for the reminder. I am working on my first small engine in pure JS as a foundation for my first full game intended to be realy released. All my tinkering in the last few years were great for building skills. but i mixed up alot of concepts over time doing that. Your video is a pearl to get it right again.
@skatehansen
@skatehansen 10 ай бұрын
Thank you ! currently developing my first game now, and want speedrunning as a focus. So I'm always scared of having inconsistent results. I mostly do FixedUpdate stuff tho. Rb char controller. But anyone know any other areas I should look out for or ways to test this easy ? the lag spike was a neat trick. Edit: oh no, im actually doing all the speed calculation in Update, time to refactor some stuff... haha
@RevenaSurniak
@RevenaSurniak 7 ай бұрын
just when you think it starts to make sense
@jakedeschamps4454
@jakedeschamps4454 9 ай бұрын
This video was great! I had a pretty good understanding of Delta time, and the problems with how it may be used, specifically when the frame rate changes, but I didn't know of any solutions until now! I never considered only adding half of the value calculated by Delta Time, and then the other half after the computation! That's very clever. Before this video, I was working on some algorithm to implement to compensate for the lower precision of lower frame rates, but this looks like it should be sufficient for my needs!
@wareya
@wareya 10 ай бұрын
Very good!!! I'm glad it's getting easier and easier to teach people about the acceleration gotcha. I'm always sad when I play a precision platformer and some of the jumps are impossible unless I limit the game to 60fps. I got 160 points!
@dexlovesgames_dlg
@dexlovesgames_dlg 10 ай бұрын
Hey you seem to understand this. can you explain why he used .5f as if it means half? isn't that hexadecimal for 95? isn't he trying to get half the acceleration for the first part of the frame and half the acceleration for the second half of the frame? if that's the case why didn't he actually just use .5? And if he wasn't trying to get half, doesn't that mean the snails would've accelerated quicker than they were when it was just one line? was the point not to get them to move the same speed but split the acceleration addition up so that it would get an average of the frame start and the frame end acceleration? to be clear, i need no explanation of delta, i understand how it works. I just don't get this bit. about splitting the acceleration into two. i get why he does it, cuz i understand why you wouldn't want the acceleration from before nor the after, but rather the midpoint of the two, i just don't understand how multiplying by .5f gets that, unless .5f is in fact just .5, but it seems like it's hexadecimal for 95 edit: oh my god, i was right the whole time it is just 1/2. 0.5f is unity notation for floats. that was so confusing as someone who uses godot. correct me if i'm wrong
@wareya
@wareya 10 ай бұрын
@@dexlovesgames_dlg yeah, f is the suffix for "this is a single-precision float, not a double-precision one"
@legendgames128
@legendgames128 6 ай бұрын
2:20 Well, arguably, Betty has the advantage here, because as she and Jerry go really far distances, Jerry is changing his x position by a very small number, which gets essentially zeroed out as he loses precision, meanwhile, Betty can keep going for a bit longer, since she is adding a bigger number to her x position, thus precision takes longer to catch up with her.
@descai10
@descai10 10 ай бұрын
19:50 I generally find it better to just use deltaTime alone as the exponent rather than multiplying by a lerp speed. This way you can adjust the 0.5 to whatever ratio you want the lerp to reach each second.
@The_Schnitzel_Man
@The_Schnitzel_Man 10 ай бұрын
Hey man, this is a great video, thanks for pumping out awesome educational videos. Keep up the good work❤
@rightwingsafetysquad9872
@rightwingsafetysquad9872 10 ай бұрын
Using the mid point to calculate the average on an exponential function should be sufficiently accurate unless your frame time is extremely large. I do it for IRL ballistics calculations with an assumed time interval
@sealsharp
@sealsharp 10 ай бұрын
A little technical precision in times of "with AI everyone can make games without learning or hard work". Wonderful.
@deltapi8859
@deltapi8859 10 ай бұрын
"betty is lacking behind, what have you done, you monster" ... beautiful... The whole concept. Beautifully done.
@JellyMudkip
@JellyMudkip 10 ай бұрын
Thanks for the video, you help me with the issue in Lerp function hahaha now I can solve it
@junaidywijaya6413
@junaidywijaya6413 8 ай бұрын
I think this is a very interesting topic because i also always use approximations because who plays games with 2 fps, but yeah it's informative nonetheless, and also for the lerp one, if you use linear lerp instead of exponential lerp can we use the same formula to calculate the time?
@cptshini
@cptshini 10 ай бұрын
Hey Jonas. I must admit that I almost wrote a slightly angry comment claming your answer, to the lerp() function example, was incorrect. However, while writing the comment, I realized you actually wrote the function as the following: current = Lerp(current, finish, t); Instead of what I thought you wrote, and based my answer off: current = Lerp(start, finish, t); So yeah... I think your way is a strange way to do it, and also causes some confusion in regards to the question you asked; at least it did for me. I would've gotten a B instead of a C if I didn't misread :') nice vids btw
@drdca8263
@drdca8263 10 ай бұрын
Ohhh i also missed that! I need to go edit my comment now
@louisdalibard818
@louisdalibard818 10 ай бұрын
Great video! However, wouldn't 19:49 still be wrong though since you are just using the deltatime for each frame and not a sum of all previous deltatimes?
@MichaelDarrow-tr1mn
@MichaelDarrow-tr1mn 2 ай бұрын
The lerp is from the current position, not the starting position.
@TylerShelton1
@TylerShelton1 9 ай бұрын
Really enjoyed this video! Seemed like kind of a new style for you and I'd love to see more like it.
@BitBeginnings
@BitBeginnings 10 ай бұрын
I really enjoyed the breakdowns and examples. I would love to have this type of common gamedev mistakes video to be a regular thing. Cheers!
@1e1001
@1e1001 10 ай бұрын
i've tried to make my own game engine before :), 155/160, here are my notes / answers: anything in [square brackets] i added after seeing the answer in the video 1. `position.x += Time.deltaTime * this.playerSpeed` since you're in `Update` (maybe add a cap on `deltaTime` to prevent intentional lag from breaking your game) 2. b (time between start of current frame processing and start of previous frame processing) [i'm counting this as +15 since end of a frame is pretty much start of the next frame (actually start of frame is better because if you present way earlier then v-sync will add a delay of it's own which can mess things up)] 3. small shift over, since the game is still presenting the same next frame [like the frame it's processing is the same as the frame that lagged] 4. replace `deltaTime` with `fixedDeltaTime` 5. `var oldSpeed = this.playerSpeed; this.playerSpeed += Time.deltaTime * this.playerAcceleration; position.x += Time.deltaTime * (oldSpeed + this.playerSpeed) / 2` integration my beloved [this is equivalent to splitting the update in half] 6. setting speed = to 10 instead of +=ing 10?? 7. thinking about this one mathamatically - lets say a speed of 1 means you get from 0 to halfway in 1 second - 1s dt = 0.5 lerp - 0.5s dt = some lerp x such that 1 - (1 - x)^2 = 0.5 - ys dt = some lerp x such that 1 - (1 - x)^1/y = 0.5 - solve for x & simplify: 1 - 0.5^y - `transform.position = Vector3.Lerp(transform.position, targetPosition, 1.0 - 0.5 ** (Time.deltaTime * lerpSpeed))` or however c# does exponents
@lucaheft
@lucaheft 10 ай бұрын
I dont think your right with the assumption that deltaTime lags behind 1 frame. Unity docs also state, that it's "The interval in seconds from the last frame to the current one". So it's basically the time since last frame to the start of calculation of the current frame. I briefly tested by logging Time.deltaTime ,Time.time and Time.frameCount. If you press Play in "Paused" mode you can see for the first frame the deltaTime is 0 but for the second frame you will get the correct deltaTime. If the deltaTime would be delayed by 1 frame you should see 0 for the first two frames. As there is nothing to compare against. Interestingly Unity seems to be buggy in regards to the deltaTime. If you don't start with Pause enabled, you somehow get a deltaTime > 0 in the first frame. Also if you do start in Paused Mode but disable it after stepping a few frames. You will somehow get a deltaTime of 0 at the frame you disabled paused mode ¯\_(ツ)_/¯
@APaleDot
@APaleDot 10 ай бұрын
I think this is an ambiguity with the phrase "current frame". In the video, he means the frame that hasn't been displayed yet, and the "start" of that frame is when it is displayed. But most game developers think about the "start" of the "current frame" as when the previous frame ended and the frame is displayed at the "end" of the frame rather than the "start".
@xijnin
@xijnin 7 ай бұрын
Well, in gamemaker it's very rare to use delta_time, but when we make a timer we use room_speed, which is the gamespeed, like my_time = 5 * room_speed; So my_time will be 5 seconds
@jigarpanchal0
@jigarpanchal0 10 ай бұрын
I am at of the video 2:32 and my senior in old company taught me about this that delta time give you the time passed between from first frame to second frame then second to third and so on which helps keep the speed consistent through out any computer regardless of FPS
@TacoTechnica
@TacoTechnica 10 ай бұрын
Loved this, a lot to chew on even for more experienced game devs! Just one extra thing, in 15:35 isn't there also a potential error where the jump input is checked after running movement code, introducing an extra frame of delay when a user wishes to jump?
@chocolate_maned_wolf
@chocolate_maned_wolf 9 ай бұрын
Good catch :)
@DaMu24
@DaMu24 10 ай бұрын
I highly appreciate the math explanations. Calculus is an important topic that can be learned as early as high school, maybe earlier if you have the perfect teacher, and solutions to game development like this are why learning advanced math is important.
@zeckma
@zeckma 6 ай бұрын
The sad thing is that teachers make a terrible case for learning calculus, algebra, and geometry, usually throwing only rocket science as an example. I went through the classes just fine but never understood why I should learn the material and could never discover a legit use case for it. That is until dealing with graphics and games, at which point I heavily regretted forgetting most of what I had learned.
@JanTGTX
@JanTGTX 3 ай бұрын
I'm with you, but schools don't seem to have an interest in teaching "real" math. It's all just about calculating numbers, like robots. Studying physics was an absolute eye opener for me. There I got taught math on a more fundamental level, which really made it click. I'm still wondering why they don't teach axiomatic systems, logic and set theory in schools and let the students be creative for once. The basics actually aren't that hard. After having achieved some knowledge of those topics, calculating stuff, even derivatives and integrals, which are the highest level topics in schools, becomes piss easy.
@risingpheonix7740
@risingpheonix7740 2 ай бұрын
Excellent video. Really useful to realise that you can graph out the change you want, and then use most o fthe concepts you get taught in Mechanics courses to get the desired outcome. very happy to see the important point of testing a game at different framerates also came up. It's important to keep testing and reassessing what you make to ensure it's all running as intended.
@TheMrKeksLp
@TheMrKeksLp 10 ай бұрын
Very good video, I never thought too much about deltatime and that you essentially need to integrate your formulas to make it mathmatically correct
@MythicLegionDev
@MythicLegionDev 10 ай бұрын
Thank you for this cursed knowledge Jonas
@muzzaclips768
@muzzaclips768 9 ай бұрын
We thought you perished!
@_stephenhubbard
@_stephenhubbard 10 ай бұрын
KZfaq game dev eduction needs more videos just like this! Really great format.
@BirnieMac1
@BirnieMac1 3 ай бұрын
Coming from only knowing the maths and modelling side (basically just the engineering modelling stuff) and next to nothing about the game development side this is super useful - especially the intricacies of how an uneven interval can introduce issues and so on
@seanthesheep
@seanthesheep 10 ай бұрын
I'm not a game dev, but I sometimes make animations for the web, and I come from Scratch, where everything runs at a fixed 30 FPS. But on the web, requestAnimationFrame (seems to be like Unity update) uses your monitor's refresh rate, so I have to take into account variable frame rate (like deltaTime). I wanted to use the following idioms in Scratch for animations: // gravity set y to (10) set [yv v] to [0] forever change [yv v] by (-0.5) change y by (yv) end // gradual approach (like exponential decay) forever change x by (((target x) - (x position)) * (0.8)) end But I didn't know how to make them work with variable frame rates, so I ended up just implementing my own fixedUpdate. So this video is quite enlightening on how I can do it without fixedUpdate
@TagaRamer
@TagaRamer 10 ай бұрын
I have a degree in electrical engineering and I changed my career into programming and finally the math I learned became useful! I loved your video !
@sixtenhugosson
@sixtenhugosson 10 ай бұрын
During the part on acceleration, you can use the equations of motion to get: transfrom.position += Vector.right*speed*dt+Vector.right*acceleration*dt*dt/2; speed += acceleration*dt; You should get the same result but in a "physically correct" manner. In the end it reduces to the same result, but it could still be useful.
@EfeDursun125
@EfeDursun125 10 ай бұрын
use * 0.5f
@mrnowhere-sc3mv
@mrnowhere-sc3mv 10 ай бұрын
Correct me if I'm wrong, but the first method (which is the same as you provide) is called the forward Euler method, which tends to artificially adds energy to the system the further it goes. Updating speed before position (the sympletic/semi-implicit Euler method) or adding half before and after (the midpoint method, which equates to 0.5 because he is using a linear function) tends to be more stable (the error is bounded)
@hardtofinduniquename
@hardtofinduniquename 10 ай бұрын
To be clear: It's not just the same result but it's also the same mathematical formula, except not applied with intermediate state (only modify speed once). It's easier to see if you simplify the formula to: transform.position += Vector.right * dt * (speed + acceleration * dt/2); speed += acceleration * dt; And then pulling out the acceleration term to apply to speed makes looks like Jonas' code: var boost = acceleration * dt/2; speed += boost; transform.position += Vector.right * dt * speed; speed += boost;
@hardtofinduniquename
@hardtofinduniquename 10 ай бұрын
​@@mrnowhere-sc3mvFor anyone who wants to go deeper on this math, "Math for Game Programmers: Building a Better Jump" goes into Euler integration, Velocity Verlet, and concludes simplified Verlet (the same result we have here) is a good compromise: kzfaq.info/get/bejne/nq1pht2C3cennWw.html
@yunimars568
@yunimars568 10 ай бұрын
This is just what I needed. Yesterday I realized that the most watched unity recoil tutorial had major mathematical errors and this perfectly summarizes how to avoid them. Thank you
@SauROnmiKE
@SauROnmiKE Ай бұрын
This video was recommended to me at 1AM in bed, stayed glued to my phone screen all of the time and still understood everything. World-class explanation. Subscribed
@rayank2010
@rayank2010 10 ай бұрын
when your use the lerp function your supposed to have a "linear" speed without acceleration because it's a Linear intERPolation, if it looks exponential it's because you change each frame the beginning position (parameter a) so : pos = lerp(pos_begin, pos_end, t) Great video though !!
@pepperdayjackpac4521
@pepperdayjackpac4521 9 ай бұрын
So, is the reason the lerp was looking exponential causes by the fact he use transform.Position, which got the current position, instead of the start position which never changes, so it should be a constant, somewhere outside the update function?
@rayank2010
@rayank2010 9 ай бұрын
@@pepperdayjackpac4521 Yes it wouldn't be exponential if he sets the initial position. You can test yourself to see.
@MiTheMer
@MiTheMer 10 ай бұрын
Please more of this format!! It was helpful and entertaining at the same time!
@astecheee1519
@astecheee1519 9 ай бұрын
Loved the video! As far as functions that approach but don't quite reach 1, there are other options available, yes? I feel like hyperbola could be useful.
@TeamUnpro
@TeamUnpro 5 ай бұрын
omg I couldn't BEGIN to work with multiplying by delta time, I'd lose it~ Ty for pointing this out, it is indeed getting a little out of hand, gotta love that stuttering!
@thecryptacoder1126
@thecryptacoder1126 10 ай бұрын
It says 0-10 for an F, what happens if I got a -10?
@GrifGrey
@GrifGrey 10 ай бұрын
give up (just kidding, keep on learning)
@TackerTacker
@TackerTacker 10 ай бұрын
Great video, I got a 🐝 Personally I'll stick to the simpler approximated version though, keeps the code simple and more readable. If your game is consistently running at ~2 FPS you got bigger problems and if it's just one hiccup it doesn't make a big enough difference IMO. At least as long as it isn't an online multiplayer game or something that needs deterministic physics.
@MaakaSakuranbo
@MaakaSakuranbo 10 ай бұрын
Make it less simple, stick it into it's own function. There, nice and readable in your normal code
@stickguy9109
@stickguy9109 10 ай бұрын
2fps was just an example. You can have something that accumulates overtime because of wrong deltaTime and gets messed up. For example I had a character controller that would get slower and slower as the frame rate drops and below 15 it would stop moving altogether. See what I mean
@TackerTacker
@TackerTacker 10 ай бұрын
This discussion about the mathematical correct version of lerp is a relatively recent topic in the indie bubble and no one was doing it that way before, without anyone ever noticing a problem, that's how big of a deal it is. I don't stop anyone from using the more complex version, I'm just saying that I myself stick to the easy version 🤷
@stickguy9109
@stickguy9109 10 ай бұрын
@@TackerTacker I use a tweening library that takes care of it. But no it has to be correct because it becomes very noticeable when frame rate drops even a little bit
@TackerTacker
@TackerTacker 10 ай бұрын
@@stickguy9109 I think you mean something different than I do. By approximate version I mean "lerp( a, b, lerp_speed * delta_time )" not no delta_time at all.
@thalianero1071
@thalianero1071 7 ай бұрын
This reminds me of Minecraft entity rendering, where the partialTicks / tickDelta parameter which appears to be this but measured in server ticks instead of seconds. MCP mappings (partialTicks) appears to think this is the fraction of the current tick you’re rendering at, while Yarn (tickDelta) appears to think this is the tick distance between the previous two frames. For actually writing entity rendering code, either interpretation works
@Mastro2k
@Mastro2k 7 ай бұрын
This video is very entertaining and engaging!! I usually fall asleep to these technical type if videos. This video kept me totally into it with your delivery and graphics!
@Serlith
@Serlith 10 ай бұрын
This lerp thing called "thecorrect way to lerp" is misleading, because in lerp we are LINEARLY interpolating, and you have showed us an easing function. Which is fine, but... Well, not what lerp is about. I'd use Vector3.SmoothDamp for that. Usually the "correct" way to use Lerp is to have a defined constant start value and an end value and calculate the t parameter by incrementing time elapsed and dividing it by the lerp duration (precalculated from speed and distance or w/e), instead of submitting the current value as the first Lerp argument for every frame. Then you can get fancy and add easing functions to that t param calculation.
@EpicGamerScout
@EpicGamerScout 10 ай бұрын
I don't think there's necessarily anything wrong with using a lerp in this way. As long as you're careful to acknowledge that you're using the lerp as a building block for your own primitive exponential easing function, and make sure to do it right, then that's probably one of the simpler and more transparent ways to think about implementing one. "I want the distance to half every X time" > "Lerp is an extremely simple way to get the halfway point" > "Here's how I can modify the lerp implementation to be robust to changing update rates". You might be reinventing the wheel a bit, but if you're more familiar with the math than the engine, it works out just fine!
@Serlith
@Serlith 10 ай бұрын
@@EpicGamerScout It has the distinct issue of having to snap the object to target position after the elapsed time, leaving us with about the same amount of code though.
@lapissea1190
@lapissea1190 10 ай бұрын
I always liked the fixed update per second model more. It is actually deterministic and it is a lot simpler to write and less bug prone. Yes it will make the game run in slow motion if you are unable to achieve the TPS but also if you can not run quickly enough with delta time, you will get large deltas and possibly break the game in a bad way such as phasing trough walls, consuming more resources than exist and such so so much more.
@bluefake_or_smt
@bluefake_or_smt 10 ай бұрын
19:27 I had as a solution: float elapsedTime; void Update() { elapsedTime += Time.deltaTime * someMul; transform.position = Mathf.Lerp(startPos, target, 1 - 1 / elapsedTime); } I was hela confused when you presented your solution, but then saw you used transform.position instead of startPos. It would work if the startPos is set, but your solution doesn't need that and is therefore still better Edit: Looking back I see the issue that you should probably split the Time.deltaTime-adding in 2 halfs
@Spelo1
@Spelo1 10 ай бұрын
Same thing, was hella confused when he didn't put in a time counter until I've noticed that the start position is not a constant one
@K_J_Coleman_Composer
@K_J_Coleman_Composer 10 ай бұрын
Please do more videos like this!!! I need it desperately >.
@norude
@norude 10 ай бұрын
What grade do I get for a total of -10 points?
@Glu10Free_Waifu
@Glu10Free_Waifu 10 ай бұрын
Negative F...
@Firestone-Games
@Firestone-Games 10 ай бұрын
New Jonas Video Lets gooooo!
@NavyPanther54
@NavyPanther54 7 ай бұрын
These visuals were insanely good. I didn't expect the answer for the linear acceleration, splitting it up like that. But it makes sense with the graphs!
@kaiiboraka
@kaiiboraka 10 ай бұрын
Educational and informative as always, but this is also funny as heck. At 10:34 I legit laughed so hard for like 2 minutes straight just at your delivery, that was so frickin funny, I was not prepared for that. 😂😂
@JeanPhilippeBoucher
@JeanPhilippeBoucher 10 ай бұрын
Jokes on you, I multiplied my grade by delta time and now I'm above the maximum!
@lFunGuyl
@lFunGuyl 12 күн бұрын
Jokes on *you*! You multiplied your grade by a number almost certainly less than one! Your grade was lowered to a fraction of what it would've been! Unless you run with less than 1 FPS in which case the joke would again be on Jonas...
@JeanPhilippeBoucher
@JeanPhilippeBoucher 12 күн бұрын
@@lFunGuyl I'll take the risk for a shot at glory!
@MatthewCoder
@MatthewCoder 10 ай бұрын
You think I'm using delta time incorrectly? Well jokes on you, I'm not using it at all. If the game lags, everything goes in slow motion and a pop up appears to insult the player's setup
@squirrrrrrrrel7483
@squirrrrrrrrel7483 10 ай бұрын
lol
@JonasTyroller
@JonasTyroller 10 ай бұрын
Genius solution. We should all start doing it like that!
@MatthewCoder
@MatthewCoder 10 ай бұрын
@@JonasTyroller just finished the video, it was greatly informative and entertaining, thanks Jonas! Sorry about the meme comment hahahaha
@MagicGonads
@MagicGonads 10 ай бұрын
in a networked example you can sync the different perspectives of the world on a fixed interval, but let them use quick approximates in between those fixed intervals (called prediction) so the error has limited time to accumulate into noticeable differences (but also interpolate between the predicted view and the corrected view to avoid jerky motion). (this also applies to rendering done on Update that relies on physics done in FixedUpdate)
@gabrielandy9272
@gabrielandy9272 9 ай бұрын
many games use this, killing floor 2, the enemys keep doing repeating the last action so if its walking forwward and lest say the internet goes down, for 4 seconds, it will keep walking forwards for this 4 seconds while its down (u can lag switch test this) when internet resumes they will smothly move to the correct position, terraria does this as well and many other games i know does this, these two games use prediction and interpolation,.
@JMO-
@JMO- 10 ай бұрын
Great to know that I have using Time.deltaTime correctly all along, except for my lerps... That explains why my character sometimes teleports around. Good video, now I got to dig through my code and fix my mistakes.
@ImNotGam
@ImNotGam 10 ай бұрын
4:20 only reason I picked A is because I’ve made my own frame rate controller lol.
@kales901
@kales901 10 ай бұрын
i chose d because i thout it made scenes... i already know thats its the ammount of lag
This Problem Changes Your Perspective On Game Dev
25:51
Jonas Tyroller
Рет қаралды 316 М.
When Optimisations Work, But for the Wrong Reasons
22:19
SimonDev
Рет қаралды 760 М.
顔面水槽がブサイク過ぎるwwwww
00:58
はじめしゃちょー(hajime)
Рет қаралды 25 МЛН
Why You Shouldn't Nest Your Code
8:30
CodeAesthetic
Рет қаралды 2,5 МЛН
Can We Make This Button Fun To Press?
7:37
Jonas Tyroller
Рет қаралды 915 М.
First Prototype to Actual Game in 22 Days!
9:53
Jonas Tyroller
Рет қаралды 114 М.
20 Advanced Coding Tips For Big Unity Projects
22:23
Tesseract
Рет қаралды 145 М.
Factorio teaches you software engineering, seriously.
21:27
Tony Zhu
Рет қаралды 1,2 МЛН
When Your Game Is Bad But Your Optimisation Is Genius
8:52
Vercidium
Рет қаралды 1,3 МЛН
How Game Designers Solved These 11 Problems
15:41
Game Maker's Toolkit
Рет қаралды 2,5 МЛН
Optimizing my Game so it Runs on a Potato
19:02
Blargis
Рет қаралды 243 М.
I Optimised My Game Engine Up To 12000 FPS
11:58
Vercidium
Рет қаралды 432 М.
The Formula for Replayable Games
18:44
Blargis
Рет қаралды 151 М.
顔面水槽がブサイク過ぎるwwwww
00:58
はじめしゃちょー(hajime)
Рет қаралды 25 МЛН