bridge-sandbox-utils.ts
Sandbox utility module exposing shape-vertex generators for blocker terrain pieces in the bridge sandbox. Returns unit-space polygon vertex arrays scaled by a caller-supplied factor; consumers feed these directly into collision and rendering pipelines.
Surface
| Export | Signature | Purpose |
|---|---|---|
makeBlockerVerts | (shapeId: string, scale: number) => Array<{ x: number; y: number }> | Produce polygon vertices for a named blocker shape, scaled by scale. |
Shape catalog
shapeId switches over a fixed set of strings. s = scale is the unit radius/half-extent.
shapeId | Vert count | Geometry |
|---|---|---|
blocker_rect | 4 | Rectangle 2s × 1.2s (half-extents ±s, ±0.6s). |
blocker_square | 4 | Square 2s × 2s (half-extents ±s, ±s). |
blocker_triangle | 3 | Equilateral-ish triangle, apex at (0, -s), base at ±0.87s, +0.5s. |
blocker_circle | 16 | 16-sided regular polygon inscribed in radius s, angles (i/16) * 2π. |
blocker_L | 6 | L-shape, width 0.5s, height s. Vertices traced top-left → top-right → mid-right → far-right → bottom-right → bottom-left. |
blocker_wall | 4 | Thin horizontal wall 4s × 0.3s (half-extents ±2s, ±0.15s). |
| (default) | 4 | Fallback unit square 2s × 2s, identical to blocker_square. |
Implementation notes
- Vertices are returned as plain
{ x, y }object literals (no shared Vec2 type). - All shapes are centered on the origin; the caller is responsible for translation/rotation to a world transform.
- Circle approximation uses
Math.cos/Math.sinwith no caching — recomputed every call. - L-shape vertex
{ x: h, y: 0 }usesh = swhile the rest of the width usesw = 0.5s; this is intentional (the inner corner sits atx = s, notx = 0.5s). - Triangle’s
0.87is a hand-picked approximation ofcos(30°) ≈ 0.866, not derived from a constant. - Unknown
shapeIdsilently falls back to a unit square — no warning, no throw.
Callers
Used by the bridge-sandbox spawn path to build blocker terrain polygons; pair with the broader sandbox/level systems that consume vertex arrays for collision and draw.
EXTRACT-CANDIDATE
- Magic constants.
0.6,0.87,0.5,0.15, the 16 circle segments — all inline literals. Should move to a named-constant table (e.g.,BLOCKER_SHAPE_CONSTANTS) per the “every number traces to a named constant” rule. - Shape ID strings. Seven
'blocker_*'literals scattered acrosscaselabels invite typos at the call site. Extract to aBlockerShapeIdunion orconst BLOCKER_SHAPES = { rect: 'blocker_rect', ... }map. - Vec2 type duplication.
{ x: number; y: number }is re-declared in the return type rather than reusing an engine-wideVec2. Consolidate with the canonical vector type if one exists. - Silent fallback. Default branch returns a unit square for any unknown shape. Project convention is “crash on bad data, no silent fallbacks” — should
throwon unknownshapeId. - Circle precompute. 16-segment circle is rebuilt every call. If hot, cache the unit-radius vertex array once and multiply by
sat call time. - L-shape definition. Mixing
h = sandw = 0.5sinside the same vertex list is hard to read; extracting to a table of unit-space tuples scaled at the end would clarify intent.