diff --git a/mods/ENVIRONMENT/mcl_physics/api.lua b/mods/ENVIRONMENT/mcl_physics/api.lua
index 86a46ad9b..d749d137d 100644
--- a/mods/ENVIRONMENT/mcl_physics/api.lua
+++ b/mods/ENVIRONMENT/mcl_physics/api.lua
@@ -7,13 +7,13 @@ function mod.register_environment_effect(effect)
 	list[#list + 1] = effect
 end
 
-function mod.get_environment_effect(pos, vel, staticdata, mass)
-	local v = vector.new(0,0,0)
-	local a = vector.new(0,0,0)
+function mod.get_environment_effect(pos, vel, staticdata, mass, entity)
+	local v = vector.zero()
+	local a = vector.zero()
 
 	-- Accumulate all enviornmental effects
 	for _,effect in ipairs(registered_environment_effects) do
-		local dv,da = effect(pos, vel, staticdata)
+		local dv,da = effect(pos, vel, staticdata, entity)
 		if dv then
 			v = v + dv
 		end
@@ -29,15 +29,21 @@ function mod.get_environment_effect(pos, vel, staticdata, mass)
 	return v,a
 end
 
+local DEFAULT_ENTITY_PHYSICS = {
+	mass = 1,
+}
 function mod.apply_entity_environmental_physics(self, data)
 	data = data or {}
 
+	local physics = self._mcl_physics or DEFAULT_ENTITY_PHYSICS
+	local mass = physics.mass or DEFAULT_ENTITY_PHYSICS.mass
+
 	local pos = self.object:get_pos()
 	local vel = self.object:get_velocity()
-	local new_velocity,new_acceleration = mcl_physics.get_environment_effect(pos, vel, data, 1)
+	local new_velocity,new_acceleration = mcl_physics.get_environment_effect(pos, vel, data, mass, self)
 
-	if new_velocity then print("new_velocity="..tostring(new_velocity)) end
-	if new_acceleration then print("new_acceleration="..tostring(new_acceleration)) end
+	--if new_velocity then print("new_velocity="..tostring(new_velocity)) end
+	--if new_acceleration then print("new_acceleration="..tostring(new_acceleration)) end
 
 	-- Update entity states
 	self._flowing = data.flowing
diff --git a/mods/ENVIRONMENT/mcl_physics/init.lua b/mods/ENVIRONMENT/mcl_physics/init.lua
index 8b7756f91..93a10d0bc 100644
--- a/mods/ENVIRONMENT/mcl_physics/init.lua
+++ b/mods/ENVIRONMENT/mcl_physics/init.lua
@@ -9,7 +9,7 @@ dofile(modpath.."/api.lua")
 -- TODO: move to Flowlib
 local FLOW_SPEED = 1.39
 local BOUANCY = 3
-mod.register_environment_effect(function(pos, vel, staticdata)
+mod.register_environment_effect(function(pos, vel, staticdata, entity)
 	-- Get the node and node definition
 	local node = minetest.get_node_or_nil(pos); if not node then return end
 	local nodedef = minetest.registered_nodes[node.name]; if not nodedef then return end
@@ -21,17 +21,20 @@ mod.register_environment_effect(function(pos, vel, staticdata)
 
 	-- Get liquid flow direction
 	local vec = vector.multiply(flowlib.quick_flow(pos, node), FLOW_SPEED)
-	return vector.new(vec.x, -0.22, vec.z),nil
+	return vector.new(vec.x, -0.22, vec.z),nil -- TODO: move bouancy velocity out of here
 end)
 
 -- Simple gravity and bouancy
-mod.register_environment_effect(function(pos, vel, staticdata)
+mod.register_environment_effect(function(pos, vel, staticdata, entity)
 	-- Get the node and node definition
 	local node = minetest.get_node_or_nil(pos);
 	local nodedef = nil
 	if node then nodedef = minetest.registered_nodes[node.name] end
 
-	if nodedef and nodedef.liquidtype == "source" then
+	if nodedef and nodedef.liquidtype == "source" then -- TODO: make this apply to flowing liquids as well
+		-- TODO: make this not apply to fish
+		--print("entity="..dump(entity))
+
 		-- Apply decceleration and bouancy if the entity moved from flowing water to
 		-- stationary water
 		return nil,vector.new(
@@ -46,16 +49,35 @@ mod.register_environment_effect(function(pos, vel, staticdata)
 end)
 
 -- Node effects
-mod.register_environment_effect(function(pos, vel, staticdata)
-	local pos_r = vector.round(pos)
-	local node = minetest.get_node(pos_r)
-	local nodedef = minetest.registered_nodes[node.name]
-	if not nodedef then return end
+local DEFAULT_NODE_PHYSICS = {
+	friction = 0.9
+}
+local function apply_node_physics(node, vel, staticdata, entity)
+	local node_def = minetest.registered_nodes[node.name] or {}
+	local node_physics = node_def._mcl_physics or DEFAULT_NODE_PHYSICS
 
-	if nodedef._mcl_physics_effect then
-		return nodedef._mcl_physics_effect(pos, vel, staticdata)
+	local node_physics_effect = node_physics.effect
+	if node_physics_effect then
+		return node_physics_effect(pos, vel, staticdata)
 	end
 
-	return -- nil,nil
+	-- Default behavior
+	local accel = vector.zero()
+
+	-- Friction
+	local friction_scale = node_physics.friction
+	accel = accel + vel * -friction_scale
+
+	return vector.zero(), accel
+end
+mod.register_environment_effect(function(pos, vel, staticdata, entity)
+	local pos1_r = vector.round(pos)
+	local v1,a1 = apply_node_physics(minetest.get_node(pos1_r), vel, staticdata, entity)
+
+	-- TODO: only apply when touching under_node
+	local pos2_r = vector.offset(pos1_r,0,-1,0)
+	local v2,a2 = apply_node_physics(minetest.get_node(pos2_r), vel, staticdata, entity)
+
+	return (v1 + v2), (a1 + a2)
 end)
 
diff --git a/mods/HUD/mcl_experience/orb.lua b/mods/HUD/mcl_experience/orb.lua
index aa77f00a2..4cb28d4ca 100644
--- a/mods/HUD/mcl_experience/orb.lua
+++ b/mods/HUD/mcl_experience/orb.lua
@@ -107,42 +107,7 @@ local function xp_step(self, dtime)
 	end
 
 	-- Slide on slippery nodes
-	local vel = self.object:get_velocity()
-	local def = node and minetest.registered_nodes[node.name]
-	local is_moving = (def and not def.walkable) or
-		vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0
-	local is_slippery = false
-
-	if def and def.walkable then
-		local slippery = minetest.get_item_group(node.name, "slippery")
-		is_slippery = slippery ~= 0
-		if is_slippery and (math.abs(vel.x) > 0.2 or math.abs(vel.z) > 0.2) then
-			-- Horizontal deceleration
-			local slip_factor = 4.0 / (slippery + 4)
-			self.object:set_acceleration({
-				x = -vel.x * slip_factor,
-				y = 0,
-				z = -vel.z * slip_factor
-			})
-		elseif vel.y == 0 then
-			is_moving = false
-		end
-	end
-
-	if self.moving_state == is_moving and self.slippery_state == is_slippery then
-		-- Do not update anything until the moving state changes
-		return
-	end
-
-	self.moving_state = is_moving
-	self.slippery_state = is_slippery
-
-	if is_moving then
-		self.object:set_acceleration(gravity)
-	else
-		self.object:set_acceleration({x = 0, y = 0, z = 0})
-		self.object:set_velocity({x = 0, y = 0, z = 0})
-	end
+	mcl_physics.apply_entity_environmental_physics(self)
 end
 
 minetest.register_entity("mcl_experience:orb", {
diff --git a/mods/ITEMS/mcl_core/nodes_base.lua b/mods/ITEMS/mcl_core/nodes_base.lua
index afc73ea05..c9e1f0a56 100644
--- a/mods/ITEMS/mcl_core/nodes_base.lua
+++ b/mods/ITEMS/mcl_core/nodes_base.lua
@@ -936,6 +936,9 @@ minetest.register_node("mcl_core:ice", {
 	_mcl_blast_resistance = 0.5,
 	_mcl_hardness = 0.5,
 	_mcl_silk_touch_drop = true,
+	_mcl_physics = {
+		friction = 0.4,
+	},
 })
 
 minetest.register_node("mcl_core:packed_ice", {
@@ -950,6 +953,9 @@ minetest.register_node("mcl_core:packed_ice", {
 	_mcl_blast_resistance = 0.5,
 	_mcl_hardness = 0.5,
 	_mcl_silk_touch_drop = true,
+	_mcl_physics = {
+		friction = 0.15,
+	},
 })
 
 -- Frosted Ice (4 nodes)