flatland_sim (faber_tweann v2.4.0)

View Source

Flatland: a minimal 2D artificial-life world engine (pure, process-free).

The instrument for the Flatland / ALife convergence front (faber-ecosystem PLAN_FLATLAND.md, exp058). A toroidal WxW grid holding plants (food cells) and avatars (evolved networks). This module is PURE physics -- sensing, movement, distance, nearest-object -- with no episode loop, no energy accounting and no randomness; the caller (the exp058 runner, later a scape adapter) owns those.

Held IDENTICAL to the 057 pursuit-evasion grid on purpose (DESIGN gate, 2026-07-23): same 9x9 torus, same 4-way argmax movement, same shortest-wrap RELATIVE-POSITION sensing modality (NOT DXNN2 range/ray sensors -- deferred as a confound). The ONLY thing Flatland adds over 057 is the energy economy (plants + eating + death), which lives in the caller. So a later coupling difference is attributable to the ecology, not the sensing.

Sensor vector (5 floats), same modality for every avatar: [OppDX, OppDY, PlantDX, PlantDY, EnergyFrac] where Opp* is the shortest-wrap signed delta to the opponent (0 if none), Plant* the delta to the nearest plant (0 if none), each normalised by W div 2, and EnergyFrac = Energy / E0.

Move codes: 0=North (y-1), 1=East (x+1), 2=South (y+1), 3=West (x-1).

Summary

Types

pos/0

-type pos() :: {integer(), integer()}.

Functions

away(_, _, W)

-spec away(pos(), pos(), pos_integer()) -> 0..3.

cheb(_, _, W)

-spec cheb(pos(), pos(), pos_integer()) -> non_neg_integer().

move(_, _, W)

-spec move(pos(), 0..3, pos_integer()) -> pos().

nearest(Pos, Cells, W)

-spec nearest(pos(), [pos()], pos_integer()) -> pos() | none.

sense(W, Self, Opp, Plants, Energy, E0)

-spec sense(pos_integer(), pos(), pos() | none, [pos()], number(), number()) -> [float()].

tdelta(A, B, W)

-spec tdelta(integer(), integer(), pos_integer()) -> integer().

toward(_, _, W)

-spec toward(pos(), pos(), pos_integer()) -> 0..3.

wrap(X, W)

-spec wrap(integer(), pos_integer()) -> integer().