# mesh

> Talos next · Since 0.6; changed in 0.7

Use it in a scene entity's `components` list as `{ "type": "mesh", … }`. The contract writes the fields flat and refuses unknown keys.

## Fields

| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
| `asset` | `string` | yes |  |  | A key of scene.assets whose kind is "glb": a model file, or a built-in mesh — builtin:cube, builtin:sphere, builtin:capsule, builtin:plane, builtin:cylinder, builtin:cone (see AssetRef.path for their sizes). |
| `material` | `string` | no |  |  |  |
| `materials` | `object` | no |  |  | Per-submesh material override: a glTF material NAME (the glb's `materials[].name`) to a key of scene.assets whose kind is "material" (the same rule as `material`). Every submesh drawn with a material of that name wears the given one; the others keep their own, or `material` when that is set (an entry here wins over `material`). A name the model has no material of draws nothing different and logs mesh-material-name-unknown, naming the available names. A glTF material with no name cannot be matched. |
| `color` | `string` | no |  |  |  |
| `castShadow` | `boolean` | no |  |  |  |
| `receiveShadow` | `boolean` | no |  |  |  |
| `colliderMode` | `ColliderMode` | no |  | `simple`, `full`, `none` | How this mesh collides: "simple", "full" or "none" (see ColliderMode). An entity with a mesh and no `collider` collides as its mesh, a static body built once at load, when nothing moves it: no `rigidbody`, `controller`, `vehicle`, `wheel`, `navagent`, `animator` or `script` on it or any parent, no `goal`, `spawn`, `trigger` or `water` on it, and not spawned by a behaviour. A `collider` component on the entity replaces it. Unset: the asset's `colliderMode`, else the scene's `meta.physics.colliderMode`, else "simple" for a generated plant and "full" for anything else. |
| `collide` | `boolean` | no |  |  | Deprecated: the earlier spelling of `colliderMode`. Still read, so no scene needs migrating: false is "none" and true is "full". When both are present and disagree, `colliderMode` wins and the contract reports mesh-collide-conflict. |

## Rules that can refuse it

- `animator-root-motion-hips`
- `component-not-writable`
- `instanced-mesh-candidate`
- `material-height-from-mixed`
- `mesh-collide-conflict`
- `mesh-material-name-unknown`
- `plant-bake-missing`
- `plant-too-heavy`
- `render.hd.black_frame`
- `render.hd.rt-proxy-invalid`
- `render.hd.rt_mesh_proxied`
- `render.hd.rt_mesh_too_large`
- `render.hd.vg_resident_full`
- `render.shader.vg-skipped`
- `render.standard.layer-mask-from-ignored`
- `scene-over-triangle-budget`
- `script-call-inapplicable`
- `ui.model-view.unresolved.tentative`

## Example

From the contract's tested fixture `fixtures/contract/full20/scene.json#ramp`.

```json
{
  "type": "mesh",
  "asset": "ramp"
}
```
