world

package
v0.0.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 6, 2026 License: MIT Imports: 9 Imported by: 0

README

Compiled world contract

Compiled worlds use the world/sectors@1 cartridge capability and the @world/main level entry. format/world accepts only its canonical encoding and validates all sectors, planes, reciprocal portals, identities, provenance, and content placement before a host prepares runtime indexes. Format version 2 adds optional typed actor transforms, sprite modes, alpha policy and bounded exact tags while readers retain version 1 compatibility.

See authoring semantics for compiler inputs.

Authored lighting, version 1

The world/lighting@1 contract adds optional authored lighting to compiled world version 3 and authoring source version 4. The cartridge declares both world/sectors@1 and world/lighting@1. Compiled versions 1–2 and source versions 1–3 reject lighting. An absent lighting field preserves every supported version's existing wire encoding and legacy rendering; source v4 also accepts absence. This independently versioned capability does not change the level envelope or cartridge manifest version.

The payload is {"version":1,"ambient":{"x":0.1,"y":0.1,"z":0.1},"lights":[]}. Each point light has id, position, color and radius fields. Ambient and point colors are finite linear RGB intensities in [0,1], represented by x, y, z; they are not sRGB color bytes. Positions are finite global world coordinates, bounded inclusively to ±1,000,000 per component, and need not fall inside a sector. There are 0–50 lights in authored order, with unique nonempty UTF-8 IDs of at most 128 bytes. An empty list permits ambient-only lighting. Lighting belongs to the root document, never a room, prefab or instance, and receives no prefab transform or sector assignment. The contract supplies no shadows, portal transport, guest lighting controls or PBR parameters.

The version-1 decision bounds radius inclusively to [0.001, 1,000,000] world units (world.MinLightRadius and world.MaxCoordinate). The lower bound keeps the host's float32 distance/attenuation calculation representable; arbitrary positive float64 radii are not valid. Both source and compiled validators enforce the same complete lighting bounds, identities and finite values. Compiled world decoding additionally requires its canonical JSON spelling and rejects unknown, duplicate or missing fields and explicit "lighting":null. A nil lights slice encodes as "lights":null and has the same ambient-only semantics as an empty array. Source JSON/YAML presence and unknown-field checks belong to the public compiler: worldsource.Validate validates typed values and does not parse author text. Future semantic changes require a new lighting capability/version.

The SDK 0.0.8 authored-lighting path uses squared Half-Lambert diffuse and bounded point-light falloff. When a material atlas is present, tangent normals affect diffuse shading, and AO scales ambient light only, once in linear RGB. Direct light remains unoccluded. Lit albedo diagnostics retain unoccluded albedo; normal and depth diagnostics keep their meanings. Material height never replaces geometric camera depth or changes silhouettes.

Material height represents positive raised relief; zero preserves the original UVs. The authored path uses two fixed-point parallax shifts with bilinear height samples, bounded to 0.025 of a texture repeat per UV component and faded at grazing angles. Albedo, normal, height and AO share the shifted UVs. A restrained stylized rim has coefficient 0.08, height/AO masks, a fourth-power view Fresnel term and actual front-facing direct-light contributions; it supplies no ambient glow or PBR/specular parameters. Legacy worlds without authored lighting retain AO-baked unlit output and ignore height. These rendering semantics introduce no new payload fields, material-atlas schema or SDK manifest version.

Ambient cube and actor lighting

The SDK 0.0.8 world/lighting@1 contract accepts optional ambient_cube with six finite linear RGB [0,1] fields: positive_x, negative_x, positive_y, negative_y, positive_z, negative_z. When present it replaces ambient: select axis colors by the unit world normal's signs and weight them by squared normal components, then apply material AO once. Identical six colors match uniform ambient. This world-global artistic cube provides no spatial probes or portal light transport. Optional actors: true lights world sprites in full camera output using geometry normals; omitted/false keeps sprites unlit. Neither optional field changes older payload encodings when absent.

Point-light motion, version 1

The SDK 0.0.8 lighting contract accepts point-light motion: {version: 1, offset: {x: 12, y: 0, z: 0.8}, period_seconds: 12}. The offset and both segment endpoints obey the ordinary finite coordinate bounds; period is finite in [0.1, 3600] seconds. Runtime position follows position + offset*(1-cos(2*pi*(t mod period)/period))/2. All cameras share a mounted-level simulation clock, reset on replacement/remount. Full surfaces and opted-in actors receive this unshadowed direct light; diagnostic views stay unchanged. A moving light cannot be selected in a static lightmap bake. Omission preserves the existing static encoding. The motion record is version 1; the guest wire contract is unchanged.

Material mapping, version 1

Compiled world v3 retains an optional material_mapping: {version: 1} marker. When present, every sector floor_uv, ceiling_uv and wall uv is required, including internal decomposition and portal edges. A mapping without the marker is invalid. Compiled v1–2 reject both the marker and surface mappings. The game cartridge declares world/material-mapping@1 alongside world/sectors@1; older hosts reject unsupported capabilities before readiness. No new guest command or level envelope version is involved.

Each SurfaceUV has projections of length one or three and equally many weights. A projection contains u and v, each an affine plane with x, y, z, offset; the host evaluates x*X+y*Y+z*Z+offset at authored geometry positions before clipping. Every coefficient and offset is finite and bounded to ±1,000,000,000,000. Weights are finite in [0,1] and sum to one within 1e-9. Three projections blend using constant surface weights derived by the compiler from geometric normals; all material channels use the same projections and weights. The runtime does not infer projection setup or authoring modes. Compiled decoding requires canonical JSON and rejects partial, null, unknown, duplicate and malformed records before publishing a world. This capability is available in SDK 0.0.8; absent mappings preserve older encodings.

Static solids, version 1

Compiled world v3 optionally carries static_solids: {version: 1, items: [...]} with the world/static-solids@1 capability, available in SDK 0.0.8. Solids are independent of room sectors and portal connectivity. Omission preserves existing encoded bytes.

Each compiled Solid contains id, a strictly convex CCW footprint (3–64 vertices), bottom/top elevation planes, nonzero side_material, top_material and bottom_material IDs, optional side_uv/top_uv/bottom_uv, and omitted-false collision. There are at most 1,024 solids; IDs are unique UTF-8 of 1–128 bytes. Coordinates, plane coefficients and evaluated elevations obey ±1,000,000 bounds; edges and thickness are at least 1e-6. Overlapping solids do not relax any room or portal validation. Collision is a blocking volume, not a walkable top. Complete validation and canonical JSON rules apply before mounting.

Mapped solids require the material-mapping marker and capability. There are no new guest commands or level-envelope versions. Incompatible contract changes require a versioned decision.

Documentation

Overview

Package world defines the bounded compiled sector format shared by level compilers and Karty hosts. It contains data contracts and validation only.

Index

Constants

View Source
const (
	MaterialMappingVersion = uint32(1)
	FeatureMaterialMapping = cartridge.FeatureWorldMaterialMappingV1
	MaxUVProjectionValue   = 1e12
	UVWeightTolerance      = 1e-9
)
View Source
const (
	StaticSolidsVersion = uint32(1)
	FeatureStaticSolids = cartridge.FeatureWorldStaticSolidsV1
	MaxStaticSolids     = 1024
	MaxSolidVertices    = 64
)
View Source
const (
	LegacyVersion      = uint16(1)
	ActorVersion       = uint16(2)
	Version            = uint16(3)
	LightingVersion    = uint32(1)
	EntryName          = "@world/main"
	Feature            = cartridge.FeatureWorldSectorsV1
	FeatureLighting    = cartridge.FeatureWorldLightingV1
	MaxEncodedSize     = 8 * 1024 * 1024
	MaxSectors         = 256
	MaxWalls           = 8192
	MaxWallsPerSector  = 256
	MaxContents        = 4096
	MaxLights          = 50
	MinLightRadius     = 0.001
	MaxIdentifierBytes = 128
	MaxKindBytes       = 128
	MaxTags            = 8
	MaxTagBytes        = 64
	MaxCoordinate      = 1_000_000.0
	MinEdgeLength      = 1e-6
	MinClearance       = 1e-6
)

Variables

View Source
var (
	ErrSize            = errors.New("world payload size is invalid")
	ErrSyntax          = errors.New("world payload syntax is invalid")
	ErrVersion         = errors.New("world payload version is unsupported")
	ErrBounds          = errors.New("world payload exceeds a declared bound")
	ErrIdentity        = errors.New("world identity is invalid")
	ErrGeometry        = errors.New("world geometry is invalid")
	ErrPortal          = errors.New("world portal is invalid")
	ErrContent         = errors.New("world content is invalid")
	ErrMaterialMapping = errors.New("world material mapping is invalid")
	ErrLighting        = errors.New("world lighting is invalid")
	ErrStaticSolids    = errors.New("world static solids are invalid")
	ErrCanonical       = errors.New("world payload is not canonical")
)

Functions

func Encode

func Encode(document Document) ([]byte, error)

Encode validates and deterministically encodes one compiled world.

func Validate

func Validate(document *Document) error

Validate checks a complete compiled document before a host prepares private indexes or publishes a mounted resource.

func ValidateLighting added in v0.0.8

func ValidateLighting(lighting *Lighting) error

ValidateLighting checks the complete lighting payload without requiring sector geometry. Optional absence is represented by Document.Lighting == nil; passing nil here is invalid. Capability/world consistency is the consumer's responsibility because the payload does not contain a cartridge manifest.

func ValidateStaticSolids added in v0.0.8

func ValidateStaticSolids(solids *StaticSolids) (err error)

ValidateStaticSolids validates every item, including the last, before mounting. Solids may overlap each other and sectors; sector validation is unchanged.

func ValidateSurfaceUV added in v0.0.8

func ValidateSurfaceUV(mapping *SurfaceUV) error

ValidateSurfaceUV validates complete bounded projection and weight lists.

Types

type Actor added in v0.0.6

type Actor struct {
	Yaw    float64  `json:"yaw"`
	Pitch  float64  `json:"pitch"`
	Roll   float64  `json:"roll"`
	Scale  Vec3     `json:"scale"`
	Sprite *Sprite  `json:"sprite,omitempty"`
	Tags   []string `json:"tags,omitempty"`
}

Actor is the optional typed ECS payload introduced by compiled-world v2. Position remains on Content so actor and non-rendered gameplay contents share the same stable identity and sector assignment.

type AmbientCube added in v0.0.8

type AmbientCube struct {
	PositiveX Vec3 `json:"positive_x"`
	NegativeX Vec3 `json:"negative_x"`
	PositiveY Vec3 `json:"positive_y"`
	NegativeY Vec3 `json:"negative_y"`
	PositiveZ Vec3 `json:"positive_z"`
	NegativeZ Vec3 `json:"negative_z"`
}

AmbientCube supplies six world-space directional ambient colors. It replaces Ambient when present; squared unit-normal components weight each selected face. Colors are finite linear RGB intensities in [0,1].

type Content

type Content struct {
	ID       string `json:"id"`
	SourceID string `json:"source_id"`
	Instance string `json:"instance"`
	Kind     string `json:"kind"`
	Sector   uint32 `json:"sector"`
	Position Vec3   `json:"position"`
	Actor    *Actor `json:"actor,omitempty"`
}

Content retains both its compiled identity and authored/prefab provenance. The component payload is deliberately deferred to its own versioned format.

type Document

type Document struct {
	Version  uint16    `json:"version"`
	Sectors  []Sector  `json:"sectors"`
	Contents []Content `json:"contents"`
	// Lighting is opt-in in compiled v3 and requires FeatureLighting in addition
	// to Feature. Nil preserves the legacy wire encoding and runtime behavior.
	Lighting        *Lighting        `json:"lighting,omitempty"`
	MaterialMapping *MaterialMapping `json:"material_mapping,omitempty"`
	StaticSolids    *StaticSolids    `json:"static_solids,omitempty"`
}

Document is one completely compiled world. Sector order is stable because portal references use sector indexes.

func Decode

func Decode(encoded []byte) (Document, error)

Decode requires the exact canonical representation produced by Encode. This rejects duplicate/unknown fields, alternate number spellings and trailing data.

type LightMotion added in v0.0.8

type LightMotion struct {
	Version       uint32  `json:"version"`
	Offset        Vec3    `json:"offset"`
	PeriodSeconds float64 `json:"period_seconds"`
}

LightMotion version 1 moves a light smoothly from Position to Position+Offset and back once per PeriodSeconds. It is runtime direct lighting, never baked. The complete segment must stay within the ordinary light coordinate bounds.

type Lighting added in v0.0.8

type Lighting struct {
	Version     uint32       `json:"version"`
	Ambient     Vec3         `json:"ambient"`
	Lights      []PointLight `json:"lights"`
	AmbientCube *AmbientCube `json:"ambient_cube,omitempty"`
	Actors      bool         `json:"actors,omitempty"`
}

Lighting is the independently versioned world/lighting@1 payload. Ambient and point colors are linear RGB intensities in [0,1]. Lights retain authored order and global world coordinates, without sector assignment, prefab transforms, shadows, portal transport or PBR parameters.

type MaterialMapping added in v0.0.8

type MaterialMapping struct {
	Version uint32 `json:"version"`
}

MaterialMapping opts a compiled v3 world into world/material-mapping@1. Every floor, ceiling and wall must then supply complete baked projections. Projection setup, authoring modes and anchors belong to the compiler.

type Plane

type Plane struct {
	A float64 `json:"a"`
	B float64 `json:"b"`
	C float64 `json:"c"`
}

Plane describes elevation z=A*x+B*y+C.

type PointLight added in v0.0.8

type PointLight struct {
	ID       string       `json:"id"`
	Position Vec3         `json:"position"`
	Color    Vec3         `json:"color"`
	Radius   float64      `json:"radius"`
	Motion   *LightMotion `json:"motion,omitempty"`
}

PointLight is one bounded global light. ID is unique within Lighting; Radius is an influence radius in world units in [MinLightRadius, MaxCoordinate].

type Sector

type Sector struct {
	ID              string     `json:"id"`
	SourceRoom      string     `json:"source_room"`
	Instance        string     `json:"instance"`
	Walls           []Wall     `json:"walls"`
	Floor           Plane      `json:"floor"`
	Ceiling         Plane      `json:"ceiling"`
	FloorMaterial   uint32     `json:"floor_material"`
	CeilingMaterial uint32     `json:"ceiling_material"`
	FloorUV         *SurfaceUV `json:"floor_uv,omitempty"`
	CeilingUV       *SurfaceUV `json:"ceiling_uv,omitempty"`
}

Sector is a strictly convex CCW cell. SourceRoom and Instance retain the authoring identity after prefab expansion and decomposition.

type Solid added in v0.0.8

type Solid struct {
	ID             string     `json:"id"`
	Footprint      []Vec2     `json:"footprint"`
	Bottom         Plane      `json:"bottom"`
	Top            Plane      `json:"top"`
	SideMaterial   uint32     `json:"side_material"`
	TopMaterial    uint32     `json:"top_material"`
	BottomMaterial uint32     `json:"bottom_material"`
	SideUV         *SurfaceUV `json:"side_uv,omitempty"`
	TopUV          *SurfaceUV `json:"top_uv,omitempty"`
	BottomUV       *SurfaceUV `json:"bottom_uv,omitempty"`
	Collision      bool       `json:"collision,omitempty"`
}

Solid is a strictly convex CCW extrusion between two elevation planes. Collision blocks movement but never makes Top a walkable floor. Optional mappings are shared by the indicated surface group; SideUV is not per-edge.

type Sprite added in v0.0.6

type Sprite struct {
	AssetID uint32       `json:"asset_id"`
	Facing  SpriteFacing `json:"facing"`
	Alpha   SpriteAlpha  `json:"alpha"`
	Width   float64      `json:"width"`
	Height  float64      `json:"height"`
	OriginX float64      `json:"origin_x"`
	OriginY float64      `json:"origin_y"`
}

type SpriteAlpha added in v0.0.6

type SpriteAlpha string
const (
	SpriteCutout SpriteAlpha = "cutout"
	SpriteBlend  SpriteAlpha = "blend"
)

type SpriteFacing added in v0.0.6

type SpriteFacing string
const (
	SpriteCameraFacing SpriteFacing = "camera-facing"
	SpriteUpright      SpriteFacing = "upright"
	SpriteCross        SpriteFacing = "cross"
	SpriteFixed        SpriteFacing = "fixed"
)

type StaticSolids added in v0.0.8

type StaticSolids struct {
	Version uint32  `json:"version"`
	Items   []Solid `json:"items"`
}

StaticSolids contains independently placed opaque volumes. They never alter the sector/portal graph. Hosts must advertise FeatureStaticSolids.

type SurfaceUV added in v0.0.8

type SurfaceUV struct {
	Projections []UVProjection `json:"projections"`
	Weights     []float64      `json:"weights"`
}

SurfaceUV contains one planar/wrapped projection or three blended projections. Weights are constant per surface, finite, nonnegative and normalized to one within UVWeightTolerance. They apply to all material channels, not just color.

type UVPlane added in v0.0.8

type UVPlane struct {
	X      float64 `json:"x"`
	Y      float64 `json:"y"`
	Z      float64 `json:"z"`
	Offset float64 `json:"offset"`
}

UVPlane evaluates X*position.X+Y*position.Y+Z*position.Z+Offset. All coefficients and Offset are finite with absolute value at most 1e12.

type UVProjection added in v0.0.8

type UVProjection struct {
	U UVPlane `json:"u"`
	V UVPlane `json:"v"`
}

UVProjection is an authored-position affine mapping to texture repeats. Hosts evaluate these planes before clipping; no projection setup is inferred.

type Vec2

type Vec2 struct {
	X float64 `json:"x"`
	Y float64 `json:"y"`
}

type Vec3

type Vec3 struct {
	X float64 `json:"x"`
	Y float64 `json:"y"`
	Z float64 `json:"z"`
}

type Wall

type Wall struct {
	Start      Vec2       `json:"start"`
	End        Vec2       `json:"end"`
	Portal     int32      `json:"portal"`
	PortalWall uint16     `json:"portal_wall,omitempty"`
	Material   uint32     `json:"material"`
	SourceEdge string     `json:"source_edge"`
	UV         *SurfaceUV `json:"uv,omitempty"`
}

Wall is one directed sector boundary. Portal is the adjacent sector index, or -1 for an opaque wall. PortalWall is one plus the reciprocal wall index in compiled-world v3; zero is reserved for v1/v2 coincident portals and opaque walls. The paired directed edges define a rigid destination-to-source portal transform. SourceEdge is empty only for compiler-generated internal decomposition edges.

type WallProfile added in v0.0.8

type WallProfile struct {
	Heights [4][2]float64
	Cuts    [8]float64
	Count   int
}

WallProfile divides a wall where any of its four linear elevation functions cross. Heights 0/1 are source floor/ceiling; 2/3 are destination elevations already transformed into the source coordinate frame. It contains no mesh or renderer state and can be used by public builders and private hosts alike.

func NewWallProfile added in v0.0.8

func NewWallProfile(heights [4][2]float64, tolerance float64) (WallProfile, error)

NewWallProfile requires finite endpoint heights and a finite positive tolerance. The four pairs have at most six interior crossings.

func (WallProfile) Controls added in v0.0.8

func (p WallProfile) Controls(t float64) (int, int)

Controls returns the maximum floor and minimum ceiling at an edge fraction.

func (WallProfile) Height added in v0.0.8

func (p WallProfile) Height(kind int, t float64) float64

Height evaluates one linear elevation at an edge fraction.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL