One fly, one body and one connectome live on a kitchen table. The fly gets hungry and goes to sugar, walking if the sugar is near and flying if it is far. It lands, eats, gets bored and goes somewhere else. This is not a whole fly made from the connectome. The brain model makes some of the decisions. Trained policies move the body, and stated rules do the rest.
| What happens | What does it | From the connectome? |
|---|---|---|
| Want food, get bored | Two numbers that rise with time. They pick a goal and turn on the input to P9. | No |
| Find the way | A compass toward the goal. The fly knows where everything is. | No |
| Walk or stand | P9 drives oDN1. Past a threshold the fly walks. | The firing, yes. The thresholds are ours. |
| Stop on sugar | Sugar neurons cut oDN1, as Sapkal et al. found [2]. | Yes |
| Reach down to eat | Sugar drives MN9 and other mouth motor neurons, and they move the mouth joints. | The firing, yes. Firing to movement is our rule. |
| Jump from a swatter | Looming neurons drive the giant fiber, DNp01. Past 20 Hz the fly takes off. | The firing, yes. The threshold is ours. |
| Dodge in the air | Looming neurons drive DNp03 on their side. | The side, yes. The saccade comes from recordings. |
| See | A rule from the object's geometry to the input of the looming neurons. The model has no eyes. | No |
| Move the legs and wings | flybody's two trained policies [3]. The motor neurons of legs and wings fire, but do not move them. | No |
| Take off and land | Stated rules between the two policies, below. | No |
| What stands on the table | Pictures. The physics has only the flat tabletop. | No |
Takeoff and landing, with no new policy
flybody's fly walks with one policy and flies with another, and neither was trained to change to the other. We first trained a takeoff policy with PPO on 2,048 flies on a GPU. It failed: after about 10.6 million steps, no fly reached flight, and each episode ended after about 0.11 s. We stopped it.
Then we asked a simpler question: how much can the flight policy recover from without any change? We started a fly in the air, with zero speed, with its thorax at different angles, and asked it to blend into cruise (tools/catch.mjs).
| Thorax at the start | Largest error after it settles |
|---|---|
| 47.5° nose up (as trained) | 0.02 cm |
| 20° nose up | 0.02 cm |
| 10° nose up | 0.02 cm |
| 0° (level, as it stands) | It falls |
So the legs have one job: lift the nose. Before a jump, a real fly sets its posture [4]. Ours reaches with the front legs and crouches on the hind legs for 0.1 s with its wings shut, which gives about 20–28°. Then the flight policy starts the wings, on a path that begins at the fly's own pose, while the middle and hind legs push. If the nose is not up by 12°, the fly does not jump. We found these numbers by random search.
To land, the path falls to 0.8 cm, brakes to a hover with the nose at 35°, waits until the fly is almost still, and sinks. At the first touch of a foot, the wings shut and the walking policy takes over. Stillness matters: a touch at 2.5 cm/s or more often tipped the fly over.
One more thing took some finding. A rotation has two equal descriptions, q and −q, but a policy reads the numbers. When the fly's heading passed 180°, the sign could disagree with the path, and the policy threw the fly on its back. Each handover now makes the signs agree.
The whole cycle, 40 trials, on new random seeds from a walking start (tools/life.mjs):
| Step | Trials that reached it |
|---|---|
| Walked, then launched | 40 |
| Flew | 38 |
| Touched the table | 38 |
| Upright, and walked 2 cm | 37 |
| Took off again | 34 |
This table is not an independent test of every number: we chose the landing settings on a similar test. Real takeoffs and landings do not necessarily look like this. A real fly touches down with its legs first and its wings still beating, and it does not always hover. We did not compare our motion with recordings.
What the one brain does
The page runs one model, on BANC [1], for everything: 162,733 neurons and 42.2 million synapses. Firing in Hz, 3 runs of 3 s each (tools/life_brain.mjs):
| Input | oDN1 | MN9 | Giant fiber | DNp03 left / right |
|---|---|---|---|---|
| P9, 150 Hz | 8.6 | 0 | 0 | 0 / 0 |
| P9 + sugar, 150 Hz | 3.8 | 10.3 | 0 | 0 / 0 |
| Sugar, 150 Hz | 0 | 14.2 | 0 | 0 / 0 |
| Looms, both eyes, 100 Hz | 0 | 0 | 43.6 | 164 / 168 |
| Looms, left eye, 100 Hz | 0 | 0 | 5.3 | 169 / 0 |
We did not fit these connections. The connectome separates walking, stopping, feeding, jumping and turning into different outputs, with the same weights. oDN1 and MN9 are weaker on BANC than on FlyWire, so our thresholds are set for BANC.
Can you swat it?
Usually, yes. A swatter of 3 cm half-width starts 30 cm away and aims at a standing fly. 20 trials per row; if the jump is off, all 120 control trials are hits. A hit is only counted. It does not hurt the fly. (SWATTEST=20 node tools/day.mjs)
| From | Speed | Jumped | Hit |
|---|---|---|---|
| Above | 30 cm/s | 20 | 18 |
| Above | 40 cm/s | 20 | 20 |
| Its right | 30 cm/s | 20 | 11 |
| Its right | 40 cm/s | 20 | 18 |
| Its right | 60 cm/s or 90 cm/s | 40 | 40 |
| Its left | 30 cm/s | 1 | 20 |
| Its left | 40–90 cm/s | 3 | 60 |
There are two results here. First, the brain's decision is good but the body is slow. A real fly's giant fiber can start a takeoff within milliseconds [5]. Ours spends 0.1 s rearing up, and the jump itself cannot throw it clear. Second, the fly hardly ever jumps from its left. The right eye drives the giant fiber and the left eye does not. We do not think this is real. BANC's left optic lobe is less complete in its annotation (it lists 2 Tm1 neurons on the left against 851), which may explain it. Do not read this as a fact about flies.
Why it dodges
In living flies, Croke et al. recorded DNp03, a pair of descending neurons. It fires more to a looming object on its own side. If you activate one DNp03 in a tethered fly in flight, the wingbeat on its side gets larger, the other gets smaller, and the head turns away. Its main inputs are the visual neurons LPLC1, LPLC4 and LC4 [15]. The model passes this test (tools/loom.py): left looming neurons at 100 Hz give DNp03 169 Hz on the left and 0 on the right, and right looming neurons give 0 and 175 Hz. In the nerve cord, one DNp03 makes the motor neurons of the wing muscles b3 and i1 fire on the other side only, as Croke et al. predict. They also predict b1 on the same side, and b1 stays silent in the model (tools/wing_turn.py).
When DNp03 left minus right passes 60 Hz, the fly makes one saccade away from the active side. The brain chooses whether and which way. The shape is fixed: from 44 saccades of real flies in flybody's data, a peak of 43 rad/s and a width of 40 ms, with 27° of roll into the turn.
We tested this in an earlier scene with the fly always in the air and contacts off (tools/dodge.mjs at commit 80772509). The object was aimed at where a straight flight would go, so a fly that does not turn was hit in all 80 runs. Ten runs per row. Clearance is the smallest distance from head to object surface, in cm.
| Object from | Turn away (the brain): hits | Clearance | Turn toward (control): hits | Clearance |
|---|---|---|---|---|
| 30°, 30 cm/s | 0 | 0.31 | 0 | 2.45 |
| 75°, 30 cm/s | 0 | 3.95 | 0 | 2.02 |
| 110°, 30 cm/s | 0 | 5.28 | 0 | 0.85 |
| 30°, 45 cm/s | 10 | −0.20 | 0 | 1.44 |
| 45°, 45 cm/s | 10 | −0.73 | 0 | 1.41 |
| 110°, 45 cm/s | 0 | 2.65 | 1 | 0.09 |
Turning away is better only when the object comes from the side or from behind. From the front, the turn takes the fly along the object's path. That test used a less sensitive eye rule than this page (full input at 6 rad/s, here 2 rad/s). The eye rule and the threshold are our choices, so these distances are not a prediction for a real fly.
The fly flies at 14 cm/s, the median speed in flybody's recordings. At 30 cm/s the policy does not hold a steady pose, and a saccade makes it fall. Its thorax is about 45° nose up, as trained, near the published body angle for hovering flies [17]. It looks upright. We judged the abdomen and the hanging legs by eye from photos. The wings beat at about 218 Hz, too fast for a screen, so they are drawn as the real poses of the last wingbeat, laid faintly over each other.
A day, in numbers
Five simulated minutes with no swatter (node tools/day.mjs): 12 flights, 8 meals, and 7 failures where we had to put the fly back on its feet. Four launches were also called off because the nose was not up. When the fly falls on its back, it cannot right itself. No policy was trained for this, so after 0.4 s we set it back on its feet, and the page counts each time. Falls come from launches, landings and walking.
The brain model
Each neuron is a leaky integrate-and-fire unit [6]. Its potential decays to rest, and synaptic input pushes it up or down. At threshold it fires, resets, and ignores input for a short time. Every neuron has the same values: rest and reset −52 mV, threshold −45 mV, membrane time constant 20 ms, synaptic time constant 5 ms, refractory period 2.2 ms, delay 1.8 ms. The connectome gives the rest. A connection's weight is its number of synapses times 0.275 mV, and its sign comes from a predicted transmitter [9]. GABA, glutamate and histamine inhibit. Without input, every neuron stays at rest.
The model runs in WebAssembly, compiled from Rust, in steps of 0.1 ms. A neuron that cannot reach threshold without new input is not stepped. When input arrives, one calculation brings it up to date, so the result does not change.
We checked the engine against Shiu et al.'s model in Brian 2 [11], on the brain-only FlyWire connectome (version 783, 138,639 neurons [7][8]) that the paper used. With the same random input in ten runs of 1 s, Brian made 1,999,953 spikes, and the engine made the same spikes, each in the same step. With separate random input, 30 runs of sugar: all 437 neurons that fired agree within 3 standard errors, and MN9 fired at 78.6 Hz in Brian and 78.2 Hz in the engine. We did not check BANC against Brian. It is the same engine on a different connectome, with the same weight per synapse.
On FlyWire, the engine repeats the paper's experiments. Rate of the readout in Hz, mean of 20 runs of 1 s (tools/experiments.mjs). Shiu et al.'s preprint reports that 91% of 164 testable predictions agreed with experiments in flies [10].
| Activated | Readout | 50 Hz | 100 Hz | 150 Hz | 200 Hz |
|---|---|---|---|---|---|
| Sugar | MN9 | 11 | 64 | 77 | 89 |
| Sugar and bitter | MN9 | 1 | 3 | 4 | 7 |
| Sugar and Ir94e | MN9 | 0 | 11 | 28 | 54 |
| Water | MN9 | 0 | 0 | 6 | 30 |
| Antenna JO-CE | aBN1 | 1 | 26 | 51 | 68 |
| Antenna JO-F | aBN1 | 0 | 1 | 1 | 3 |
Stopping on sugar. Sapkal et al. found that sugar stops walking in real flies, and showed why in this model [2]. We repeated it on FlyWire (tools/intent.py). With P9 at 100 Hz, oDN1 fires at 13.4 Hz. Sugar at 50, 100 and 150 Hz reduces it to 9.5, 2.8 and 1.0 Hz. Bitter at 150 Hz does not (13.8 Hz).
From firing to the mouth. McKellar et al. recorded what each proboscis muscle does [16], and BANC names their motor neurons. So the page knows which neurons move which joint: MN9 and MN1, MN2 for the rostrum, MN4 and MN3 for the haustellum, MN7 for the labellum. No recording gives force for a firing rate, so we chose a rule: activation is 1 − e−r/40 Hz of the mean rate over 30 ms.
It can run away. On FlyWire, 12 LB3b taste neurons on the fly's right at 150 Hz spread through excitatory local neurons of the antennal lobe until about 8,400 neurons fire, among them about 3,400 Kenyon cells. Brian does the same. We do not know which missing part of the model causes this.
Shiu et al. list the model's limits [6]. All neurons have the same parameters, and many real fly neurons do not fire spikes. There are no gap junctions, neuropeptides, neuromodulation or internal state. Transmitter predictions can be wrong. Neurons have no activity at rest, so inhibition of a silent neuron has no effect. Absolute firing rates are not reliable; changes in rate are more reliable.
Can it walk by itself?
No. The legs on this page move by a trained policy. We activated DNg100, a descending neuron that starts walking in real flies, at 50–200 Hz on BANC. About 60–100 of the 393 leg motor neurons fire, with no rhythm, and flexors and extensors of a joint fire together. A leg would stiffen, not step. We then activated each of the 473 types of descending neuron in turn. 175 types make leg motor neurons fire. None makes a rhythm clearly above random firing, and none makes flexors and extensors alternate.
Pugliese et al. found a walking rhythm in a rate model of the nerve cord [12]. We wrote their model again from their Methods and ran it on BANC (tools/rate_vnc.py). Their result holds: with DNg100 driven, all six legs' networks make a rhythm at 8–10 Hz in 8 of 8 runs at a moderate input, and most runs stop with stronger input. We sent this rhythm to flybody's legs, tethered (tools/leg_drive.py). The feet move by less than 0.1 mm, the middle legs almost not at all, and the phase between legs changes from run to run.
Real flies set a clear test. Sapkal et al. activated DNg100 in flies with no head and little leg feedback. All six legs stepped, left and right alternated, and the legs kept a tripod [13]. The model on BANC does not do this (tools/phase.py). Muscles that swing a front leg forward and back are about 45–60° apart, not 180°. The front legs are nearly in phase. There is no tripod at any input. So the wiring holds part of what walking needs, but this model does not walk from it.
Smell fails too. A real fly turns toward the antenna that smells more, through DNa02 [14]. On FlyWire, olfactory input usually ignites the whole brain or does nothing, and DNa02 fires on the fly's left whichever antenna gets the input (tools/intent.py steer). Silencing Kenyon cells, excitatory antennal lobe neurons or all neuromodulator neurons, or weakening all synapses, did not help. It may be an error in the model, not in the fly.
The jump does not reach the muscles. Looming neurons drive the giant fiber, but it does not drive the jump muscle's motor neuron: in the fly that synapse is mostly electrical, and the connectome has chemical synapses only. So a threshold on the giant fiber's rate starts the jump.
What is wrong with this fly
- The brain does not calm down. After looming input at 30 Hz or more, the model stays at about 32,000 spikes per second for as long as we ran it, with no input. A real brain recovers. So one second after an object goes, we clear the brain's state. The page counts each time. It is the largest cheat on this page.
- It smells nothing and sees nothing. Odor input ignites the model (see Can it walk by itself?), and visual input from photoreceptors does not reach the looming neurons in this model (
tools/vision_reach.py). The fly knows where the sugar is because we tell it. - Landing has no brain. We looked for a landing command. LPLC4 drives DNp07, but about the same from one eye (70 / 0 Hz) as from two (79 / 80 Hz), and that does not pass the test we set in advance (
tools/land.py). So a rule decides. - Hunger is one number. Thirst, sleep, mating, grooming and learning are absent.
- A flat world. The fly cannot walk on the fruit or land on the mug, because the walking policy knows only flat ground. Its goals stay clear of what stands there.
- No feeling of its own body. The legs, wings and halteres send no input to the model.
Data
Connectome: BANC version 888 [1]. Body and policies: flybody [3] (model Apache 2.0; weights and wing pattern from doi:10.25378/janelia.25309105, GPL 3). Numbers on FlyWire use its version 783 as prepared by Shiu et al. (CC BY 4.0); the page does not download it. The page downloads about 40 MB. In our test (headless Chrome on an Apple M4 Mac) it runs at about 0.7× real time on the table and 0.3× in the air, because in the air physics runs at 20 kHz with every leg joint free. The clock shows the speed.