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>
110 lines
3.5 KiB
Markdown
110 lines
3.5 KiB
Markdown
# 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`.
|
|
|
|
```text
|
|
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.
|
|
|
|
```text
|
|
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.
|