FOnline Engine
Current 2026.1.118-dev GitHub
Documentation Docs/en/reference/image-format/fofrm.md

FOFRM Descriptor Reference

Generated reference. Do not edit directly. Update BuildTools/ImageFormatInterface.json, then run python BuildTools/docs_image_format.py --write.

Index Formats FOFRM Options Baking Runtime Validation Canonical JSON Guide

FOFRM is the authored composition layer for static images, animations, direction sheets, and imported legacy sources. References are relative to the descriptor directory.

Stable ID Field/rule Requirement Why Source
image-format.field.fps Fps Root-only positive uint32 Fps replaces timeline defaults; total milliseconds is floor(1000*final_count/Fps) and must provide at least one millisecond per frame. Frame/Frames default to 10 fps; Source preserves imported per-frame timing when no explicit timeline applies. Fps zero and same-section Duration/FrameDurations conflicts fail. Positive uniform boundaries are computed after final frame selection; runtime uses the resulting per-frame durations. Source/Tools/ImageBaker-Fofrm.cpp
image-format.field.count Derived reference count Count is not an authored key. Each direction derives 1..65535 final frames after grid, flattening and FrameIndices; directions may differ. Source counts as one input reference for transform arrays. Each referenced source can itself contain multiple frames. Source/Tools/ImageBaker-Fofrm.cpp, Source/Tools/ImageRecipe.cpp
image-format.field.sequence-offset Offset Offset requires exactly two signed integers; omitted pairs carry forward from root or the previous parsed direction. Invalid pairs and out-of-range values fail. The parser reuses the current offset pair between directions. Source/Tools/ImageBaker-Fofrm.cpp
image-format.field.effect Effect Effect is removed and rejected before source resolution, even when empty or pointing to an absent effect. Select render effects at the GUI/map/model/script consumer; the baker does not serialize resource effects. Refusal uses FO_TEMPORARY_COMPAT(FofrmRetiredEffect, “2026-12-31”). A recognized key must have observable semantics or fail explicitly; no dormant EffectName remains. Source/Tools/ImageRecipe.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.direction-section HexDir / SquareDir The unnamed root always supplies direction 0. Use HexDir 1..5 or SquareDir 1..7 with canonical decimal indexes, never degrees. Named zero and obsolete Dir forms fail before Source. An absent second sequence without an indexed section means one direction; a section without frames fails. SpriteSheet accepts exactly one direction or GameSettings::MAP_DIR_COUNT directions. Source/Tools/ImageBaker-Fofrm.cpp, Source/Tools/ImageRecipe.cpp, Source/Client/DefaultSprites.cpp, Source/Tests/Test_ImageBaker.cpp
image-format.field.frame-reference Frame / Frames Use only Frame or Frames. Frame is one whole relative path; Frames is a nonempty ordered AnyData String array. Quote paths with spaces; author one reference per continued line and retain repeats. References are joined with the descriptor directory and then dispatched by the referenced extension. Source/Tools/ImageRecipe.cpp, Source/Tools/ImageBaker-Fofrm.cpp
image-format.field.frame-offsets FrameOffsets Optional FrameOffsets requires exactly one signed int32 X Y pair per Frame/Frames reference before flattening, in the same section. AnyData String-array tokens are parsed as strict integer pairs. Each pair adds draw placement to every flattened child frame, plus Offset and child frame placement, without accumulation or changes to imported Motion root-motion deltas. Present empty, malformed, out-of-range or wrong-count lists and lists without references fail. Source uses one reference, including named overrides. Draw placement has a distinct authored key and storage from imported root-motion deltas; omitted pairs are zero and do not carry between directions. Source/Tools/ImageBaker-Fofrm.cpp, Source/Tools/ImageImport.h, Source/Tools/ImageBaker.cpp, Source/Tests/Test_ImageBaker.cpp
image-format.field.size Size Size requires exactly two strict AnyData String-array integer tokens in 1..65535 and sets exact pixel canvas dimensions for every reference. The root value defaults all directions; named Size is local with no carry. Size and FrameSizes in one section fail. Physical resampling is separate from draw placement and runtime scale. Source/Tools/ImageBaker-Fofrm.cpp, Source/Tests/Test_ImageBaker.cpp
image-format.field.frame-sizes FrameSizes FrameSizes is an AnyData String-array of strict integer pairs in 1..65535, one per local Frame/Frames reference before flattening. Each pair sizes every child frame; it is not inherited and overrides inherited root Size. Empty, malformed, wrong-count or reference-free lists fail, including unused sections. Source uses one reference, including named overrides. List cardinality follows references, not flattened animation frames. Source/Tools/ImageBaker-Fofrm.cpp, Source/Tests/Test_ImageBaker.cpp
image-format.field.flattening Nested sequence flattening Frame/Frames append the selected Main sequence by default, or InputDir, preserving child frame placement and motion while discarding child sequence placement and other directions. Crop/grid/transforms run per reference before flattening; FrameIndices selects the final sequence. Source retains complete collections and per-frame durations. Final frame count and duration are independent per direction. Each final direction owns its frame table and timeline; child sequence anchors are excluded only during Frame/Frames composition. Source/Tools/ImageBaker-Fofrm.cpp
image-format.field.timing FOFRM whole-sequence timing Frames use positive timespan Duration. Files require whole uint32 ms per frame and direction. Frame/Frames default to 100 ms per final frame; Source inherits selected frame durations, including repeats/grid. Local FrameDurations or Duration replaces root Duration/Fps defaults. Root FrameDurations belongs only to direction0. Uniform boundaries floor(i*Duration/count) preserve the total without zero-length frames. Wrapping a collection does not lose timing; flattening animated references keeps the requested default cadence. Source/Tools/ImageBaker-Fofrm.cpp, Source/Tools/ImageImport.cpp
image-format.field.source Whole collection Source Root Source forwards the complete binary or FOFRM collection, preserving directions, sequence/frame offsets, movement and timing. Source and Frame/Frames are mutually exclusive. Root transforms default all existing directions; named sections may override transforms without repeating references. Authored Offset adds to the inherited sequence anchor. Explicit root Fps replaces inherited timing. Alias is rejected with a dated refusal. Whole-collection inheritance and selected Main-sequence composition have explicit, separate placement and timing rules. Source/Tools/ImageBaker-Fofrm.cpp, Source/Tools/ImageRecipe.cpp
image-format.field.input-dir InputDir Select an existing input direction before pixels are transformed. For Source, an explicit root InputDir selects a single sequence and preserves its anchor. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.frame-input-dirs FrameInputDirs One input-direction index per reference, before flattening. Mutually exclusive with InputDir in the same section. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.frame-indices FrameIndices Nonempty AnyData integer list after grid and flattening; permits reordering and repeats, rejects out-of-range indices. Source root defaults every direction; a local list overrides it. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.crop Crop Crop every input frame before grid: nonnegative origin, positive size, wholly inside its source. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.frame-crops FrameCrops One crop rectangle per reference before flattening; replaces inherited Crop, mutually exclusive with local Crop. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.grid Grid Slice every cropped input frame left-to-right then top-to-bottom. Positive cell dimensions must divide the image exactly; no silent remainder clipping. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.flip Flip Reflect each grid cell before rotation; literal placement and movement vectors do not change. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.frame-flips FrameFlips One flip token per source reference before grid/flattening; mutually exclusive with local Flip. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.rotate Rotate Rotate clockwise after flip and before resize. Quarter turns exchange image axes, not placement or motion axes. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.frame-rotations FrameRotations One clockwise rotation per source reference; mutually exclusive with local Rotate. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.canvas Canvas After resize, place the image onto an exact transparent uint16-sized canvas. The image must fit completely; use Crop to remove pixels. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.frame-canvases FrameCanvases One canvas pair per source reference; mutually exclusive with local Canvas. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.canvas-offset CanvasOffset Nonnegative top-left position within Canvas. Requires an effective Canvas and rejects any clipping. Does not alter Offset. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.frame-canvas-offsets FrameCanvasOffsets One canvas-placement pair per source reference; mutually exclusive with local CanvasOffset. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.move Motion Explicit signed int16 pair replaces Motion on every expanded frame; absence preserves imported motion. Independent of Offset/FrameOffsets and bitmap transforms. Legacy Move/FrameMoves keys are refused before Source resolution with FofrmLegacyMotionKeys temporary compatibility marker. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp, Source/Tools/ImageRecipe.cpp
image-format.field.frame-moves FrameMotions One signed int16 motion pair per reference, before flattening. Mutually exclusive with local Motion; never accumulated as placement. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.resample Resample Nearest copies source channel values. Bilinear uses Q16 pixel centers. Area uses exact rational pixel coverage for downsampling or identity only; upsampling fails. Identity preserves bytes. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.pixel-usage PixelUsage Color filters premultiplied alpha. Data filters four independent channels. Normal filters signed RGB vectors, normalizes using integer square root, falls back to +Z for zero, and filters alpha independently. Nearest and identity preserve bytes. ColorSpace is forbidden for Data/Normal. Data/Normal preserve all channels through baking: alpha mesh/cropping is disabled, including shared pixel owners. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.color-space ColorSpace Color-only filtering. Linear decodes through the fixed sRGB linear16 table before premultiplied-alpha interpolation, then encodes to the nearest table entry (ties upward). Encoded retains existing Q16 bytes. Transform order and source-reference cardinality are explicit. Source/Tools/ImageTransforms.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.duration Duration Positive uint32 whole-sequence milliseconds; at least one per final frame. Uniform floor boundaries preserve the total. Root Duration defaults directions; local Duration/FrameDurations overrides it. Same-section Fps/FrameDurations conflicts fail. Timeline cardinality follows the final logical sequence. Source/Tools/ImageBaker-Fofrm.cpp, Source/Tests/Test_ImageTransforms.cpp
image-format.field.frame-durations FrameDurations AnyData positive uint32 durations, exactly one per final frame after selection; sum fits uint32. Local list only, not per reference and not inherited. Mutually exclusive with same-section Duration/Fps. Timeline cardinality follows the final logical sequence. Source/Tools/ImageBaker-Fofrm.cpp, Source/Tests/Test_ImageTransforms.cpp
Start typing to search.