---
title: "data (asset type)"
description: "A .data instance is a configured value binding to a dataType contract: values.yaml names the contract and supplies the field values the contract's schema declares. Instances carry values only —…"
section: "Types"
slug: "types-data"
canonical: "https://origozero.ai/docs/types-data"
updated: "2026-07-31T07:12:26.536672211+00:00"
tags: ["asset-type", "reference"]
---

# data (asset type)

## When to use one

- You have a `dataType` contract (e.g. `weapon`, `questObjective`) and
  need one or more concrete, named configurations of it (`smg`,
  `rifle`, `sniper`).
- You want the configuration to persist as authored content, discovered
  by `asset.list("data")` / `contractType:instances()`, and validated
  against the contract on every edit.
- Mutable *runtime* state (ammo remaining, cooldown timers) belongs on
  a component, not here — a `.data` instance is configuration, not
  simulation state.

If you don't have a contract yet, author one first
(`asset.create("dataType", ...)`).

## Where it lives

- Source: `/zero/source/.../<Name>.data/`
- Identity: `<Name>` (the `.data` suffix strips).
- Folder shape:
  - `values.yaml` — `contract: <dataTypeName>` plus a `values:` map of
    the contract's fields. **Required.**
  - `README.md` — instance documentation: what this configuration is
    for and where it's used. **Required.**
  - `.metadata` — description + tags for search. **Required.**

Play-mode edits fork a runtime copy (`runtime_copy: true`) — tweaking
values while gameplay runs never writes back to the source instance.

## How to create one

```luau
asset.create("data", "<Name>", { contract = "<dataTypeName>" })
-- Creates: /zero/source/<Name>.data/
--   values.yaml   (contract binding + the contract's declared defaults)
--   README.md     (instance README template)
--   .metadata     (empty description/tags — fill both to publish)
```

`opts.contract` is required — creating without it, or naming a
contract that isn't a registered `dataType`, errors loudly and names
`contract` in the message. The seeded `values.yaml` fills every field
the contract declares a default for, so a fresh instance is immediately
valid wherever every required field has a default.

## Ref surface (`AssetRef<data>`)

- `ref:contract()` — the bound `AssetRef<dataType>`.
- `ref:satisfies(wanted)` — `(ok, reason?)`: whether this instance's
  contract chain includes `wanted` (the bound contract itself, or any
  contract it extends). `reason` is a string explaining a `false`
  result (unrelated contract, unresolvable binding, invalid values).
- `ref:validate()` — `(ok, violations)` against the bound contract's
  merged schema. `violations` is an array of `{ path, message }`.
- `ref:data(wanted?)` — the resolved, read-only value object: this
  instance's `values.yaml` with the bound contract's schema defaults
  filled in, `assetRef` / `dataRef` fields materialized (`assetRef` →
  `AssetRef`, `dataRef` → a nested value object resolved the same way),
  and the bound contract chain's `behavior.luau` methods reachable by
  field-style call — `v:someMethod()` alongside `v.someField`. Method
  resolution is **child-first**: the bound contract's own methods win
  over an inherited one of the same name, and either loses to an
  explicit instance value of that name (values always shadow methods).
  A contract with no `behavior.luau` simply contributes no methods —
  it still inherits its ancestors' via the chain.

  Pass `wanted` to assert the instance's bound contract satisfies that
  contract before resolving (same semantics as `:satisfies`) — it's an
  assertion of intent, not a filter: the returned object still carries
  the full bound schema and full method chain, not a view scoped to
  `wanted`.

  Raises when the instance's values violate its contract (same
  violations `:validate()` reports), when `wanted` doesn't appear
  in the bound contract's chain, and when `dataRef` fields form a
  circular chain (instance A referencing B referencing A).

  The object is read-only at the top level — assigning a field raises;
  change configuration by editing `values.yaml` instead. Nested plain
  tables (struct and array values) are private copies of the resolved
  snapshot: mutating them changes only your snapshot, never the source
  instance or any other caller's resolve.

  Generalized iteration (`for k, v in w do`) walks the resolved value
  fields (explicit values + filled defaults); methods are reachable by
  name but never appear in iteration.

  ```luau
  local w = smg:data()             -- resolved value object
  print(w.damage, w.fireMode)      -- schema values (with defaults)
  print(w:dps())                   -- a behavior.luau method, if the contract ships one

  local weapon = smg:data("weapon") -- asserts smg's contract chain includes "weapon"
  ```

## Discovery

- `asset.list("data")` — every registered instance, as `AssetRef`s.
- `<contractRef>:instances()` — every `.data` instance bound to that
  contract or to a contract that extends it (see `dataType`'s ref
  surface).
- `asset.inspect("<name>")` — the instance's files, bound contract,
  values, and this type README.
- `cat /zero/source/<Name>.data` — same summary.

## Authoring conventions

- Name instances for the specific thing they configure (`smg`,
  `rifle`), not for the contract they bind (that's `values.yaml::contract`).
- Keep `values.yaml` limited to configuration; anything that changes
  during gameplay belongs on a component instead.
- Document what this specific configuration is tuned for in
  `README.md` — the contract's own README documents field meaning.

## Common pitfalls

- **Missing or unknown contract at creation.** `opts.contract` must
  name an existing `dataType`; both a missing `opts` and an unknown
  contract name error before any file is written.
- **Values drifting from the contract.** Editing `values.yaml` re-runs
  validation immediately; a violation warns rather than silently
  passing through.
- **Confusing configuration with runtime state.** A `.data` instance
  never mutates during play — components own live state.

## Related types

- `.dataType` — the contract this instance is bound to; owns
  structure, validation, and (optional) behavior.
- `.preset` — a snapshot of one component's properties, not a typed
  multi-field contract.
