Skip to content

Syntax overview

This page explains which elements a .mochi.xml is made of, what each becomes in Unity, and in what order they are expanded. The rules for each element are in Element reference, and how to write attribute values is in Value grammar.

FormatWell-formed XML. Case-sensitive
Root elementOne per file, named the same as the file name without .mochi.xml (MOCHI1003)
Comments, XML declaration, processing instructionsAllowed. Skipped when read
Whitespace and line breaks between elementsSkipped when read
Line breaks and tabs inside attribute valuesReplaced with spaces by the XML rules before the value is read
SyntaxHandlingNumber
Text inside an element (<Object>Hall</Object>, CDATA)Not allowed. Values go in attributesMOCHI1006
Writing a value as a child element (a <Transform> element)Not allowed. Position, rotation, and scale are host attributesMOCHI1004
Namespaces (xmlns, prefixes)Not allowedMOCHI1007
DOCTYPENot allowedMOCHI1001

Elements fall into the following 6 categories, by what they create in Unity.

CategoryMeaningElements
Root elementThe top-level element of a file. Its name is the part’s name; in an entry point, it becomes the prefab’s root GameObjectA tag named after the part
HostAn element that creates one GameObject. Accepts common attributes such as name and position<Object>, <Row>, <Grid>, <Prefab>, part tags
Component tagAn element that adds a component to its parent GameObject. Its name is the Unity component’s type name<MeshRenderer>, <Light>, and so on
ControlAn element that expands its content once per data row, or only when a condition is true. It creates nothing itself<For>・<If>
DeclarationAn element that declares the props a part receives. It creates nothing<Props>・<Prop>
InsertionAn element that marks where content goes. <Slot> receives content written by the caller, and <At> points to a GameObject inside a prefab. It creates nothing itself<Slot>・<At>

Only 6 kinds of tags create GameObjects: the root element and the hosts.

TagWhat it createsName when name is omitted
Root element (<Hall prefab="true"> and so on)When generated as an entry point, the prefab’s root GameObjectThe part’s name (name can’t be written)
<Object>One GameObjectGameObject
<Row>One GameObject (arranges its children along +X)Row
<Grid>One GameObject (arranges its children in a grid)Grid
<Prefab>One instance of the prefabThe name of the prefab’s root GameObject
Part tag (<Plaque/> and so on)One GameObject. The contents of the part’s file become its childrenThe part’s name
Component tagNone. It becomes a component of the parent GameObjectNone
<For>・<If>None. The hosts in its content become children of the parent of <For> or <If>None
<Slot>None. The hosts in the content written by the caller become children of the parent of <Slot>None
<At>None. Its child hosts become children of the GameObject it points to inside the prefabNone
<Props>・<Prop>NoneNone

Generating the following example gives the prefab the hierarchy in the figure below.

Assets/Hall/Hall.mochi.xml
<Hall prefab="true">
<Object name="Floor">
<MeshFilter mesh="builtin:Plane"/>
<MeshRenderer/>
</Object>
<Row spacing="0.5" position="0 1.5 4">
<For each="art" in="folder('../Gallery/art/')">
<Plaque title="{art.title}"/>
</For>
</Row>
<Prefab src="../Kit/KitFrame.prefab" position="3 0 0"/>
</Hall>
<!-- file: Assets/Hall/Plaque.mochi.xml -->
<Plaque>
<Props>
<Prop name="title" type="string"/>
</Props>
<Object name="{title}" size="1 0.5 0.1"/>
</Plaque>
Hall ← root element (the prefab's root)
├─ Floor ← <Object name="Floor">, with MeshFilter and MeshRenderer
├─ Row ← <Row>, named Row because name is omitted
│ ├─ Plaque ← <Plaque> (row 1 of <For>, 01_Sea.png)
│ │ └─ Sea ← <Object name="{title}"> in Plaque.mochi.xml
│ └─ Plaque ← <Plaque> (row 2 of <For>, 02_Moon.png)
│ └─ Moon
└─ KitFrame ← <Prefab>, named after the prefab's root
├─ Canvas ← from here down, the contents of KitFrame.prefab
├─ Plate
│ └─ Label
└─ Mount
Assets/Hall/Hall.mochi.xml
<Hall prefab="true">
<Plaque name="Entrance" title="Welcome"/>
<Plaque name="Exit" title="Goodbye" offset="0 2 0" position="6 0 0"/>
</Hall>
<!-- file: Assets/Hall/Plaque.mochi.xml -->
<Plaque>
<Props>
<Prop name="title" type="string"/>
<Prop name="offset" type="Vector3" default="0 1.5 0"/>
</Props>
<Object name="{title}" position="{offset}"/>
</Plaque>
PartOne .mochi.xml file. The file name without .mochi.xml is the part’s name, and the root element has the same name
Using a partWrite the part’s name as a tag. One GameObject is created where it’s used, and the contents of the part’s file (except <Props>) become its children
propsThe part’s arguments. The part declares names, types, and default values with <Prop> in <Props>, and the caller passes values by writing prop names as attributes on the part tag
Rules for passing propsAs with function arguments, an undeclared name can’t be passed (MOCHI3005), and a prop without default can’t be left out (MOCHI3008). Common host attributes (name, position, and so on) aren’t props; they become attributes of the GameObject where the part is used
Entry pointsA part whose root element has prefab="true". Saving generates one prefab from this file. It can also be used as a part from other files
An entry point’s propsThere’s no caller to pass values, so every prop needs a default
Where values are writtenOnly in attributes. There’s no way to write a value as text inside an element or as a child element
TypesFixed per attribute (position is a Vector3, active is a bool, and so on). The written text is read as a value of that type
BindingWriting the whole value as {name} or {row.column} reads the value of a prop or a <For> row. It can’t appear partway through text
Common host attributes14 attributes such as name, key, and position. A GameObject with a RectTransform gives its position and size with the RectTransform attributes (GameObjects with a RectTransform)
Element-specific attributes<Prefab src>, <For each>, <Row spacing>, and so on
Attributes of a part tagThe common host attributes and the props that part declares
Attributes of a component tagThe C# property names of the Unity component (<Light intensity="2"/>)
The slot attributeWritten on a child of a part tag to choose which <Slot> that child goes to

Values fixed at generation time and values that change at runtime

Section titled “Values fixed at generation time and values that change at runtime”
Value fixed at generation timeA value fixed when you save in Unity and the prefab is generated, and written into the prefab. Constants, props without runtime, and <For> rows are all of this kind
<For> and <If>Expanded at generation time. The number of rows and the conditions don’t change while the world runs
Value that changes at runtimeA value bound, inside a part with a T# script, to a prop with runtime="true" or to a C# member of that part
Where a value that changes at runtime can be writtenOnly active and props with runtime="true". Other attributes give MOCHI5004, and <If test> gives MOCHI5003 (Value that changes at runtime)
StageDescription
1. Part catalogRegisters each .mochi.xml under Assets/ and Packages/ as a part, by file name. A file’s contents are read when its tag is used
2. Reading the entry pointReads it as XML and checks the root element’s name, the prefab attribute, and <Props>. Props get their default values
3. ExpansionExpands the root element’s children in the order written. A host reads its attribute values, creates its GameObject, and then expands its children
3a. Part tagsReads the prop values on the caller’s side, then expands the contents of the part’s file as children of the GameObject where it’s used
3b. <For>・<If><For> expands its content once per data row, and <If> only when test is true, in place
4. Arranging<Row> and <Grid> decide their children’s positions after all children are expanded
5. WritingOnly when there are no errors at all, the prefab and the material copies are written (Generation on save)

The names a {name} binding can read depend on where it’s written, in the following 7 ways.

Where it’s writtenNames that can be read
Inside a part’s fileThe props declared in that file’s <Props> and the rows of the <For> elements enclosing the attribute (in the same file)
The caller’s props and rows, seen from inside a partCan’t be read. To use them inside a part, pass them as props
Content the caller writes as children of a part tagThe props and rows of the file where the content is written. The part’s props can’t be read
Nested <For>The inner one can also read the outer rows. A row with the same name as an outer row hides it
A row with the same name as a propInside that <For>, the row takes precedence
<Prop default>Can’t read names (a binding gives MOCHI5001)
Body of a part with a T# scriptA name that is neither a prop nor a row is read as a C# member of that part (a value that changes at runtime)