tecs.gfx

The public scene-rendering values a game spawns.

Renderable3D selects indexed meshes with Transform3D, Mesh, Bounds3D and MeshMaterial. Models load shared glTF geometry and independent animation poses. Particles keep individual particle state on the GPU; entities author their emitters. View selects ordered 2D and 3D cameras.

Tint, Sprite, and Renderable2D accompany tecs.ecs.Transform2D on a drawable entity, and Camera2D with ActiveCamera selects the view every frame is projected through.

PreviousTransform2D opts an entity into fixed-step presentation interpolation. The extractor blends position and the shortest rotation arc using the world's residual fixed time. Lights and shadow geometry use the same presented pose. Scale, depth and layer use current values, and entities without history render directly from their current transform. Physics seeds history automatically; an authored history should initially match the entity's creation pose.

const image = tecs.gfx.images.upload({name = "tiles/grass", width = 2, height = 2, pixels = grassRgba8})

world:spawn(tecs.gfx.Camera2D(320, 180, 1, 0), tecs.gfx.ActiveCamera)
world:spawn(
    tecs.ecs.Transform2D(320, 180, 0, 1, 0, 64, 64),
    tecs.gfx.Tint(1, 1, 1, 1),
    tecs.gfx.Sprite(image),
    tecs.gfx.Renderable2D
)

tecs.gfx.lighting owns the deferred lighting resolve, the two shadow mechanisms, and optional bloom, and it is where PointLight2D, Occluder2D, and DropShadow2D are documented. tecs.gfx.layers decides the order and placement of those entities, tecs.gfx.images owns image identity and residency, tecs.gfx.clips owns the target-pixel regions Clip selects, tecs.gfx.sheet and tecs.gfx.animation cut an image into frames and play them, tecs.gfx.fonts owns font identity and the glyph atlas, tecs.gfx.text lays a string out into glyph entities that draw through the same textured path a sprite does, tecs.gpu.materials numbers the materials a Material selects, and tecs.gpu.passes declares the render passes and render targets a frame is drawn through.

Submodules

ModuleDescription
tecs.gfx.animationFixed-step sprite-sheet playback.
tecs.gfx.camera3dA perspective camera maps a right-handed 3D world to one viewport.
tecs.gfx.clipsTarget-pixel clip regions and the component that selects one.
tecs.gfx.flycamera3dA free-fly controller turns mouse and keyboard input into a 3D camera pose.
tecs.gfx.fontsFont identity, glyph metrics, and the atlas that carries glyphs to the backend.
tecs.gfx.frametableShared sprite animation tables.
tecs.gfx.imagesImage identity, residency, and the commands that carry pixels to the backend.
tecs.gfx.layersDepth bands, sorting, coordinate spaces, parallax, and lighting.
tecs.gfx.lightingDeferred two-dimensional lighting, the shadows it casts, and optional bloom.
tecs.gfx.meshesPer-view 3D lighting, shadows, ambient probes and environments.
tecs.gfx.modelsResident glTF models and allocation-stable node animation.
tecs.gfx.particlesGPU particle effects, emitter playback, pool sizing, and rendering limits.
tecs.gfx.screenshotCapture the next presented frame, including UI and post-processing.
tecs.gfx.sheetA sprite sheet divides one image into frames, tags, and slices.
tecs.gfx.textShaped text as entities in the rendered world.
tecs.gfx.truetypeTrueType outlines, metrics, coverage rasterization, and signed distance fields.

Module contents

Constructors

ConstructorDescription
newCamera2DCreates a camera value for a View or coordinate conversion outside an entity.
newCamera3DCreates a right-handed perspective camera looking along negative Z.
newTextBuilds a text value that belongs to no entity, for measurement.
newTTFLoads a TrueType font and reads its metrics.

Types

TypeKindDescription
AnimationstructSprite-sheet playback state stored on an entity.
Bounds3DtypeStores the Bounds3D data for one 3D primitive.
Camera2DstructA view onto the world, in world units and target pixels.
Camera3DtypeA perspective camera with quaternion orientation.
ClipstructA clip region selected by a renderable entity.
DropShadow2DstructA stretched ground shadow, stored on a renderable entity.
FontrecordA loaded font and the atlas its glyphs live in.
MaterialstructA material selection stored on a renderable entity.
MeshtypeStores the Mesh data for one 3D primitive.
MeshMaterialtypeStores the MeshMaterial data for one 3D primitive.
MeshMorphtypeStores the MeshMorph data for one 3D primitive.
MeshSkintypeStores the MeshSkin data for one 3D primitive.
Occluder2DstructA silhouette that blocks light, stored on a renderable entity.
PointLight2DstructA light the deferred resolve accumulates.
PointLight3DtypeOmnidirectional mesh light positioned by Transform3D.
SpotLight3DtypeConical mesh light aimed along Transform3D local negative Z.
SpritestructAn image region stored on a renderable entity.
TextrecordA string laid out into glyph entities.
TileChunktypeA native 16 by 16 grid of static atlas tiles.
TintstructA four-channel color stored on a renderable entity.
ViewtypeDescribes an ordered viewport with its own camera.

Values

ValueKindDescription
ActiveCameravariableSelects the camera entity extraction projects the scene through.
AnimationvariableConstructs playback state directly.
AnimationEventsvariableRequests tecs.gfx.animation.Completed and tecs.gfx.animation.Looped for one entity.
Bounds3DvariableConstructs the Bounds3D component for a 3D primitive.
Camera2DvariableConstructs a camera centered on the world origin at zoom one.
ClipvariableConstructs a clip selecting a region set with tecs.gfx.clips.setRegion.
DirtyTileChunkvariableRequests synchronization after a nested tile-array edit.
DropShadow2DvariableConstructs a drop-shadow caster at full height.
LIGHT_CASTS_SHADOWSvariableRequests a slot in the local-light shadow atlas.
MaterialvariableConstructs a material selection, defaulting to textured at parameter one quarter.
MeshvariableConstructs the Mesh component for a 3D primitive.
MeshMaterialvariableConstructs the MeshMaterial component for a 3D primitive.
MeshMorphvariableConstructs the MeshMorph component for a 3D primitive.
MeshSkinvariableConstructs the MeshSkin component for a 3D primitive.
Occluder2DvariableConstructs an occluder at full height.
PivotvariableAnchors a sprite at normalized X/Y coordinates or an authored sheet slice.
PointLight2DvariableConstructs a light at height sixty-four, reaching two hundred and fifty-six world units, in white at full strength.
PointLight3DvariableConstructs a point light with radius, linear RGB, intensity and LIGHT flags.
Renderable2DvariableMarks an entity as contributing geometry to the two-dimensional scene.
Renderable3DvariableMarks geometry for the 3D renderer.
SpotLight3DvariableConstructs a spot light with radius, inner and outer half-angles in radians, linear RGB, intensity and LIGHT flags.
SpritevariableConstructs a sprite whose omitted UV rectangle covers the whole image.
TextvariableConstructs a text whose omitted fields default to an empty left-aligned string at em size sixteen with no wrapping.
TextGlyphvariableMarks an entity as one glyph tecs.gfx.text placed for a Text.
TILE_CHUNK_SIZEvariableThe number of cells along a tile chunk edge.
TileChunkvariableConstructs a tile chunk positioned by its top-left Transform2D.
TintvariableConstructs a tint whose omitted channels default to one.
ViewvariableConstructs a viewport from a camera and optional rectangle, order and enabled fields.

Constructors#

newCamera2Dconstructor#

function newCamera2D(options: {
    x: number?,
    y: number?,
    zoom: number?,
    rotation: number?
}?): Camera2D

Creates a camera value for a View or coordinate conversion outside an entity.

Arguments

NameTypeDescription
options{ x: number?, y: number?, zoom: number?, rotation: number? }?

The caller supplies world position, positive zoom and radians of rotation.

Returns

TypeDescription
Camera2D

The camera value, centered at zero with zoom one by default.

Raises

  • When zoom is not positive or a value is not finite.

newCamera3Dconstructor#

function newCamera3D(options: Options?): Camera3D

Creates a right-handed perspective camera looking along negative Z.

Arguments

NameTypeDescription
optionsOptions?

Returns

TypeDescription
Camera3D

newTextconstructor#

function newText(value: string?, font: fonts.Font?, size: number?, align: Align?, wrapWidth: number?): Text

Builds a text value that belongs to no entity, for measurement.

Arguments

NameTypeDescription
valuestring?

the string to lay out, defaulting to empty

fontfonts.Font?

the font supplying the glyphs, or nil to draw nothing

sizenumber?

the em size in world units, defaulting to sixteen

alignAlign?

the alignment, defaulting to "left"

wrapWidthnumber?

the maximum line width in world units, defaulting to zero, which disables wrapping

Returns

TypeDescription
Text

the text value, which the caller owns

Raises

  • when the alignment is not one of its declared values, or when the wrap width is negative

newTTFconstructor#

function newTTF(options: TTFOptions): Font?, string?

Loads a TrueType font and reads its metrics.

Arguments

NameTypeDescription
optionsTTFOptions

the source path or bytes, the identity, the raster point size, and the raster mode; name defaults to source, size to DEFAULT_SIZE, and raster to "sdf"

Returns

TypeDescription
Font?

the font, or nil when the file could not be read or parsed

string?

why the font could not be loaded, when unsuccessful

Raises

  • when neither source nor bytes is given, when the size is not greater than zero, or when the raster is not one of its declared values

Types#

Animationstruct#

struct Animation
    sheet: integer
    tag: integer
    speed: number
    time: number
    frame: integer
    loop: boolean
    playing: boolean
    crossed: integer
end
@derive(nupp.derive.Debug, nupp.derive.Serde)

Sprite-sheet playback state stored on an entity.

Fields

sheet#
sheet: integer

Caller-writable. Selects a sheet by its registration index. Zero plays nothing.

tag#
tag: integer

Caller-writable. Selects a tag by its Sheet.tagId index. Zero plays the whole sheet in order.

speed#
speed: number

Caller-writable. Multiplies the timing the sheet carries. One is the timing as authored and two is twice as fast. Zero or less holds the current frame and stops time advancing, which is a pause that leaves playing alone.

How long each frame is held is the sheet's answer rather than an entity's, because that is where an artist sets it: a hold frame is a frame with a long duration, which no single rate can express.

time#
time: number

Caller-writable. Supplies the phase used when frame is zero. To seek, write time and reset frame to zero. Read live phase with timeOf.

frame#
frame: integer

Engine-owned. Holds -1 for encoded GPU playback, or zero to request re-encoding from time. Ordinary game code should call frameOf, which answers for an entity carrying no Animation too. Writing zero asks playback to rewrite the Sprite, which is what play, restart, of, and a restored snapshot do.

loop#
loop: boolean

Caller-writable. Controls whether the tag restarts after its last frame.

playing#
playing: boolean

Caller-writable. Controls whether time advances.

crossed#
crossed: integer

Engine-owned. Retains the serialized component layout; GPU playback leaves this legacy event scratch field at zero. Ordinary game code should observe Completed and Looped instead. The reporting system clears it, and a snapshot drops it.

Bounds3Dtype#

type Bounds3D = Bounds3D2

Stores the Bounds3D data for one 3D primitive.

Camera2Dstruct#

struct Camera2D
    x: number
    y: number
    zoom: number
    rotation: number
    function matrix(borrows self: Camera2D, width: number, height: number): {number} end

    function viewBounds(borrows self: Camera2D, width: number, height: number): number, number, number, number end

    function toWorld(
        borrows self: Camera2D,
        screenX: number,
        screenY: number,
        width: number,
        height: number
    ): number, number end

    function toScreen(
        borrows self: Camera2D,
        worldX: number,
        worldY: number,
        width: number,
        height: number
    ): number, number end
end
@derive(nupp.derive.Debug, nupp.derive.Serde)

A view onto the world, in world units and target pixels.

Methods

matrix#
matrix: function matrix(borrows self: Camera2D, width: number, height: number): {number}

Returns the world-to-clip matrix for a viewport of width by height.

Column major, because that is how a shader reads a four-by-four uniform: the first four numbers are the first column, not the first row. Transposing them renders something plausible rather than nothing, which is how the mistake survives review.

The matrix owns the only y flip in the camera. toScreen and toWorld each spell out the same negated scale rather than sharing one helper, so a mismatch between the three stays visible.

Arguments
NameTypeDescription
borrows selfCamera2D

the camera to project through

widthnumber

the viewport width in target pixels

heightnumber

the viewport height in target pixels

Returns
TypeDescription
{number}

a fresh sixteen-number table the caller owns, indexed from one

viewBounds#
viewBounds: function viewBounds(borrows self: Camera2D, width: number, height: number): number, number, number, number

Returns the world rectangle this camera can see.

A rotated camera reports the axis-aligned box enclosing the view's corners, so culling keeps a little more than it must. Keeping too much costs a few instances; keeping too little drops geometry that should have drawn, which is why the error goes this way.

Arguments
NameTypeDescription
borrows selfCamera2D

the camera to bound

widthnumber

the viewport width in target pixels

heightnumber

the viewport height in target pixels

Returns
TypeDescription
number

the smallest x, then the smallest y, then the largest x, then the largest y

number
number
number
toWorld#
toWorld: function toWorld(borrows self: Camera2D, screenX: number, screenY: number, width: number, height: number): number, number

Converts a target point to world space.

Arguments
NameTypeDescription
borrows selfCamera2D

the camera to project through

screenXnumber

the pixels from the left of the viewport

screenYnumber

the pixels from the top of the viewport, running down

widthnumber

the viewport width in target pixels, the same one the matrix was built with

heightnumber

the viewport height in target pixels, the same one the matrix was built with

Returns
TypeDescription
number

the world x, then the world y; a point outside the viewport converts too and lands outside the view rectangle

number
toScreen#
toScreen: function toScreen(borrows self: Camera2D, worldX: number, worldY: number, width: number, height: number): number, number

Converts a world point to target space.

Exactly the inverse of toWorld at the same width and height, and the same mapping matrix applies, so a point round-trips.

Arguments
NameTypeDescription
borrows selfCamera2D

the camera to project through

worldXnumber

the world x

worldYnumber

the world y, running down

widthnumber

the viewport width in target pixels, the same one the matrix was built with

heightnumber

the viewport height in target pixels, the same one the matrix was built with

Returns
TypeDescription
number

the pixels from the left, then the pixels from the top; neither is clamped to the viewport

number

Fields

x#
x: number

Caller-writable. Sets the horizontal center of the view in world units.

y#
y: number

Caller-writable. Sets the vertical center of the view in world units. Increasing y moves the view towards the bottom of the world.

zoom#
zoom: number

Caller-writable. Sets the zoom. Values above one magnify about the center without moving the point under the middle of the target.

rotation#
rotation: number

Caller-writable. Sets the rotation in radians. Positive values turn the scene counter-clockwise on screen.

Camera3Dtype#

type Camera3D = Camera3D2

A perspective camera with quaternion orientation.

Clipstruct#

struct Clip
    index: integer
end
@derive(nupp.derive.Debug, nupp.derive.Serde)

A clip region selected by a renderable entity.

Fields

index#
index: integer

Caller-writable. Selects a region set with setRegion, from one to MAX - 1. Zero, the default, means no clipping.

DropShadow2Dstruct#

struct DropShadow2D
    height: number
end
@derive(nupp.derive.Debug, nupp.derive.Serde)

A stretched ground shadow, stored on a renderable entity.

Fields

height#
height: number

Caller-writable. Sets how far lights throw the shadow, from zero to one of the world's configured shadow height.

Fontrecord#

record Font
    name: string
    source: string
    size: number
    raster: Raster
    ascent: number
    descent: number
    lineGap: number
    lineHeight: number
end

A loaded font and the atlas its glyphs live in.

Fields

name#
name: string

Read-only. Reports the identity a snapshot stores and find resolves.

source#
source: string

Read-only. Reports the path the bytes were read from, or the empty string for a font handed over as bytes.

size#
size: number

Read-only. Reports the point size glyphs are rasterized at. It is not the size text is drawn at.

raster#
raster: Raster

Read-only. Reports whether the atlas holds a distance field or direct coverage.

ascent#
ascent: number

Read-only. Reports the distance from the baseline to the top of the typographic ascent, in em units.

descent#
descent: number

Read-only. Reports the distance from the baseline to the bottom of the typographic descent, in em units. It is negative in every ordinary font.

lineGap#
lineGap: number

Read-only. Reports the extra leading between two lines, in em units.

lineHeight#
lineHeight: number

Read-only. Reports the baseline-to-baseline distance in em units, which is the ascent less the descent plus the leading.

Materialstruct#

struct Material
    id: integer
    param: number
end
@derive(nupp.derive.Debug, nupp.derive.Serde)

A material selection stored on a renderable entity.

Fields

id#
id: integer

Caller-writable. Selects a material by an id id returned. Zero draws through textured.

param#
param: number

Caller-writable. Passes a value from zero to one to the material. What it means is the material's business.

Meshtype#

type Mesh = Mesh2

Stores the Mesh data for one 3D primitive.

MeshMaterialtype#

type MeshMaterial = MeshMaterial2

Stores the MeshMaterial data for one 3D primitive.

MeshMorphtype#

type MeshMorph = MeshMorph2

Stores the MeshMorph data for one 3D primitive.

MeshSkintype#

type MeshSkin = MeshSkin2

Stores the MeshSkin data for one 3D primitive.

Occluder2Dstruct#

struct Occluder2D
    height: number
end
@derive(nupp.derive.Debug, nupp.derive.Serde)

A silhouette that blocks light, stored on a renderable entity.

Fields

height#
height: number

Caller-writable. Sets the occluder height from zero to one of the world's configured shadow height.

PointLight2Dstruct#

struct PointLight2D
    height: number
    radius: number
    r: number
    g: number
    b: number
    intensity: number
end
@derive(nupp.derive.Debug, nupp.derive.Serde)

A light the deferred resolve accumulates.

Fields

height#
height: number

Caller-writable. Sets the height above the surface plane in world units. At zero the Lambert term vanishes and the light contributes nothing.

radius#
radius: number

Caller-writable. Sets the light's reach in world units. Falloff is smooth and reaches exactly zero at the radius.

r#
r: number

Caller-writable. Sets the red channel from zero to one.

g#
g: number

Caller-writable. Sets the green channel from zero to one.

b#
b: number

Caller-writable. Sets the blue channel from zero to one.

intensity#
intensity: number

Caller-writable. Scales the light's contribution. Values above one are meaningful, because the resolve writes a wider-than-eight-bit target.

PointLight3Dtype#

type PointLight3D = PointLight3D2

Omnidirectional mesh light positioned by Transform3D.

SpotLight3Dtype#

type SpotLight3D = SpotLight3D2

Conical mesh light aimed along Transform3D local negative Z.

Spritestruct#

struct Sprite
    image: integer
    u0: number
    v0: number
    u1: number
    v1: number
end
@derive(nupp.derive.Debug, nupp.derive.Serde)

An image region stored on a renderable entity.

Fields

image#
image: integer

Caller-writable. Selects an image by its tecs.gfx.images id. Zero selects no image.

u0#
u0: number

Caller-writable. Sets the left edge of the sampled UV rectangle.

v0#
v0: number

Caller-writable. Sets the top edge of the sampled UV rectangle.

u1#
u1: number

Caller-writable. Sets the right edge of the sampled UV rectangle.

v1#
v1: number

Caller-writable. Sets the bottom edge of the sampled UV rectangle.

Textrecord#

record Text
    text: string
    font: fonts.Font?
    size: number
    align: Align
    wrapWidth: number
    width: number
    height: number
end

A string laid out into glyph entities.

Fields

text#
text: string

Caller-writable. Sets the laid-out string. A newline starts a line and wrapWidth may introduce further breaks.

font#
font: fonts.Font?

Caller-writable. Selects the font that supplies the glyphs. Without one, the text draws nothing.

size#
size: number

Caller-writable. Sets the em size in world units.

align#
align: Align

Caller-writable. Selects the alignment within the block's widest line.

wrapWidth#
wrapWidth: number

Caller-writable. Sets the maximum line width in world units. Zero disables wrapping.

width#
width: number

Engine-owned. Reports the width of the last layout in world units, before the Transform2D scale. Assigning it has no effect.

height#
height: number

Engine-owned. Reports the height of the last layout in world units, on the same terms. Assigning it has no effect.

TileChunktype#

type TileChunk = TileChunk2

A native 16 by 16 grid of static atlas tiles.

Tintstruct#

struct Tint
    r: number
    g: number
    b: number
    a: number
end
@derive(nupp.derive.Debug, nupp.derive.Serde)

A four-channel color stored on a renderable entity.

Fields

r#
r: number

Caller-writable. Sets the red channel from zero to one.

g#
g: number

Caller-writable. Sets the green channel from zero to one.

b#
b: number

Caller-writable. Sets the blue channel from zero to one.

a#
a: number

Caller-writable. Sets opacity from transparent at zero to opaque at one.

Viewtype#

type View = View2

Describes an ordered viewport with its own camera. Explicit views replace the synthesized full-frame camera; coordinates are fractions of the frame.

Values#

ActiveCameravariable#

const ActiveCamera: components.Component

Selects the camera entity extraction projects the scene through.

Extraction reads the lowest live entity carrying both Camera2D and this tag. A world with no such entity draws through a camera centered on the render target at zoom one, which places world unit and target pixel on top of each other with the origin at the top left corner.

Animationvariable#

Constructs playback state directly. Prefer tecs.gfx.animation.of, which resolves a sheet and a tag name for you.

AnimationEventsvariable#

Requests tecs.gfx.animation.Completed and tecs.gfx.animation.Looped for one entity.

Bounds3Dvariable#

const Bounds3D: components.FFIComponent<Bounds3D>

Constructs the Bounds3D component for a 3D primitive.

Camera2Dvariable#

const Camera2D: components.FFIComponent<Camera2D>

Constructs a camera centered on the world origin at zoom one.

Clipvariable#

Constructs a clip selecting a region set with tecs.gfx.clips.setRegion.

DirtyTileChunkvariable#

Requests synchronization after a nested tile-array edit.

DropShadow2Dvariable#

const DropShadow2D: components.FFIComponent<DropShadow2D>

Constructs a drop-shadow caster at full height.

LIGHT_CASTS_SHADOWSvariable#

const LIGHT_CASTS_SHADOWS: integer

Requests a slot in the local-light shadow atlas.

Materialvariable#

const Material: components.FFIComponent<Material>

Constructs a material selection, defaulting to textured at parameter one quarter.

Meshvariable#

const Mesh: components.FFIComponent<Mesh>

Constructs the Mesh component for a 3D primitive.

MeshMaterialvariable#

const MeshMaterial: components.FFIComponent<MeshMaterial>

Constructs the MeshMaterial component for a 3D primitive.

MeshMorphvariable#

const MeshMorph: components.TableComponent<MeshMorph>

Constructs the MeshMorph component for a 3D primitive.

MeshSkinvariable#

const MeshSkin: components.TableComponent<MeshSkin>

Constructs the MeshSkin component for a 3D primitive.

Occluder2Dvariable#

const Occluder2D: components.FFIComponent<Occluder2D>

Constructs an occluder at full height.

Pivotvariable#

const Pivot

Anchors a sprite at normalized X/Y coordinates or an authored sheet slice. Use Sheet:pivot to keep animated slice anchors synchronized with the GPU frames.

PointLight2Dvariable#

const PointLight2D: components.FFIComponent<PointLight2D>

Constructs a light at height sixty-four, reaching two hundred and fifty-six world units, in white at full strength.

PointLight3Dvariable#

const PointLight3D: components.FFIComponent<PointLight3D>

Constructs a point light with radius, linear RGB, intensity and LIGHT_* flags.

Renderable2Dvariable#

const Renderable2D: components.Component

Marks an entity as contributing geometry to the two-dimensional scene.

Renderable3Dvariable#

Marks geometry for the 3D renderer.

SpotLight3Dvariable#

const SpotLight3D: components.FFIComponent<SpotLight3D>

Constructs a spot light with radius, inner and outer half-angles in radians, linear RGB, intensity and LIGHT_* flags.

Spritevariable#

const Sprite: components.FFIComponent<Sprite>

Constructs a sprite whose omitted UV rectangle covers the whole image.

Textvariable#

Constructs a text whose omitted fields default to an empty left-aligned string at em size sixteen with no wrapping.

TextGlyphvariable#

const TextGlyph: components.Component

Marks an entity as one glyph tecs.gfx.text placed for a Text.

TILE_CHUNK_SIZEvariable#

const TILE_CHUNK_SIZE: integer

The number of cells along a tile chunk edge.

TileChunkvariable#

const TileChunk: components.FFIComponent<TileChunk>

Constructs a tile chunk positioned by its top-left Transform2D.

Tintvariable#

const Tint: components.FFIComponent<Tint>

Constructs a tint whose omitted channels default to one.

Viewvariable#

const View: components.TableComponent<View>

Constructs a viewport from a camera and optional rectangle, order and enabled fields.