Page 6 · Recognition & Perception

Teach DAI What It Is Looking At

Targeting answers “which block/entity is selected?” Recognition answers a deeper question: “does this collection of blocks satisfy the structure or material pattern my datapack cares about?”

GroupsReusable sets of block identifiers.
Recognition DefinitionsScan rules, group counts, structural requirements, and result IDs.
PerceptionRecognition results can feed actions, conditions, and Available menus.

Recognition Files

ContentDirectoryResulting ID
Recognition groupsobjectives/groups/Namespace + relative filename
Recognition definitionsobjectives/recognition/Namespace + relative filename

Recognition Groups

A recognition group is a reusable list of block IDs. Multiple datapacks can contribute to a group unless a definition uses replace: true.

dai_fun_survival:harvest_grass group
{
  "replace": false,
  "entries": [
    "minecraft:short_grass",
    "minecraft:tall_grass"
  ]
}

This example deliberately contains vegetation blocks, not grass blocks such as the dirt-like minecraft:grass_block.

Recognition Definition Shape

typeDefaults to structure.
scanDefines how and how far DAI captures candidate blocks.
groupsNames local groups and connects them to registered recognition groups.
requirementsStructural rules that the captured groups must satisfy.
result.idThe semantic recognition result returned when everything matches.

Scan Parameters

FieldDefaultPurpose
modeconnectedRecognition scan mode.
origintargeted_blockWhere the structural scan begins.
max_blocks512Maximum captured blocks.
max_radius12General scan radius.
horizontal_radius12Horizontal bound for scan modes that use it.
upward_range12Vertical range above the origin.
downward_range4Vertical range below the origin.

Group Rules

Local group rule
"trunk": {
  "registry": "decisions_and_impulses:logs",
  "minimum": 3,
  "maximum": 512
}

registry points to a recognition group ID. minimum defaults to 0; maximum defaults to no practical upper bound.

Registered Structural Requirements

RequirementPurpose
connectedRequires the selected groups to form one face-connected structure.
vertical_columnRequires a contiguous vertical column of at least minimum_height.
touches_groundRequires at least one block in the group to have a full collision block beneath it.
near_upper_regionRequires a minimum ratio of one group to lie near the upper half of another group.
contains_groupChecks the group's captured count against generic minimum/maximum parameters.
dimensionsEvaluates configured structure dimension constraints.
group_ratioEvaluates a configured ratio between group counts.

Example: Tree Recognition

The built-in tree definition illustrates how block groups become semantic structure recognition.

decisions_and_impulses:tree
{
  "type": "structure",
  "scan": {
    "mode": "connected",
    "origin": "targeted_block",
    "max_blocks": 512,
    "max_radius": 12
  },
  "groups": {
    "trunk": {
      "registry": "decisions_and_impulses:logs",
      "minimum": 3
    },
    "foliage": {
      "registry": "decisions_and_impulses:leaves",
      "minimum": 4
    }
  },
  "requirements": [
    {
      "type": "connected",
      "groups": ["trunk", "foliage"]
    },
    {
      "type": "vertical_column",
      "group": "trunk",
      "minimum_height": 3
    },
    {
      "type": "touches_ground",
      "group": "trunk"
    },
    {
      "type": "near_upper_region",
      "group": "foliage",
      "relative_to": "trunk",
      "minimum_ratio": 0.5
    }
  ],
  "result": {
    "id": "decisions_and_impulses:tree"
  }
}
Targeted block
   ↓
Connected structural scan
   ↓
logs → trunk group
leaves → foliage group
   ↓
connected?
vertical trunk?
touches ground?
foliage near upper region?
   ↓
YES
   ↓
decisions_and_impulses:tree

Example: A Third-Party Recognition

DAI Fundamentals — Survival demonstrates that third-party datapacks can define their own recognition groups and results.

dai_fun_survival:harvest_grass
{
  "type": "structure",
  "scan": {
    "mode": "connected",
    "origin": "targeted_block",
    "max_blocks": 512,
    "max_radius": 12
  },
  "groups": {
    "primary": {
      "registry": "dai_fun_survival:harvest_grass",
      "minimum": 1,
      "maximum": 512
    }
  },
  "requirements": [
    {
      "type": "connected",
      "groups": ["primary"]
    }
  ],
  "result": {
    "id": "dai_fun_survival:harvest_grass"
  }
}

Using Recognition From Actions

recognize_target evaluates recognition against the selected target. recognize_block is different: it searches for a matching block/block tag and selects a block target.

Targeting and recognition solve different problems. Use simple block targeting when a block ID/tag is enough. Use recognition when the relationship between multiple blocks matters.

Nearby Recognition as Perception

Condition
{
  "type": "nearby_recognition",
  "parameter": "decisions_and_impulses:tree",
  "number_value": 24.0
}

nearby_recognition is non-mutating: it asks whether a recognition definition/result exists nearby without stealing the active DAI target.

The current perception layer allows menus to query this condition every client tick while expensive structural scans are cached and refreshed every 10 game ticks (normally twice per second). Requested nearby radii are bounded by the runtime.

Available Menu tick
   ↓
nearby_recognition
   ↓
fresh cache? ── YES → return cached result
   │
   NO
   ↓
candidate block/group filtering
   ↓
structural scan + evaluation
   ↓
cache result
   ↓
menu condition

Recognition → Conditions → Menus

Recognition Definition
   ↓
"tree exists nearby"
   ↓
nearby_recognition condition
   ↓
Harvest button becomes eligible
   ↓
Available menu exposes Harvest Wood
   ↓
Objective executes targeting/mining behavior

This is one of DAI's most powerful third-party patterns: semantic world perception can directly determine which gameplay choices are currently exposed.