Piper Method

Behaviours

A walker is a point body with a radius, a desired speed, a trip, and a target portal. Motion is the force law in forces.md. This page is everything around that law: who appears, where they are going, and when the force law is replaced. The order those compose is in algorithm.md.

Population

Desired speed is sampled once, at spawn, as desired_speed × (1 + u × speed_jitter) with u uniform in −1…1 and speed_jitter clamped to 0–0.9, so the jitter is a fraction of the mean, not m/s. The floor is 0.2 m/s. Radius scales slightly with that speed: the ratio of sampled to mean speed is clamped to 0.8–1.2, and the radius is the base radius × (0.9 + 0.1 × ratio), so 0.98–1.02 of the base, and never below 0.12 m.

Each spawned walker is on a trip:

  • Board — heading for a platform or train door (or the non-street side of a flipped scenario).
  • Alight — heading for the street.

Street portals are those whose id starts with street_. A portal with targets draws each walker's exit at spawn from the weights, over the listed portals that accept arrivals and have a positive weight; the random stream is the scenario seed. A drawn exit is the walker's own and is not changed by trip rules or a flip. Otherwise a portal may name its target, and failing that, destinations rotate through the portals that accept arrivals on the correct side of the trip.

p_impaired and p_disable are independent chances, at spawn, that the walker prefers an elevator over a stair. A scenario-wide elevator route forces that preference for everyone. The two probabilities are separate rolls; they do not describe a medical model beyond “use the lift”.

States

StateCodeMeaning
Walk0Integrated, or held at zero velocity
Teleport1Waiting out a vertical pair delay or riding an elevator car; position is frozen until release
Done2Reached a destination portal that accepts arrivals
Removed3Taken out of the run
In store4Inside a store, standing on one of its slots; no forces, not on the floor

Done and removed bodies stay in the frame so indices remain stable. They no longer spawn forces.

Route

The target is the nearest part of a portal (see algorithm). On the same floor the path is a walkable polyline that steps around obstacles, floor holes, and attractors that are already full. The grid is 0.7 m. A straight cut between waypoints is kept only when the body radius stays clear of those blockers. Steps within 0.35 m of a wall cost up to 3.5 times their length, so the path holds a comfort gap from walls; it closes that gap only in an aisle too narrow to keep it. Every 0.5 s the leg to the current waypoint is re-checked. If a crowd has pushed the walker so that the leg now clips a wall or void, the path is rebuilt, rather than waiting for the stuck timer. A waypoint the walker has already passed (within 1.5 m) counts as reached, so they do not turn back to touch it. The step off a stair (below) is the exception.

The path is a centre line, not a rail. Each spawned walker keeps a fixed side of it, a lane share from −1 (right) to 1 (left), spread evenly over spawns. Each leg on open floor has a slack on each side, up to 1.5 m: the widest shift of the corner point, among 1.5, 1.1, 0.75, 0.45 and 0.2 m, for which the straight walk from the start of the leg to the shifted point keeps the body and the 0.35 m comfort gap off every wall, plus half a nav cell. The walker aims at the corner shifted by its share of that slack, so a crowd on one route walks abreast across a wide hall, and passes a column on its open side instead of all grazing the same corner. Next to a wall the slack on that side is zero. A leg into a mouth or the goal closes the shift back onto the point over its last 6 m, so walkers still converge into gates and stairs. Legs through a gate or stair have no slack. Walkers placed by the scenario (not spawned) have lane share 0 and follow the centre line. A stair or escalator well is not open floor: the path may enter it only through the open mouth, and it may not cut in through a side wall or the far end. Full attractors are blocked so later walkers route around the crowd standing there.

Walkers also steer clear of three soft obstacles they could walk through, but would rather not:

  • Mouth aprons. The floor in front of every stair, escalator and gate end costs extra, fading to normal 4 m out, across the mouth width plus 1 m each side. How much depends on the direction of the step. Crossing the front of the mouth costs up to 5 times its length (4 extra). Walking straight in or out along the mouth's axis costs only 15 % of that. Someone passing by bends round the foot of an escalator instead of cutting across the people stepping on and off. Someone who has just stepped off a stair walks straight out for a few metres before turning, instead of turning across the people waiting to go the other way. Someone heading for that mouth ignores its apron: within 10 m of a gate or escalator they will board, or 2 m of a stair mouth.
  • Crowds. The path cost also counts the crowd on the floor over the last few seconds, not the all-time map. What a walker feels depends on which way it is going. Standing people and people walking towards it count in full. People walking the same way count a quarter, so a stream going your way is joined, not avoided. A felt density above 0.35 ped/m² (the Fruin walkway LOS B/C boundary) adds 2.5 times the excess for each metre walked, up to 2 ped/m² of excess. The crowd at the walker's own goal does not count: its queue, or within the free radius of the target given above.
  • Queue lines. A formed line behind a gate or escalator mouth (1.8 m or longer), and each column of people waiting at a train door, marks a band 0.6 m either side of it. Walking through that band costs 7 times its length, so someone passing goes round the tail, or through a gap, instead of pushing between the people waiting. The walker's own queue costs nothing; for a train door that is anyone boarding or leaving through that door.

None of these is a wall: if going round costs more than walking through, the walker walks through. Every 2 s each walker checks the next 15 m of its path against the crowd as it is now. If the crowd cost there has grown by more than 1.5 m equivalent since the last check, the path is rebuilt round it. This check is not made by walkers who are queued, on a door-line aim, waiting at a crossing curb, captured, held, on a belt, or inside a connector.

A different floor inserts a connector:

  • Stair (default route) — a zone with a pair_id that is not an escalator. Two-way unless dir is along or against. Speed is desired_speed * speed_factor. Walkers on the flight are clamped inside the side walls. Someone in the hall who is not actually changing floors is sent back out the end they entered. On a stair at least 2 m wide that is not single file, each direction has a lane band on its keep_left side, out to 0.4 m off the side wall. How much of the width a direction gets follows the traffic: the people on the flight, plus those within 6 m of a mouth who have picked this stair, counted each way. With nobody coming the other way (none counted, and none in sight on the flight) the band is the whole flight, so a one-way crowd uses the full width instead of backing up behind half of it. Otherwise each direction gets its share of the width by count, between 30 % and 70 %, and the band starts 0.2 m past the divide on the walker's side, never further over than the lane line. Walkers aim for that band at the mouth on the way in and on the way out, each at the point across it given by their lane share, so a group arrives abreast rather than in single file. Inside the band, sight yaw (sidestep, follow) works as on any walk, so people go abreast and overtake. A walker who leaves the band heads for a point 1 m further up the flight back inside it: towards the middle of the band from the centre side, or towards the band edge from the wall side. The sideways offset of that point is capped at 1 m, so the turn is at most 45°. Climbers and descenders use opposite halves from the landing onward instead of meeting in the middle.
  • Escalator — kind: "escalator". One direction (dir along is z_from → z_to; against is the reverse), and only boarded on the entry floor. The walker walks onto the belt and boards within 0.3 m of the entry edge. Boarding does not move them; the belt draws them sideways onto the centreline at 0.9 m/s while it carries them, one file, held off the person ahead. Social forces are not applied on the belt. At the exit they step off where the belt's last step leaves them, just past the end edge, at belt speed. A fare gate is the same belt on one floor; dir both lets it run either way.
  • Elevator — a teleport pair with no walked zone, served by one car. Two or more landings share the pair_id, one per floor the car stops on. A walker who reaches the landing while the car stands there with room boards and stands still inside the car (drawn like a visitor in a store). The car leaves when it is full, or hold_s after the last person boarded if nobody else is waiting at that landing; someone still walking up holds it, but never past 3 × hold_s. It only runs to a floor that has a call (a waiter on that landing) or a rider whose destination is that floor; it does not cycle through quiet floors. An empty car goes to the nearest called floor. The ride takes delay_s per storey. On arrival only riders bound for that floor step out; the rest stay aboard. A landing with a door is used only through it: walkers step in from just in front of the doorway, and riders step out a row at a time, as many abreast as the doorway fits (0.55 m each, at most 3), each row once the one before has walked clear (or after 2 s). Nobody boards until the last rider for this floor is out. A landing without a door is entered from any edge, and those getting off step out together, spread across it. While the car is away, full or unloading, walkers headed for it stand about 1.4 m back from the door (or the landing); someone still behind the door line, coming round the shaft, is not yet waiting. Walkers use the nearest elevator on their floor. teleport_lock_s (default 0.75 s) stops an immediate re-entry.

Same-floor fare gates (kind: "gate") are the same one-file conveyor as an escalator, without a floor change. Default dir is one-way along the rise; against flips it and both serves either mouth. A walker waits at the mouth until the belt has a gap of about one body spacing, and steps off just past the far edge. Only their own gate counts: someone in the next gate of a bank does not hold them. If their gate is busy they slow to a stand 0.55 m short of the mouth instead of stopping dead. If it is clear they walk straight in. At the head of a line they keep one spacing behind the last person to go through.

A bank of gates side by side is shared. Within 12 m of the mouths a walker weighs each gate that serves the crossing: the walk to its mouth, plus 1.5 m for every person already bound for it and closer to the mouth, or riding it. They settle on the cheapest, re-weigh about once a second, and switch only when another gate is at least 1.6 m cheaper. Within 2 m behind the mouth the choice is final. Equal gates are split by a small per-walker offset, so a crowd fans out across the bank rather than stacking on the nearest lane.

Stairs and escalators are chosen the same way, but in seconds rather than metres, and from anywhere on the floor. A walker on the stair route who has to change floor weighs every stair and every escalator running the right way:

  • the walk to its mouth, by way of the back of its line when one has formed and the walker stands beside it;
  • the wait: the people bound for it and nearer the mouth, at 1.3 s each per one-file lane (an escalator is one lane; a stair is one lane per 0.7 m of width), minus the walk, since that much of the queue clears before the walker gets there;
  • the crossing: belt length over belt speed, or flight length over the walker's stair speed;
  • for a stair, 6 s of extra effort going up, or 2 s going down.

They re-weigh about once a second and switch only for a saving of at least 3 s. Within 2 m of the held mouth the choice is final. With nobody waiting, the nearest mouth wins, and the escalator is preferred when the walk to each is about the same. Once an escalator queue costs more than the stair beside it, newcomers take the stair, and so do walkers already in the back of the line.

A walked stair hands the walker to the other floor where they stand when they step past the landing line, so the floor change is not a jump in plan. The far edge of a flight is a wall on the floor being left, so a walker can sit right on the line for a few ticks. Anyone who was on the flight and is now off it, within 0.6 m past the line, has stepped off, whether or not this tick's step crossed the line.

Off the flight, the first leg goes 1.8 m straight out of the mouth at the walker's own offset across it, so they stay in the lane they came up in (1.1 m if a wall is closer). Only then do they turn, however sharp the turn to their destination. Until they reach that point, or walk past it, it is not cut as an already-passed corner. A train door line or a gate queue does not take over their heading until then either. Someone bound for a door to one side of the stair therefore clears the mouth before turning, instead of swinging across the people lining up to go the other way.

Walkers see by drawn height, not by floor tag. Someone on a flight still counts as the floor they started on, but their height follows the tread. Anyone within 3 m of that height sees them, so a walker at the foot of a stair sees people on the lower half of the flight coming down. The usual opposing-traffic yaw then moves both to the keep_left side before they meet at the mouth. Bodies on the flight and on open floor also push on each other across the mouth when their heights are within 0.6 m.

Queues

Gates and escalators admit one person at a time, so a line forms behind the mouth. The line is the axis running back from the mouth's centre. Each tick, the walkers heading for that mouth who stand within the strip around the axis (half the zone width, at least 0.45 m, plus 0.15 m) are the queue, provided each is within 1.3 m of the one in front and the first is within 1.4 m of the mouth. For someone already in the line that first gap may be up to 3 m, so the line does not dissolve each time its head steps on. Speed does not matter either. The tail is the last of them.

  • Someone heading for an escalator with a formed line, from off to the side of it and behind its back, or more than 2.5 m out to the side, walks to the back of the line first and only then follows the line to the mouth. That leg goes round the line, not along it. Their path is checked every 20 ticks (once a second at dt 0.05 s); if the back has moved more than 1.5 m from where it was going, the path is rebuilt. A walker counts as heading for a mouth when it is among their next four waypoints, so they line up while still on the way to the back. Someone already level with the line or ahead of its back, within 2.5 m of it, is never sent back: they walk on to the mouth.

  • Everyone in the line behind the head holds a spacing behind the person in front: 0.75 m at a gate, 0.6 m at an escalator. They ease into that spot and stand, rather than closing up into a blob.

  • Newcomers who are not yet in the line take successive spots behind the tail, nearest first, one spacing apart. They do not squeeze in from the side or wrap round the head.

  • Nobody is turned back. Someone who still ends up beside or in front of the line, rather than at its back, steps into the line where they stand and boards in turn from there, instead of stopping and walking back to the tail, which would hold up the line behind them. Their spot in line never lies behind where they stand.

  • Anyone else within 10 m behind the mouth heads for a point on the axis 1.4 m ahead of them. They merge onto the line at a shallow angle instead of turning hard at the mouth.

  • A walker standing off the axis gets a sideways pull back toward it, up to 0.9 m/s² at 0.6 m offset. Stopped bodies are capped near 0.14 m/s, so a bent line straightens over a few seconds by small shuffles.

  • In line, sight yaw (lanes, follow) is off; the heading is the queue axis.

A queue target is used only when the straight walk to it is clear of walls. Otherwise the walker keeps the planned path.

A zone stop_delay_s holds the walker once, the first time they enter, then sets a bit so the same zone does not stop them again.

Spawn and arrival

Portals with mode spawn or both emit. count is a finite budget; rate_per_min spaces them (60 / rate seconds). A rate of zero dumps the remaining count as fast as clear spots allow. Each spawn tries up to 48 random points inside the polygon, rejecting obstacles and anyone closer than two radii.

Arrival is geometric: on the destination floor, inside a portal whose mode is despawn or both, the walker becomes Done. A train door is the exception: it only accepts arrivals while its train is boarding.

Trains

A track runs a fixed cycle every headway_s: the train brakes in over approach_s at constant deceleration, stands with its doors open for dwell_s, pulls out over depart_s, then the platform is empty until the next one. Run-in and run-out cover the train length plus 30 m.

When the doors open, the train's alight count is split evenly over its doors. A door is as many lanes wide as 0.6 m fits into its width (two for a 1.45 m door), and it lets people off a row at a time, one per lane side by side, every 60 × lanes / alight_rate_per_min s while it is open. Each stands inside the train, 0.3 m in from the edge, at their lane's place across the doorway; a lane whose spot is still taken misses that row. The door is a walkable inset in the train: the platform edge opens across the doorway and the three far sides are walls. They are on an Alight trip like anyone else. Whoever has not stepped off when the doors close stays on.

Boarders do not crowd the door. Each door has two lines, one each side of it, starting 0.45 m beside the door edge and running straight in from the platform edge at 0.65 m spacing. A line that reaches a wall or a void, or six people, spills into a second and then a third column, 0.6 m further from the door; the third stops after eight. A line also stops short of a column or other solid (1 m clear), of the 4 m in front of a stair or escalator mouth, so nobody waits where people leave the flight, and of the 1.6 m beside a stair or escalator well, so the strip past the well stays open.

When someone steps off, they first walk straight out from the door, past the deepest person waiting at it (0.8 m beyond, 2–7 m in), close to the door's centre line and between its two lines. Only then do they turn for their exit. On that first stretch they do not sidestep, and are pulled back onto the straight walk if pushed off it, so they leave between the lines instead of turning into them. Other people walking along the platform route round the waiting columns.

Once on the platform and within reach of their train, a boarder picks the line of that train that costs least. The cost is half the walk to the line's tail, plus 4 m for every person already in it or walking to it, plus a penalty of up to 12 m when the tail stands in a stair or escalator mouth, plus 30 m when the line is full. Each walker also has a preferred spot along the train, spread evenly over spawns from one end door to the other, and a pull of up to 1.2 m per metre away from it. People off one stair therefore fan out to the ends of the train instead of all taking the nearest doors. They re-weigh once a second and only move to a line at least 2 m cheaper. Doors are not tied to where they first aimed, so a crowd off one stair spreads along the train. Within 0.9 m of the tail they join and from then on keep their place in their own column: each column is a file in arrival order, each person easing into their slot and standing.

board_after_s after the doors open, and once that door has nobody left to step off and nobody stepping off within 1.5 m of it, each line lets the column head who has waited longest go to the door, one person per line per second. Only that column moves up one slot; the others stand, so the line stays tidy as it empties. Doors close on whoever is still waiting, and the next train takes them first. A released walker caught by the doors closing goes back to the head of their line.

Standing in a line never counts as being stuck, and no one in a line is rerouted round the crowd they are part of.

Crossings

Paths ignore the signal: the crossing is planned through like open floor. The signal acts on walking instead.

  • While a crossing shows flashing or don't walk, a walker whose remaining path enters it within 8 m slows to stop 0.35 m short of the curb. The slowdown runs over the last 1.6 m, so they ease into a stop instead of braking at the line. If several crossings are ahead, the nearest entry counts.
  • The curb crowd keeps its space without forming a queue. A walker held at the curb also stops 0.45 m, body to body, short of anyone standing in front of them, easing in over the last 0.7 m. "In front" means within 0.7 m of their heading line or within 60° of their heading. Anyone further to the side does not stop them, so later arrivals fill in beside the front row and the crowd spreads along the curb instead of filing behind. A walker not yet held, coming from further back, stops the same way behind anyone held who faces their way, so the crowd can grow past the 8 m reach without packing.
  • Someone who stepped onto the crossing during walk may finish: while it shows anything else they walk at 1.3 times their desired speed until they are off it.
  • Nobody who did not step on during walk can cross the curb onto a closed crossing: the step is refused the same way a wall refuses it, and they slide along the edge instead. Overshooting the stop or being pushed by the crowd behind therefore does not put them on the road.
  • Someone who is on the crossing but did not step on during walk (seeded there, for example) stands where they are until it shows walk. The flag that they stepped on during walk clears once they are off every crossing.
  • Waiting at the curb never counts as being stuck, and nobody waiting is rerouted round the crowd at the curb. Standing still behind the curb crowd, with a path onto the closed crossing within 20 m, does not count as stuck either.

Walkers do not anticipate the change: someone reaching the curb with one second of walk left steps on and then hurries. That is the behaviour the flash phase is meant to cover.

A zebra (a crossing with lanes and no signal timing) has no phases. It counts as showing walk while every vehicle coming on its lanes could stop short of it, and as don't walk otherwise (see vehicles); every rule above then applies unchanged. Someone already on it when a vehicle that cannot stop comes into reach hurries off it. Once anyone is on or about to step on, vehicles stop for them, so a stream of walkers keeps a zebra open.

Arriving and leaving by vehicle

Walkers also come from vehicles at a kerb or lot linked to a portal (see vehicles). They step out of that portal, a car's people as one group, and walk to a target drawn from the portal's targets. Each remembers the vehicle and the mode it came by. People who parked come back, after the stay at the portal they reached, and walk to the lot's portal. People set down at a kerb come back to the kerb's portal and wait there to be picked up.

A portal with mode_share draws, for each walker it spawns, whether they leave on foot, by a car parked before the run (they walk to a lot's portal), or by pick-up (they walk to a kerb's portal and wait). A visitor shops first and goes to that portal instead of its exit. Someone waiting for a pick-up stands still in the kerb portal until the vehicle has docked, then gets in. Waiting there never counts as being stuck.

Attractors

An attractor is a place a walker may stop (a kiosk, a retail front). On entering the polygon, once, they are offered the stop. They accept with probability p_affect, then stand for dwell_s. capture_limit is how many may be held at once; a full attractor is refused and becomes a navigation obstacle for everyone else on that floor. After release the walker will not accept that attractor again. Only the first 64 attractors in the scenario, across all floors, are tracked (a bitset); later ones never capture.

p_affect of 0 releases anyone already held.

A seat (kind: "seat") is a chair, or one place on a bench, and holds one person. Its polygon is the seat itself, drawn over the furniture obstacle. Walkers don't have to step into it, which nobody would do on a solid chair:

  • The offer. A free seat is offered to a walker within 4 m who is walking toward it. They are offered it once, and again only after they have moved more than 5 m away.
  • Walking to it. A walker who accepts goes to a standing spot beside the seat: the free side of the chair nearest them, not one against another chair or a wall. There they sit, placed on the seat and held still for dwell_s. Pushes from others don't move them.
  • Getting up. They stand up onto the same spot and carry on to their original destination. They don't sit again that trip.
  • While taken. From the moment someone accepts until they leave, the seat is not offered to anyone else, and nobody reroutes around it. The chair is already solid, so others simply pass it.
  • Giving up. Someone who gets stuck on the way to a seat gives it up.

Visitors

Everything above is origin to destination. A portal with a visit plan spawns visitors instead: walkers who go shopping on the way, take detours, tire and rest, and come in groups. A visitor still has the exit drawn at spawn; it is where they go once the plan is done.

Stores

A store is a solid block with a door on one edge. It is entered, not walked round: the visitor walks to the door, steps in onto the first free standing slot (a 0.7 m grid inside, nearest the door first), and is out of the crowd until the visit ends. The visit lasts dwell_s × 0.5–1.5. Then they step back out onto a clear spot just past the door line, waiting half a second at a time while every spot is taken.

At spawn a visitor draws how many stores to visit, uniformly in stops [min, max]. Each next store is drawn among those not yet visited, by weight × exp(−d / 40 m), where d is the straight distance to the door plus 2.5 m per metre of height. A store counts as full when the people inside, plus everyone else already heading there, plus this visitor's own party, would pass its capacity; a full store is not drawn. A visitor who finds it full at the door counts the visit as made and moves on. With no store left to draw, they head for their exit.

Detours

Shortest paths make every walker from one door to another take the same line. wander (0–1) gives each walker its own smooth cost field over the plan, cells about 7 m across, adding up to 1.6 × wander extra cost per metre, scaled per walker by 0.5–1.5. Path search then bends round that walker's own high patches, so a stream fans out over the floor. It applies to every walker, visitor or not, on open floor.

The bend is capped. When a wander path is more than detour_max times the straight distance plus 1 m, the plain shortest path is computed too, and the wander path is kept only while it is no more than detour_max times that plus 1 m. Default 1.3: up to 30 % farther.

Browsing

After each store pick, with chance p_browse, a visitor first stops at another store's front on the same floor, 2–30 m away, drawn by weight × exp(−d / 12 m). They stand about 0.9 m out from the frontage, beside its door (not in it), for 3–8 s, then walk on to the store they picked. A spot not reached within 60 s is given up.

Stamina and rest

Each visitor has stamina in 0–1, starting between 0.7 and 1. Walking drains stamina_drain per 100 m walked; each store visit takes 0.04 more. Sitting recovers recover_sit per second, standing still at a rest spot recover_stand. With stamina_drain at 0 none of this runs.

Once stamina drops below rest_below, the visitor looks for a place to rest within rest_reach on its floor, every 3 s until it finds one:

  • Seats. Any free seat attractor, scored by its distance minus 10 m, so a seat is preferred over standing.
  • Standing spots. A 2 m lattice of points with 0.6 m of open floor all round, a wall, rail, obstacle or floor edge within 1.4 m, and no zone or portal (store doors included) within 2.5 m. People rest against something, out of the way. A spot is taken while anyone stands within 1.5 m of it or has picked it.

Both are also scored by how busy the spot is: 25 m per ped/m² standing or passing there now, and 8 m per walker a minute that has crossed each metre of width there so far. The lowest score wins, so a tired visitor picks the quiet seat over the one in the stream, and a quiet corner over a busy one. They rest until stamina reaches rest_until, then carry on with their plan.

rest_p on the visit plan is the chance a visitor also makes one planned rest: after the first store, a sit or stand for 0.3 more stamina, tired or not.

Groups

group_sizes weights the chance a visitor arrives alone, or as a party of 2 to 6. Spawn rates count parties, not people. The first walker spawned is the leader; the others appear beside them. Everyone walks at the slowest member's desired speed.

The leader decides: the members copy its stores, exit and route noise, and change plan when it does. On open floor a member near the leader (within 6 m, same floor) steers for its place in a loose formation: two beside the leader 0.8 m apart, then rows of three 1 m behind, or single file where the formation's place is not open floor. A member who has fallen behind walks up to 25 % faster. The leader slows, down to a fifth of its pace, while any member is more than group_gap metres off. Groupmates push each other at 0.3 of ped_a and only once nearer than 0.3 m, and they do not slow for each other's headway, so a group walks closer and more abreast than strangers do.

A group shops together. Store capacity is checked for the whole party. Each member stepping in takes the leaving time of the groupmate already inside (at least a second away), so the party steps out together. A member who cannot get in while the leader is inside waits at the door. When the leader stops to browse or rest, the members stand round the same spot, or round the seat, about 0.9 m out. The group rests when its most tired member drops below rest_below, and the leader gets up only once that member has recovered as far as the rest calls for. If the leader leaves the run, the members carry on alone.

Recovery

Progress is the distance to the current drive point. If a walking body makes no progress for unstick_s (default 3 s), or creeps in a hall for that long:

  • On a stair, they are pointed at the mouth they should use and repath.
  • On a wide connector, they are given a small shove along the axis.
  • On a one-file belt, the stuck timer is cleared and the belt spacing is left in charge.
  • Otherwise the nearest hole or obstacle is ignored for 1.6 s (the soft wall force only; the integrator and contacts still refuse a step into a solid), velocity is set sideways, and the path is rebuilt. An elevator shaft (a floor hole under an elevator landing) is never ignored, so a rider stuck beside the doors after stepping out cannot walk into the void.

This exists so a body pinned on a corner or a muted wall force does not stand until the run ends. It is not a behavioural choice the scenario author tunes per person.

What the force law does not do

Escalators and fare gates do not steer with social forces. Sight does not reduce speed. Same-direction repulsion does not push the queue backward. Density and Fruin level of service are measurements; they do not feed back into the acceleration.