I have a Minecart in my game, and looked at a bunch of approaches while working on my project.
Don’t:
Physically model the Minecart based on real-world mechanisms:
Real-world mechanisms work because of real-world laws of physics. When you model mechanisms based on their real-world counterparts, you run the risk of it breaking down when those laws aren’t the same in Roblox. You also take on all limitations of the real-world mechanism e.g. cart will derail if moving too fast / may derail if mass not micromanaged to reflect real-world counterpart.
Use CFrame:
Moving objects like characters use physics to move around – they’re not built to work with objects moving with CFrame. You lose a lot of awesome functionality like interpolation and bodies following the moving part horizontally, and experience problems like bodies clipping through moving parts or getting flung far away because a part teleported into them. There are ways to mitigate this, but implementing custom physics with CFrame is a major hack. It doesn’t provide any real benefits, and is a massive headache.
Use legacy body movers:
Old physics objects like BodyGyro/BodyPosition are no longer being actively supported and can have unpredictable behavior.
Solution:
To dictate where the minecart should travel, I use the node system suggested by @SteadyOn earlier. If you look at the track below, you can see green dots. These are attachments which I use to designate the next node the cart should travel to:
To move the Minecart, I use AlignOrientation/AlignPosition. These are normally used for keeping an object in-place rather than moving it, so I connected them to a proxy part which I move with CFrame. The proxy part being moved in the following video is pink, and the minecart is attached to that pink part with AlignOrientation/AlignPosition.
With this, you get the control of CFrame, but the benefits of physics simulation at the same time. In the following in-game (with latency) video, the minecart’s network ownership is set to the player sitting in the cart. The video is recorded from the perspective of the player standing on the cart.
Note that because the minecart’s location is being controlled by CFrame, it does not speed up or slow down on slopes. This was intentional for my use case, as I wanted to be able to build tracks without worrying if the minecart had enough speed to get to the end – it just goes the same speed always and predictably. If you wanted a more accurate physics simulation, you could probably use a different set of constraints.