Skip to content

Spawner clones of traveling move-mode protos: absent from unit queries, lose altitude #53

Description

@dsrw

Bug: spawner clones of traveling move-mode protos misbehave

Observed 2026-06-11 in the nimconf level, while building an alien world
with ~250 units. Enu source referenced in errors: /Users/scott/src/enu.

Summary

Instances created with Proto.new(...) whose script enters move me and
then translates (cruising flyers) exhibit two problems that root units
running the identical script do not:

  1. They never appear in units_near (or any unit query), even though
    they spawn, draw, and animate — verified visually via screenshot.
  2. They lose their spawn altitude and end up resting on the ground
    (observed with a loop: state-machine behavior; a forever: loop
    with an explicit "climb back up" workaround keeps a clone airborne).

Clones that stay put are fine: static protos (trees, tendrils) and
animated-but-stationary protos (a beacon that spins in place via
move me; forever: turn right) appear correctly in units_near
including one floating at a spawned y = 60 — and hold position.

Repro

Proto (scripts/build_flyer.nim):

name Flyer(tint = red)
let lamp = tint
cylinder(size = 5, height = 1, at = vec3(0, 0, 0), color = black)
cylinder(size = 7, height = 1, at = vec3(0, 1, 0), color = white)
sphere(size = 3, at = vec3(0, 2, 0), color = black)
place(3, 1, 0, lamp)

move me
speed = 12
forever:
  turn -40.0 .. 40.0
  forward 10 .. 22

Spawner (different script):

drawing = false
Flyer.new(position = vec3(0, 60, 190), tint = red)

Then:

  • units_near(0, 60, 190, radius = 35) → clone absent (tree clones and
    the spawner unit at the same spot are listed). Same result when the
    clone is spawned via eval from the spawner's module, and same result
    seconds after spawn (not a "wandered away" artifact — tether was 70).
  • A screenshot at (0, 60, 190) shows the craft flying there.
  • The root self-copy of the same proto (json origin y = 85) is always
    listed in units_near at its live, moving position, and holds y = 85
    exactly while cruising.

Altitude-loss detail

The original Flyer used a loop: state machine (cruise/hover/go_home,
patterned on .claude/examples/ufo.nim). After a full level load, all 18
fleet clones sat ON THE GROUND (human observation in-world) while the
proto's root self-copy cruised at its json altitude of y = 85. Because
the clones are invisible to unit queries, their y could not be confirmed
programmatically. A rewritten body (forever: + each iteration:
let sag = start_position.y - position.y; if sag > 2.0: up sag) keeps a
clone visibly airborne — i.e. the sag is continuous and fightable, not a
one-time spawn-at-ground.

Possibly related index gap

Clone voxels are invisible to the voxel queries even for clone types
that DO appear in units_near: floor_at(x, z) returns -1 at tree-clone
positions whose trees are visibly present (e.g. an OrbTree clone whose
trunk demonstrably covers its origin column), while proto self-copies'
voxels are found fine. So:

unit kind in units_near voxels in floor_at holds altitude
root unit (any) yes yes yes
static clone (tree) yes NO n/a
stationary animated clone (beacon) yes (untested) yes (y=60 float)
traveling animated clone (flyer) NO (untested) NO

Speculation: clones aren't registered in the same spatial/unit indexes as
root units, and whatever transform path moving clones use both bypasses
the unit index and re-resolves their vertical position against the
ground.

Workaround used

Traveling units are root units (build_flyer_h1..h5, build_flyer_l1..l5
— one json + script pair each); build_flyer_fleet retired to a no-op.
Works perfectly: queryable, altitude-stable.

Environment

  • One MCP session (enu_mcp), multiple agent bots.
  • Both symptoms present before AND after the 2026-06-11 engine bug-fix
    restart (the absent-from-queries symptom verified on both; grounding
    observed after; pre-restart altitudes unverifiable due to the renderer
    backlog at the time).
  • Unrelated note for the same backlog: eval of units_in_box raised
    unit sign_… not in node_map [AssertionDefect]
    (vmlib/enu/vm_bridge_utils.nim(10,4)) while a sign unit existed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions