Can you edit this code: Serverscript: -- RollerCoasterManager (ServerScript)
-- Place this script in ServerScriptService

-- Services
local RunService = game:GetService("RunService")
local Workspace = workspace
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Require the RollerCoasterModule
local RollerCoasterModule = require(script:WaitForChild("RollerCoasterModule"))

-- List of Roller Coaster Folder Names
local coasterFolderNames = {
	"Coaster",    -- Existing coaster
	"Coaster2",   -- Additional coaster
	"Coaster3",   -- Add more as needed
	-- Add more coaster folder names here
}

-- Table to hold RollerCoasterController instances
local RollerCoasterControllers = {}

-- Function to Initialize All Roller Coasters
local function InitializeRollerCoasters()
	for _, folderName in ipairs(coasterFolderNames) do
		local coasterFolder = Workspace:FindFirstChild(folderName)
		if coasterFolder then
			-- Ensure each folder has a "Cart" part
			local cart = coasterFolder:FindFirstChild("Cart")
			if cart and cart:IsA("BasePart") then
				-- Instantiate the RollerCoasterController
				local controller = RollerCoasterModule.new(folderName)
				table.insert(RollerCoasterControllers, controller)

				-- Optional: Start Physics Automatically
				controller:StartPhysics()

				print("[RollerCoasterManager] Initialized and started physics for:", folderName)
			else
				warn("[RollerCoasterManager] Folder '" .. folderName .. "' is missing a 'Cart' part or it's not a BasePart.")
			end
		else
			warn("[RollerCoasterManager] Folder '" .. folderName .. "' not found in Workspace.")
		end
	end
end

-- Call the initialization function at script start
InitializeRollerCoasters()

-- Example Function: Start Physics for a Specific Coaster
local function StartPhysicsForCoaster(folderName)
	for _, controller in ipairs(RollerCoasterControllers) do
		if controller.coasterFolder.Name == folderName then
			controller:StartPhysics()
			print("[RollerCoasterManager] Physics started for:", folderName)
			return
		end
	end
	warn("[RollerCoasterManager] No controller found for '" .. folderName .. "'.")
end

-- Example Function: Stop Physics for a Specific Coaster
local function StopPhysicsForCoaster(folderName)
	for _, controller in ipairs(RollerCoasterControllers) do
		if controller.coasterFolder.Name == folderName then
			controller:StopPhysics()
			print("[RollerCoasterManager] Physics stopped for:", folderName)
			return
		end
	end
	warn("[RollerCoasterManager] No controller found for '" .. folderName .. "'.")
end

-- Example Function: Set Velocity for a Specific Coaster
local function SetVelocityForCoaster(folderName, newVelocity)
	for _, controller in ipairs(RollerCoasterControllers) do
		if controller.coasterFolder.Name == folderName then
			controller:SetVelocityExternal(newVelocity)
			print("[RollerCoasterManager] Velocity set to", newVelocity, "m/s for:", folderName)
			return
		end
	end
	warn("[RollerCoasterManager] No controller found for '" .. folderName .. "'.")
end

-- Example Function: Activate Booster for a Specific Coaster
local function ActivateBoosterForCoaster(folderName, boostAmount)
	for _, controller in ipairs(RollerCoasterControllers) do
		if controller.coasterFolder.Name == folderName then
			controller:ActivateBooster(boostAmount)
			print("[RollerCoasterManager] Booster activated by", boostAmount, "m/s for:", folderName)
			return
		end
	end
	warn("[RollerCoasterManager] No controller found for '" .. folderName .. "'.")
end

-- Example Function: Restart Coaster
local function RestartCoaster(folderName)
	for _, controller in ipairs(RollerCoasterControllers) do
		if controller.coasterFolder.Name == folderName then
			controller:RestartCoaster()
			print("[RollerCoasterManager] Coaster restarted for:", folderName)
			return
		end
	end
	warn("[RollerCoasterManager] No controller found for '" .. folderName .. "'.")
end

-- Function to Handle External Event Requests (Optional)
-- For example, using RemoteEvents to control coasters from client-side scripts or UI.

--[[
    -- Example Setup for RemoteEvents
    -- Create RemoteEvents for each function you want to expose

    -- Define RemoteEvents in ReplicatedStorage for easy access
    local RemoteEvents = {
        StartPhysics = Instance.new("RemoteEvent"),
        StopPhysics = Instance.new("RemoteEvent"),
        SetVelocity = Instance.new("RemoteEvent"),
        ActivateBooster = Instance.new("RemoteEvent"),
        RestartCoaster = Instance.new("RemoteEvent"),
    }

    -- Name and parent the RemoteEvents
    for eventName, eventObject in pairs(RemoteEvents) do
        eventObject.Name = eventName .. "Event"
        eventObject.Parent = ReplicatedStorage
    end

    -- Connect RemoteEvents to Manager Functions
    ReplicatedStorage.StartPhysicsEvent.OnServerEvent:Connect(function(player, folderName)
        StartPhysicsForCoaster(folderName)
    end)

    ReplicatedStorage.StopPhysicsEvent.OnServerEvent:Connect(function(player, folderName)
        StopPhysicsForCoaster(folderName)
    end)

    ReplicatedStorage.SetVelocityEvent.OnServerEvent:Connect(function(player, folderName, newVelocity)
        SetVelocityForCoaster(folderName, newVelocity)
    end)

    ReplicatedStorage.ActivateBoosterEvent.OnServerEvent:Connect(function(player, folderName, boostAmount)
        ActivateBoosterForCoaster(folderName, boostAmount)
    end)

    ReplicatedStorage.RestartCoasterEvent.OnServerEvent:Connect(function(player, folderName)
        RestartCoaster(folderName)
    end)
]]

--[[
    -- Example Usage from Command Line or Another Script

    -- Start Physics for "Coaster2"
    StartPhysicsForCoaster("Coaster2")

    -- Stop Physics for "Coaster3"
    StopPhysicsForCoaster("Coaster3")

    -- Set Velocity for "Coaster" to 20 m/s
    SetVelocityForCoaster("Coaster", 20)

    -- Activate Booster for "Coaster2" with 15 m/s boost
    ActivateBoosterForCoaster("Coaster2", 15)

    -- Restart "Coaster3"
    RestartCoaster("Coaster3")
]]

--[[
    -- Example of Using RemoteEvents (If Implemented)

    -- From a LocalScript or GUI:

    -- To Start Physics
    ReplicatedStorage.StartPhysicsEvent:FireServer("Coaster2")

    -- To Stop Physics
    ReplicatedStorage.StopPhysicsEvent:FireServer("Coaster3")

    -- To Set Velocity
    ReplicatedStorage.SetVelocityEvent:FireServer("Coaster", 20)

    -- To Activate Booster
    ReplicatedStorage.ActivateBoosterEvent:FireServer("Coaster2", 15)

    -- To Restart Coaster
    ReplicatedStorage.RestartCoasterEvent:FireServer("Coaster3")
]]

--[[
    -- Advanced: Dynamically Add Coaster Folders

    -- If you plan to add coaster folders dynamically during gameplay, you can monitor the Workspace for new folders.

    Workspace.ChildAdded:Connect(function(child)
        if child:IsA("Folder") and table.find(coasterFolderNames, child.Name) then
            local cart = child:FindFirstChild("Cart")
            if cart and cart:IsA("BasePart") then
                local controller = RollerCoasterModule.new(child.Name)
                table.insert(RollerCoasterControllers, controller)
                controller:StartPhysics()
                print("[RollerCoasterManager] Initialized and started physics for newly added:", child.Name)
            else
                warn("[RollerCoasterManager] Newly added folder '" .. child.Name .. "' is missing a 'Cart' part or it's not a BasePart.")
            end
        end
    end)
]]

Module:-- MultiCoasterManagerScript (ServerScriptService)
-- Place this script in ServerScriptService

local RollerCoasterModule = require(game.ServerScriptService:WaitForChild("RollerCoasterModule"))

-- List of Coaster Folder Names
local coasterFolders = {"Coaster", "Coaster2", "Coaster3"} -- Add as many as you like

-- Table to hold controller instances
local RollerCoasterControllers = {}

for _, folderName in ipairs(coasterFolders) do
	local folder = workspace:FindFirstChild(folderName)
	if folder then
		-- Ensure each folder has a "Cart" object
		if folder:FindFirstChild("Cart") and folder.Cart:IsA("BasePart") then
			-- Instantiate a new RollerCoasterController
			local controller = RollerCoasterModule.new(folderName)
			table.insert(RollerCoasterControllers, controller)

			-- Optionally, start physics automatically
			controller:StartPhysics()

			print("[MultiCoasterManager] Started physics for:", folderName)
		else
			warn("[MultiCoasterManager] Folder '" .. folderName .. "' is missing a 'Cart' part or it's not a BasePart.")
		end
	else
		warn("[MultiCoasterManager] Folder '" .. folderName .. "' not found in Workspace.")
	end
end

-- Optional: Functions to manage controllers, e.g., start/stop all physics
function StartAllPhysics()
	for _, controller in ipairs(RollerCoasterControllers) do
		controller:StartPhysics()
	end
end

function StopAllPhysics()
	for _, controller in ipairs(RollerCoasterControllers) do
		controller:StopPhysics()
	end
end

-- Example usage: Bind to game events or triggers to start/stop physics

Module:-- RollerCoasterModule (ModuleScript)
-- Place this in ServerScriptService

local RollerCoasterController = {}
RollerCoasterController.__index = RollerCoasterController

-- Services
local RunService = game:GetService("RunService")
local Workspace = workspace

-- Constants (Adjust as needed)
local GRAVITY = 9.8 -- Gravity acceleration (m/s²)
local FRICTION_COEFFICIENT = 0.2 -- Kinetic friction coefficient (0 < μ < 1)
local SAMPLE_STEP = 0.001 -- Arc-length sampling step (smaller for higher accuracy)
local VISUALIZATION_STEP = 0.05 -- Step size for visual track generation
local INITIAL_SPEED = 0 -- Starting speed of the cart (m/s)

-- Constructor
function RollerCoasterController.new(coasterFolderName)
	local self = setmetatable({}, RollerCoasterController)

	-- References
	self.coasterFolder = Workspace:WaitForChild(coasterFolderName)
	self.cart = self.coasterFolder:WaitForChild("Cart") -- Each coaster has its own Cart

	-- Verify Cart Properties
	self.cart.Anchored = false -- Ensure cart is not anchored
	self.cart.Velocity = Vector3.new(0, 0, 0) -- Reset initial velocity

	-- Track Data
	self.trackPoints = {} -- Sorted list of track point positions
	self.arcLengthMap = {} -- Mapping of cumulative arc-length to spline parameters
	self.totalTrackLength = 0 -- Total length of the track
	self.touchableSList = {} -- List of s positions where touchable points are located
	self.touchedTouchableS = {} -- Table to keep track of already touched touchable points

	-- Initialize touchedTouchableS table
	for i = 1, 100000 do
		self.touchedTouchableS[i] = false
	end

	-- Template for visual track parts (for debugging and aesthetics)
	self.trackPartTemplate = Instance.new("Part")
	self.trackPartTemplate.Size = Vector3.new(0.5, 0.5, 0.5)
	self.trackPartTemplate.Anchored = true
	self.trackPartTemplate.CanCollide = false
	self.trackPartTemplate.Material = Enum.Material.SmoothPlastic
	self.trackPartTemplate.BrickColor = BrickColor.new("Dark stone grey")

	-- Load and sort track points
	self:loadTrackParts()

	-- Precompute arc-length mapping
	self:precomputeArcLengthMap()

	-- Calculate total track length
	self:calculateTotalTrackLength()

	-- Identify and record touchable points
	self:identifyTouchablePoints()

	-- Generate visual track for debugging and aesthetics
	self:generateVisualTrack()

	-- Initialize movement variables
	self.s = 0 -- Current arc-length position
	self.v = INITIAL_SPEED -- Current velocity (m/s)
	self.isPhysicsRunning = false
	self.moveConnection = nil

	print("[RollerCoasterController] Initialized for folder:", coasterFolderName)
	return self
end

-- Load and Sort Track Parts
function RollerCoasterController:loadTrackParts()
	local unsortedParts = {}

	for _, part in ipairs(self.coasterFolder:GetChildren()) do
		if part:IsA("Part") then
			local orderValue = part:FindFirstChild("Value")
			if orderValue and orderValue:IsA("IntValue") then
				table.insert(unsortedParts, { part = part, order = orderValue.Value })
			else
				warn("[RollerCoasterController] Part missing 'Value' IntValue: ", part.Name)
			end
		end
	end

	-- Sort parts based on the IntValue in ascending order
	table.sort(unsortedParts, function(a, b)
		return a.order < b.order
	end)

	-- Populate trackPoints with sorted positions
	for _, entry in ipairs(unsortedParts) do
		table.insert(self.trackPoints, entry.part.Position)
	end

	-- Ensure there are enough points to form a track
	if #self.trackPoints < 2 then
		error("[RollerCoasterController] Not enough track points loaded in '" .. self.coasterFolder.Name .. "'. At least two points are required.")
	end

	print("[RollerCoasterController] Loaded " .. #self.trackPoints .. " track points for:", self.coasterFolder.Name)
end

-- Catmull-Rom Spline Interpolation
function RollerCoasterController:catmullRomSpline(p0, p1, p2, p3, t)
	local t2 = t * t
	local t3 = t2 * t

	return 0.5 * (
		(2 * p1) +
			(-p0 + p2) * t +
			(2 * p0 - 5 * p1 + 4 * p2 - p3) * t2 +
			(-p0 + 3 * p1 - 3 * p2 + p3) * t3
	)
end

-- Get Spline Point
function RollerCoasterController:getSplinePoint(t, segment)
	local p0 = self.trackPoints[math.max(segment - 1, 1)]
	local p1 = self.trackPoints[segment]
	local p2 = self.trackPoints[math.min(segment + 1, #self.trackPoints)]
	local p3 = self.trackPoints[math.min(segment + 2, #self.trackPoints)]

	return self:catmullRomSpline(p0, p1, p2, p3, t)
end

-- Get Spline Tangent
function RollerCoasterController:getSplineTangent(t, segment)
	local epsilon = 0.0001 -- Small step for derivative approximation
	local t1 = math.max(t - epsilon, 0)
	local t2 = math.min(t + epsilon, 1)
	local point1 = self:getSplinePoint(t1, segment)
	local point2 = self:getSplinePoint(t2, segment)
	local tangent = (point2 - point1).Unit
	return tangent
end

-- Precompute Arc-Length Mapping
function RollerCoasterController:precomputeArcLengthMap()
	self.arcLengthMap = {}
	local cumulativeLength = 0

	for segment = 1, #self.trackPoints - 1 do
		local lastPos = self:getSplinePoint(0, segment)
		for t = SAMPLE_STEP, 1, SAMPLE_STEP do
			local currentPos = self:getSplinePoint(t, segment)
			local delta = (currentPos - lastPos).Magnitude
			cumulativeLength = cumulativeLength + delta
			table.insert(self.arcLengthMap, { s = cumulativeLength, segment = segment, t = t })
			lastPos = currentPos
		end
	end

	print("[RollerCoasterController] Precomputed Arc Length Map with " .. #self.arcLengthMap .. " entries for:", self.coasterFolder.Name)
end

-- Find Spline Parameters Using Binary Search
function RollerCoasterController:findSplineParameters(s)
	if #self.arcLengthMap == 0 then
		return nil, nil
	end

	if s <= 0 then
		return self.arcLengthMap[1].segment, self.arcLengthMap[1].t
	end

	if s >= self.arcLengthMap[#self.arcLengthMap].s then
		return self.arcLengthMap[#self.arcLengthMap].segment, self.arcLengthMap[#self.arcLengthMap].t
	end

	local left = 1
	local right = #self.arcLengthMap
	local mid = 0

	-- Binary search for efficiency
	while left <= right do
		mid = math.floor((left + right) / 2)
		if self.arcLengthMap[mid].s < s then
			left = mid + 1
		elseif self.arcLengthMap[mid].s > s then
			right = mid - 1
		else
			return self.arcLengthMap[mid].segment, self.arcLengthMap[mid].t
		end
	end

	-- Safeguard to ensure 'right' is within bounds
	if right < 1 then right = 1 end
	if right > #self.arcLengthMap then right = #self.arcLengthMap end

	local s1 = self.arcLengthMap[right].s
	local s2 = self.arcLengthMap[left].s

	if s2 == s1 then
		-- Prevent division by zero
		return self.arcLengthMap[right].segment, self.arcLengthMap[right].t
	end

	local ratio = (s - s1) / (s2 - s1)
	local segment = self.arcLengthMap[right].segment
	local t = self.arcLengthMap[right].t + ratio * (self.arcLengthMap[left].t - self.arcLengthMap[right].t)
	return segment, t
end

-- Generate Visual Track for Debugging and Aesthetics
function RollerCoasterController:generateVisualTrack()
	for segment = 1, #self.trackPoints - 1 do
		local t = 0
		while t < 1 do
			local currentPoint = self:getSplinePoint(t, segment)
			local nextT = t + VISUALIZATION_STEP
			if nextT > 1 then nextT = 1 end
			local nextPoint = self:getSplinePoint(nextT, segment)

			local trackPart = self.trackPartTemplate:Clone()
			local distance = (currentPoint - nextPoint).Magnitude
			trackPart.Size = Vector3.new(0.5, 0.5, distance)
			local orientation = CFrame.lookAt(currentPoint, nextPoint)
			trackPart.CFrame = orientation * CFrame.new(0, 0, -distance / 2)

			trackPart.Parent = self.coasterFolder -- Parent to respective coaster folder

			t = nextT
		end
	end

	print("[RollerCoasterController] Visual track generated for:", self.coasterFolder.Name)
end

-- Calculate Total Track Length
function RollerCoasterController:calculateTotalTrackLength()
	if #self.arcLengthMap > 0 then
		self.totalTrackLength = self.arcLengthMap[#self.arcLengthMap].s
		print("[RollerCoasterController] Total Track Length:", self.totalTrackLength, "meters for:", self.coasterFolder.Name)
	else
		self.totalTrackLength = 0
		error("[RollerCoasterController] Arc Length Map is empty for:" .. self.coasterFolder.Name)
	end
end

-- Identify Touchable Points
function RollerCoasterController:identifyTouchablePoints()
	for _, part in ipairs(self.coasterFolder:GetChildren()) do
		if part:IsA("Part") then
			local touchableValue = part:FindFirstChild("Touchable")
			if touchableValue and touchableValue:IsA("BoolValue") and touchableValue.Value == true then
				-- Find the arc-length position corresponding to this track point
				local orderValue = part:FindFirstChild("Value")
				if orderValue and orderValue:IsA("IntValue") then
					local index = orderValue.Value
					if index >= 1 and index <= #self.trackPoints then
						-- Calculate approximate s for this track point
						local pos = self.trackPoints[index]
						local minDistance = math.huge
						local targetS = 0
						for _, entry in ipairs(self.arcLengthMap) do
							local currentPos = self:getSplinePoint(entry.t, entry.segment)
							local distance = (currentPos - pos).Magnitude
							if distance < minDistance then
								minDistance = distance
								targetS = entry.s
							end
						end
						table.insert(self.touchableSList, targetS)
						print("[RollerCoasterController] Touchable point added at s =", targetS, "meters for:", self.coasterFolder.Name)
					end
				end
			end
		end
	end
end

-- Calculate Net Acceleration
function RollerCoasterController:calculateAcceleration(tangent, velocity)
	-- Compute the slope angle theta
	-- sin(theta) = tangent.Y
	local sinTheta = tangent.Y
	local cosTheta = math.sqrt(1 - sinTheta ^ 2) or 0.0001 -- Prevent division by zero

	-- Net acceleration along the track:
	-- a = -g * sin(theta) - μ * g * cos(theta) * sign(v)
	local a_gravity = -GRAVITY * sinTheta

	-- Determine friction direction based on velocity
	local frictionDirection = 0
	if velocity > 0 then
		frictionDirection = -1
	elseif velocity < 0 then
		frictionDirection = 1
	else
		frictionDirection = 0
	end

	local a_friction = FRICTION_COEFFICIENT * GRAVITY * cosTheta * frictionDirection

	-- Total acceleration
	local a_total = a_gravity + a_friction

	return a_total
end

-- Start Physics Simulation
function RollerCoasterController:StartPhysics()
	if self.isPhysicsRunning then
		warn("[RollerCoasterController] Physics simulation is already running for:", self.coasterFolder.Name)
		return
	end

	self.isPhysicsRunning = true

	-- Initialize cart's state
	self.s = 0 -- Current arc-length position
	self.v = INITIAL_SPEED -- Current velocity (m/s)

	-- Position the cart at the starting point
	local startPos = self.trackPoints[1]
	self.cart.Position = startPos
	local initialTangent = self:getSplineTangent(0, 1)
	self.cart.CFrame = CFrame.lookAt(startPos, startPos + initialTangent)
	self.cart.Velocity = Vector3.new(0, 0, 0) -- Reset any existing velocity

	-- Connect to Heartbeat for frame-synced updates
	self.moveConnection = RunService.Heartbeat:Connect(function(deltaTime)
		if not self.isPhysicsRunning then
			return -- Skip physics updates if simulation is stopped
		end

		-- Prevent division by zero
		if self.totalTrackLength <= 0 then
			warn("[RollerCoasterController] Total track length is zero or undefined for:", self.coasterFolder.Name)
			self.moveConnection:Disconnect()
			return
		end

		-- Calculate acceleration based on current position
		local segment, t = self:findSplineParameters(self.s)
		if not segment or not t then
			self.moveConnection:Disconnect()
			print("[RollerCoasterController] Cart has reached the end of the track for:", self.coasterFolder.Name)
			return
		end

		local tangent = self:getSplineTangent(t, segment)
		local a = self:calculateAcceleration(tangent, self.v)

		-- Update velocity: v = v + a * dt
		self.v = self.v + a * deltaTime

		-- Update position: s = s + v * dt
		self.s = self.s + self.v * deltaTime

		-- Clamp s to track limits with tolerance
		local tolerance = 0.0001
		if self.s < 0 then
			self.s = 0
			self.v = 0
		elseif self.s > self.totalTrackLength + tolerance then
			self.s = self.totalTrackLength
			self.v = 0
			self.moveConnection:Disconnect()
			self.isPhysicsRunning = false
			print("[RollerCoasterController] Cart has reached the end of the track for:", self.coasterFolder.Name)
			return
		end

		-- Find new spline parameters based on updated s
		local newSegment, newT = self:findSplineParameters(self.s)
		if newSegment and newT then
			local newPos = self:getSplinePoint(newT, newSegment)
			self.cart.Position = newPos

			-- Update cart orientation based on new tangent
			local newTangent = self:getSplineTangent(newT, newSegment)
			if newTangent and newTangent.Magnitude > 0 then
				self.cart.CFrame = CFrame.lookAt(newPos, newPos + newTangent)
			end
		else
			warn("[RollerCoasterController] Failed to find spline parameters for s =", self.s, "in:", self.coasterFolder.Name)
		end

		-- Detect and handle touchable points
		for _, touchS in ipairs(self.touchableSList) do
			-- Check if the cart has just passed a touchable point within this frame
			if not self.touchedTouchableS[touchS] and self.s >= touchS then
				self.touchedTouchableS[touchS] = true -- Mark as touched to prevent re-triggering
				-- Trigger the touchable event
				print("[RollerCoasterController] Touchable point reached at s =", touchS, "meters in:", self.coasterFolder.Name)
				-- Call a custom function or emit an event here
				-- Example booster: Increase velocity by a fixed amount
				self:ActivateBooster(15) -- Boost by 15 m/s
			end
		end

		-- Optional: Debugging Information
		-- Uncomment the following line to print the current position and velocity each frame
		-- print("[RollerCoasterController] Coaster:", self.coasterFolder.Name, "s =", self.s, "m, v =", self.v, "m/s")
	end)

	print("[RollerCoasterController] Physics simulation started for:", self.coasterFolder.Name)
end

-- Stop Physics Simulation
function RollerCoasterController:StopPhysics()
	if not self.isPhysicsRunning then
		warn("[RollerCoasterController] Physics simulation is not running for:", self.coasterFolder.Name)
		return
	end

	self.isPhysicsRunning = false

	if self.moveConnection then
		self.moveConnection:Disconnect()
		self.moveConnection = nil
	end

	print("[RollerCoasterController] Physics simulation stopped for:", self.coasterFolder.Name)
end

-- Set Velocity Manually
function RollerCoasterController:SetVelocityExternal(newVelocity)
	self.v = newVelocity
	print("[RollerCoasterController] Cart velocity set to:", newVelocity, "m/s for:", self.coasterFolder.Name)
end

-- Activate Booster (Interactive Feature)
function RollerCoasterController:ActivateBooster(boostAmount)
	self.v = self.v + boostAmount
	print("[RollerCoasterController] Booster activated! Velocity increased by", boostAmount, "m/s. New velocity:", self.v, "m/s for:", self.coasterFolder.Name)

	-- Example: Play a sound or trigger a visual effect
	local boosterSound = self.coasterFolder:FindFirstChild("BoosterSound")
	if boosterSound and boosterSound:IsA("Sound") then
		boosterSound:Play()
	end

	-- Example: Change Cart Appearance
	local cartMaterial = self.cart:FindFirstChild("CartMaterial")
	if cartMaterial and cartMaterial:IsA("StringValue") then
		local materialEnum = Enum.Material[cartMaterial.Value]
		if materialEnum then
			self.cart.Material = materialEnum
		else
			warn("[RollerCoasterController] Invalid material name in CartMaterial for:", self.coasterFolder.Name)
		end
	end
end

-- Restart Coaster
function RollerCoasterController:RestartCoaster()
	print("[RollerCoasterController] Restarting coaster:", self.coasterFolder.Name)
	self:StopPhysics()
	self.s = 0
	self.v = INITIAL_SPEED
	for _, touchS in ipairs(self.touchableSList) do
		self.touchedTouchableS[touchS] = false
	end
	self:StartPhysics()
	print("[RollerCoasterController] Coaster restarted:", self.coasterFolder.Name)
end

-- Add more functions as needed

return RollerCoasterController

Make it so All the functions are in the modules so i can easily call on them from my code. Also make sure there is a function to detect touches with labeled parts so i can run code in them.