A couple people have told me that it’s disturbing, which was not completely intentional. I think the asset bundle screams “cozy farm game” but then you get into it and it’s irreverent, absurdity which defies peoples’ expectations.
It’s a combination of the standardcontact_point_responsesolution that’s in the docs for handling solid collisions and those raycasts that I added to deal with edge cases. Now that you mention it I should probably go back and see how many of thecontact_point_response handlers are still needed after adding the raycasts.
This is the part I’m assuming you want to see. Here are the horizontal raycasts but also have vertical ones too.
if original_velocity.x ~= 0 then
local horizontal_dir = vmath.normalize(vmath.vector3(original_velocity.x, 0, 0))
local right = vmath.vector3(0, 1, 0)
local left = vmath.vector3(0, -1, 0)
local middle = vmath.vector3()
local start_pos_right = pos + right * offset_distance
local start_pos_left = pos + left * offset_distance
local start_pos_middle = pos + middle
local end_pos_right = start_pos_right + horizontal_dir * (math.abs(original_velocity.x) * dt + buffer)
local end_pos_left = start_pos_left + horizontal_dir * (math.abs(original_velocity.x) * dt + buffer)
local end_pos_middle = start_pos_middle + horizontal_dir * (math.abs(original_velocity.x) * dt + buffer)
local hit_right = physics.raycast(start_pos_right, end_pos_right, collision_mask)
local hit_left = physics.raycast(start_pos_left, end_pos_left, collision_mask)
local hit_middle = physics.raycast(start_pos_middle, end_pos_middle, collision_mask)
-- msg.post("@render:", "draw_line", { start_point = start_pos_right, end_point = end_pos_right, color = vmath.vector4(1, 0, 0, 1) }) -- Red
-- msg.post("@render:", "draw_line", { start_point = start_pos_left, end_point = end_pos_left, color = vmath.vector4(0, 1, 0, 1) }) -- Green
-- msg.post("@render:", "draw_line", { start_point = start_pos_middle, end_point = end_pos_middle, color = vmath.vector4(0, 0, 1, 1) }) -- Blue
if hit_right or hit_left or hit_middle then
velocity.x = 0
end
-- Push through single tile gap
local horizontal_dir = vmath.normalize(vmath.vector3(original_velocity.x, 0, 0))
local function can_move_in_direction(direction)
local check_start = pos + horizontal_dir * buffer
local check_end = check_start + direction * offset_distance
local hit = physics.raycast(check_start, check_end, collision_mask)
-- msg.post("@render:", "draw_line", { start_point = check_start, end_point = check_end, color = vmath.vector4(0, 1, 1, 1) })
return not hit
end
if hit_right and not hit_left then
if can_move_in_direction(left) then
is_colliding_toward_opening = true
velocity.y = velocity.y - ((is_knockback or is_dodging) and original_velocity.y or self.speed)
end
elseif hit_left and not hit_right then
if can_move_in_direction(right) then
is_colliding_toward_opening = true
velocity.y = velocity.y + ((is_knockback or is_dodging) and original_velocity.y or self.speed)
end
end
end
IMO that last bit is the most interesting. For each direction there are three casts. If an outer most cast is the only one that lands on a solid, it infers that the player is possibly trying to move into a one tile space. It will then do another cast in the direction that will allow the player to move through the opening and if that does not land, it will push the player towards the opening. This helps with letting the player walk through one tile spaces they would otherwise have to line up precisely and avoids the annoyance of getting stuck on corners easily.