Instead of summing an analytic point-source field, this version solves the actual reaction-diffusion PDE for chemokine concentration C on a live 2D grid every frame:
∂C/∂t = D·∇²C − k·C + S(x,y)
∇²C ≈ (C_left+C_right+C_up+C_down−4·C_c) / h² (5-point Laplacian)
S(x,y) = Σ Q · δ_grid(bacterium position)
D is the diffusion rate, k a chemokine decay rate, and S the source term deposited by every live bacterium. The finite-difference update is iterated in several small sub-steps per animation frame to stay numerically stable (explicit-Euler stability needs Δt ≤ h²/4D).
A neutrophil doesn't see the source list — it only ever samples the grid, bilinearly interpolated, and estimates the local gradient with a central difference:
∇C ≈ ( [C(x+h,y)−C(x−h,y)] / 2h , [C(x,y+h)−C(x,y−h)] / 2h )
v = normalize( s·∇C + (1−s)·jitter ) · speed
That is the same biased-random-walk chemotaxis law as the 3D version, but here it is measured off a genuinely simulated diffusion field rather than computed analytically — exactly how a real leukocyte reads a locally diffusing, decaying chemokine cloud rather than a clean inverse-square law.
- Phagocytosis — a neutrophil within its capture radius of a bacterium engulfs it with a per-frame probability.
- NETosis — once local bacterial density around a neutrophil exceeds the NETosis threshold, it ruptures and releases a NET that immobilises nearby bacteria, which then decay instead of being individually engulfed.
- The concentration field itself is rendered as a heatmap behind the agents, so you can watch the steady-state gradient bloom, saturate and dissipate as the source population changes.