I have encountered this strange problem, in relation with seats and NPCs. My game is about Barbershops, a server script spawns an NPC and right after that NPC spawns, another server script named CustomersHandler will take care of it, and will make the NPC walk inside the place and seat on an available seat. If the customer is not taken care of, they will get mad and eventually leave the place. So my problem is, there’s this client-server desync thing. On the client’s side, the NPC stands up. On the other hand, the NPC stays in the seat in the server.
Please see this video so you know what I mean: NPC seat problem - YouTube
I have no idea what is causing this. Note that, it sometimes happens that way and sometimes it does not. I thought to myself, the problem might be with the unsitting of the NPC. I tried two methods of unsitting the NPC from the seat,
-- METHOD 1
Humanoid.Jump = true
-- METHOD 2 (CURRENTLY IM USING)
Humanoid.Sit = false
But it did not make any difference, there’s still that problem. I have tried looking for solutions for this problem, and have seen similar problems that I have. But, I don’t find their solution solving my issue.
Posts such as:
Now, this code is a part of my CustomersHandler script (mainly takes care of the NPC whenever it spawns in the workspace) that looks for an available seat for the NPC and making them seat on it:
local CustomersFunction = require(game.ServerScriptService.CustomerFunctions)
local assignedSeat = CustomersFunction.FindSeat(Config.WorkspaceFolders.BarberSeats) -- CUSTOMER FINDSEAT FUNCTION (LOOKS FOR AN AVAILABLE SEAT FOR THE CUSTOMER)
if assignedSeat then -- CHECKS IF AN AVAILABLE SEAT IS FOUND
CustomersFunction.SeatCustomer(customer, assignedSeat) -- CUSTOMER SEATCUSTOMER FUNCTION (MAKES THE CUSTOMER GO TO THE SEAT AND TAKE A SEAT
NPCStatus.Value = "Seated" -- CHANGES THE NPC STATS TO SEATED
else -- THERE ARE NO AVAILABLE SEATS FOUND, THEREFORE MAKING THE NPC LEAVE
NPCStatus.Value = "Failed" -- CHANGES THE NPC STATUS TO FAILED
local exitPart = Config.WorkspaceFolders.CustomerSpawns:GetChildren()[math.random(#Config.WorkspaceFolders.CustomerSpawns:GetChildren())] -- CHOOSES A RANDOM EXIT PART FOR THE CUSTOMER
CustomersFunction.Exit(customer, exitPart) -- CUSTOMER EXIT FUNCTION (MAKES THE CUSTOMER LEAVE THE PLACE)
end
game.ServerScriptService.CustomerSpawner.Disabled = false -- RE-ENABLES THE CUSTOMER SPAWNER SCRIPT (THE CUSTOMER SPAWNER SCRIPT DISABLES ITSELF AFTER SPAWNING AN NPC, THAT IS HOW IT WORKS AT THE MOMENT)
if NPCStatus.Value == "Seated" then -- IF THE NPC IS SEATED
local barberSuccess = CustomerMechanism.ToggleBarberMechanism(customer, assignedSeat, Config.CustomerWaitingTime.Barber) -- TELLS WHETHER THE BARBER WAS SUCCESS OR NOT (WHETHER THE CUSTOMER WAS TAKEN CARE OF OR IGNORED)
if barberSuccess then
NPCStatus.Value = "Success"
CustomersFunction.ChatCustomer(customer, CustomerMessages.CustomerHaircutDoneMessages[math.random(#CustomerMessages.CustomerHaircutDoneMessages)]) -- MAKES THE CUSTOMER SAY RANDOM MESSAGES
wait(2)
humanoid.Sit = false -- UNSITS THE CUSTOMER
CustomersFunction.GoToCounter(customer, game.Workspace.CustomerWalkpoints)
else
NPCStatus.Value = "Failed"
CustomersFunction.ChatCustomer(customer, CustomerMessages.CustomerMadMessages[math.random(#CustomerMessages.CustomerMadMessages)]) -- MAKES THE CUSTOMER SAY RANDOM MESSAGES
local exitPart = Config.WorkspaceFolders.CustomerSpawns:GetChildren()[math.random(#Config.WorkspaceFolders.CustomerSpawns:GetChildren())] -- CHOOSES A RANDOM EXIT PART FOR THE CUSTOMER
wait(2)
humanoid.Sit = false -- UNSITS THE CUSTOMER
CustomersFunction.Exit(customer, exitPart) -- CUSTOMER EXIT FUNCTION (MAKES THE CUSTOMER LEAVE THE PLACE)
end
end
And, this code is from my CustomersFunction module script. These functions are the ones used in the script above:
local module = {}
function module.Exit(customer, exitPart) -- MAKES THE CUSTOMER LEAVE THE PLACE
local PathService = game:GetService("PathfindingService")
local humanoid = customer:FindFirstChild("Humanoid")
if humanoid then -- CHECKS IF THE HUMANOID EXISTS
local Path = PathService:CreatePath()
Path:ComputeAsync(customer.PrimaryPart.Position, exitPart.Position) -- COMPUTES PATH TO THE EXIT PART
if Path.Status == Enum.PathStatus.Success then -- CHECKS IF THE PATH COMPUTATION SUCCEEDS
local Waypoints = Path:GetWaypoints() -- GATHERS THE WAYPOINTS OF THE COMPUTER PATH
for i, point in pairs(Waypoints) do -- LOOPS THROUGH WAYPOINTS
if point.Action == Enum.PathWaypointAction.Jump then -- MAKES THE NPC JUMP IF IT NEEDS TO
humanoid.Jump = true
end
humanoid:MoveTo(point.Position)
humanoid.MoveToFinished:Wait()
end
customer:Destroy()
print("Customer left")
end
end
end
function module.GoToCounter(customer, walkpoints) -- MAKES THE CUSTOMER GO TO THE COUNTER SO THAT THEY CAN PAY FOR THEIR HAIRCUT
local PathService = game:GetService("PathfindingService")
local humanoid = customer:FindFirstChild("Humanoid")
if humanoid then -- CHECKS IF THE HUMANOID EXISTS
local Path = PathService:CreatePath()
Path:ComputeAsync(customer.PrimaryPart.Position, walkpoints.Counter.Position) -- COMPUTES PATH
if Path.Status == Enum.PathStatus.Success then -- CHECKS IF THE PATH COMPUTATION SUCCEEDS
local Waypoints = Path:GetWaypoints() -- GATHERS THE WAYPOINTS OF THE COMPUTER PATH
for i, point in pairs(Waypoints) do -- LOOPS THROUGH WAYPOINTS
if point.Action == Enum.PathWaypointAction.Jump then -- MAKES THE NPC JUMP IF IT NEEDS TO
humanoid.Jump = true
end
humanoid:MoveTo(point.Position)
humanoid.MoveToFinished:Wait()
end
end
print("Customer is now at counter")
end
end
function module.FindSeat(seats) -- LOOKS FOR AN AVAILABLE SEAT
for i, seat in pairs(seats:GetChildren()) do -- LOOPS THROUGH ALL OF THE SEATS
if not seat.Seat.Occupant then -- CHECKS IF THE SEAT HAS AN OCCUPANT
return seat -- RETURNS SEAT IF AVAILABLE
end
end
return nil -- RETURNS NIL IF THERE IS NO SEAT AVAILABLE
end
function module.SeatCustomer(customer, seat) -- MAKES THE CUSTOMER SEAT ON THE AVAILABLE SEAT
local PathService = game:GetService("PathfindingService")
local humanoid = customer:FindFirstChild("Humanoid")
if humanoid then -- CHECKS IF THE HUMANOID EXISTS
local Seat = seat.Seat -- ASSIGNS THE ACTUAL SEAT TO A VARIABLE
local Path = PathService:CreatePath()
Path:ComputeAsync(customer.PrimaryPart.Position, Seat.Position) -- COMPUTES PATH
if Path.Status == Enum.PathStatus.Success then -- CHECKS IF THE PATH COMPUTATION SUCCEEDS
local Waypoints = Path:GetWaypoints() -- GATHERS THE WAYPOINTS OF THE COMPUTER PATH
for i, point in pairs(Waypoints) do -- LOOPS THROUGH WAYPOINTS
if point.Action == Enum.PathWaypointAction.Jump then -- MAKES THE NPC JUMP IF IT NEEDS TO
humanoid.Jump = true
end
humanoid:MoveTo(point.Position)
humanoid.MoveToFinished:Wait()
end
end
Seat:Sit(humanoid) -- SITS THE CUSTOMER TO THE SEAT
print("Customer is now seated")
end
end
return module
Again, my problem is I don’t know what am I doing wrong that causes this. Correct me if I am wrong though, I don’t seem to have any problems with my script. So I would like your help in order to get around this, I need someone to tell me what’s the problem.
Thank you in advance!
IMPORTANT: I HAVE NO LOCAL SCRIPTS PRESENT IN THE GAME YET. SO THESE TWO CODES I SENT BELONGS TO A SERVER SCRIPT
While nothing is marked as solution, then it’s not solved yet.