Jailbreak train platform system?

INFO
Recently jailbreak pushed an update, which utilities the new roblox platform system with its trains.
Most of you may know, its not possible to stay on the same platform when jumping, meanwhile jailbreak has fixed this somehow.

PROBLEM
I have no clue as to how they have achieved this, could they be moving a platform up and down as you jump?

EXTRA INFO
-Ive realized that this system will work on vehicles, could be only due to the fact that the player is inside.
-The platform has a max height, and if your within it, it will move you, even if you are not ontop of the platform, for example, the train is under me, i jump onto a hill a bit higher, i will get pushed into the hill, following the direction of the train, however wont go trough.

If anyone has any clue as to how they have achieved this, please let me know.

55 Likes

I’m guessing there’s a value that’s given to the player whenever they touch the train. The value would then give them the same velocity as the train.

Again, this is just a guess.

6 Likes

Thought of this, so I tried it, though it’s got so many problems that it’s not worth it, one main issue is it only apples velocity, not accounting the position exactly, causing the part to slide

3 Likes

I thought there was a physics update in the last year or so that made this work by default?

4 Likes

yeah. im pretty sure that is how jailbreak’s trains got fixed haha.

2 Likes

Characters on Moving Platforms - Now Live As @Crazyman32 it was an update and thats probably how jailbreak did it

2 Likes

If you read that posts replies, you’ll see that the update doesn’t maintain player velocity, it stops players from sliding off moving platforms.

2 Likes

Oh yea I completely forgot about that

1 Like

They fixed this a long time before the new physics update. This feature was implemented into jailbreak with vehicles pretty soon after it was released.

1 Like

Jailbreak has a very custom-made train system that was designed to work before Characters On Moving Platforms was released.

9 Likes

I gave badcc some insight on how we do our trains which he used to implement into jb’s new update, if he used exactly what we suggested, it’s actually pretty simple. For anchoring yourself to the train we just multiply the player’s rootpart CFrame to stay with the movement of the train car.

image

For anchoring other players, it’s a tiny bit harder but still pretty straight forward.

We essentially have a relative cframe from the center of the train car on the server and, after trains are cframed, have your client take that info, loop through other players and if they’re on a train then set their hrp.cframe to trainroot * relativecframe(the one sent from the server)

Hope this helps!

55 Likes

Yep! @tyridge77 tipped me off on the idea of CFraming the Character along with train movement. I didn’t originally want to do this because it’s kind of a fake momentum feel (if train goes around corner and you jump in the air, you’ll turn with it). But it makes everything feel super smooth, so I decided to finally add. Previously I was manually calculating Velocity/RotVelocity for every anchored train part, and the character would move along with it. This broke down a bit on Xbox, something is different there.

Now at start of train update frame I raycast down and check if player is standing on train, perform train update step, and check CFrame of that same part I raycasted earlier in frame. In my code above, that’s LastTrainCF and TrainCF. This way no matter what far the update step is, character moves with it. It’s beautiful. We also have some invisible platforms in between the train cars so that the ray hits it when you jump across.

In Tyridge’s fancy train demo he also broadcasts clients relative CFrame to train base part to every other client. I’m not doing this atm. You should show them some videos of yours @tyridge77 :smiley:

77 Likes

Yeah, there is, though as soon as you jump your removed from that platform, causing you to just fall back.

3 Likes

Thank you, very helpful.

3 Likes

What’s the LastTrainCframe? And what’s the need of inverting it? Thank you btw.

3 Likes

I think I understand this, and they can correct me if I’m wrong.

The system can be likened to a loop. Even if it is a connection to a RunService event, it acts like a loop so I will call it one.

Every loop, it moves players by the difference in position of the car between loops. So if the train car moved 14 studs in one loop (as an example), it would move the players inside 14 studs also. The script knows how far the train travelled in one loop by comparing where it was last loop and where it is this loop. So if it was at 45 studs last loop and it’s now at 59, 59-45 = 14 studs of movement. The delta is always calculated by taking the current position and subtracting the previous position.

This gets a little more complicated when 3D is taken into account. Since the cars exist in 6 dimensions (position and rotation), there needs to be a way to know exactly how the position and rotation changed. This is where CFrame comes in. CFrames are special and you can’t add or subtract them directly, but the basics of it is that :inverse() is the way to make a CFrame “negative”, and multiplying is the way CFrames add to each other.

So in a sense, they are taking the current CFrame and subtracting the previous CFrame from it to find the amount of position and rotation that changed during the loop. This change is called Rel. And the last line uses Rel to move the player to the Relative spot it was last loop; relative to the train car.

image

Now, the specifics of implementation, I don’t know, but I’m pretty sure it happens client-side based on some hints that @badcc was giving. Supposedly, Jailbreak’s implementation relies on network ownership to update the player positions between players which stutters based on connection due to the unusual nature of the movement, and Tyridge’s implementation sends the relative position to all players outright for smoother-looking movement. Also unknown is whether or not the update is occurring in RenderStepped, Heartbeat, or Stepped. All three are usable, as the load of the script is very small so there won’t be any concern about delaying render when using RenderStepped.

22 Likes

Ahh makes sense, thanks for explaining it in further depth, I’ll give it an attempt let you guys know how it turns out, may give it to you guys if you would like it.

3 Likes

This is my code, however it wont cframe as a local script doesn’t seem to be able to do that.

8 Likes

you need to set LastTrainCFrame after you calculate Rel. Otherwise you’re calculating the difference between something and itself (which is zero). You also need to break out LastTrainCFrame out of the loop either as an upvalue or as a global. And maybe what you have for finding the humanoid works in Play Solo, but you’ll have to move to Player.CharacterAdded event to get the current humanoid in a live game.

5 Likes

MY CODE

local Players = game:GetService("Players")

local LastTrainCF

local function onCharacterAdded(player)

while true do

wait(0.0001)

--------------------------------------------------------------- CHECK PLATFORM BELLOW

local RootPart = player.HumanoidRootPart

local Ignore = player

local ray = Ray.new(RootPart.CFrame.p,Vector3.new(0,-50,0))

local Hit, Position, Normal, Material = workspace:FindPartOnRay(ray,Ignore)

if Hit.Name == "InertiaPart" then

--------------------------------------------------------------- MOVE PLAYER TO NEW POSITON FROM OLD POSITION

local Train = Hit

local TrainCF = Train.CFrame

LastTrainCF = Hit.CFrame

local Rel = TrainCF * LastTrainCF:Inverse()

RootPart.CFrame = Rel * RootPart.CFrame

end

end

end

--------------------------------------------------------------- CONNECTED

local function onPlayerAdded(player)

player.CharacterAdded:Connect(onCharacterAdded)

end

Players.PlayerAdded:Connect(onPlayerAdded)

QUESTION

Thanks for the heads up, though i have no idea on what i’m doing wrong?

6 Likes