acdream/docs/research/2026-04-30-precipice-slide-pseudocode.md
Erik 261322b48e fix(physics): #32 L.2c precipice edge-slide context
Port the first retail precipice-slide slice from named retail/ACE: terrain and BSP walkable hits now preserve polygon vertices, failed step-down edges back-probe to rediscover the walkable polygon, and edge-slide can run precipice/cliff slide instead of only hard-stopping.

Adds pseudocode anchors plus regression coverage for terrain polygon context and loaded-terrain boundary edge-slide.

Co-authored-by: Codex <codex@openai.com>
2026-04-30 08:04:37 +02:00

3.5 KiB

Precipice Slide Pseudocode

Date: 2026-04-30

Phase: L.2c - Movement & Collision Conformance

Retail Anchors

  • Named retail: CTransition::edge_slide, acclient_2013_pseudo_c.txt:273001
  • Named retail: CTransition::cliff_slide, acclient_2013_pseudo_c.txt:272397
  • Named retail: SPHEREPATH::precipice_slide, acclient_2013_pseudo_c.txt:274316
  • ACE cross-check: Transition.EdgeSlide, Transition.CliffSlide, SpherePath.PrecipiceSlide
  • ACE cross-check: Polygon.find_crossed_edge

Edge-Slide Flow

When a grounded mover has contact state but the next candidate position has no walkable surface within step-down reach, retail does not immediately accept the fall or hard-stop. It enters CTransition::edge_slide.

edge_slide(transitionState, stepDownHeight, walkableZ):
  if object is not OnWalkable or EdgeSlide is disabled:
    clear walkable
    restore candidate check position
    clear current contact plane
    mark cell array valid
    transitionState = OK
    return handled

  if current collision has a contact plane below walkableZ:
    transitionState = cliff_slide(contact plane)
    clear walkable and restore candidate check position
    clear current contact plane
    return not-final

  if sphere_path.walkable exists:
    transitionState = precipice_slide()
    clear current contact plane and restore candidate check position
    return transitionState == Collided

  if current collision has any contact plane:
    clear walkable
    restore candidate check position
    clear current contact plane
    transitionState = OK
    return handled

  move CheckPos back from failed candidate to the current sphere center
  step_down(stepDownHeight, walkableZ) to rediscover the walkable polygon
  clear current contact plane
  restore the failed candidate check position

  if a walkable polygon was discovered:
    set walkable_check_pos from the candidate sphere in walkable space
    transitionState = precipice_slide()
    return transitionState == Collided

  clear walkable
  mark cell array valid
  transitionState = Collided
  return handled

Precipice Slide

SPHEREPATH::precipice_slide is the edge-normal half of edge-slide. The crucial input is the walkable polygon that the mover just left; without that polygon, there is no crossed edge to slide along.

precipice_slide():
  normal = zero
  found = walkable.find_crossed_edge(walkable_check_pos, walkable_up, normal)

  if not found:
    clear walkable
    return Collided

  clear walkable
  step_up = false

  normal = walkable_pos.frame.LocalToGlobalVec(normal)

  blockOffset = LandDefs.GetBlockOffset(curr cell, check cell)
  movementOffset = global_sphere.center - global_curr_center.center + blockOffset

  if dot(normal, movementOffset) > 0:
    normal = -normal

  return global_sphere.slide_sphere(transition, normal, global_curr_center.center)

Porting Notes

acdream already had the Polygon.find_crossed_edge math inside BSPQuery, but the live diagnostic showed walkableValid=False at the failed step-down edge branch. The port must therefore preserve or rediscover the walkable polygon, not just pass the EdgeSlide flag.

For the first L.2c slice:

  • terrain supplies the exact current triangle vertices alongside its plane;
  • BSP step-down/find-walkable records world-space polygon vertices when the caller supplies the object's world origin;
  • the failed step-down edge branch performs the retail back-probe to current position before calling precipice slide;
  • CELLARRAY, full cell_bsp ownership, and cross-cell building portals remain L.2e work.