model-format.rule.lexical-syntax |
Whitespace tokenization |
Directives and arguments are whitespace-separated; # and ; start comments; there is no quoting or escaping for paths containing spaces. |
The parser strips comments and feeds each line through istringstream token extraction. |
model-format.rule.multiple-directives |
Sequential line parsing |
A line may contain multiple directives; each directive consumes its exact argument count and parsing continues with the next token. |
Compact layer entries are legal, but ordering changes which current link or mesh selector receives later modifiers. |
model-format.rule.selector-order |
Selector ordering |
After Layer or Value, author Root, Attach, or AttachParticles before link modifiers such as transforms, materials, disables, or cuts. |
Layer and Value point at a dummy link and clear Mesh; modifiers written before a real link is created are discarded. |
model-format.rule.template-files |
Template naming |
Name include-only files with a basename beginning TEMPLATE_; concrete files must not use that prefix. |
Template files participate in include timestamps and parsing but ModelInfoBaker does not emit them as independent resources or animation-metadata sections. |
model-format.rule.include-replacements |
Include replacement scope |
Include arguments are name/value pairs replacing every literal %name% occurrence in the included text before tokenization. |
Replacement is plain text and does not understand token boundaries; choose placeholder names that cannot collide accidentally. |
model-format.rule.relative-paths |
Path ownership |
Model, Include, Attach, and Cut paths resolve relative to their declaring .fo3d file; animation files resolve relative to the concrete description unless ModelFile is used; particle and effect paths are global baked-resource paths. |
Moving a template or concrete description can change the asset paths contributed by directives inside that file. |
model-format.rule.zero-identity |
Zero is transform identity |
Treat zero transform and Speed fields as no contribution. The + and * variants initialize a zero field from their operand before applying later operations. |
Runtime SetAnimData skips zero fields, while parser accumulation deliberately makes template-only Scale* and Speed* useful. |
model-format.rule.layer-zero |
Layer zero value is inactive |
A runtime layer value of zero selects no link; authored Root and Attach entries require a non-zero Value. |
The composition loop skips zero layer values and the baker rejects links created with zero. |