# shared
One-paragraph description of what this module provides and who consumes
it.
## Exports
- `M.exampleFn(arg) -> result` — what it does and when to call it.
- `M.exampleValue: type` — what value it carries.
## Usage
Replace `<identity>` with the string `asset.create` returned — this
module's source path with `/` written as `.` and each segment's type
suffix dropped, the way a module at `/source/lib/thing.module` is
`lib.thing` and one at `/source/kit.package/thing.module` is
`kit.thing`.
```luau
local M = require("<identity>")
M.exampleFn("foo")
```
## Notes
- Anything callers need to know about THIS module: required runtime
ordering, state ownership, side effects.
# shared
Cross-tool helpers for the firstLightMaps toolbox. Every tool inside the
toolbox can pull these in with `require(".shared")`. Holds the small
set of helpers that more than one tool needs — typically the
`ok(value, formatted?)` / `fail(message, exitCode?)` constructors that
produce the canonical `firstLightMapsToolResult` shape, plus any toolbox-wide
parsers, validators, or shared state. Per-tool implementation stays
inside each `<x>.tool/init.luau`; this module is not a place to
forward logic from.
## Exports
- `M.ok(value: any?, formatted: string?) -> firstLightMapsToolResult` — success envelope (`exitCode = 0`, `ok = true`).
- `M.fail(message: string, exitCode: number?) -> firstLightMapsToolResult` — failure envelope (`exitCode` defaults to 1, `ok = false`).
Types:
- `firstLightMapsToolResult = { stdout: string, stderr: string, exitCode: number, ok: boolean, value: any? }`
- `stdout` — human-readable formatted output; empty when the op produces no text.
- `stderr` — error message on failure; empty on success.
- `exitCode` — POSIX-style exit code: `0` success, `1` generic failure, `2` bad arguments.
- `ok` — `true` iff `exitCode == 0`.
- `value` — structured return from the underlying op; `nil` for void ops.
## Usage
```luau
local shared = require(".shared")
function M.someTool(args)
if not args.id then
return shared.fail("missing id", 2)
end
return shared.ok({ id = args.id }, "created " .. args.id)
end
```
## Notes
- Pure constructors — no engine calls, no state. Safe to call from any
context.
- Tools that opt into this shape get a stable envelope every other tool
in the toolbox can rely on. Tools that do something custom can return
whatever shape they want — `firstLightMapsToolResult` is opt-in.
- Per-tool implementations still own their own `--!desc` / `--!arg` /
`--!return` / `--!example` annotations even when their result is
constructed through these helpers.
Authoritative five-circuit catalogue: ids, names, descriptions, control polygons, biome and half-width. Consumed by rainline.shared, the circuit builder, selection menu and firstLightMaps tools.
# FIRST LIGHT map authoring
The circuit catalogue lives at rainline/maps/catalog.module/init.luau. It defines five independent closed layouts, names, descriptions, biome and road half-width. rainline.shared builds their smooth paths, and rainline.visuals.circuit produces the road, barriers, details and lighting.
Use in edit mode:
1. tools.use("firstLightMaps","inspect",4) — inspect length, bounds and source points.
2. tools.use("firstLightMaps","setLayout",4,points) — save an ordered array of {x,z} points. Use 6–80 points at least24m apart. Coordinates exclude the circuit's world offset. Crossing control polygons are rejected.
3. tools.use("firstLightMaps","rebuild",4) — switch to that circuit as the root editing scene, rebuild and save it.
4. tools.use("scene","load","scenes.rainline") — return to the multiplayer game.
Always inspect the smoothed result from above and road height. Polygon validation does not prove spline/road clearance. Rebuild after changing catalogue parameters or circuit set dressing. Preserve literal references when extending StageLoader with a new stage. The menu paginates the catalogue automatically. Stage content stays unloaded until selected.
Black Quarry uses biome3 rock cuts without the forest canopy; Saltspan uses biome1 with an open-water viaduct instead of an infield. Their structural detail is authored in circuit.sceneModule, alongside the reusable apron props, tar seams, drainage and road fixtures.