diff --git a/mods/carts/cart_entity.lua b/mods/carts/cart_entity.lua
index 434ea94..38337db 100644
--- a/mods/carts/cart_entity.lua
+++ b/mods/carts/cart_entity.lua
@@ -27,6 +27,10 @@ function cart_entity:on_rightclick(clicker)
 	elseif not self.driver then
 		self.driver = player_name
 		carts:manage_attachment(clicker, self.object)
+
+		-- player_api does not update the animation
+		-- when the player is attached, reset to default animation
+		player_api.set_animation(clicker, "stand")
 	end
 end
 
@@ -36,7 +40,7 @@ function cart_entity:on_activate(staticdata, dtime_s)
 		return
 	end
 	local data = minetest.deserialize(staticdata)
-	if not data or type(data) ~= "table" then
+	if type(data) ~= "table" then
 		return
 	end
 	self.railtype = data.railtype
@@ -52,6 +56,13 @@ function cart_entity:get_staticdata()
 	})
 end
 
+-- 0.5.x and later: When the driver leaves
+function cart_entity:on_detach_child(child)
+	if child and child:get_player_name() == self.driver then
+		self.driver = nil
+	end
+end
+
 function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
 	local pos = self.object:get_pos()
 	local vel = self.object:get_velocity()
@@ -82,7 +93,7 @@ function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities,
 			local player = minetest.get_player_by_name(self.driver)
 			carts:manage_attachment(player, nil)
 		end
-		for _,obj_ in ipairs(self.attached_items) do
+		for _, obj_ in ipairs(self.attached_items) do
 			if obj_ then
 				obj_:set_detach()
 			end
@@ -165,6 +176,7 @@ local function get_railparams(pos)
 	return carts.railparams[node.name] or {}
 end
 
+local v3_len = vector.length
 local function rail_on_step(self, dtime)
 	local vel = self.object:get_velocity()
 	if self.punched then
@@ -201,17 +213,23 @@ local function rail_on_step(self, dtime)
 
 	local stop_wiggle = false
 	if self.old_pos and same_dir then
-		-- Detection for "skipping" nodes
-		local found_path = carts:pathfinder(
-			pos, self.old_pos, self.old_dir, ctrl, self.old_switch, self.railtype
+		-- Detection for "skipping" nodes (perhaps use average dtime?)
+		-- It's sophisticated enough to take the acceleration in account
+		local acc = self.object:get_acceleration()
+		local distance = dtime * (v3_len(vel) + 0.5 * dtime * v3_len(acc))
+
+		local new_pos, new_dir = carts:pathfinder(
+			pos, self.old_pos, self.old_dir, distance, ctrl,
+			self.old_switch, self.railtype
 		)
 
-		if not found_path then
-			-- No rail found: reset back to the expected position
-			pos = vector.new(self.old_pos)
+		if new_pos then
+			-- No rail found: set to the expected position
+			pos = new_pos
 			update.pos = true
+			cart_dir = new_dir
 		end
-	elseif self.old_pos and cart_dir.y ~= -1 and not self.punched then
+	elseif self.old_pos and self.old_dir.y ~= 1 and not self.punched then
 		-- Stop wiggle
 		stop_wiggle = true
 	end
@@ -223,12 +241,14 @@ local function rail_on_step(self, dtime)
 	local dir, switch_keys = carts:get_rail_direction(
 		pos, cart_dir, ctrl, self.old_switch, self.railtype
 	)
+	local dir_changed = not vector.equals(dir, self.old_dir)
 
 	local new_acc = {x=0, y=0, z=0}
 	if stop_wiggle or vector.equals(dir, {x=0, y=0, z=0}) then
 		vel = {x = 0, y = 0, z = 0}
 		local pos_r = vector.round(pos)
-		if not carts:is_rail(pos_r, self.railtype) then
+		if not carts:is_rail(pos_r, self.railtype)
+				and self.old_pos then
 			pos = self.old_pos
 		elseif not stop_wiggle then
 			pos = pos_r
@@ -239,7 +259,7 @@ local function rail_on_step(self, dtime)
 		update.vel = true
 	else
 		-- Direction change detected
-		if not vector.equals(dir, self.old_dir) then
+		if dir_changed then
 			vel = vector.multiply(dir, math.abs(vel.x + vel.z))
 			update.vel = true
 			if dir.y ~= self.old_dir.y then
@@ -291,7 +311,7 @@ local function rail_on_step(self, dtime)
 	end
 
 	self.object:set_acceleration(new_acc)
-	self.old_pos = vector.new(pos)
+	self.old_pos = vector.round(pos)
 	if not vector.equals(dir, {x=0, y=0, z=0}) and not stop_wiggle then
 		self.old_dir = vector.new(dir)
 	end
@@ -338,9 +358,15 @@ local function rail_on_step(self, dtime)
 	end
 	self.object:set_animation(anim, 1, 0)
 
-	self.object:set_velocity(vel)
+	if update.vel then
+		self.object:set_velocity(vel)
+	end
 	if update.pos then
-		self.object:set_pos(pos)
+		if dir_changed then
+			self.object:set_pos(pos)
+		else
+			self.object:move_to(pos)
+		end
 	end
 
 	-- call event handler
diff --git a/mods/carts/functions.lua b/mods/carts/functions.lua
index 8408cc1..a54b594 100644
--- a/mods/carts/functions.lua
+++ b/mods/carts/functions.lua
@@ -99,6 +99,16 @@ function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
 		right.z = -dir.x
 	end
 
+	local straight_priority = ctrl and dir.y ~= 0
+
+	-- Normal, to disallow rail switching up- & downhill
+	if straight_priority then
+		cur = self:check_front_up_down(pos, dir, true, railtype)
+		if cur then
+			return cur
+		end
+	end
+
 	if ctrl then
 		if old_switch == 1 then
 			left_check = false
@@ -106,14 +116,14 @@ function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
 			right_check = false
 		end
 		if ctrl.left and left_check then
-			cur = carts:check_front_up_down(pos, left, false, railtype)
+			cur = self:check_front_up_down(pos, left, false, railtype)
 			if cur then
 				return cur, 1
 			end
 			left_check = false
 		end
 		if ctrl.right and right_check then
-			cur = carts:check_front_up_down(pos, right, false, railtype)
+			cur = self:check_front_up_down(pos, right, false, railtype)
 			if cur then
 				return cur, 2
 			end
@@ -122,9 +132,11 @@ function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
 	end
 
 	-- Normal
-	cur = carts:check_front_up_down(pos, dir, true, railtype)
-	if cur then
-		return cur
+	if not straight_priority then
+		cur = self:check_front_up_down(pos, dir, true, railtype)
+		if cur then
+			return cur
+		end
 	end
 
 	-- Left, if not already checked
@@ -158,33 +170,37 @@ function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
 	return {x=0, y=0, z=0}
 end
 
-function carts:pathfinder(pos_, old_pos, old_dir, ctrl, pf_switch, railtype)
-	if vector.equals(old_pos, pos_) then
-		return true
-	end
+function carts:pathfinder(pos_, old_pos, old_dir, distance, ctrl,
+		pf_switch, railtype)
 
 	local pos = vector.round(pos_)
+	if vector.equals(old_pos, pos) then
+		return
+	end
+
 	local pf_pos = vector.round(old_pos)
 	local pf_dir = vector.new(old_dir)
+	distance = math.min(carts.path_distance_max,
+		math.floor(distance + 1))
 
-	for i = 1, 3 do
-		pf_dir, pf_switch = carts:get_rail_direction(
-			pf_pos, pf_dir, ctrl, pf_switch, railtype)
+	for i = 1, distance do
+		pf_dir, pf_switch = self:get_rail_direction(
+			pf_pos, pf_dir, ctrl, pf_switch or 0, railtype)
 
 		if vector.equals(pf_dir, {x=0, y=0, z=0}) then
 			-- No way forwards
-			return false
+			return pf_pos, pf_dir
 		end
 
 		pf_pos = vector.add(pf_pos, pf_dir)
 
 		if vector.equals(pf_pos, pos) then
 			-- Success! Cart moved on correctly
-			return true
+			return
 		end
 	end
-	-- Cart not found
-	return false
+	-- Not found. Put cart to predicted position
+	return pf_pos, pf_dir
 end
 
 function carts:register_rail(name, def_overwrite, railparams)
diff --git a/mods/carts/init.lua b/mods/carts/init.lua
index b2ba5f3..fe45303 100644
--- a/mods/carts/init.lua
+++ b/mods/carts/init.lua
@@ -7,6 +7,8 @@ carts.railparams = {}
 carts.speed_max = 7
 -- Set to -1 to disable punching the cart from inside (min = -1)
 carts.punch_speed_max = 5
+-- Maximal distance for the path correction (for dtime peaks)
+carts.path_distance_max = 3
 
 
 dofile(carts.modpath.."/functions.lua")