Help us shape the future of Go! Take the 2026 Go Developer Survey

worldgpuchunk

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 12 Imported by: 0

README

GPU-ready spatial chunks

This contract ships with the 0.1.0 SDK/host release. Rebuild earlier cartridges and levels for the matching WebGPU host; the release does not add a runtime conversion path for previous GPU buffers.

world/gpu-chunks@2 selects karty.world-gpu-chunks@2. It requires prepared world materials and sectors. Physics/probe catalogs and completed lighting remain optional; live-only cells use a neutral three-layer RNM image. The root contains @world/gpu-chunks/catalog (KGC2) and the kartyWorldGPUChunks marker. Each referenced cell KLD contains @world/gpu-chunks/cell (KGP2), @world/gpu-chunks/rnm.ktx2 and the kartyWorldGPUCell marker. Marker values equal the schema string. Root and cell entries cannot coexist in one envelope; partial or undeclared data is invalid.

Spatial ownership and portals

Cells retain whole authored room or geometry extents inside enclosing XY grid bounds, with full XYZ bounds. Grid lines bound those extents; they do not require cuts through rooms. PortalSpaces joins only reciprocal portals with coincident, reversed edges. Directed, transformed and unrelated overlapping spaces stay separate. The lowest sector ID identifies each component. Catalog cells have dense IDs and canonical (SpaceID, Group, GridY, GridX, GridSpan, FirstSectorID) order. GridSpan is a power of two from 1 through 4096 and scales the base cell size. Distinct room owners can share the same enclosing grid key; their first sector IDs provide the final canonical tie. Group is zero for ordinary geometry and one for authored spatial geometry. Explicit sector and physical ownership lists are sorted and unique. Overlapping loading extents never establish adjacency or duplicate ownership across unrelated spaces.

Portal traversal selects required cells and lookahead in each retained portal context. Grid adjacency never establishes visibility, reachability or prefetch. Bounds cull whole cells inside the appropriate context. Rendering submits their prebuilt draw ranges without subdividing them into sector windows. A transformed portal can require a distant cell while a nearby disconnected cell remains unloaded. The existing physics/probe catalog uses worldchunk.PhysicalSchema (KCC6); it owns no render geometry or RNM image.

The catalog binds the canonical world geometry digest and shared material layout SHA-256. Each cell descriptor binds its entire KLD SHA-256 and transport size, final GPU byte count and decoded RNM byte count. Existing 32 MiB module, 16 MiB level envelope and 8 MiB entry bounds remain unchanged. Admission also verifies ownership against PortalSpaces and the admitted physical catalog.

Immutable GPU ABI

All GPU words are little endian. The container uses bounded binwire version-1 headers and typed counts. It rejects trailing bytes and unknown versions. The public ABI name is karty.webgpu-cell@2. Catalogs use KGC2; payloads use KGP2 and require payload ABI word 2. Legacy KGC1/KGP1, the 164-byte cell ABI and unknown versions are rejected. Metadata keys and entry names remain stable; the new capability gates compatibility. No runtime repacking is needed.

Stream Stride Contents
Source vertex 96 Position XYZ at 0, normal XYZ at 12, tangent XYZW at 24, material UV at 40, lightmap UV at 48, bake tangent at 56, bake bitangent at 68, motion XYZW at 80
Draw address 8 Cell-local source vertex index and cell-local record index
Index 4 Cell-local draw address index
Instance/material record 368 Existing shared shader ABI; packed by AppendStaticRecord

Each draw has a representative record, alpha mode, full bounds and explicit sector coverage. Draw index ranges are contiguous, complete triangle lists. Addresses may reference other records only when their sector/solid owner kind and ID match the representative for blended draws; opaque draws may address independent owners. Every record and local reference is admitted before publication. RecordRef identifies canonical material ID, sector/solid owner and source surface kind (wall/floor/ceiling). Material IDs can be sparse; packed texture layer indexes match their positions in the shared root layout.

Opaque and cutout records share chunk batches with draw alpha mode zero; the fragment shader retains each record's cutout discard. Prepared liquid records use alpha mode two and a separate owner batch. All records addressed by such a draw must also use alpha mode two. Blended cell commands retain portal-aware depth ordering with dynamic blended objects.

Cell records use RNM lighting, prepared material detail and local light layer zero. Prepared liquids retain authored opacity, specular controls, UV flow and wave motion in the existing shader ABI. Water is an explicit boolean record flag; its vertex motion uses the existing mode-two representation. Unit normals, orthogonal unit tangents and tangent handedness are checked without normalizing or regenerating them. Skinning and per-vertex RNM fields are absent in this cell profile. Dynamic mesh and character formats retain their separate ABI.

Particle, skinning, clipping and portal state are absent from cell records. Portal transforms and clipping use separate dynamic draw context metadata. Fixed probe slots are admitted against the immutable root probe table. ValidateRecord admits one complete changed record independently of unchanged geometry, addresses or other records.

Cell lighting and permitted loading work

RNM is the directional lightmap and belongs to each cell. Albedo, detail and SSBump material arrays remain shared immutable root assets.

Each cell owns one linear RGBA8_UNORM + Zstandard KTX2 array, inspected by ktx2.InspectRGBA8. It has one mip and exactly three array layers in RNM basis order, dimensions at most 2048 and RGBM range declared in the payload. Its allocation is exactly 12 × width × height bytes. No root-wide lighting array or fixed global lighting layer registry exists.

The catalog's sorted, unique BakedLights indexes identify the union of authored point sources already included in cell lighting. ValidateLights binds those indexes to the root lighting table before cells load. This preserves selective prebaking even when no physical catalog exists; live-only cells leave the union empty. Cells may retain bounded layout and bake-manifest provenance, while the compiler's intermediate QOI images are omitted.

The producer resolves clipping, tangents, vertex conversion, indexing, materials, draw grouping, chart constants, resizing, packing and mips offline. The loader verifies hashes, typed metadata, references and device limits, decodes the required compression once and uploads the existing bytes. Renderers retain independent per-cell GPU resources. Unchanged cells require no vertex conversion, merging, address rewriting, image assembly or upload. Runtime resource and aggregate allocation bounds still apply to the complete resident set. DecodePayloadWithCheckpoint performs the same complete admission with an optional callback between bounded scan batches. A host can cancel or yield to its event loop; the callback does not transform data, and failure returns no partial cell.

Actors, active movers, terrain and sky retain their separate rendering profiles. Prepared liquid surfaces use the cell blend path described above. Gameplay physics is never duplicated into render cells.

Documentation

Overview

Package worldgpuchunk defines portal-selected spatial cells containing final GPU buffers and independently resident, offline prepared RNM images.

Index

Constants

View Source
const (
	Feature                = "world/gpu-chunks@2"
	Schema                 = "karty.world-gpu-chunks@2"
	MetadataKey            = "kartyWorldGPUChunks"
	CellMetadataKey        = "kartyWorldGPUCell"
	CatalogEntry           = "@world/gpu-chunks/catalog"
	PayloadEntry           = "@world/gpu-chunks/cell"
	RNMEntry               = "@world/gpu-chunks/rnm.ktx2"
	ABI                    = "karty.webgpu-cell@2"
	VertexStride           = 96
	AddressStride          = 8
	IndexStride            = 4
	RecordStride           = 368
	MaxCells               = 4096
	MaxRecords             = 8192
	MaxDraws               = 1024
	MaxVertices            = 262144
	MaxIndices             = 1572864
	MaxDimension           = 2048
	MaxEncodedSize         = level.MaxEntrySize
	OwnerSector     uint32 = 0
	OwnerSolid      uint32 = 1
)

Variables

View Source
var ErrChunk = errors.New("GPU-ready spatial chunk is invalid")

Functions

func AppendStaticRecord

func AppendStaticRecord(destination []byte, record StaticRecord) ([]byte, error)

AppendStaticRecord writes an identity-transform RNM record. Its local RNM base layer is always zero; a cell owns precisely its three prepared planes.

func AppendVertex

func AppendVertex(destination []byte, vertex Vertex) []byte

AppendVertex writes exactly one little-endian, 96-byte source vertex.

func EncodeCatalog

func EncodeCatalog(catalog Catalog) ([]byte, error)

EncodeCatalog emits the bounded canonical KGC2 root grid catalog.

func EncodePayload

func EncodePayload(payload Payload) ([]byte, error)

EncodePayload writes metadata and the final GPU byte streams without changing any vertex, address, index or record bytes. ValidatePayload admits root refs.

func PortalSpaces

func PortalSpaces(document *world.Document) ([]uint32, error)

PortalSpaces labels admitted sectors by their lowest connected sector index. Only reciprocal portals with an identity coordinate transform join spaces. Directed, transformed and absent links never imply coordinate adjacency. This is bounded topology inspection, not visibility or prefetch selection.

func ValidateDeclaration

func ValidateDeclaration(entries []level.Entry, metadata level.Metadata, features []string) error

ValidateDeclaration requires complete, explicitly selected root or cell data. Reserved entries cannot silently select a legacy renderer or partial asset.

func ValidatePayload

func ValidatePayload(payload Payload, materialIDs []uint32, sectorCount, solidCount int) error

ValidatePayload additionally binds owners and canonical shared material layers to admitted root metadata. The root layout order is the material layer order.

func ValidateRecord

func ValidateRecord(record []byte, materialLayer uint32, rgbmRange float64, probeCount uint32) error

ValidateRecord admits one complete changed metadata record before any writes. MaterialLayer is the canonical root array index, not an authored material ID. ProbeCount is the admitted immutable root probe table length (at most 511).

Types

type Catalog

type Catalog struct {
	BakedLights                          []uint32
	GeometrySHA256, MaterialLayoutSHA256 [32]byte
	Origin                               [2]float64
	CellSize                             float64
	Cells                                []Cell
}

Catalog groups whole room/geometry extents inside enclosing XY grid bounds. Portal topology, rather than grid adjacency, determines loading and visibility.

func DecodeCatalog

func DecodeCatalog(encoded []byte) (Catalog, error)

DecodeCatalog validates all counts before allocating typed metadata.

func (Catalog) Validate

func (catalog Catalog) Validate() error

Validate checks canonical identities, spatial ownership and allocation bounds.

func (Catalog) ValidateCell

func (catalog Catalog) ValidateCell(id uint32, payload Payload, rnm []byte) error

ValidateCell binds the complete payload and its independently prepared RNM image to one content-addressed root descriptor. Module hashing stays with the level loader because the descriptor identifies the entire KLD, not its image.

func (Catalog) ValidateLights

func (catalog Catalog) ValidateLights(lightCount int) error

ValidateLights binds the sorted baked-source union to the root authored light table. It preserves selective prebaking without runtime double contribution.

func (Catalog) ValidateReferences

func (catalog Catalog) ValidateReferences(sectorSpaces []uint32, physicalCount int) error

ValidateReferences checks catalog ownership against admitted root metadata. sectorSpaces must come from the root's coincident identity-portal components.

type Cell

type Cell struct {
	ID, SpaceID              uint32
	Group                    uint32
	GridSpan                 uint32
	Grid                     [2]int32
	Bounds                   [6]float64
	Sectors, PhysicalIDs     []uint32
	ContentSHA256            [32]byte
	Size, GPUBytes, RNMBytes uint64
}

Cell is a content-addressed independent render asset. Sectors are explicit topological ownership, including for solids; PhysicalIDs never own rendering. Grid/GridSpan enclose the extent without requiring room cuts. The first sector ID distinguishes canonical room owners sharing the same enclosing grid key.

type CompileOptions

type CompileOptions struct {
	RGBMRange                 float64
	SectorProbes, SolidProbes []uint32
	SolidSectors              [][]uint32
	CellSectors               []uint32
	SkipTerrainSectors        []uint32
}

CompileOptions provides only immutable, offline lighting/ownership inputs. Probe values are one-based slots in the shared root reflection resource.

type Draw

type Draw struct {
	FirstIndex, IndexCount, Record, AlphaMode uint32
	Bounds                                    [6]float64
	Sectors                                   []uint32
}

Draw refers only to cell-local address/index and same-owner record buffers. Sectors retain build-time ownership. Renderers submit complete prebuilt ranges without subdividing them by internal sector boundaries.

type GPUData

type GPUData struct {
	Vertices, Addresses, Indices, Records []byte
	RecordRefs                            []RecordRef
	Draws                                 []Draw
}

GPUData contains final shader ABI bytes, already ordered and indexed offline. Decoders borrow buffer bytes; callers must retain immutable source storage.

func CompileReady

func CompileReady(
	ready worldchunk.Ready,
	document *world.Document,
	materials worldmaterial.Layout,
	options CompileOptions,
) (GPUData, error)

CompileReady converts source-oriented Ready streams into the final cell ABI. It runs only in the asset build. Runtime code consumes GPUData unchanged.

type Payload

type Payload struct {
	CellID               uint32
	Bounds               [6]float64
	MaterialLayoutSHA256 [32]byte
	RGBMRange            float64
	GPUData
}

Payload is paired with one cell-local, three-layer lossless RNM KTX2 image. All buffers and lighting use authored coordinates; portal contexts are dynamic draw metadata and never modify this asset.

func DecodePayload

func DecodePayload(encoded []byte) (Payload, error)

DecodePayload borrows immutable GPU bytes and validates all local references. It neither converts vertices nor constructs draw addresses or image pools.

func DecodePayloadWithCheckpoint

func DecodePayloadWithCheckpoint(encoded []byte, checkpoint func() error) (Payload, error)

DecodePayloadWithCheckpoint performs the same complete admission while letting a host cancel or cooperatively yield during bounded scan batches. The callback must not mutate encoded bytes; failure never returns a partial cell.

type RecordRef

type RecordRef struct{ MaterialID, OwnerKind, OwnerID, SurfaceKind uint32 }

RecordRef binds a packed immutable GPU record to canonical authored owners and a material ID in the root's bound material layout.

type StaticRecord

type StaticRecord struct {
	Layer, AlphaMode, Probe uint32
	RGBMRange, Emission     float32
	Water                   bool
	Opacity, Exponent       float32
	Specular                [3]float32
	UVTransform             [4]float32
}

StaticRecord contains the material-dependent values in an immutable cell record. Owner and surface metadata are carried separately by RecordRef.

type Vertex

type Vertex struct {
	Position, Normal           [3]float32
	Tangent                    [4]float32
	UV, LightUV                [2]float32
	BakeTangent, BakeBitangent [3]float32
	Motion                     [4]float32
}

Vertex matches the versioned shader storage ABI, without host struct padding. Build tools fill these fields; runtime cell loaders upload the encoded bytes.

Jump to

Keyboard shortcuts

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