Files
2026-05-27 23:29:53 +01:00

4.1 KiB

ADDED Requirements

Requirement: Sky colour via Rayleigh/Mie scattering

The system SHALL compute sky colour from sun altitude, AtmosphereConfig.rayleighCoefficient, and mieCoefficient.

Scenario: Earth noon sky

  • WHEN the sun is at zenith on an Earth-like planet
  • THEN the computed skyColour is deep blue (high B, moderate G, low R)

Scenario: Earth sunset sky

  • WHEN the sun is near the horizon on an Earth-like planet
  • THEN the computed skyColour is orange/red (high R, moderate G, low B)

Scenario: Mars noon sky

  • WHEN the sun is at zenith on a Mars-like planet with CO₂ atmosphere
  • THEN the computed skyColour is butterscotch (high R, moderate G, low B)

Scenario: Vacuum world

  • WHEN the observer's planet has no AtmosphereConfig
  • THEN skyColour is black always

Requirement: Twilight star visibility thresholds

The system SHALL apply magnitude limits based on sun altitude and twilight phase.

Scenario: Civil twilight limit

  • WHEN sun altitude is between 0 and -6 degrees
  • THEN only stars with apparentMagnitude <= 1 are visible

Scenario: Astronomical twilight limit

  • WHEN sun altitude is between -12 and -18 degrees
  • THEN stars with apparentMagnitude <= 6 are visible

Scenario: Full dark

  • WHEN sun altitude is below -18 degrees
  • THEN all naked-eye stars are visible

Scenario: Vacuum collapse

  • WHEN the planet has no atmosphere
  • THEN all stars are visible regardless of sun altitude

Requirement: Multi-satellite moonlight

The system SHALL compute per-satellite moonlight proportional to phase illumination, angular diameter squared, and albedo, summing across all satellites.

Scenario: Single moon night

  • WHEN a planet with one satellite has a full-moon phase
  • THEN moonContributions contains one entry with significant light value

Scenario: Multiple moons

  • WHEN a planet with two satellites both above the horizon is evaluated
  • THEN totalAmbientLight includes the sum of both contributions

Requirement: Gameplay modifiers

The system SHALL export EnvironmentModifiers with totalAmbientLight, stealthBonus, visibilityRangeMetres, and npcSleepProbability as continuous functions of ambient light.

Scenario: Stealth at midnight

  • WHEN totalAmbientLight is near 0
  • THEN stealthBonus is near 1

Scenario: Visibility at noon

  • WHEN totalAmbientLight is near 1
  • THEN visibilityRangeMetres is at its maximum

Requirement: Plain ECS component interfaces

The system SHALL export DayNightClock, LightState, and DayNightAffected as plain TypeScript interfaces with no @suaveplan/ecs dependency.

Scenario: Interface shapes

  • WHEN the exports are inspected
  • THEN they are interface declarations, not class constructors or archetype registrations

Requirement: RenderPayload shape

The system SHALL export RenderPayload as the canonical per-tick output for downstream render integrations.

Scenario: Payload completeness

  • WHEN a render payload is generated at a tick
  • THEN it contains skyColour, sunAltitude, sunAzimuth, horizonColour, totalAmbientLight, moonContributions, fogDensity, rayleighTint, textures, and optional weather

Requirement: Texture manifest pass-through

The system SHALL pass PlanetTextureManifest identifiers through verbatim without loading or storing assets.

Scenario: Texture identifiers

  • WHEN a PlanetConfig with textures: { diffuse: "earth-diffuse", night: "earth-night" } is used
  • THEN the RenderPayload.textures contains the same identifiers
  • AND no file loading occurs

Requirement: Weather state pass-through

The system SHALL include WeatherState in RenderPayload and LightState when a WeatherProvider is registered, without breaking when absent.

Scenario: No weather provider

  • WHEN no WeatherProvider is registered in the underlying UniverseClient
  • THEN RenderPayload.weather is undefined
  • AND lighting computation continues without weather modulation