I’m really not sure how to get better at it other than (A) doing it a lot, or (B) having a mentor.
But you should certainly read up on design patterns and refactoring, if you’re not already intimately familiar with those. Just search Amazon and pick some recent-ish books with good reviews (I like this and this, but there may be newer ones that are even better).
I would say the #1 concept you want to internalize is: hide implementation details as much as possible, so that you can change them without breaking the rest of your program. For example, take the “simulation of the engine” part of your example. The important thing to think about is how that interfaces with the rest of the code. Perhaps you make an Engine class, with a very small number of public methods to return the speed and torque given the accelerator and gear inputs (or whatever).
Now, your first implementation of that should just be hard-coded in some brain-dead simple way; maybe just a couple of if statements that return fixed speed/torque for each gear, or something like that. You know it’s wrong, but you don’t care, as long as it compiles and runs and provides just enough functionality for you to work on something else.
Then you’ll cycle back later and replace the dumb implementation with a slightly smarter one that actually simulates RPMs or something. The rest of your code won’t care, so you can sit down with just the engine code for an hour or two and focus on that without breaking anything else.
Oh, and that reminds me of critical concept #2: a software program is way, way too complicated for a human to keep all the details in their head all at once. So this is the second reason you hide implementation details; when you’re working on one part of the code, you want to be able to forget all the details of the rest of the code. You only need to know the interfaces (public methods/properties), and those should be as small as possible, to make it easier for you.
So contrast this approach — dividing the problem into classes/modules with all the details hidden — with a more naive approach, where all your properties and methods are public, classes call into other classes or even change their properties willy-nilly, and so on. Such a project is in a world of hurt because (1) when you try to change the implementation of something, it breaks code that was using the old implementation, and (2) in order to add or change anything, you have to keep way too many details from all over the project in mind.
So… that was a long diatribe. In answer to your question, no, I don’t start at the top and break down the whole giant problem before I start working on it. Instead I use successive approximations, starting with whatever fruit is easiest to reach, and using dead-simple “stub” implementations (as described above) wherever possible to keep moving forward. I keep the interfaces thin and make stuff protected/private as much as possible, and just keep refining until it’s done. It probably takes practice, but hang in there — you can do it!