Week 38: Matching edge trajectories to odd surface shapes

An animated GIF showing trajectories for navigation pre-selections as the player directs the character around oddly-shaped surfaces.
Improvements for trajectories around oddly-shaped surfaces.

tl;dr: I continued adding support for oddly-shaped surfaces. In particular, I made improvements to character trajectories along intra-surface edges and against concave neighbor surfaces.

What happened last week?


  • I improved logic for projecting a shape onto a surface.
    • For supporting oddly-shaped surfaces.
    • In particular, I added support for ensuring that the character trajectory doesn't collide with concave neighbor surfaces.
  • I refactored how intra-surface edges are calculated.
    • And calculate trajectories for them that match the surface shape.

Laundry list

  • Improve logic for projecting a shape onto a surface (for oddly-shaped surfaces):
    • Fix how the path-preselection-annotator draws the edges of the selected surface.
    • Update legacy project-point-onto-surface-with-offset logic to use the new project-shape-onto-surface logic.
    • Fix an issue with out-of-surface-bounds shape-position projections.
    • Fix an issue with 0 and INF slopes in shape-to-segment-projection.
    • Fix an issue with project_shape_onto_segment mutating the RotatedShape argument.
    • Add support for project_shape_onto_surface to be called with an infinite coordinate for the axis that we're projecting along.
    • Fix an issue with adjusted shape values not being fully updated when redirecting to circle/rectangle calculations from capsule calculations in project_shape_onto_segment.
    • Fix issue with segment-normal value for single-vertex surfaces.
    • Fix an issue with out-of-bounds shape-positions not being nudged for single-vertex surfaces.
    • Fix PositionAlongSurface to use the new project_shape_onto_surface function.
    • Fix shape-projection to handle null-shape arguments.
    • Fix some issues in project_shape_onto_segment.
    • Add support for considering all middle segments and not just end segments with project-shape-onto-surface.
    • Use shape-projection instead of naïve shape-based-trig for calculating rounding-corner trajectories.
    • Add support for configuring in app-manifest whether oddly-shaped surfaces are used.
    • Fix a divot in the playback trajectory for fall-from-floor edges.
    • Implement support for handling early collisions with next concave neighbors during climb-to-adjacent-surface trajectory calculations.
    • Add a broad-phase bounding-box check when checking for early-trajectory-collision with concave next neighbors.
    • Consolidate project-shape-away-from-concave-neighbor-surface logic.
    • Use the new project_shape_onto_segment_and_away_from_concave_neighbors function.
    • Fix a bug with project_away_from_concave_neighbor.
A screenshot showing a trajectory path that ends slightly offset from a cusp in the wall.
  • This trajectory has been updated by calculating a collision with the concave neighbor surface.
  • Notice how the trajectory ends off-to-the-left of the cusp.
  • This takes into account the shape of the character.
  • Before, my naïve rounding-corner calculations would calculate a trajectory that would place the character directly above the wall-cusp-lower-corner-point, which would cause the character to intersect with the wall.
  • Refactor how intra-surface edges are calculated (and calculate trajectories for them that match the surface shape):
    • Refactor intra-surface-edge creation to use a factory pattern.
    • Refactor edge classes to always expect more state to be provided at instantiation time.
    • Implement IntraSurfaceCalculator.create_correction_interstitial.
    • Add trajectories to intra-surface-edges.
    • Update intra-surface-edge distance and duration to use axially-aligned distance rather than Euclidean.
    • Fix intra-surface-edge trajectory start-frame calculation.
    • Fix intra-surface-edge is-degenerate calculation.
A screenshot showing a trajectory path that follows the curvature of oddly-shaped surfaces.
Intra-surface edge trajectories now follow the curve of the surface!
    • Miscellaneous:
      • Fix ceiling-surface-collision with edge-matching at end of jump.
      • Implement climb-to-adjacent-surface concave-case trajectories.
      • Fix edge-playback-stuck detection in SurfaceNavigator.
      • Fix an issue with surface-grabs being cancelled.
      • Fix A* search heuristic weight to use duration instead of distance, depending on a flag.
      • Fix an issue with duplicate edge-calculation-debugging entries showing-up in the inspector.
      • Fix fall-from-air-edge re-calculation in SurfaceNavigator.
      • Add a check for unexpected collisions for various types of edges.
      • Update action logs to print all active actions and velocity.
      • Update surface-state logic to not treat character as rounding a corner when triggering wall-release.
      • Add play-time to error logs.
      • Refactor character-surface-state logic to still track normal physics-system-contacts while applying forced-rounding-corner contacts.
      • Add logic to force a collision with the expected surface at the end of an edge, even if its trajectory falls short.
      • Fix nudge-position-logic-to-not-be-too-close-to-surface-edge logic to preserve shape-projection onto the surface.
      • Update edge-interruption-check logic to also consider neighbor collisions as interruptions unless they are on the first frame of edge playback.
      • Add support for ending climb-to-adjacent-surface edge playback when touching the next neighbor surface.
      • Add support for not detecting an edge as interrupted when touching the next neighbor surface.
      • Add logic to end intra-surface-edge trajectories early when colliding with a concave next neighbor.
      • Update level 10 tiles.
      • Add support for left-walls and right-walls being neighbors.
      • Update surface validation to happen earlier, and to only check for neighbor assignments.
      • Fix a few if vs elif statements in calculate_collision_surface.
      • Add a smaller font for ruler and grid-indices text annotations.
      • Refactor calculate_collision_surface to support adjusting the collision normal that's being considered in order to correct for slightly-off values provided from Godot's move_and_slide API.

    What's next?

    • I'll finish up my current work to support oddly-shaped surfaces.
    • I'll be doing another Ludum Dare game jam next weekend!
    • So I'll spend most of my time this week making sure I haven't broken anything important with any recent changes in my Surfacer framework.

    🎉 Cheers!

    This is a simple icon representing my sabbatical.