Log inGet started
World

Fruit Fly

Branchmain
Branchesmain
Commit83f1b94a81

README.md

FruitFly

An embodied fly driven by a FruitFlyBrain. Every frame it writes the world into the network's sensory neurons and reads a motor command out of named motor and descending cell types.

Which side of the body a sense or a command belongs to is the dataset's answer, not this component's. MaleCNS v1.0 labels a side on the looming detectors and on the leg motor neurons, and labels the tarsal and labellar taste neurons "unknown", so looming is driven per eye and taste is not.

sensecell typesdriven by
tarsal tasteclaw_tpGRN, dorsal_tpGRN (60, side unknown)either front foot on a FoodPatch
labellar tasteLB* (165, side unknown)the extended proboscis on a FoodPatch
looming, left eyeLPLC2 side L (94), LC4 side L (71)anything growing in the left eye's field, the arena wall included
looming, right eyeLPLC2 side R (91), LC4 side R (55)the same for the right eye

The two looming classes are separate drives, so silencing LPLC2 leaves LC4 driven and the ablation has an answer.

commandcell types
walkleg motor neurons (vnc_motor types ending in MN), left 189 and right 185, averaged
turnDNa01 + DNa02 left minus right, plus the leg motor neurons right minus left
proboscisMN9
flightDLMn + DVMn wing power-muscle motor neurons
jumpa DNp01 burst above escapeHz

Beating wings lift the fly only once it is already off the ground: on six legs the beat is a beat, and the legs keep walking underneath it.

The arena

arenaRadius is a circle around the world origin the fly cannot leave. Inside arenaMargin of it the wall is read by each eye as something looming, so the fly meets the wall with the circuits it already has; the body is clamped at the radius as well, so whatever the circuits do the fly is still in the arena.

The wall is only a stimulus while the fly is carrying itself into it, and the detectors adapt to it over WALL_ADAPT_S and recover over WALL_RECOVER_S. A fly walking at the edge gets the burst that turns it; a fly resting against the edge is looking at something that has stopped arriving, and drives nothing. That matters beyond the fly: a standing drive on 165 looming neurons puts the whole network into a spreading state, and every reading anyone takes in this world is taken from that network.

escapeHz is a RISE, not a level. The reading is how far DNp01 has gone above the rate it has been holding, averaged over ESCAPE_BASELINE_S. The network's own recurrence holds the giant fibre at a standing rate with nothing looming at all, and a threshold on the absolute rate reads that as a permanent emergency and hops the fly for ever.

Fields: brain, bodyLength, walkSpeed, turnRate, legTurnGain, motorFullHz, flightFullHz, tasteHz, loomHz, loomFov, escapeHz, arenaRadius, arenaMargin, groundY, wander, wanderTurn.

wander and wanderTurn are the walking and the turning this fly does that its connectome is not asking for, and motor() reports both apart from brainWalk and turn, which are the network's. Set them to zero for a fly that does only what the wiring says; leave them and a quiet network leaves a fly that explores its arena instead of walking one straight line to the edge. Methods: motor(), senses(), readouts(), sensoryNeurons(), drives(), soundVolumes(). Events: onJump, onFeed (once per meal).

local fly = entity.spawn("Fly")
fly.component.add("FruitFly", { brain = entity.find("Brain"), bodyLength = 0.6, wander = 0.15, arenaRadius = 12 })

motor() reports brainWalk (the leg-motor term alone) and wander (the baseline added to it) beside speed. senses() reports sugarFootL and sugarFootR per front foot, loomLPLC2 and loomLC4 in Hz, loomSide (-1 the left eye to +1 the right) and wall (0 to 1).

The fly's own drives are filed under the source fly, so clearing them leaves the bench's and a protocol's standing.

On a shared world the entity's owner writes the senses into the brain (a synced call); every peer poses its own copy from its own network.