Headless Collisions Outside of Update loop?

I’m trying to update the war battles project to be multiplayer and server authoritative. So far I batch the player movements and send them to the server. On the server I receive the batched inputs and run them one after the other on_message.

This works great if there are no collisions and the client and server final positions are spot on (assuming no packet loss). But as soon as I start colliding, the sever just keeps updating movement.

I assume because it can’t see the collisions while inside the on_message loop, the updates need to happen in the update function? But if I have batched inputs and want to play them as fast as possible, I can’t run them in the update function. Also not sure how I would from on_message, as calling update from on_message doesn’t seem to work. Any ideas on how I could get the collision to trigger?

(for collisions I’m using the standard code from Resolving kinematic collisions in Defold) Here’s my basic movement function in on_message:

	if message_id == hash("movement") then
	local steps = message[1]
	local final_x = message[2]
	local final_y = message[3]
	local client_final_pos = vmath.vector3(final_x, final_y, 1)
	
	print("Moving the player on the server!")
	for key, step in pairs(steps) do
		local input_x = step[1]
		local input_y = step[2]
		local dt_sum = step[3]
		self.input = vmath.vector3(input_x, input_y, 0)
		
		if vmath.length(self.input) > 0 then
			self.moving = true
			self.dir = vmath.normalize(self.input)           
		end

		-- update(self, dt_sum)  //doesn't seem to work

		self.correction.x = 0
		self.correction.y = 0
		self.correction.z = 0
		
		if self.moving then
			local pos = go.get_position()
			new_pos = pos + self.dir * (self.speed * dt_sum)
			go.set_position(new_pos)
		end

		self.input.x = 0
		self.input.y = 0

		self.moving = false
		self.firing = false
	end 

	print("final server position:")
	print(go.get_position())
	print("final client position:")
	print(client_final_pos)