Piper Method

Elements

A scenario is one local frame in metres. origin is a longitude/latitude pair stored for the fixture; the integrator does not project coordinates. Every geometry vertex is already in that frame.

Features share an id (unique) and a ped_role. Unknown roles are rejected.

Floor

Walkable slab. floor_z is the height in metres. Geometry is a GeoJSON polygon. The exterior is oriented counter-clockwise and holes clockwise, so a left-hand normal points into walkable space. Holes (shafts, open voids) stay voids: their edges become wall segments. A hole that sits on a connector can be muted while the walker is on that flight, so the shaft does not push them off the stair. A column is an obstacle drawn as its own feature, not a hole filled in.

A walker is always snapped to the nearest floor height. Stairs still report a progress along the flight for display; the stored z is the floor they currently belong to.

Obstacle

A solid on one floor (kiosk, planter, column drawn as its own feature). Geometry is a polygon oriented so the normal points away from the object. Obstacles are walls and are excluded from spawn points.

Wall

A partition drawn as a LineString (or multi-segment polyline) on one floor. The parser offsets the line by half thickness into an obstacle of the same id, square-capped and miter-joined (offset_polyline in geom.rs, then Polygon::obstacle). The editor keeps the line; the sim sees the thick polygon. Walls are not joined into the floor outline.

FieldDefaultMeaning
floorrequiredFloor the wall stands on
thickness0.2 mWidth across the line, clamped 0.05–2
height3 mDrawn height. The sim is 2D

Portal

A region that emits walkers, receives them, or both.

FieldMeaning
modespawn, despawn, or both
floorFloor id
countHow many to emit (0 if this portal only receives)
rate_per_minEmission rate; 0 means “as fast as the polygon allows”
targetOptional destination portal id
targetsOptional map of destination portal id to weight. Each walker spawned here draws one exit, with chance weight / sum. Overrides target
visitOptional visit plan: stops [min, max] stores per visitor (default [1, 3], at most 32) and rest_p (0–1, default 0), the chance of one planned rest. Walkers spawned here are visitors and may name this portal as their exit
mode_shareOptional map of park, pickup, walk to weight: how each walker spawned here leaves. park sends them to a lot's portal to drive off, pickup to a kerb's portal to wait for a pick-up, walk to their drawn exit. park needs a lot with a portal, pickup a kerb with one. Without it everyone walks
stay_sSeconds people who came by vehicle and arrived here stay before heading back to it, from when the first of their party arrives. Default 300

See behaviours.md for trips and the street-id convention, and for visitors.

Store

A shop on one floor, solid to walkers, entered through its door. See behaviours.md.

FieldDefaultMeaning
floorrequiredFloor the store is on
doorrequiredTwo [x, y] points on the store's edge, at least 0.6 m apart. A door whose midpoint is within 3 m of the block is moved onto the nearest edge, so redrawing a block does not strand it
weight1Pull when a visitor picks the next store or a shopfront to browse. 0 takes it out of choice
dwell_s90Mean time inside; each visit is 0.5–1.5 times this
capacityevery slotPeople inside at once, at most the slots that fit

The block is also an obstacle with the same id. The parser adds a door portal, {store}_door, a strip 1 m deep in front of the door; only a visitor bound for that store arrives through it.

Crossing

A road crossing on one floor: a polygon walkers may only step onto while it shows walk. A signalled one runs a fixed cycle of walk, flashing, then don't walk. One with lanes and none of the three phase fields is a zebra: it shows walk while every vehicle coming on those lanes could stop short of it (vehicles.md).

FieldDefaultMeaning
floorrequiredFloor the crossing lies on
green_s30Walk
flash_s6Flashing: nobody new steps on, those on it finish
red_s60Don't walk
offset_s0Time a walk phase starts, to stagger crossings
lanesnoneLane ids that run through the polygon. Vehicles on them stop for walkers on or about to step onto the crossing, and during walk on a signalled one. Each must pass through the polygon

The polygon is walkable floor like any other; the road around it is simply not part of the floor. See behaviours.md for how walkers treat the signal.

Lane

One lane of carriageway, drawn as a LineString along its centreline in the direction of travel. Vehicles drive it as described in vehicles.md. A lane is not a wall. To keep walkers off the road, leave the carriageway out of the floor.

FieldDefaultMeaning
floorrequiredFloor the lane is on. It sets the height vehicles are drawn at
speed_kmh30Speed limit, 5–130
modesallWhich of car, moto, bike may use it
width3 mCarriageway width, 1–10. Over 3.2 m, motorcycles filter past queued cars
nextautoLanes a vehicle may drive onto at this lane's end. Without it, every lane on the same floor that starts within 0.5 m of this one's end
left, rightnoneThe parallel lane on each side. Vehicles change into it by MOBIL, and routes may use it
yield_tononeLanes that have priority where they meet this one, at a merge or a crossing. Drivers on this lane wait at the give-way point for a gap

Where lanes meet, cross or fork is found from their geometry; see vehicles.md.

Vehicle signal

A vsignal is a LineString stop line drawn across one or more lanes on its floor. It must cross at least one. Each lane it crosses gets a stop line where it crosses. Vehicles stop there on red, and on amber if they can stop comfortably (vehicles.md).

FieldDefaultMeaning
floorrequiredFloor of the lanes
phases[30, 3, 30]Green, amber and red, in seconds
offset_s0Time a green phase starts, to stagger signals
groupnoneSignals with the same group share one plan: the first one's phases and offset_s. Retiming any one retimes the group

Vehicle source

A Point that emits vehicles onto the lane whose centreline passes nearest it, within 3 m, on its floor.

FieldDefaultMeaning
floorrequiredFloor of the lane
rate_per_min0Vehicles per minute
mix{ "car": 1 }Mode to weight. At least one mode the lane allows must have a positive weight
targetsevery reachable sink, weight 1Vehicle sink, dropoff or parking id to weight. Each vehicle draws one among those that take its mode. Every target named must be reachable from the source and take at least one of its modes

Vehicle sink

A Point bound to the nearest lane in the same way. Vehicles bound for it leave when their front passes it. It has no fields except floor.

Drop-off kerb

A dropoff is a Polygon drawn beside a lane on its floor: the kerb vehicles pull in to, to set down or pick up. It binds to the lane nearest its middle (the mean of its corners), within 6 m. The kerb's stretch is the polygon's span along that lane. Bays split it evenly, bay 0 at the downstream end. A vehicle standing in a bay is drawn at the polygon middle's offset from the lane. How vehicles queue, pull in and leave is in vehicles.md.

FieldDefaultMeaning
floorrequiredFloor of the lane
baysas many as fitNumber of bays. By default, the stretch over the longest accepted body plus its standstill gap. Each bay must be at least as long as the longest accepted body
dwell_s30Seconds a set-down stands, without a portal
pickup_s45Most seconds a called pick-up waits for its walkers
modesallWhich of car, moto, bike may stop here
portalnoneThe walkers' portal at the kerb. Occupants of a vehicle docked here step out of it, and walkers waiting there are picked up (vehicles.md). It must be a portal

Parking

A parking lot is a Polygon on its floor holding bays for one mode, off an entry lane. Its bays are either a count, laid side by side along the polygon's span on the entry lane, nose in, each centred at the polygon middle's offset; or child bay polygons. Each bay's mouth is where its middle is nearest the entry lane, and its exit mouth likewise on the exit lane. The gate stands 6 m before the first bay mouth, or at the start of the entry lane.

FieldDefaultMeaning
floorrequiredFloor of the lot
modecarThe mode it takes. Both lanes must allow it
baysrequired without bay polygonsNumber of bays. Not allowed together with bay polygons
entry_lanerequiredLane id the bays open onto
exit_laneentry_laneLane id vehicles pull out onto. It must lead to a vehicle_sink
gate_s0Seconds the gate serves each vehicle, one at a time. 0 is no gate
park_s300Seconds a vehicle stays parked, without a portal
portalnoneThe walkers' portal at the lot. Occupants of a parked vehicle step out of it, and the car leaves once they have all come back to it. It must be a portal

A bay is a Polygon with parking set to its lot's id and nothing else. A vehicle in it faces from the entry lane towards the bay's middle.

Zone

A polygon that changes speed or carries a walker between floors.

FieldMeaning
speed_factorMultiplies desired speed while inside
z_from, z_toHeights at the two ends
rise_alongDirection of travel: x+, x-, y+, y- (also x / y for the positive axes), or a bearing in degrees clockwise from north (+y), so x+ is 90 and y- is 180. If omitted, the long side of the bounds is used (x+ or y+)
stop_delay_sOne-time standstill on entry
floorOptional floor id. Stairs apply on both floors they connect
pair_idJoins the zone to a teleport pair. Present on walked connectors
kindescalator, gate, or omitted (a stair when pair_id is set; a plain speed patch otherwise)
dirboth (two-way), along (one-way with the rise), or against (the reverse). Stairs default to two-way; escalators and gates default to one-way along the rise. Escalators cannot be two-way.
lane1 marks a single file
fixed_speedtrue to lock the belt to desired speed times speed_factor, or a positive number in m/s

A zone is a connector when it has a pair_id. It is a stair when it is a connector and not an escalator or a gate. It is single file when it is a gate, an escalator, has lane: 1, has a fixed speed, or is at most 1.2 m wide.

Escalators are walkable only on the entry floor (z_from when dir is along, z_to when against). Stairs are walkable from either end, and only on the two floors at their end heights, so flights stacked in one well on a taller building do not block each other. A two-way stair is taken when its far end is nearer the destination floor; a one-way stair or escalator only when it serves that ascent. Gates serve a same-floor crossing: one-way along the rise (or against it), or both ways when dir is both.

A zone may face any angle. Its shape is read as the rectangle that bounds the polygon along rise_along: the foot edge is where travel starts, the top edge where it ends, and the two sides run with travel. Every end, mouth, lane and progress test is made in that rectangle, so a stair drawn at 30 degrees behaves like the same stair drawn along x.

Long sides of a zone are walls, so a flight keeps people on the tread. The open ends are the mouths.

Teleport

A landing of a vertical pair. A stair or escalator has exactly two landings. An elevator may have a landing on every floor it serves, each on a different floor. delay_s is how long the walker is frozen (for an elevator, the ride of one storey); the pair uses the largest delay. An elevator pair also has capacity (people per car) and hold_s (how long the doors wait after the last person boards), again the larger of the landings. Each elevator landing may name a door, the doorway segment on its edge; walkers then board and step out only through it. Pair each landing with a floor hole of the same outline so the shaft is solid on every floor.

Geometry is a polygon (area trigger) or a line (the trigger segment). For a walked stair or escalator, a leftover pad uses the hallway’s exit edge as the trigger. A walked stair's line on each floor sits at the end away from that floor: the lower floor's at the top, the upper floor's at the foot. Elevator pairs have no zone; the walker must enter the landing polygon. Elevator doors may sit at a shaft edge, so a landing slightly inside a floor hole is still reachable (about 1 m).

Attractor

A polygon on one floor that may capture a walker. See behaviours.md.

FieldDefaultMeaning
kindomittedseat for a chair or one place on a bench; omitted for a standing stop
capture_limit (or capacity)1Simultaneous holds. Always 1 for a seat
dwell_s6Stand time, or sitting time for a seat
p_affect0.35Chance to accept, once per entry (once per approach for a seat)
unstick_sscenario unstick_sParsed and stored. The stuck-timer reads the scenario value, not this field

Track

A platform edge with a train timetable. Geometry is a two-point line along the edge; the train runs from the first point to the second, on the side away from the platform. The platform is the side given by platform_side, or else the side with more open floor (floor not covered by an obstacle or a store) just beyond each door, at 0.6, 1.5 and 3 m in; a tie goes to the left. So a floor drawn under the track still works when the track bed is an obstacle, and platform_side settles any case the floor cannot. Doors are placed by the train, so they move with cars, car_length and stop_at instead of being drawn. Each door is a walkable inset DOOR_DEPTH (0.8 m) into the train: the floor plate grows a U-bay at the doorway, and the three far sides are walls.

FieldDefaultMeaning
floorrequiredPlatform floor
headway_s300One train every this many seconds
dwell_s60Doors open; shortened if the cycle would not fit the headway
offset_s0Time of the first run-in, to stagger tracks
approach_s, depart_s18Braking in and pulling out
cars, car_length4, 23 mTrain
car_width3.2 mDrawn only; the sim ignores it
doors_per_car, door_width4, 1.45 mDoors, evenly spaced along each car
stop_atmiddle of the lineWhere the train's middle stands, metres along the line
alight60People getting off each train
alight_rate_per_min100Flow off each open door, over all its lanes
board_after_s6Wait after the doors open before boarders go in
platform_sidefrom the floorleft or right of the line's direction: the side the platform is on

Each door becomes a portal ({track}_d0, _d1, … in car order) that boarders target and alighters spawn from. See behaviours.md.

Seed agents

Optional agents array: already-placed walkers with id, x, y, optional z or floor, a target portal, and route (stair or elevator, default stair). Portals do the bulk of the population; seed agents are the sample already on the floor when the run loads.