jes / nightdrive

Night-time driving simulation
https://incoherency.co.uk/nightdrive/
178 stars 17 forks source link

Lane changing breaks if frames are throttled #4

Open evoyy opened 8 months ago

evoyy commented 8 months ago

I have been studying this code out of curiosity. Your step function has logic that keeps track of time elapsed since the last step which I assume is to provide a consistent sense of speed and continuity in case of throttled or dropped frames. When running at full speed everything seems to work fine, but if frames are dropped, resulting in a larger value of dt (delta time, I assume), the lane changing logic is broken; cars change lanes into each other, indicate in the opposite direction, don't turn off their indicators, etc.

You can reproduce this by throttling frames like this:


let frameCount = 0;

function render() {
    if (frameCount++ % 5) return;

    //...
}
jes commented 8 months ago

I just tried this out (note your suggested reproduction doesn't work, it needs to call window.requestAnimationFrame(render) instead of just returning) but I don't think it works any worse than it normally does.

The planning is not as good as it should be and cars can drive through each other despite making some small attempt not to.

Are you definitely sure it works worse when frames are being dropped?

evoyy commented 8 months ago

Thanks for the quick response and sorry about the incomplete reproduction. You do need to move the requestAnimationFrame call to the start of the render function before short-circuiting it, but I think you realised this.

Cars do seem to drive through each other, and indicating sometimes goes out of sync with the direction of the lane changing. Cars will indicate one way while moving the other way, and occasionally some cars will not stop indicating at all. It becomes more apparent the more the frame rate is throttled. With a factor of 5 you should see what I mean.

I wondered why this might be and if it's a simple fix or too much trouble to bother with. I did try following the path of dt into car.step(), but it doesn't look simple to me. I'd need to spend some time really analysing the code to have any chance.

The reason I'm throttling the frame rate is because I have a website where I develop audio visualizers of my own, and I also showcase others that I find on the internet, with credits and backlinks to the creators. I'd like to plug Nightdrive into my website. One of the features of my website is the ability to throttle frame rates for low powered devices, to save CPU, battery, etc.

evoyy commented 8 months ago

I decided to undertake a full re-write of the project, converting to ES6 classes and my own coding style. More as a learning exercise than anything else because I have never done vector math or game dev before and there are many new concepts in here for me to explore. I found your blog post as well which is very insightful. If I do get to the bottom of the lane changing / frame sync issue I will let you know.

jes commented 8 months ago

Good luck!