Car's motors don't want to be stopped from server

Hello guys. I’m making custom car building system with energy limit. So, if vehicle runs out of energy, it should stop.
Everything physics related active on client, but server checks for impossible actions. So, for server, motors have 0 AngularVelocity, while Player have 31.4 AngularVelocity, but Player can make that velocity only if server allows such action.
When motor active, it will use some energy from battary via SERVER. If battary haven’t anymore energy, SERVER should stop motors from spin.

BUT THERE'S 1 PROBLEM:

Server sees always motor’s AngularVelocity as 0, and it changed only on client. So, if I’ll try to change motor’s AngularVelocity to 0 on server, this WON’T AFFECT CLIENT! IDK if this should work like this, but I think it works like this for some Roblox optimization.
Is there any way to change client’s AngularVelocity to 0 via server script, if server already sees it as 0? (IK about variant “Set it to 0.001 and after set it to 0”, but I’m looking for better ones.)

Well since this is scripting support you may want to post your code here so others can look at it.
How are you updating the server AngularVelocity value and how are you reading that from the server?

Remember to put 3 backticks before and after your code so it formats properly here.

I don’t really think I need to post code here, because my problem consist of:
Client have motor speed 30.
Server sees that as 0.
Vehicle runs out of fuel.
Server tries to set motor speed to 0.
Roblox systems don’t replicate this thing and Client motor speed is still 30.
And I need fix that.

How I update AngularVelocity of motor:

Motor.Constraints.HingeConstraint.AngularVelocity = 30 <-- client

Motor.Constraints.HingeConstraint.AngularVelocity = 0 <-- server

Server don’t reads Motor Angular Velocity. It only receives “true” signal from client and starts to consume fuel.
Sorry if I understood this one incorrectly.

That’s what I don’t get.
If you are checking from the server what the AngularVelocity of the HingeConstraint is set to it should read that value.
I was asking to see the script to see if you are just checking the AngularVelocity once, or using a function to check for a change in the value.

I neither check Angular velocity once not use function to check value change.
Client:

local Vehicle = {}
Vehicle.__index = Vehicle

function Vehicle:Initialize(Enabled, SentModule)
	self.Enabled = false
	self.CurrentSeat = nil
	self.BindedKeys = {}
	self.AllowedBinds = {}
	self.ActiveModule = SentModule
	return self
end

function Vehicle:ChangeVehicle(Object)
	if not UserInputService.KeyboardEnabled then
		return false
	end

	if Object == nil then
		self:UnbindActions()
		self:DisconnectFocusEvents()
		return false
	else
		print(self.ActiveModule)
		local FoundKeybinds
		local Parts = Object:GetChildren()
		for a = 1, #Parts, 1 do
			local Special = Parts[a]
			if Special:IsA("Model") and Special.Name ~= "Seat" then -- Checking, if smth is Motor, Piston or etc.
				local Properties = Special.Properties
				if Special.Name == "SteeringWheel" or Special.Name == "Lever" or Special.Name == "Button" then
					--This 3 things give you ability to bind keys.
					...
				else
					--otherwise, we will add keybinds motors requested to dicitonary.
					...
				end
			end
		end
		
		for Key, Specials in pairs(self.BindedKeys) do
			local PossibleInputType = self.AllowedBinds[Key]
			if PossibleInputType then
				local BestInputType = PossibleInputType
				local FunctionToBind = function(actionName, inputState, inputObject)
					if inputState == Enum.UserInputState.Begin then
						local Pending = {}
						for i = 1, #Specials, 1 do
							local Object = Specials[i]
							if PrefferedInputTypes[Object.Name] == "Hold" and string.match(BestInputType, "Hold") then
								table.insert(Pending, Object)
							elseif PrefferedInputTypes[Object.Name] == "Click" and string.match(BestInputType, "Click") then
								table.insert(Pending, Object)
							elseif PrefferedInputTypes[Object.Name] == "Hold" then
								table.insert(Pending, Object)
							end
						end
						local Success = Remotes:WaitForChild("VehicleEventTwoWay"):InvokeServer("ActivateSpeciality", Pending, true)
						--Asking server, can we activate "Pending" motors?
						if Success then
							for i = 1, #Pending, 1 do
								local Object = Pending[i]
								if PrefferedInputTypes[Object.Name] == "Hold" and string.match(BestInputType, "Hold") then
									local Mover = SpecialsConstraints[Object.Name]
									if Mover == "HingeConstraint" then
										local KeyDirection = if Object.Properties:GetAttribute("KeybindClockwise") == Key then 1 else -1
										--Bc there's only 2 possible inputs, so if 1 is clockwise, second WILL be anticlockwise.
										local Motor = Object.Constraints[Mover]
										if Object.Name == "Motor" then
											local Speed = Object.Properties:GetAttribute("Speed")
											Motor.AngularVelocity += Speed * KeyDirection
										elseif string.match(Object.Name, "Servo") then
											Motor.TargetAngle = KeyDirection == 1 and Motor.UpperAngle or Motor.LowerAngle
										end
									end
								elseif PrefferedInputTypes[Object.Name] == "Click" and string.match(BestInputType, "Click") then
									print(Object.Name .. " is activated")
									local Mover = SpecialsConstraints[Object.Name]
									if Mover == "Spotlight" then
										local Motor = Object.Constraints[Mover]
										Motor.Enabled = not Motor.Enabled
									end
								elseif PrefferedInputTypes[Object.Name] == "Hold" then
									print(Object.Name .. " is activated but badly")
									local Mover = SpecialsConstraints[Object.Name]
									if Mover == "HingeConstraint" then
										local KeyDirection = if Object.Properties:GetAttribute("KeybindClockwise") == Key then 1 else -1
										--Bc there's only 2 possible inputs, so if 1 is clockwise, second WILL be anticlockwise.
										local Motor = Object.Constraints[Mover]
										if Object.Name == "Motor" then
											local Speed = Object.Properties:GetAttribute("Speed")
											if Motor.AngularVelocity == Speed * KeyDirection then
												Motor.AngularVelocity = 0
											else
												Motor.AngularVelocity = Speed * KeyDirection
											end
										elseif string.match(Object.Name, "Servo") then
											if Motor.TargetAngle == (KeyDirection == 1 and Motor.UpperAngle or Motor.LowerAngle) then
												Motor.TargetAngle = 0
											else
												Motor.TargetAngle = KeyDirection == 1 and Motor.UpperAngle or Motor.LowerAngle
											end
										end
									end
								end
							end
						end
					elseif inputState == Enum.UserInputState.End and string.match(BestInputType, "Hold") then
						--print("Keycode " .. Key .. " is end")
						local Pending = {}
						for i = 1, #Specials, 1 do
							local Object = Specials[i]
							if PrefferedInputTypes[Object.Name] == "Hold" then
								local Mover = SpecialsConstraints[Object.Name]
								if Mover == "HingeConstraint" then
									local Motor = Object.Constraints[Mover]
									table.insert(Pending, Object)
									if Object.Name == "Motor" then
										Motor.AngularVelocity = 0
									elseif Object.Name == "Servo" then
										Motor.TargetAngle = Motor.CurrentAngle
									elseif Object.Name == "ReturningServo" then
										Motor.TargetAngle = 0
									end
								end
							end
						end
						Remotes:WaitForChild("VehicleEventOneWay"):FireServer("ActivateSpeciality", Pending, false)
						--bc we need to toggle off motors, we don't need to ask server, can we do this, and only send signal that we want do such things.
					end
					return Enum.ContextActionResult.Pass
				end
				self.ActiveModule:ConnectNewAction("VehicleKeycode" .. Key, FunctionToBind, Enum.KeyCode[Key])
			end
		end
	end
	
	return true
end


return Vehicle--:Initialize()

Server:

local RS = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

local Remotes = RS:WaitForChild("Remotes")
local VehicleEvent = Remotes:WaitForChild("VehicleEventOneWay")
local VehicleFunction = Remotes:WaitForChild("VehicleEventTwoWay")

local VehiclesOnTrack = {}

local SpecialsForTrack = {"Motor", "Servo", "ReturningServo", "Headlight"}
local SpecialsConstraints = {
	Motor = "HingeConstraint",
	Servo = "HingeConstraint",
	ReturningServo = "HingeConstraint",
	Headlight = "Spotlight",
	Jet = "VectorForce",
	Piston = "RodConstraint",
}

local VehiclePowerUsageFunction = nil

local function ChangeNetworkOwner(Player, Part)
	Part:SetNetworkOwner(Player)
	return true
end

local function SitPlayer(Player, Seat)
	if Seat.Parent.Name ~= "Seat" then
		Player:Kick("You can't sit on NON-SEATS. Toggle off your hacks, dude.")
		return false
	end
	if Seat.Parent.Properties:GetAttribute("CurrentPlayer") == nil or Seat.Parent.Properties:GetAttribute("CurrentPlayer") == "" and Seat.Parent.Parent.Name == "Vehicle" then
		local Weld = Instance.new("Weld")
		Weld.Part0 = Seat
		Weld.Part1 = Player.Character.HumanoidRootPart
		Weld.C0 = CFrame.new(0, 1, 0)
		Weld.Parent = Player.Character.HumanoidRootPart
		Seat.Parent.Properties:SetAttribute("CurrentPlayer", Player.Name)
		local NetworkOwner = Seat:GetNetworkOwner()
		if NetworkOwner == nil or NetworkOwner == Player.Name then
			if NetworkOwner == nil then
				ChangeNetworkOwner(Player, Seat)
			end
			local Vehicle = Seat.Parent.Parent
			VehiclesOnTrack[Vehicle] = {}
			local Objects = Vehicle:GetChildren()
			for i = 1, #Objects, 1 do
				local Object = Objects[i]
				if Object:IsA("Model") and table.find(SpecialsForTrack, Object.Name) then
					VehiclesOnTrack[Vehicle][Object] = false
				end
			end
		end
	end
	return true
end

local function ActivateSpecials(Player, Objects, Active)
	local Vehicle = Objects[1].Parent
	local Players = Vehicle:GetChildren()
	local Success = false
	for i = 1, #Players, 1 do
		if Players[i].Name == "Seat" and Players[i].Properties:GetAttribute("CurrentPlayer") == Player.Name then
			Success = true
			break
		end		
	end
	if Success then
		if Active == true then
			local PreEnergyUse = Vehicle.Properties:GetAttribute("CurrentEnergyUsage")
			warn(#Objects)
			for a = 1, #Objects, 1 do
				local Object = Objects[a]
				local EnergyUsage = Object.Properties:GetAttribute("EnergyUsage")
				if not VehiclesOnTrack[Vehicle] then
					Player:Kick("How you driving this vehicle?")
				end
				--print(VehiclesOnTrack[Vehicle][Object])
				if VehiclesOnTrack[Vehicle][Object] == false then
					PreEnergyUse += EnergyUsage
					--print("Energy usage increased by " .. tostring(EnergyUsage) .. " by " .. Object.Name)
				end
			end
			--print("Total energy usage: " .. tostring(PreEnergyUse))
			local CurrentEnergy = 0
			local Battaries = Vehicle:GetChildren()
			for i = 1, #Battaries, 1 do
				if Battaries[i].Name == "Battary" then
					CurrentEnergy += Battaries[i].Properties:GetAttribute("CurrentEnergy")
				end
			end
			if CurrentEnergy >= PreEnergyUse then
				for a = 1, #Objects, 1 do
					local Object = Objects[a]
					VehiclesOnTrack[Vehicle][Object] = true
					--print(Object.Name .. " is activated")
				end
				Vehicle.Properties:SetAttribute("CurrentEnergyUsage", PreEnergyUse)
				if VehiclePowerUsageFunction == nil then
					local CurrentTime = 0
					VehiclePowerUsageFunction = RunService.Heartbeat:Connect(function(Delta)
						CurrentTime += Delta
						if CurrentTime >= 1 then
							local Multiplier = math.floor(CurrentTime / 1)
							CurrentTime = CurrentTime % 1
							for Vehicle, Specials in pairs(VehiclesOnTrack) do
								local Parts = Vehicle:GetChildren()
								local Battaries = {}
								local CurrentEnergy = 0
								local MaxEnergy = 0
								for i = 1, #Parts, 1 do
									if Parts[i].Name == "Battary" then
										table.insert(Battaries, Parts[i])
										CurrentEnergy += Parts[i].Properties:GetAttribute("CurrentEnergy")
										MaxEnergy += Parts[i].Properties:GetAttribute("MaxEnergy")
									end
								end
								if CurrentEnergy >= Vehicle.Properties:GetAttribute("CurrentEnergyUsage") * Multiplier then
									CurrentEnergy -= Vehicle.Properties:GetAttribute("CurrentEnergyUsage") * Multiplier
									for i = 1, #Battaries, 1 do
										local BattaryWeight = Battaries[i].Properties:GetAttribute("MaxEnergy") / MaxEnergy
										local BattaryEnergy = math.floor(CurrentEnergy * BattaryWeight)
										Battaries[i].Properties:SetAttribute("CurrentEnergy", BattaryEnergy)
										CurrentEnergy -= BattaryEnergy
										MaxEnergy -= Battaries[i].Properties:GetAttribute("MaxEnergy")
									end
									for Special, Active in pairs(Specials) do
										if Active == false then
											local Mover = SpecialsConstraints[Special.Name]
											if Mover == "HingeConstraint" then
												local Motor = Special.Constraints[Mover]
												if Special.Name == "Motor" then
													Motor.AngularVelocity = 0.001
													Motor.AngularVelocity = 0
												elseif Special.Name == "Servo" then
													Motor.TargetAngle = Motor.CurrentAngle
												elseif Special.Name == "ReturningServo" then
													Motor.TargetAngle = 0
												end
											end
										end
									end
								else
									for i = 1, #Battaries, 1 do
										Battaries[i].Properties:SetAttribute("CurrentEnergy", 0)
									end
									for Special, Active in pairs(Specials) do
										if Active == true then
											VehiclesOnTrack[Vehicle][Special] = false
											local Mover = SpecialsConstraints[Special.Name]
											if Mover == "HingeConstraint" then
												local Motor = Special.Constraints[Mover]
												if Special.Name == "Motor" then
													Motor.AngularVelocity = 0.001
													Motor.AngularVelocity = 0
												elseif Special.Name == "Servo" then
													Motor.TargetAngle = Motor.CurrentAngle
												elseif Special.Name == "ReturningServo" then
													Motor.TargetAngle = 0
												end
											end
										end
									end
								end
							end
						end
					end)
				end
				return true
			else
				return false
			end
		else
			local PreEnergyUse = Vehicle.Properties:GetAttribute("CurrentEnergyUsage")
			for a = 1, #Objects, 1 do
				local Object = Objects[a]
				local EnergyUsage = Object.Properties:GetAttribute("EnergyUsage")
				
				if VehiclesOnTrack[Vehicle] then
					if VehiclesOnTrack[Vehicle][Object] == true then
						VehiclesOnTrack[Vehicle][Object] = false
						PreEnergyUse -= EnergyUsage
					end
				end
			end
			if PreEnergyUse < 0 then
				Player:Kick("If you are cheater: you can't drive vehicles at no-cost. If you are innocent: Report this bug to developer.")
			end
			Vehicle.Properties:SetAttribute("CurrentEnergyUsage", PreEnergyUse)
			return true
		end
	end
	return false
end

VehicleEvent.OnServerEvent:Connect(function(Player, Action, ...)
	if Action == "Sit" then
		SitPlayer(Player, ...)
	elseif Action == "ActivateSpeciality" then
		ActivateSpecials(Player, ...)
	end
end)

VehicleFunction.OnServerInvoke = function(Player, Action, ...)
	local Success = false
	if Action == "Sit" then
		Success = SitPlayer(Player, ...)
	elseif Action == "ActivateSpeciality" then
		Success = ActivateSpecials(Player, ...)
	end
	return Success
end