Skip to content

Rewrite FrogSim as TypeScript web app with 3D visualization - #1

Open
ArvisPrime wants to merge 3 commits into
masterfrom
claude/project-scope-simulation-y0cp00
Open

Rewrite FrogSim as TypeScript web app with 3D visualization#1
ArvisPrime wants to merge 3 commits into
masterfrom
claude/project-scope-simulation-y0cp00

Conversation

@ArvisPrime

Copy link
Copy Markdown
Owner

Summary

Complete rewrite of FrogSim from a PHP CRUD application into a sophisticated individual-based amphibian population simulation engine with interactive 2D, 2.5D, and 3D visualizations. The new implementation is built in TypeScript with React, runs in the browser with a Web Worker simulation backend, and includes comprehensive ecological modeling backed by peer-reviewed literature.

Key Changes

Core Simulation Engine

  • Implemented full individual-based population model with daily tick pipeline covering weather, hydrology, resources, pathogen dynamics, larval development, individual behavior, breeding, and seasonal transitions
  • Added support for 7 real anuran species with species-specific life history parameters
  • Implemented quantitative genetics system supporting heritable variation, inbreeding depression, and adaptive evolution
  • Added Batrachochytrium dendrobatidis (Bd) chytridiomycosis disease dynamics
  • Created deterministic, serializable RNG (xoshiro128**) for reproducible simulations

Ecological Models

  • Implemented temperature-dependent development (Briere rate function)
  • Added density-dependent larval growth via shared resource pools (Monod kinetics)
  • Implemented Wilbur-Collins metamorphosis decision model
  • Added post-metamorphic energetics, hydration, and survival budgets
  • Implemented correlated random walk movement with behavior-dependent turning angles
  • Added chorus dynamics and mate choice with acoustic active space calculations

Interactive Visualization

  • 2D analytical view: True plan projection for measuring dispersal and habitat relationships
  • 2.5D diorama view: Dimetric projection with billboarded sprites and contact shadows
  • 3D perspective view: WebGL/three.js with displaced terrain, animated water surfaces, instanced frog meshes, and dynamic lighting tracking photoperiod
  • GPU-free picking system for agent selection across all views

User Interface

  • React-based control panel with scenario selection, parameter adjustment, and real-time analysis
  • Transport controls with variable playback speeds (0.25× to 60×)
  • Interactive terrain painting and pond placement tools
  • Time-series charts for population dynamics, larval cohorts, hydrology, and evolution
  • Dark, dense instrument-panel styling optimized for data visualization

Architecture

  • Web Worker simulation backend decoupled from render loop (~35ms per day at 18k agents)
  • Snapshot protocol using transferable typed arrays for efficient worker communication
  • Timeline scrubber with full state snapshots for temporal navigation
  • Comprehensive test suite covering ecological functions and emergent vital rates

Documentation

  • Complete model specification in docs/MODEL.md with equations, sources, and calibration constants
  • Reference bibliography in docs/REFERENCES.md
  • Inline code documentation explaining biological assumptions and implementation choices

Notable Implementation Details

  • The simulation tick order is carefully sequenced to avoid one-day lags in state dependencies (weather → hydrology → temperature → resources → pathogen → eggs → larvae → individuals → breeding → seasonal)
  • Larvae and eggs are modeled as cohorts (count + mean + CV) rather than individuals to handle 10⁴-10⁵ tadpoles efficiently
  • All state is plain data structures (no class instances) to enable structural cloning for the timeline scrubber
  • Terrain is procedurally generated with deterministic value noise and affects pond hydrology, habitat quality, and movement costs
  • Emergent vital rates are validated against published field ranges in integration tests

https://claude.ai/code/session_01PVhCMnzYeAk457moZNTEco

claude added 3 commits July 31, 2026 17:10
The 2017 project was a Core-PHP CRUD demo whose README listed four tasks that
were never built. This implements them as actual population ecology, with 2D,
2.5D and 3D interactive views. The original PHP app is preserved in legacy-php/.

Engine (src/engine/) — deterministic, DOM-free, one simulated day per tick:
- Post-metamorphic animals are individual agents; eggs and larvae are cohorts
  with a size CV, because one pond holds 10^4-10^5 tadpoles.
- Richardson stochastic weather generator; Hamon PET; CBM photoperiod.
- Stage-volume pond water balance (V = k*d^p), driving hydroperiod — the master
  variable structuring temperate amphibian communities.
- Degree-day development on a Briere curve; growth from a grazed periphyton
  pool under scramble competition; Wilbur-Collins metamorphosis.
- Holling Type III larval predation with size refuge and induced defences.
- Acoustic mate choice inside a computed active space, giving an emergent
  mate-finding Allee effect rather than an imposed one.
- Load-based Bd model with an environmental zoospore pool and thermal window.
- Infinitesimal quantitative genetics with Wright's inbreeding recursion.

Rendering (src/render/) — three views behind one interface: top-down analytical
2D with a scale bar, oblique depth-sorted 2.5D diorama, and instanced-mesh 3D.
The 2.5D view is also the automatic fallback when WebGL is unavailable.

Architecture: the engine runs in a Web Worker and posts flat typed-array
snapshots, so a ~35 ms tick at 18k agents never blocks the 60 fps render loop.

Interactivity: transport controls, click-to-inspect frogs and ponds, terrain
brushes, pond editor, species editor, live parameters, seven scenarios.

Tests: tests/ecology.test.ts pins the mathematics of each named model;
tests/vitalRates.test.ts runs simulated decades and asserts that emergent
vital rates land inside published field ranges. The latter is what caught
every calibration bug found while building this.

Docs: docs/MODEL.md is the full specification with equations and sources;
docs/REFERENCES.md states explicitly which citation details are unverified.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVhCMnzYeAk457moZNTEco
Each of these was found by the vital-rate suite, not by inspection:

- Larval mass was unbounded when development lagged growth. A cohort in a cold
  pond kept growing while waiting for degree-days and produced "metamorphs" an
  order of magnitude heavier than any adult of their species. Mass is now
  capped at 1.15x maxMetaMass, which is also the correct representation of the
  overwintering-larva case that confines bullfrogs to permanent water.

- Breeding values were unbounded. The infinitesimal model as usually written
  has no selection limit, so sustained sexual selection on male size drove
  growth breeding values past +7 SD. Clamped to +-4 founder SD, standing in for
  finite additive genetic variance.

- The chart refresh interval depended on an object whose identity changed every
  render, so it was torn down faster than its own period and rarely fired.

- The visual day/night clock chased a quantised sim clock and could run
  backwards. It now tracks absolute simulated time monotonically, rate-limited
  to one cycle per eight real seconds so it does not strobe at 60x.

Two test assertions were wrong rather than the code, and the reasons are now
documented in MODEL.md §6:

- Density dependence is asserted on size at metamorphosis, not per-egg
  survival. Survival responds to scramble competition and predator satiation
  pulling in opposite directions; under a Type III response, per-prey risk
  peaks near 10 larvae/m^2 and falls above it, so at high stocking satiation
  wins and survival rises with density. Size at metamorphosis is unambiguous
  and is the signature Wilbur actually reported.

- Road mortality is asserted across replicate seeds. Once the parameter
  differs the RNG streams diverge, so a single paired comparison is two
  different random trajectories and can come out either way.

Also adds tests/interventions.test.ts: 21 tests covering everything a user can
trigger from the UI, including destroying every pond, culling the entire
landscape, running with zero ponds or zero species, and extreme parameters.

Realised vital rates over a 15-year run now sit inside published field ranges:
egg->metamorph 3.9%, metamorph->adult 4.4%, egg->breeding adult 0.17%.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVhCMnzYeAk457moZNTEco
The suite ran for over 20 minutes and three assertions were still wrong. Both
problems are fixed; all 82 tests now pass in ~75 seconds.

Speed: the expensive simulations lived directly in `describe` bodies, so they
ran during vitest's *collection* phase — every fixture in the file executed
even when a single test was selected with `-t`. They are now lazy and memoised,
which took a targeted run from 196 s to under 4 s. The vital-rate fixture is
also sized to what its assertions need rather than to realism: two
two-year-maturing species over six years. Longer horizons are the headless
script's job.

Correctness — in each case the model was right and the test was wrong:

- Density dependence is now asserted on size at metamorphosis, in a
  predator-free pond, which is how Wilbur's experiments were actually run.
  With predators present the Type III response culls the cohort early, so the
  survivors are no longer crowded and both densities reach maximum metamorph
  size. That interaction is real; it just masks the competition signal, exactly
  as it would confound a field enclosure.

- The metamorph-to-adult assertion failed on a five-year run containing a
  four-year-maturing species: the rate is a whole-run cumulative, so every
  metamorph from the second half of the run counts as a failure to mature.

- Road mortality is asserted across three replicate seeds. Once the parameter
  differs the RNG streams diverge, making a single paired comparison two
  different random trajectories.

The analysis panel now reports maturation-dependent rates as "too early" until
five simulated years have passed, instead of flagging a structural zero as
out-of-range.

MODEL.md §6 records each of these, because they are properties of the model
rather than of the code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVhCMnzYeAk457moZNTEco
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants