https://old.reddit.com/r/skyrim/comments/twwqqt/can_someone_...
I recently played Minnit [1], a very small and cute game with a very unique proposal: that you only have 1 minute of gameplay before being warped to a starting point.
But time is not checked asynchronously but as a function of the frame rate, so my playthrough was basically sped up and lasted for 45 seconds each time. Turned out I didn't realize until almost the end, when a _very_ difficult movement seemed almost impossible to make in time (I did end up achieving 100% doable things in the game, but it cost me a good amount of attempts!)
Gamedevs, please, do not count frames and assume they'll be whatever amount per second you believe they'll be. Because they won't.
To be clear: it was at that time that I discovered that some wrong settings in the Steam Deck had been affecting the in-game FPS, so after correcting them and getting to the designed runtime speeds, the challenge got from impossible to barely achievable :)
I brought it into to the professor's office (it was our final) to demo it, and it was so fast on his machine that you couldn't see it. I freaked out, but he had seen that kind of problem before and just sprinkled some sleeps throughout so it was visible to a human and gave me a B.
EDIT to add: Also https://www.youtube.com/@MartinDonald has some good stuff as well. And here's a subset of Handmade Hero you might find interesting: https://www.youtube.com/playlist?list=PLEMXAbCVnmY6Mnkt-EZC_...
As for game logic-it does make sense. Tying logic and rendering to a system timer / frame counter leads to all kinds of issues.
Think of it like this: Imagine you have an expensive tween animation for particles, and every frame you have to use your CPU to calculate where the particle should have moved as part of it's animation, and send those updated coordinates to the GPU. Imagine you have millions of such objects, so it's quite the burden for the CPU, both in terms of calculating the tween animation, but also in terms of constantly updating every particle's x,y values over and over.
Instead, you could seed each particle on the GPU with x1,y1,x2,y2 values, and then just provide a global "time" value for them all to share. When you update time = time + 1, all particles on the GPU will recalculate their position without needing to be helped by the CPU. The trick is that they don't save this new position though, instead, they do the job all over again from scratch at time = time + 2, which is a lot cheaper since we didn't need to "save" our previous result, which is hard work on the GPU.
For instance, here is a DVD logo bounce animation in Shadertoy:
This, and shaders in general, are great examples of better ways to do things.
Often: Dynamic calculation > state
Anyway, now I wonder if this could be done in this style. Bullet position = its origin, vector and then you can determine its location at any point in time, instead of updating its position at every tick.
Doing that one will likely cause issues across a network or if framerate (or game tick rate) is unstable / unpredictable.
It certainly can! Not an expert, but what you are describing can probably be done as a bullet shader.
> Doing that one will likely cause issues across a network or if framerate (or game tick rate) is unstable / unpredictable.
I kind of want to know if a seamless experience is possible without a server... but for now I assume there is one. At that point client frame rate / tick rate does not really matter. Each client sends current character position and origin + vector of all the bullets to the server. Note that current location of the bullets is not important to update the world state - only the origination point and direction. Based on that it can independently do all the hit calculations. Of course this makes cheating possible and any kind of latency extremely annoying, but margins of this post and my available coffee break time are too thin to offer my amateurish take on those problems.
Yes, the technical term for this is Euler integration: https://en.wikipedia.org/wiki/Euler_method
It's good enough for a lot of parts of a game simulation, especially if you have a fixed framerate. But it can get wonky if you have a lot of stuff moving around this way and interacting with each other. Full fledged physics engines in games tend to use more sophisticated algorithms to do the integration to avoid that.
> Bullet position = its origin, vector and then you can determine its location at any point in time, instead of updating its position at every tick.
Unfortunately, no. The linked blog post is a really cool way to think about simple animations but you will very often hit a wall (metaphorically and literally) where this technique no longer works.
The key problem is that the state of an object at time T depends on all possible interactions the object may have had before T. In the linked article, the only interactions are bouncing off walls, which are regular enough in time that you can model them analytically.
(But even in this trivial example, it still doesn't really work. Notice that if you resize your window, the DVD box jumps all over the place. That's because the analytic solution can't understand the notion of a window whose size changes. All it can do is calculate where the box would be now if the window had always been its current size. I digress.)
You can analytically calculate the position of a bullet at any time T given its origin and velocity, but only if the bullet doesn't interact with anything else. If you have, say, a human controller play that is running through the path of the bullet and gets hit, your simulation needs to understand that the bullet won't keep moving after that.
For a use case as simple as this, you may be able to model it statefully by just deleting the bullet entirely once it hits something. But, in general, there is always some level of state that you'll need in order to simulate anything beyond trivial complexity.
One important thing to note is that is not about eliminating all state (that would be absurd after-all a game is all about the state of the main character), but crucially to never take the `t - 1` state of the thing being animated. In games for example, a function animating a blade of grass may take into account many parts of the game state, they often take the character position as a multiplier to amplify the movement if the character is close, imitating collision with the character without actually having to calculate collisions.