On this page
  1. tecs.gfx.layers
  2. Sort modes
  3. Coordinate spaces
  4. Module contents
    1. Types
    2. Functions
    3. Values
  5. Types
    1. Config
    2. Sort
  6. Functions
    1. bandOf
    2. configure
    3. depthIn
    4. depthOf
    5. depthResolution
    6. entryOf
    7. isScreenSpace
    8. revision
    9. sortOf
    10. viewCulled
  7. Values
    1. MAX
    2. maxY
    3. maxZ
    4. virtualHeight
    5. virtualWidth

tecs.gfx.layers

Depth bands, sorting, coordinate spaces, parallax, and lighting.

A layer occupies one of sixteen depth bands. Entities sort inside their band and never against another band. Higher layer numbers draw nearer, so a HUD on layer 8 covers a world on layer 1.

tecs.gfx.layers.configure(1, {sort = "topdown", parallax = 0.4})
tecs.gfx.layers.configure(
    8, {sort = "z", screenSpace = true, unlit = true}
)

world:spawn(
    tecs.Transform2D(16, 16, 0, 8, 0, 96, 24),
    tecs.gfx.Tint(1.0, 1.0, 1.0, 1.0),
    tecs.gfx.Renderable2D()
)

The fourth Transform2D argument selects the layer.

Sort modes

"topdown" sorts by Y with Z for height. "z" ignores position. "isometric" combines X, Y, and Z for a diamond grid. Equal depths retain instance order.

maxZ and maxY define the authored extents that each sort maps into its band. Values past an extent clamp to its edge. They still draw, but clamped entities no longer sort against one another. Reduce an extent when Renderer:depthSortCollapse reports that the target depth format merges nearby values.

Coordinate spaces

World coordinates form the default. screenSpace uses target pixels and ignores the camera. virtualCoords stretches one virtualWidth by virtualHeight coordinate system to the target. ignoreZoom follows camera position while preserving drawn size. parallax scales camera movement.

One layer cannot combine screenSpace and virtualCoords. Virtual coordinates preserve the authored coordinate system but do not letterbox or preserve square pixels.

unlit bypasses scene lighting for UI, debug overlays, and other content that must retain its own color.

configure replaces the complete layer configuration. Any omitted option returns to its default.

Module contents

Types

Type Kind Description
Config record Defines every decision a layer makes about its contents.
Sort enum Selects how a layer orders its contents within its own band.

Functions

Function Kind Description
bandOf Static Returns the two terms depthIn takes, resolved once for a layer.
configure Static Sets what a layer does with its contents.
depthIn Static Returns one entity's depth on a band bandOf already resolved.
depthOf Static Returns one entity's depth from zero to one, with zero nearest.
depthResolution Static Returns the smallest depth difference depthOf produces between two entities one unit apart, taken over every sort mode.
entryOf Static Returns the four floats that position and light one layer: its mode, its parallax offset factor, whether it ignores...
isScreenSpace Static Returns whether a layer uses screen-pixel coordinates.
revision Static Returns the layer table's configuration revision.
sortOf Static Returns a layer's sort as the identifier accepted by depthOf.
viewCulled Static Returns whether the camera's view rectangle culls this layer.

Values

Value Type Description
MAX integer Read-only. Reports how many bands divide the depth range.
maxY number Caller-writable. Sets half the expected world extent used to normalize position into a band.
maxZ number Caller-writable. Sets the highest z a scene expects to use and the resulting resolution of sorting within a band.
virtualHeight number Caller-writable. Sets the vertical resolution used to author a virtual-coordinate layer.
virtualWidth number Caller-writable. Sets the horizontal resolution used to author a virtual-coordinate layer.

Types

tecs.gfx.layers.Config record

Defines every decision a layer makes about its contents. A field left out takes its default, so this says what a layer is rather than amending what it was.

record tecs.gfx.layers.Config
    sort: Sort
    screenSpace: boolean
    ignoreZoom: boolean
    virtualCoords: boolean
    unlit: boolean
    parallax: number
end

tecs.gfx.layers.Config.sort field

Caller-writable. Selects how contents sort within the layer's band. The caller must set this field.

tecs.gfx.layers.Config.sort: Sort

tecs.gfx.layers.Config.screenSpace field

Caller-writable. Positions contents in screen pixels and ignores the camera entirely. What a HUD wants. Defaults to false.

tecs.gfx.layers.Config.screenSpace: boolean

tecs.gfx.layers.Config.ignoreZoom field

Caller-writable. Makes contents follow the camera's position but not its zoom, so they stay a constant size on screen while moving with the world. Defaults to false.

tecs.gfx.layers.Config.ignoreZoom: boolean

tecs.gfx.layers.Config.virtualCoords field

Caller-writable. Positions contents in virtualWidth by virtualHeight; Tecs scales that coordinate system to fill the target. Defaults to false and cannot combine with screenSpace.

tecs.gfx.layers.Config.virtualCoords: boolean

tecs.gfx.layers.Config.unlit field

Caller-writable. Makes contents bypass the lighting pass and appear at their own color. Defaults to false. A material can ask for the same thing, and a fragment is lit only where the material and the layer agree.

tecs.gfx.layers.Config.unlit: boolean

tecs.gfx.layers.Config.parallax field

Caller-writable. Sets how much the camera's position carries the contents. One moves them with the world; a half drifts them at half speed, which is what a background wants. Defaults to one.

tecs.gfx.layers.Config.parallax: number

tecs.gfx.layers.Sort enum

Selects how a layer orders its contents within its own band.

enum tecs.gfx.layers.Sort
    "isometric"
    "topdown"
    "z"
end

Functions

tecs.gfx.layers.bandOf Static

Returns the two terms depthIn takes, resolved once for a layer.

What depthOf works out before it looks at an entity at all, and what a caller writing many depths on one layer should work out once instead of once a row: the band's near edge, and which sort decides where in the band a row lands.

function tecs.gfx.layers.bandOf(layer: integer): number, integer

Arguments

Name Type Description
layer integer One to MAX. Outside that range this resolves the nearest layer whole, exactly as depthOf does, so the sort answered here is the clamped layer's and not what sortOf answers for the same argument.

Returns

Type Description
number The band's near edge, then the sort identifier.
integer

tecs.gfx.layers.configure Static

Sets what a layer does with its contents.

Replaces the layer's configuration rather than amending it. A Config defines the whole layer, so each omitted field takes its default instead of retaining its previous value.

function tecs.gfx.layers.configure(
    layer: integer, config: layers.Config
)

Arguments

Name Type Description
layer integer One to MAX. Anything else raises.
config layers.Config Raises on a missing or unknown sort, and on asking for screenSpace and virtualCoords together.

Returns

None.

tecs.gfx.layers.depthIn Static

Returns one entity's depth on a band bandOf already resolved.

The per-row half of depthOf, split out so a caller writing a run of rows on one layer pays the band lookup once. Bit for bit what depthOf answers for the layer the two terms came from.

function tecs.gfx.layers.depthIn(
    base: number, sort: integer, z: number, x: number, y: number
): number

Arguments

Name Type Description
base number The band's near edge, from bandOf.
sort integer The sort identifier, from bandOf.
z number Height in the sort, against maxZ. Read by every sort mode.
x number World x, read only by the isometric sort, against maxY.
y number World y, read by the topdown and isometric sorts, against maxY. Larger is lower on screen and so nearer.

Returns

Type Description
number A depth inside the band, held to zero and one the same way depthOf holds its own.

tecs.gfx.layers.depthOf Static

Returns one entity's depth from zero to one, with zero nearest.

Exact ties carry no tie-breaker. The renderer draws instances in index order and the depth test lets an equal fragment through, so two entities at the same depth already resolve the same way every frame: the later one wins. Nudging depth by identity would resolve them the other way, since a larger value is farther, and quietly invert the order a scene was built expecting.

function tecs.gfx.layers.depthOf(
    layer: integer, z: number, x: number, y: number
): number

Arguments

Name Type Description
layer integer One to MAX, which picks the band and, through sortOf, what the rest of the arguments mean. Outside that range this takes the nearest layer whole and goes on sorting within it, because a band is the only thing a depth can name.
z number Height in the sort, against maxZ. Read by every sort mode.
x number World x, read only by the isometric sort, against maxY.
y number World y, read by the topdown and isometric sorts, against maxY. Larger is lower on screen and so nearer.

Returns

Type Description
number Returns a depth inside the layer's own band. The function normalizes and clamps each argument to zero through one, so a scene beyond the configured extent stops sorting instead of spilling into the next layer.

tecs.gfx.layers.depthResolution Static

Returns the smallest depth difference depthOf produces between two entities one unit apart, taken over every sort mode.

A depth buffer must preserve this difference. A format with a larger step keeps the bands, so layer order remains safe, but loses the sort inside them: the two entities land on one depth value and draw in write order rather than their sorted order.

The calculation includes every mode because configure may assign any sort after the depth target exists. MAX, maxZ, and maxY determine the result, so raising an extent changes it.

function tecs.gfx.layers.depthResolution(): number

Arguments

None.

Returns

Type Description
number A depth difference, in the input that moves depth least. That is the topdown sort's y at the defaults, which spends the smallest share of a band on the widest range.

tecs.gfx.layers.entryOf Static

Returns the four floats that position and light one layer: its mode, its parallax offset factor, whether it ignores zoom, and whether it is lit.

Returns these values together because consumers pack them together when revision changes, not every frame.

function tecs.gfx.layers.entryOf(
    layer: integer
): number, number, number, number

Arguments

Name Type Description
layer integer One to MAX. Outside that every return is nil, since only that range is ever filled in.

Returns

Type Description
number The positioning mode, then the camera position's multiplier, then one when the layer ignores zoom, then one when it is lit.
number
number
number

tecs.gfx.layers.isScreenSpace Static

Returns whether a layer uses screen-pixel coordinates.

function tecs.gfx.layers.isScreenSpace(layer: integer): boolean

Arguments

Name Type Description
layer integer One to MAX. Outside that this answers false, which is what an unconfigured layer answers too.

Returns

Type Description
boolean Whether configure selected screenSpace for the layer.

tecs.gfx.layers.revision Static

Returns the layer table's configuration revision.

function tecs.gfx.layers.revision(): integer

Arguments

None.

Returns

Type Description
integer A count that starts at zero and only rises. A consumer compares it against the value it packed at, so the number itself means nothing beyond having changed.

tecs.gfx.layers.sortOf Static

Returns a layer's sort as the identifier accepted by depthOf.

function tecs.gfx.layers.sortOf(layer: integer): integer

Arguments

Name Type Description
layer integer One to MAX. Outside that this answers topdown rather than raising, since it is the default every layer starts on.

Returns

Type Description
integer The sort identifier, which is an internal number and not one of the Sort strings.

tecs.gfx.layers.viewCulled Static

Returns whether the camera's view rectangle culls this layer.

False on a layer the camera does not place where its world bound says: screen-space and virtual-coordinate contents have no world position for the view to test, and parallax and ignore-zoom draw them somewhere the bound does not describe. Extraction reads this per row and gives those contents a bound that every view contains, so they draw regardless of camera position. Layers using none of these modes retain exact culling.

function tecs.gfx.layers.viewCulled(layer: integer): boolean

Arguments

Name Type Description
layer integer One to MAX. Outside that this answers true, which is what an unconfigured layer answers too.

Returns

Type Description
boolean Whether extraction should write this row's real world bound.

Values

tecs.gfx.layers.MAX variable

Read-only. Reports how many bands divide the depth range.

Load-bearing at sixteen. A sort mode packs into two bits, this value sizes the vertex shader's table, and the shader recovers a layer by multiplying depth by it. LAYER_BANDS in assets/shaders/instance.vert.glsl is the same number, and the two only work while they agree. Raising it is not a constant change.

tecs.gfx.layers.MAX: integer

tecs.gfx.layers.maxY variable

Caller-writable. Sets half the expected world extent used to normalize position into a band. A scene larger than this still sorts, with entities beyond the edge compressed against it.

tecs.gfx.layers.maxY: number

tecs.gfx.layers.maxZ variable

Caller-writable. Sets the highest z a scene expects to use and the resulting resolution of sorting within a band. A scene reaching past this still draws, with entities beyond the edge resting on it and no longer sorting against each other.

tecs.gfx.layers.maxZ: number

tecs.gfx.layers.virtualHeight variable

Caller-writable. Sets the vertical resolution used to author a virtual-coordinate layer. Tecs scales it with virtualWidth to fill the target.

tecs.gfx.layers.virtualHeight: number

tecs.gfx.layers.virtualWidth variable

Caller-writable. Sets the horizontal resolution used to author a virtual-coordinate layer.

Every such layer shares one resolution because a game has one authored layout size. Tecs scales it to fill the target, so the layout keeps its internal proportions at any window size and stretches with the window's aspect.

tecs.gfx.layers.virtualWidth: number