On this page
tecs.assets
Acquires and decodes assets without blocking the SDL host.
Loads return their values directly. Inside a frame system dispatched by world:update, a worker decode transparently suspends the logical update:
return tecs.newApplication({
plugin = function(world: tecs.World, app: tecs.Application)
local loaded = false
world:addSystem({
name = "game.SpawnHero",
phase = tecs.ecs.phases.PreUpdate,
run = function()
if loaded then
return
end
local image <const> = tecs.assets.loadImage(
tecs.io.files.assetPath("sprites/hero.png")
)
local sprite <const> = app.renderer.sprites:registerImage(image)
world:spawn(
tecs.Transform2D(100, 100),
sprite,
tecs.gfx.Renderable2D()
)
loaded = true
end,
})
end,
})The loader decodes pixels but creates no GPU resource. The renderer decides texture residency. Audio follows the same split between decoded clips and voices.
Image cache misses read through SDL AsyncIO, decode in the bounded native CPU lane, and publish on the main thread. newMesh constructs immutable procedural geometry synchronously. loadGLTF decodes glTF 2.0 and GLB scenes through the maintained Rust glTF importer on a warmed isolated worker, including images, metallic-roughness materials, vertex colors, alpha masks, BLEND modes, skins, and node animation clips including morph weights. One opaque native allocation retains the import; the main thread borrows its geometry through flat views instead of serializing large strings through the worker channel. Both produce CPU-owned data that the mesh domain consumes when it becomes resident. A model with a BLEND material requires a mesh domain created with transparency = true.
Primitives without authored tangents use MikkTSpace tangent generation. Tangent discontinuities split vertices while color, skin, and morph streams follow the split, preserving normal-map seams without changing authored tangents.
One imported primitive becomes one independently bounded GPU-culling command. The decoder splits a primitive above 65,536 triangles into bounded commands, remapping the vertices and optional color, skin, and morph streams in each chunk. Meshoptimizer then reorders opaque and masked triangles for the vertex cache and remaps every vertex stream into first-use order. Alpha-blended triangles retain their authored order because order affects their result, but their vertex streams still receive the lossless fetch remap.
The repository's large-scene fetch command can replace source images with complete BC3 mip chains in KTX2 containers. The maintained Rust parser validates the container before exposing its blocks. Those images remain compressed through upload and require a mesh domain created with textureFormat = tecs.assets.IMAGE_BC3, mipmaps = true, and packTextures = false. PNG, JPEG, SVG, and ordinary glTF images remain decoded RGBA8.
Lifetime
Application installs and shuts down the asset lanes. Headless code calls install before model or sound loading and shutdown afterwards. A load outside a world update blocks and drives its private producer until the value or failure arrives; a system suspends at the same direct call.
Release a payload after its consumer takes ownership. The final release frees the decoded memory.
Overlapping image loads for one path share a decode and receive holds on the same image. A later load after settlement decodes again. Sound loads never share.
loadString reads a complete file into a binary-safe string without interpreting it. Image loads accept PNG, JPEG, static SVG, and linear BC3 KTX2 mip chains. SVG renders at its intrinsic dimensions. It uses the bundled JetBrains Mono for all text and ignores external image references, so installed fonts and the worker's current directory cannot change its pixels. tecs.audio.decoders() reports the sound formats linked into the current build. Sound mode "resident" decodes the complete clip, "stream" opens a source for each voice, and "auto" chooses from the duration threshold.
Release each payload after its consumer takes ownership.
Module contents
Constructors
| Constructor | Description |
|---|---|
newMesh |
Builds procedural mesh data in the renderer's fixed vertex layout. |
Types
| Type | Kind | Description |
|---|---|---|
Image |
record | Represents decoded pixels or an imported compressed mip chain and the caller's hold on them. |
Mesh |
record | Describes one immutable indexed triangle mesh before GPU registration. |
MeshMorphTarget |
record | Supplies one procedural morph target to newMesh. |
MeshOptions |
record | Supplies procedural geometry to newMesh. |
Model |
record | Represents one decoded glTF 2.0 scene and its node animations. |
ModelAnimation |
record | Describes one decoded glTF node-animation clip. |
ModelAnimationChannel |
record | Describes one decoded glTF animation channel. |
ModelDraw |
record | Describes one static primitive instance in a decoded glTF scene. |
ModelMaterial |
record | Describes one decoded glTF material before GPU registration. |
ModelNode |
record | Describes one node in a decoded glTF transform hierarchy. |
ModelSkin |
record | Describes one initial joint palette decoded from a glTF skin instance. |
Sound |
record | Represents a loaded clip and the caller's hold on it. |
Functions
| Function | Kind | Description |
|---|---|---|
install |
Static | Starts the loading worker. |
installed |
Static | Reports whether the loading worker is running. |
loadGLTF |
Static | Queues glTF 2.0 or GLB decoding on the asset worker. |
loadImage |
Static | Loads an image and returns its decoded pixels. |
loadSound |
Static | Loads a sound and returns its decoded or streaming payload. |
loadString |
Static | Reads a complete file and returns its bytes. |
pending |
Static | Returns the number of asset loads still in flight. |
shutdown |
Static | Stops the loading worker. |
waitAll |
Static | Blocks until every queued load has finished. |
Values
| Value | Type | Description |
|---|---|---|
ANIMATION_CUBIC |
integer |
Read-only. Selects cubic-spline interpolation. |
ANIMATION_LINEAR |
integer |
Read-only. Selects linear interpolation. |
ANIMATION_ROTATION |
integer |
Read-only. Selects a rotation animation channel. |
ANIMATION_SCALE |
integer |
Read-only. Selects a scale animation channel. |
ANIMATION_STEP |
integer |
Read-only. Selects held-key interpolation. |
ANIMATION_TRANSLATION |
integer |
Read-only. Selects a translation animation channel. |
ANIMATION_WEIGHTS |
integer |
Read-only. Selects a morph-weight animation channel. |
IMAGE_BC3 |
integer |
Read-only. Selects a complete imported BC3 image mip chain. |
IMAGE_RGBA8 |
integer |
Read-only. Selects decoded, uncompressed RGBA8 image storage. |
Constructors
tecs.assets.newMesh Static
Builds procedural mesh data in the renderer's fixed vertex layout.
function tecs.assets.newMesh(options: MeshOptions): MeshArguments
| Name | Type | Description |
|---|---|---|
options |
MeshOptions |
The caller supplies a name, interleaved vertices, and zero-based triangle indices. |
Returns
| Type | Description |
|---|---|
Mesh |
Returns CPU geometry that renderer.meshes:registerMesh consumes or the caller releases. |
Types
tecs.assets.Image record
Represents decoded pixels or an imported compressed mip chain and the caller's hold on them.
What loadImage returns. Reference counts govern the pixels rather than owning them outright, because two overlapping loads share a decode: each caller holds the same Image, and the last caller to release it one that frees. Reading pixels after that is reading freed memory, which is why a released image reads nil there rather than looking uploadable. Read-only. Exposes the decoded image type.
record tecs.assets.Image
path: string
pixels: loader.CValue
width: integer
height: integer
pitch: integer
format: integer
storageWidth: integer
storageHeight: integer
levels: integer
byteCount: integer
release: function(self)
endtecs.assets.Image.path field
Read-only. Contains the requested path unchanged. The loader does not resolve it, so it is whatever the caller passed.
tecs.assets.Image.pixels field
Read-only. Contains decoded RGBA pixels or BC3 blocks until the last release, then becomes nil.
tecs.assets.Image.width field
Read-only. Reports the width in pixels.
tecs.assets.Image.height field
Read-only. Reports the height in pixel rows.
tecs.assets.Image.pitch field
Read-only. Reports the row stride in bytes, which a decoder may pad beyond width * 4.
tecs.assets.Image.format field
Read-only. Selects decoded RGBA8 pixels or an imported BC3 mip chain with an assets.IMAGE_* integer constant.
tecs.assets.Image.storageWidth field
Read-only. Reports the texture width represented by the uploaded mip chain. It equals width for decoded RGBA8 images.
tecs.assets.Image.storageWidth: integertecs.assets.Image.storageHeight field
Read-only. Reports the texture height represented by the uploaded mip chain. It equals height for decoded RGBA8 images.
tecs.assets.Image.storageHeight: integertecs.assets.Image.levels field
Read-only. Reports the number of consecutive mip levels in pixels.
tecs.assets.Image.byteCount field
Read-only. Reports bytes available from pixels. Decoded RGBA8 images report pitch * height.
tecs.assets.Image:release Instance
Gives up this caller's hold on the pixels, and frees at the last.
Called once whatever needed them has taken a copy, which for an image means after the caller uploads it. Where several loads shared one decode, this releases one of them.
Releasing an image already down to nothing does nothing, so a shutdown path need not know whether something else got there first.
function tecs.assets.Image.release(self)Arguments
| Name | Type | Description |
|---|---|---|
self |
Image |
Returns
None.
tecs.assets.Mesh record
Describes one immutable indexed triangle mesh before GPU registration.
Vertices use one fixed interleaved layout: position xyz, normal xyz, tangent xyzw, and texture uv. Indices are zero-based unsigned 32-bit values. A mesh may therefore contain far more than 65,535 vertices, and a primitive is one indexed range rather than one triangle.
renderer.meshes:registerMesh copies both arrays into device-local storage and releases this object. The Lua-number constructor is intended for procedural and example geometry. A file decoder can build the same record directly without expanding a large mesh into Lua tables. Read-only. Exposes the immutable CPU mesh type.
record tecs.assets.Mesh
name: string
vertices: loader.CArray
colorVertices: loader.CArray
indices: loader.CArray
skinVertices: loader.CArray
morphVertices: loader.CArray
morphTargetCount: integer
morphWeights: {number}
vertexCount: integer
indexCount: integer
centerX: number
centerY: number
centerZ: number
radius: number
release: function(self)
endtecs.assets.Mesh.name field
Read-only. Contains the stable name used by meshId and snapshots.
tecs.assets.Mesh.vertices field
Read-only. Contains interleaved vertex floats until release runs.
tecs.assets.Mesh.colorVertices field
Read-only. Contains optional linear RGBA vertex colors until release runs. Nil means every vertex is white.
tecs.assets.Mesh.colorVertices: loader.CArraytecs.assets.Mesh.indices field
Read-only. Contains zero-based unsigned 32-bit indices until release runs.
tecs.assets.Mesh.skinVertices field
Read-only. Contains optional joint indices and weights as eight floats per vertex until release runs. Nil means rigid geometry.
tecs.assets.Mesh.skinVertices: loader.CArraytecs.assets.Mesh.morphVertices field
Read-only. Contains optional position, normal, and tangent deltas as nine floats per target vertex until release runs. Nil means the geometry has no morph targets.
tecs.assets.Mesh.morphVertices: loader.CArraytecs.assets.Mesh.morphTargetCount field
Read-only. Reports the number of consecutive morph targets.
tecs.assets.Mesh.morphTargetCount: integertecs.assets.Mesh.morphWeights field
Read-only. Contains one default weight per morph target.
tecs.assets.Mesh.morphWeights: {number}tecs.assets.Mesh.vertexCount field
Read-only. Reports the number of vertices, not floats.
tecs.assets.Mesh.vertexCount: integertecs.assets.Mesh.indexCount field
Read-only. Reports the number of indices. It is always a multiple of three.
tecs.assets.Mesh.indexCount: integertecs.assets.Mesh.centerX field
Read-only. Reports the local-space bounding-sphere center x.
tecs.assets.Mesh.centerY field
Read-only. Reports the local-space bounding-sphere center y.
tecs.assets.Mesh.centerZ field
Read-only. Reports the local-space bounding-sphere center z.
tecs.assets.Mesh.radius field
Read-only. Reports the non-negative local-space bounding-sphere radius.
tecs.assets.Mesh:release Instance
Gives up the CPU geometry. Calling it again does nothing.
function tecs.assets.Mesh.release(self)Arguments
| Name | Type | Description |
|---|---|---|
self |
Mesh |
Returns
None.
tecs.assets.MeshMorphTarget record
Supplies one procedural morph target to newMesh. Read-only. Exposes one procedural morph-target description.
tecs.assets.MeshMorphTarget.positions field
Caller-writable. Supplies three position deltas per vertex.
tecs.assets.MeshMorphTarget.positions: {number}tecs.assets.MeshMorphTarget.normals field
Caller-writable. Supplies three normal deltas per vertex, or nil for zero deltas.
tecs.assets.MeshMorphTarget.normals: {number}tecs.assets.MeshMorphTarget.tangents field
Caller-writable. Supplies three tangent deltas per vertex, or nil for zero deltas. Tangent handedness is unchanged.
tecs.assets.MeshMorphTarget.tangents: {number}tecs.assets.MeshOptions record
Supplies procedural geometry to newMesh.
global record tecs.assets.MeshOptions
name: string
vertices: {number}
colors: {number}
indices: {integer}
joints: {integer}
weights: {number}
morphTargets: {MeshMorphTarget}
morphWeights: {number}
endtecs.assets.MeshOptions.name field
Caller-writable. Supplies the stable non-empty mesh name.
tecs.assets.MeshOptions.name: stringtecs.assets.MeshOptions.vertices field
Caller-writable. Supplies interleaved position xyz, normal xyz, tangent xyzw, and texture uv floats.
tecs.assets.MeshOptions.vertices: {number}tecs.assets.MeshOptions.colors field
Caller-writable. Supplies optional linear RGBA colors, four per vertex. Nil makes every vertex white without allocating a color array.
tecs.assets.MeshOptions.colors: {number}tecs.assets.MeshOptions.indices field
Caller-writable. Supplies zero-based triangle indices.
tecs.assets.MeshOptions.indices: {integer}tecs.assets.MeshOptions.joints field
Caller-writable. Supplies four zero-based joint indices per vertex. Nil requires weights to be nil and builds rigid geometry.
tecs.assets.MeshOptions.joints: {integer}tecs.assets.MeshOptions.weights field
Caller-writable. Supplies four non-negative joint weights per vertex. Each group is normalized by newMesh and requires joints.
tecs.assets.MeshOptions.weights: {number}tecs.assets.MeshOptions.morphTargets field
Caller-writable. Supplies morph targets in file order. Each target carries vertex-count-matched position deltas and optional normal and tangent deltas.
tecs.assets.MeshOptions.morphTargets: {MeshMorphTarget}tecs.assets.MeshOptions.morphWeights field
Caller-writable. Supplies one finite default weight per morph target. Omitted weights default to zero.
tecs.assets.MeshOptions.morphWeights: {number}tecs.assets.Model record
Represents one decoded glTF 2.0 scene and its node animations.
Meshes use the same fixed vertex layout as newMesh. Images remain decoded CPU pixels. renderer.meshes:registerModel consumes all of them and returns shared residency that creates independently posed instances. Skinning includes the initial joint pose. Morph data includes immutable deltas and default weights. Animation clips retain allocation-stable CPU sampling data for node transforms and morph weights. Read-only. Exposes the decoded glTF scene type.
record tecs.assets.Model
path: string
mipmaps: boolean
meshes: {Mesh}
images: {Image}
materials: {ModelMaterial}
skins: {ModelSkin}
nodes: {ModelNode}
animations: {ModelAnimation}
draws: {ModelDraw}
release: function(self)
endtecs.assets.Model.path field
Read-only. Contains the requested .gltf or .glb path unchanged.
tecs.assets.Model.mipmaps field
Read-only. Reports whether the source sampler requires a complete linearly filtered mip chain.
tecs.assets.Model.meshes field
Read-only. Contains unique decoded primitive geometry.
tecs.assets.Model.images field
Read-only. Contains unique decoded source images.
tecs.assets.Model.materials field
Read-only. Contains decoded metallic-roughness material descriptions.
tecs.assets.Model.materials: {ModelMaterial}tecs.assets.Model.skins field
Read-only. Contains initial joint palettes referenced by model draws.
tecs.assets.Model.nodes field
Read-only. Contains every node in source-index order.
tecs.assets.Model.animations field
Read-only. Contains decoded translation, rotation, and scale clips.
tecs.assets.Model.animations: {ModelAnimation}tecs.assets.Model.draws field
Read-only. Contains the selected scene's flattened static draws.
tecs.assets.Model:release Instance
Releases every CPU mesh and image not already consumed. Calling it again does nothing.
function tecs.assets.Model.release(self)Arguments
| Name | Type | Description |
|---|---|---|
self |
Model |
Returns
None.
tecs.assets.ModelAnimation record
Describes one decoded glTF node-animation clip. Read-only. Exposes one decoded node-animation clip.
record tecs.assets.ModelAnimation
name: string
duration: number
channels: {ModelAnimationChannel}
endtecs.assets.ModelAnimation.name field
Read-only. Contains the authored clip name or a stable generated name.
tecs.assets.ModelAnimation.name: stringtecs.assets.ModelAnimation.duration field
Read-only. Reports the last key time in seconds.
tecs.assets.ModelAnimation.duration: numbertecs.assets.ModelAnimation.channels field
Read-only. Contains translation, rotation, scale, and morph-weight channels.
tecs.assets.ModelAnimation.channels: {ModelAnimationChannel}tecs.assets.ModelAnimationChannel record
Describes one decoded glTF animation channel. Read-only. Exposes one decoded animation channel.
record tecs.assets.ModelAnimationChannel
node: integer
path: integer
interpolation: integer
width: integer
times: {number}
values: {number}
endtecs.assets.ModelAnimationChannel.node field
Read-only. Selects a one-based target node.
tecs.assets.ModelAnimationChannel.node: integertecs.assets.ModelAnimationChannel.path field
Read-only. Selects ANIMATION_TRANSLATION, ANIMATION_ROTATION, ANIMATION_SCALE, or ANIMATION_WEIGHTS.
tecs.assets.ModelAnimationChannel.path: integertecs.assets.ModelAnimationChannel.interpolation field
Read-only. Selects ANIMATION_LINEAR, ANIMATION_STEP, or ANIMATION_CUBIC.
tecs.assets.ModelAnimationChannel.interpolation: integertecs.assets.ModelAnimationChannel.width field
Read-only. Reports packed values per key. It is three for translation and scale, four for rotation, and the target count for morph weights.
tecs.assets.ModelAnimationChannel.width: integertecs.assets.ModelAnimationChannel.times field
Read-only. Contains strictly increasing key times in seconds.
tecs.assets.ModelAnimationChannel.times: {number}tecs.assets.ModelAnimationChannel.values field
Read-only. Contains packed key values. Cubic keys contain incoming tangent, value, and outgoing tangent rows.
tecs.assets.ModelAnimationChannel.values: {number}tecs.assets.ModelDraw record
Describes one static primitive instance in a decoded glTF scene. Read-only. Exposes one flattened glTF primitive instance.
record tecs.assets.ModelDraw
mesh: integer
material: integer
skin: integer
node: integer
weights: {number}
x: number
y: number
z: number
rotationX: number
rotationY: number
rotationZ: number
rotationW: number
scaleX: number
scaleY: number
scaleZ: number
endtecs.assets.ModelDraw.mesh field
Read-only. Selects a one-based entry in Model.meshes.
tecs.assets.ModelDraw.material field
Read-only. Selects a one-based entry in Model.materials, or zero for the neutral material.
tecs.assets.ModelDraw.skin field
Read-only. Selects a one-based entry in Model.skins, or zero for a rigid primitive.
tecs.assets.ModelDraw.node field
Read-only. Selects the one-based scene node this primitive follows.
tecs.assets.ModelDraw.weights field
Read-only. Contains this node's initial morph weights in target order.
tecs.assets.ModelDraw.x field
Read-only. Reports world translation x from the selected glTF scene.
tecs.assets.ModelDraw.y field
Read-only. Reports world translation y.
tecs.assets.ModelDraw.z field
Read-only. Reports world translation z.
tecs.assets.ModelDraw.rotationX field
Read-only. Reports world quaternion x.
tecs.assets.ModelDraw.rotationY field
Read-only. Reports world quaternion y.
tecs.assets.ModelDraw.rotationZ field
Read-only. Reports world quaternion z.
tecs.assets.ModelDraw.rotationW field
Read-only. Reports world quaternion w.
tecs.assets.ModelDraw.scaleX field
Read-only. Reports world scale x.
tecs.assets.ModelDraw.scaleY field
Read-only. Reports world scale y.
tecs.assets.ModelDraw.scaleZ field
Read-only. Reports world scale z.
tecs.assets.ModelMaterial record
Describes one decoded glTF material before GPU registration. Read-only. Exposes one glTF material description.
record tecs.assets.ModelMaterial
name: string
model: integer
alphaMode: integer
baseColorImage: integer
normalImage: integer
metallicRoughnessImage: integer
occlusionImage: integer
emissiveImage: integer
alphaCutoff: number
baseR: number
baseG: number
baseB: number
baseA: number
emissiveR: number
emissiveG: number
emissiveB: number
metallic: number
roughness: number
normalScale: number
occlusionStrength: number
doubleSided: boolean
endtecs.assets.ModelMaterial.name field
Read-only. Contains the stable material name.
tecs.assets.ModelMaterial.name: stringtecs.assets.ModelMaterial.model field
Caller-writable. Until model registration, selects metallic-roughness PBR at zero, unlit at one, or Lambert diffuse at two. This defaults to the decoded glTF model.
tecs.assets.ModelMaterial.model: integertecs.assets.ModelMaterial.alphaMode field
Read-only. Selects opaque, masked, or blended rendering with a MeshDomain.ALPHA_* integer constant.
tecs.assets.ModelMaterial.alphaMode: integertecs.assets.ModelMaterial.baseColorImage field
Read-only. Selects a one-based entry in Model.images, or zero.
tecs.assets.ModelMaterial.baseColorImage: integertecs.assets.ModelMaterial.normalImage field
Read-only. Selects a tangent-space normal image, or zero.
tecs.assets.ModelMaterial.normalImage: integertecs.assets.ModelMaterial.metallicRoughnessImage field
Read-only. Selects a glTF metallic-roughness image, or zero.
tecs.assets.ModelMaterial.metallicRoughnessImage: integertecs.assets.ModelMaterial.occlusionImage field
Read-only. Selects an occlusion image, or zero.
tecs.assets.ModelMaterial.occlusionImage: integertecs.assets.ModelMaterial.emissiveImage field
Read-only. Selects an emissive image, or zero.
tecs.assets.ModelMaterial.emissiveImage: integertecs.assets.ModelMaterial.alphaCutoff field
Read-only. Reports the alpha-mask cutoff. Zero keeps every fragment.
tecs.assets.ModelMaterial.alphaCutoff: numbertecs.assets.ModelMaterial.baseR field
Read-only. Reports the base-color red factor.
tecs.assets.ModelMaterial.baseR: numbertecs.assets.ModelMaterial.baseG field
Read-only. Reports the base-color green factor.
tecs.assets.ModelMaterial.baseG: numbertecs.assets.ModelMaterial.baseB field
Read-only. Reports the base-color blue factor.
tecs.assets.ModelMaterial.baseB: numbertecs.assets.ModelMaterial.baseA field
Read-only. Reports the base-color alpha factor.
tecs.assets.ModelMaterial.baseA: numbertecs.assets.ModelMaterial.emissiveR field
Read-only. Reports the emissive red factor.
tecs.assets.ModelMaterial.emissiveR: numbertecs.assets.ModelMaterial.emissiveG field
Read-only. Reports the emissive green factor.
tecs.assets.ModelMaterial.emissiveG: numbertecs.assets.ModelMaterial.emissiveB field
Read-only. Reports the emissive blue factor.
tecs.assets.ModelMaterial.emissiveB: numbertecs.assets.ModelMaterial.metallic field
Caller-writable. Until model registration, this multiplies sampled metallic and defaults to the decoded glTF factor.
tecs.assets.ModelMaterial.metallic: numbertecs.assets.ModelMaterial.roughness field
Caller-writable. Until model registration, this multiplies sampled roughness and defaults to the decoded glTF factor.
tecs.assets.ModelMaterial.roughness: numbertecs.assets.ModelMaterial.normalScale field
Read-only. Reports tangent-space normal strength.
tecs.assets.ModelMaterial.normalScale: numbertecs.assets.ModelMaterial.occlusionStrength field
Read-only. Reports sampled occlusion strength.
tecs.assets.ModelMaterial.occlusionStrength: numbertecs.assets.ModelMaterial.doubleSided field
Read-only. Reports whether both triangle faces must render.
tecs.assets.ModelMaterial.doubleSided: booleantecs.assets.ModelNode record
Describes one node in a decoded glTF transform hierarchy. Read-only. Exposes one decoded model node.
record tecs.assets.ModelNode
parent: integer
x: number
y: number
z: number
rotationX: number
rotationY: number
rotationZ: number
rotationW: number
scaleX: number
scaleY: number
scaleZ: number
matrix: {number}
endtecs.assets.ModelNode.parent field
Read-only. Selects the one-based parent node, or zero for a root.
tecs.assets.ModelNode.x field
Read-only. Contains the base translation x.
tecs.assets.ModelNode.y field
Read-only. Contains the base translation y.
tecs.assets.ModelNode.z field
Read-only. Contains the base translation z.
tecs.assets.ModelNode.rotationX field
Read-only. Contains the base quaternion x.
tecs.assets.ModelNode.rotationY field
Read-only. Contains the base quaternion y.
tecs.assets.ModelNode.rotationZ field
Read-only. Contains the base quaternion z.
tecs.assets.ModelNode.rotationW field
Read-only. Contains the base quaternion scalar component.
tecs.assets.ModelNode.scaleX field
Read-only. Contains the base x scale.
tecs.assets.ModelNode.scaleY field
Read-only. Contains the base y scale.
tecs.assets.ModelNode.scaleZ field
Read-only. Contains the base z scale.
tecs.assets.ModelNode.matrix field
Read-only. Contains a fixed column-major local matrix when the source node used matrix, or nil when its local matrix is composed from TRS.
tecs.assets.ModelSkin record
Describes one initial joint palette decoded from a glTF skin instance. Read-only. Exposes one decoded initial joint palette.
record tecs.assets.ModelSkin
name: string
matrices: {number}
node: integer
joints: {integer}
inverseBindMatrices: {number}
endtecs.assets.ModelSkin.name field
Read-only. Contains the stable palette name used during registration.
tecs.assets.ModelSkin.matrices field
Read-only. Contains column-major joint matrices, sixteen floats per joint, in the skinned mesh's local coordinate space.
tecs.assets.ModelSkin.node field
Read-only. Selects the one-based mesh node whose local space contains this palette.
tecs.assets.ModelSkin.joints field
Read-only. Contains one-based joint-node indices in palette order.
tecs.assets.ModelSkin.inverseBindMatrices field
Read-only. Contains column-major inverse bind matrices, sixteen floats per joint.
tecs.assets.ModelSkin.inverseBindMatrices: {number}tecs.assets.Sound record
Represents a loaded clip and the caller's hold on it.
What loadSound returns. Two overlapping loads of one path do not share, unlike images, so a Sound normally has one holder; the count is here so that releasing twice frees once rather than twice. Read-only. Exposes the loaded sound type.
record tecs.assets.Sound
path: string
audio: loader.CValue
resident: boolean
durationMs: integer
release: function(self)
endtecs.assets.Sound.path field
Read-only. Contains the requested path unchanged.
tecs.assets.Sound.audio field
Read-only. Contains the loaded clip until the last release. It is nil for one that streams, which holds nothing, and nil once released.
tecs.assets.Sound.resident field
Read-only. Reports whether memory holds the decoded audio. It is false for a clip each voice reads from the file for itself.
tecs.assets.Sound.durationMs field
Read-only. Reports the length in milliseconds, or -1 when the container cannot say.
tecs.assets.Sound.durationMs: integertecs.assets.Sound:release Instance
Gives up this caller's hold on the clip, and frees at the last.
A voice reads a clip where it lies, so release a clip when nothing will play it again. A track holds its own reference, so releasing one that is still sounding is safe: the mixer drops it when the last track using it does.
Releasing a clip already down to nothing does nothing.
function tecs.assets.Sound.release(self)Arguments
| Name | Type | Description |
|---|---|---|
self |
Sound |
Returns
None.
Functions
tecs.assets.install Static
Starts the loading worker.
Installing twice is installing once. Spawning unconditionally would leave the first thread running with both its channels and nothing reading them, and every queued decode would answer into an abandoned channel, so a load in flight across the second call would never resolve.
function tecs.assets.install(luaPath: string)Arguments
| Name | Type | Description |
|---|---|---|
luaPath |
string |
package.path for the worker's own state, which shares no loaded modules with this one. Defaults to this state's, which is what makes the worker resolve the same modules the game does. |
Returns
None.
tecs.assets.installed Static
Reports whether the loading worker is running.
For a subsystem that loads an asset of its own and has no way of knowing whether the game has started the worker yet.
function tecs.assets.installed(): booleanArguments
None.
Returns
| Type | Description |
|---|---|
boolean |
Whether the worker exists, which is a fact about the process rather than about any world. False means a load raises rather than queueing, so this is the guard rather than an optimization. |
tecs.assets.loadGLTF Static
Queues glTF 2.0 or GLB decoding on the asset worker.
External buffers and images resolve relative to the model path. Data URIs and embedded GLB resources are supported. Triangle primitives, static node transforms, metallic-roughness PBR, normal, occlusion, emissive, alpha-mask, alpha-blended, and unlit materials are decoded. JOINTS0, WEIGHTS0, skins, inverse bind matrices, sparse accessors, morph targets, mesh and node weights, and node animation clips are decoded. Missing tangents are generated with MikkTSpace, splitting vertices at tangent discontinuities and remapping every optional vertex stream. Non-triangle input and texture-coordinate transforms raise at the direct load call instead of loading incompletely. A primitive above 65,536 triangles is split into independently bounded and culled mesh records. Opaque and masked records are optimized for vertex-cache and vertex-fetch locality. Alpha-blended records preserve authored triangle order and receive only the lossless vertex-fetch remap. Registering a model containing alpha blending requires a mesh domain created with transparency = true.
function tecs.assets.loadGLTF(path: string): ModelArguments
| Name | Type | Description |
|---|---|---|
path |
string |
The caller supplies a .gltf or .glb asset path. |
Returns
| Type | Description |
|---|---|
Model |
Returns the decoded model. The call suspends its system while the worker runs, or blocks when called outside a world update. |
tecs.assets.loadImage Static
Loads an image and returns its decoded pixels.
Two loads of one path that overlap share a decode, because decoding the same PNG twice at once duplicates work without producing another result. They share the Image, so the last caller to release it frees the pixels. A load that starts after the first has settled decodes again: nothing here is a cache.
function tecs.assets.loadImage(path: string): ImageArguments
| Name | Type | Description |
|---|---|---|
path |
string |
The caller supplies a PNG, JPEG, static SVG, or linear BC3 KTX2 path. KTX2 input must contain one complete mip chain for one image. The loader renders SVG at its intrinsic width and height, uses bundled JetBrains Mono for text, and ignores external image references. Another format fails during decoding. |
Returns
| Type | Description |
|---|---|
Image |
Returns the decoded image. Inside a system, the call suspends only while its decode is pending. A missing file or decode failure raises. |
tecs.assets.loadSound Static
Loads a sound and returns its decoded or streaming payload.
Whatever the mixer's decoders can read loads, so the format is the file's business rather than the caller's.
mode is "resident", "stream", or "auto", and auto keeps anything shorter than streamMs resident.
This call initializes the library instead of the worker because MIX_Init does not support concurrent calls. Initialization before sending the task puts it in order ahead of every decode without a lock.
Two overlapping loads of one path do not share, unlike images: each gets its own clip, because that is what MIX_LoadAudio produces. The returned Sound has exactly one holder.
function tecs.assets.loadSound(
path: string, mode: string, streamMs: integer
): SoundArguments
| Name | Type | Description |
|---|---|---|
path |
string |
|
mode |
string |
"resident", "stream" or "auto". Any other value selects "stream". |
streamMs |
integer |
The boundary "auto" decides on, in milliseconds. Read only under "auto", and a file whose length the container cannot state streams whatever it says. |
Returns
| Type | Description |
|---|---|
Sound |
Returns the loaded sound. Mixer initialization or decode failure raises. |
tecs.assets.loadString Static
Reads a complete file and returns its bytes.
The returned string preserves embedded NUL bytes. The operation uses the common file lane; callers that need retained reuse store the returned immutable string in their own asset resource.
function tecs.assets.loadString(path: string, kind: string): stringArguments
| Name | Type | Description |
|---|---|---|
path |
string |
The caller supplies an absolute path or one from assetPath. |
kind |
string |
The caller supplies the content kind used by file watching, or omits it to record a document. |
Returns
| Type | Description |
|---|---|
string |
Returns the complete bytes. A missing or unreadable file raises with the platform's own reason behind the path it could not read. |
tecs.assets.pending Static
Returns the number of asset loads still in flight.
function tecs.assets.pending(): integerArguments
None.
Returns
| Type | Description |
|---|---|
integer |
Every image decode, model load, and sound load owned by this module, not one caller's. loadString uses the shared file lane directly and is not counted. A model or sound load every caller has canceled remains counted until the worker answer is taken and destroyed. |
tecs.assets.shutdown Static
Stops the loading worker.
Blocks until the thread exits. This call cancels loads still in flight, so drain with waitAll first when their results matter. Releasing an Image or a Sound that already settled still works afterwards; this frees nothing.
function tecs.assets.shutdown()Arguments
None.
Returns
None.
tecs.assets.waitAll Static
Blocks until every queued load has finished.
This global barrier is for startup, shutdown, and tests outside a system. Applications use the process runtime during frames.
It waits on every load in this process, including work a subsystem started, rather than only loads one caller initiated.
function tecs.assets.waitAll(timeoutMs: number)Arguments
| Name | Type | Description |
|---|---|---|
timeoutMs |
number |
Wall-clock milliseconds, defaulting to 5000. Running out is not an error and is not reported, so read assets.pending afterwards to tell the two endings apart. |
Returns
None.
Values
tecs.assets.ANIMATION_CUBIC variable
Read-only. Selects cubic-spline interpolation.
tecs.assets.ANIMATION_CUBIC: integertecs.assets.ANIMATION_LINEAR variable
Read-only. Selects linear interpolation.
tecs.assets.ANIMATION_LINEAR: integertecs.assets.ANIMATION_ROTATION variable
Read-only. Selects a rotation animation channel.
tecs.assets.ANIMATION_ROTATION: integertecs.assets.ANIMATION_SCALE variable
Read-only. Selects a scale animation channel.
tecs.assets.ANIMATION_SCALE: integertecs.assets.ANIMATION_STEP variable
Read-only. Selects held-key interpolation.
tecs.assets.ANIMATION_STEP: integertecs.assets.ANIMATION_TRANSLATION variable
Read-only. Selects a translation animation channel.
tecs.assets.ANIMATION_TRANSLATION: integertecs.assets.ANIMATION_WEIGHTS variable
Read-only. Selects a morph-weight animation channel.
tecs.assets.ANIMATION_WEIGHTS: integertecs.assets.IMAGE_BC3 variable
Read-only. Selects a complete imported BC3 image mip chain.
tecs.assets.IMAGE_BC3: integertecs.assets.IMAGE_RGBA8 variable
Read-only. Selects decoded, uncompressed RGBA8 image storage.
tecs.assets.IMAGE_RGBA8: integer