How can I save players custom built Vehicles?


im currently creating a game where players can build modular vehicles.
However I can’t figure out on how to save their vehicles in DataStore(2).
So I asked my self how this game achieves it, because it really saves every single parts position.

So in my game for example I got a Vehicle with all its Modules sorted in a Table:

local vehicle = {
[1] = "Engine",
[2] = "Tank",
[3] = "Cabin",
[4] = "Door"

where the Index 1 is the lowest Part of the Vehicle and 4 the highest (sorted with Bubblesort Algorithm and Part.Position.Y)
So there would be no Problem saving this table and just adding those modules when a player wants to load it.
But how could I achieve this when a Player is adding Modules to the “side” of the Vehicle?

Any kind of help would be helpful


Well, with the new DataStore Size, you should be able to store it all in one data store.

All components in a vehicle will be connected, either directly or indirectly through other components. That means the entire vehicle can be represented as a graph where nodes are components and edges are connections between components. To serialize such a graph, you’ll need to serialize the nodes and the edges.

Each node can be represented with it’s component type (ideally a number) and it’s CFrame.

Each edge can be represented as a reference to two different components that are connected through that edge. That means we must be able to tell which node is which, so nodes additionally need a unique ID. Something like this could work, although it’s completely untested but it shows the basic idea.

function tableValues(t: {any}): {any}
    local values = {}
    for _, value in pairs(t) do
        table.insert(values, value)
    return values

function vehicleToTable(vehicle: Model): {any}
    local components = getVehicleComponents(vehicle)
    local rootComponent = components[1]

    local componentDatas = {}    
    for i, component in ipairs(components) do
        componentDatas[component] = {
            Id = i,
            Type = component.Type.Value,
            CFrame = rootComponent.PrimaryPart.CFrame:ToObjectSpace(component.PrimaryPart.CFrame)
    local connectionDatas = {}
    for _, component in ipairs(components) do
        for _, otherComponent in ipairs(getConnectedComponents(component)) do
            table.insert(connectionDatas, { 
                Component0 = componentDatas[component].Id, 
                Component1 = componentDatas[otherComponent].Id
    return {
        RootComponent = componentDatas[rootComponent].Id,
        Components = tableValues(componentDatas),
        Connections = connectionDatas,

function tableToVehicle(data: {any}, rootCFrame: CFrame): Model
    local vehicle ="Model")
    local components = {}
    local componentDatas = {}
    local idComponents = {}
    local rootComponent
    for _, componentData in ipairs(data.Components) do
        local component = game.ServerStorage.Components[componentData.Type]:Clone()
        table.insert(components, component)
        componentDatas[component] = componentData
        idComponents[componentData.Id] = component
        if componentData.Id == data.RootComponent then
            rootComponent = component
    for _, component in ipairs(components) do
        component:SetPrimaryPartCFrame( rootCFrame * componentDatas[component].CFrame )
    for _, connectionData in ipairs(data.Connections) do
        local weld ="WeldConstraint")
        weld.Parent = idComponents[connectionData.Component0]
        weld.Part0 = idComponents[connectionData.Component0].PrimaryPart
        weld.Part0 = idComponents[connectionData.Component1].PrimaryPart
    return vehicle
1 Like

You need to serialize the data into a format which can be stored inside DataStores, so tables, numbers, strings etc. to represent the individual parts/properties of the vehicle. Then when you load this value from the DataStore you’ll need to deserialize it and appropriately convert the deserialized data into the physical vehicle again by instancing the parts and setting the values of certain properties as necessary.