# 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.