The pack
sectorView
function sectorView(): Pack<{ sectorView: SectorViewApi }>
The sector-view pack: composing it checks the packs the view draws with are there, and puts create under
game.sectorView. No options.
Helpers
createSectorView
function createSectorView(game: SectorViewGame, options: SectorViewOptions = {}): SectorView
Draw sector maps into a composed game. Needs world-3d, render-3d and lighting-3d; uses particles-3d (torch flames, blasts, trails), post with post-bloom, post-grade, post-grain and post-looks (the lit look's chain) and ssao-3d when they are composed. Throws on options out of range.
Constants
PICTOGRAMS
const PICTOGRAMS: ReadonlySet<string>
The picture names a sign, poster or screen can show.
SECTOR_SKIES
const SECTOR_SKIES: Readonly<Record<string, SectorSky>>
The skies a map can name; anything else is night.
splitName
const splitName = (name: string): [string | null, string]=> …
A theme-qualified name's parts: industrial:ceiling → ['industrial', 'ceiling'].
Types
BillboardLight
type BillboardLight = 'sprite' | 'pickup' | 'glow' | 'none'
How a billboard takes light: sprite (a little glow keeps it readable), pickup (more), glow (burning, blooms), none (unlit).
SectorBillboards
interface SectorBillboards
A pool of billboards keyed by what each shows; anything not asked for between begin and end is hidden.
begin(): void— Start a frame's asking.get(id: string): [ViewMesh, boolean]— The billboard forid, and whether it was just made (snap it after placing it).end(): void— End the frame: billboards not asked for are hidden and kept for reuse.clear(): void— Hide them all.
SectorDecal
type SectorDecal = 'bullet' | 'scorch' | 'blood'
A mark decal leaves: a bullet hole, a scorch mark or blood.
SectorGrade
type SectorGrade = 'warm' | 'cool' | 'neutral' | Record<string, unknown>
A colour grade for the lit look: a name or post-grade's own params.
SectorLook
type SectorLook = 'lit' | 'flat'
How the view draws: lit (lamps, normal maps, post) or flat (sector light painted on, unlit).
SectorRide
interface SectorRide
A light riding on something that moves: a projectile, a glowing pickup.
color: string— Colour, CSS.intensity: number— Brightness, beforeflashes.radius: number— Reach.flicker?: number— Flicker 0..1. Default 0.trail?: { effect: string; scale?: number }— A looping particle effect to trail behind it ('fireball'), with its scale. Default none.
SectorSky
interface SectorSky
A sky as a map names it (sky in its data): sky-3d's clock and clouds, and the sun or moon it puts over the yards.
hour: number— sky-3d's hour, 0..24.clouds: number— Cloud cover 0..1.density: number— Cloud opacity 0..1.storm: number— The storm dial 0..1.haze: number— Horizon haze 0..1.stars: number— Stars and moon 0..1.sun: number— The sun's (or moon's) strength on the map.sunColor: string— Its colour, CSS.dir: [number, number, number]— The way its light travels: x, y (down is negative) and z.ambient: number— Ambient light under it.fog?: string— Fog colour; default the view's.
SectorView
interface SectorView
The view.
look: SectorLook— How it draws; setting it rebuilds what changes.brightness: number— Exposure in the lit look.lamps: number— Lamp intensity multiplier; setting it re-lights the map.bloom: boolean— Bloom on or off.weather: SectorWeather— Weather under the open sky; it falls only while the camera is in or beside a sector open to the sky.fullbright: boolean— Everything at full light, as light-amplification goggles show it. Default false.ambient: number | null— The lit look's ambient light, or null for the map's default (0.18 indoors, 0.2 with sky).readonly map: SectorMap | null— The map shown, or null.readonly set: string— The surface set in use.surfaceNames(maps: ReadonlyArray<SectorMapData>): string[]— Every surface name a list of maps draws with, eachtheme:namewhen its map names a theme.prepare(maps: ReadonlyArray<SectorMapData>): Promise<void>— Make the surfaces these maps need ahead of showing them (the game's own art may need loading).useSurfaces(source: SurfaceSource | null, set: string): Promise<void>— Switch surface source;nullis retro-textures alone. Redraws the map shown.show(map: SectorMap, data?: SectorMapData | null): void— Draw a map: its meshes, lamps and fittings, the look for it.datais the map data it was made from, whosemeta.themenames its surfaces' theme. Surfaces not prepared are made from retro-textures there and then.frame(dt: number): void— Run the view on bydtseconds: moved sectors, light levels, lamps switched, flashes, flowing and scrolling surfaces.flash(x: number, y: number, z: number, color: string, intensity: number, radius: number, life: number, rise?: boolean): void— A short light: grows tointensity(rise) or fades from it overlifeseconds. Lit look only.effect(name: string, x: number, y: number, z: number, opts?: { scale?: number; yaw?: number; pitch?: number; life?: number }): ViewEffect | null— A particle effect (particles-3d), lit look only;yawandpitchin degrees. A looping effect (sparks, a short circuit) runs until stopped: givelife(seconds) and the view stops it then and removes it once its particles are gone, or keep the handle it returns and stop it yourself. Null when it is not composed or the look is flat.rides: { begin(): void; ride(id: string, x: number, y: number, z: number, light: SectorRide): void; end(): void }— Lights on moving things: callbegin, thenridefor each one this frame, thenendturns off the rest.torch(on: boolean, intensity?: number, opts?: { cone?: number; inner?: number; range?: number; color?: string }): void— A torch on the camera: a spot that follows the view,intensityits brightness now (a game's flicker goes in it).coneis its half-angle in radians (default 0.42; π or more lights all round, a lantern),innerthe half-angle of its full-brightness core (default 0.16; nearerconeis a harder edge),rangeits reach (default 30) andcolorits colour (default warm white).mood(m: { vignette?: number; distort?: number; saturation?: number; grain?: number }): void— The lit look's mood, live:vignette0..1 (the edges darkening),distort0..1 (a chromatic split and a wave, for a scare),saturation(1 as is, 0 grey) andgrain. Fields left out stay as they are.decal(x: number, y: number, z: number, kind?: SectorDecal, size?: number): void— A mark left on the world: a bullet hole, a scorch, a splash of blood. It lies flat on the nearest wall (facing the camera) or on the floor, and stays until 96 newer marks have pushed it out.sizein world units.lightAt(x: number, y: number, z: number): [number, number, number]— Roughly how much light reaches a point, as 0..1-ish rgb: what a HUD sprite (the gun in hand) is tinted by.tintAt(x: number, z: number): string— The tint for a billboard standing at a point: the sector's light.billboards(texture: string, opts?: { light?: BillboardLight; face?: 'y' | 'full' }): SectorBillboards— A billboard pool wearingtexture. Rebuilt by the view when the look changes.dispose(): void— Take everything off the world.
SectorViewApi
interface SectorViewApi
game.sectorView: create is createSectorView, taking the game as its first argument.
create(game: SectorViewGame, options?: SectorViewOptions): SectorView— Draw sector maps into the game; seecreateSectorView.
SectorViewGame
interface SectorViewGame
The game the view draws into: what world-3d, render-3d, lighting-3d and the optional packs give it.
world3d: { /** Spawn a mesh. */ spawn(spec: ViewSpawn): ViewMesh; /** Define (or redefine) a mesh from vertices; returns its id. */ defineMesh(name: string, verts: Float32Array): number; /** Register a material; returns its id. */ material(def: { name: string; normalFrame?: number; bump?: number; rough?: number; metallic?: number; emissive?: number; srgbColor?: boolean; unlit?: boolean; shadow?: boolean }): number; /** A material's live definition. */ materialAt(id: number): object | undefined; /** The camera. */ readonly camera: { x: number; y: number; z: number; yaw: number; pitch: number }; }— world-3d.render3d: { /** The lighting record. */ readonly lighting: ViewLighting; /** Put a surface effect on a mesh, or take it off. */ surface(handle: ViewMesh, opts: { effect: SurfaceEffect } | null): void; }— render-3d.lights: { /** Add a light. */ add(spec: { x?: number; y?: number; z?: number; color?: string; intensity?: number; radius?: number; flicker?: number; flickerSpeed?: number; cone?: number; innerCone?: number; dir?: number; pitch?: number }): ViewLight; /** Most lights sent to the renderer. */ max: number; }— lighting-3d.assets: { /** Add strips that must share a page. */ addStrips(items: ReadonlyArray<{ key: string; src: CanvasImageSource | null; w: number; h: number; count?: number }>): number[]; /** Paint a picture with frames, at \res` pixels a unit; the same key and size again repaints it in place. / paint(key: string, w: number, h: number, draw: (ctx: CanvasRenderingContext2D, frame: number) => void, opts?: { frames?: number; res?: number }): number; /* A key's first frame, by global index. */ frames(key: string): number; }` — The atlas.particles3d?: { /** Play a registered effect. */ effect(name: string, opts: { x: number; y: number; z: number; scale?: number; yaw?: number; pitch?: number }): ViewEffect; /** Every registered effect's name. */ readonly available: ReadonlyArray<string>; }— particles-3d, when composed.post?: { /** Add an effect to the chain. */ add(name: string, params?: Record<string, unknown>): ViewPost; }— post, when composed.sky?: { hour: number; clouds: number; cloudDensity: number; storm: number; haze: number; stars: number }— sky-3d, when composed: the view sets its clock and clouds to the map's sky.ssao?: { enabled: boolean; radius: number; strength: number }— ssao-3d, when composed.
SectorViewOptions
interface SectorViewOptions
What createSectorView takes. Every field is also live on the view.
look?: SectorLook—'lit'(default) or'flat'.brightness?: number— Exposure in the lit look; retro-textures art is dark, as the originals were. Default 2.lamps?: number— A multiplier on every map lamp's intensity. Default 2.5.bloom?: boolean— Bloom in the lit look (needs post-bloom). Default true.grade?: SectorGrade— The grade in the lit look (needs post-grade). Default'warm'.fog?: string— Fog colour. Default'#060408'.fogRange?: [number, number] | null— Where the lit look's fog starts and where it is thickest, world units. Default[6, 44]indoors,[8, 52]with sky.ambient?: number | null— The lit look's ambient light, the floor every surface keeps. Default 0.18 indoors, the sky's with sky.sky?: string | null— A sky by name for every map (SECTOR_SKIES), or null to take each map's ownsky(night when it names none).flashes?: number— Strength of short lights (flashes, blasts, projectiles) against their authored values. Default 0.6.surfaces?: SurfaceSource | null— The game's own surface art, asked before retro-textures; null for retro-textures only. Default null.set?: string— A name forsurfaces' set, so switching between sets reuses what was made. Default'retro', or'custom'withsurfaces.themes?: string[]— Themes to look surface names up in after a map's ownmeta.theme. Default none.scale?: number— Texels per world unit across walls and floors (buildMeshes'wallScaleandflatScale). Default 2.maxLights?: number— Most lights sent to the renderer (lighting-3d'smax). Default 96.ambience?: boolean— Dress the map from what it is: gas over slime, a glow on teleporters, sparks from failing lamps. Default true.ripple?: boolean— Liquid floors shimmer with render-3d'srippleunless the map gives them an effect. Its light ignores the dark, so a very dark level may want it off. Default true.weather?: SectorWeather— Weather under the open sky:'none','rain','storm'(rain and lightning) or'snow'. Default'none'.onLightning?: (delay: number) => void— Called at each lightning strike, with how far away the thunder is in seconds: play it.
SectorWeather
type SectorWeather = 'none' | 'rain' | 'storm' | 'snow'
Weather under the open sky.
SurfaceEffect
interface SurfaceEffect
One of render-3d's surface effects, as a map asks for it on a floor, a ceiling or a wall.
kind: 'holo' | 'glow' | 'dissolve' | 'fire' | 'shine' | 'gild' | 'ripple' | 'frost'—ripple(a liquid),shine(a bar of light sweeping),holo(foil),glow(pulsing),frost,fire,dissolveorgild.amount?: number— How strong, 0..1.speed?: number— How fast.color?: string— Its colour, CSS.param?: number— The effect's own dial.
SurfacePixels
interface SurfacePixels
Pixels for a surface, from any source: one frame, or a strip of frames side by side.
width: number— One frame's width in pixels.height: number— One frame's height in pixels.rgba: Uint8ClampedArray— RGBA bytes, row by row,width * frameswide.heights?: Float32Array— Height per pixel 0..1 for the normal map; from brightness when absent.frames?: number— Frames side by side; default 1.kind?: string— What the surface is made of, for its material: a retro-textures kind, or a word ('metal','stone','liquid'…).
SurfaceSource
type SurfaceSource = (name: string) => SurfacePixels | null | Promise<SurfacePixels | null>
A game's own surface art: pixels for a name (theme:name when the map names a theme), or null to use retro-textures.
ViewEffect
interface ViewEffect
A running particle effect (particles-3d).
start(): void— Start emitting again.stop(): void— Stop emitting; living particles finish.kill(): void— Remove it now.moveTo(x: number, y: number, z: number): void— Move it.
ViewLight
interface ViewLight
A point or spot light (lighting-3d).
x: number— Position.y: number— Height.z: number— Position.light3d: { color: string; intensity: number; radius: number; on: number; flicker: number; dir: number; pitch: number; cone: number; innerCone: number }— The light's live fields: colour, brightness, reach, on (1 or 0), flicker, a spot's direction, tilt and cone (radians).snap(): void— Jump to where it is now.kill(): void— Take it off the world.
ViewMesh
interface ViewMesh
A 3D object the view spawns: a map mesh, a lamp's fitting, a billboard, a decal.
x: number— Position, world units.y: number— Height, world units.z: number— Position, world units.sx: number— Width (a billboard's).sy: number— Height (a billboard's).yaw: number— Turn, radians.pitch: number— Tilt about its own x, radians (after the yaw).sz: number— Depth (a box's).visible: boolean— Drawn or not.tint: string— Colour it is multiplied by, CSS.alpha: number— Opacity 0..1.frame: number— The atlas frame it shows, by global index.snap(): void— Jump to where it is now, without sliding from where it was.kill(): void— Take it off the world.


