OverviewThis WebsiteHome LabTrading BotEcosimProcedural Generation
Source Code

src/pages/projects/ecosim.rs

use leptos::*;
use leptos_meta::{Meta, Title};

use super::data::ALL_PROJECTS;

#[component]
pub fn Ecosim() -> impl IntoView {
    let project = ALL_PROJECTS
        .iter()
        .find(|p| p.slug == "ecosim")
        .unwrap();
    let skills_view = project
        .skills
        .iter()
        .map(|&s| view! { <li>{s}</li> })
        .collect::<Vec<_>>();

    view! {
        <Title text="Ecosim – Peter Pinto"/>
        <Meta name="description" content="A planet-scale ecosystem simulator built on Bevy, with procedural generation, hierarchical simulation, and a deterministic multiplayer architecture."/>
        <div class="page">
            <span class="eyebrow">"Projects"</span>
            <h1>"Eco" <em style="font-style:italic; color: var(--accent)">"sim"</em></h1>
            <p class="lead">
                "A planet-scale ecosystem simulator. The goal: model populations of plants, animals,
                and microorganisms from global climate patterns down to individual organism behaviour —
                and let players intervene at any level."
            </p>

            <ul class="skills-list" style="margin-top: 1.5rem;">
                {skills_view}
            </ul>

            <hr class="divider"/>

            // ── Vision ────────────────────────────────────────────
            <section class="project-section">
                <span class="eyebrow">"Concept"</span>
                <h2>"What It Is"</h2>
                <p>
                    "Ecosim is the umbrella application that ties together a set of purpose-built
                    libraries — procedural planet generation, orbital camera, GPU shaders, and
                    input binding — into a single runnable game. The simulation is designed
                    around several gameplay modes:"
                </p>
                <ol class="project-steps">
                    <li>
                        <strong>"Plague Inc-style"</strong>
                        " — control an invasive species and spread it across the globe"
                    </li>
                    <li>
                        <strong>"From Scratch"</strong>
                        " — seed a barren planet and guide an ecosystem to stability"
                    </li>
                    <li>
                        <strong>"Competitive"</strong>
                        " — race another player to accumulate the most biomass"
                    </li>
                </ol>
            </section>

            <hr class="divider"/>

            // ── Architecture ──────────────────────────────────────
            <section class="project-section">
                <span class="eyebrow">"Architecture"</span>
                <h2>"Bevy ECS"</h2>
                <p>
                    "The application is built on "
                    <a href="https://bevyengine.org" target="_blank" rel="noopener noreferrer" class="prose-link">"Bevy 0.18"</a>
                    ", a data-driven game engine based on an Entity Component System. Game state
                    is managed through a type-safe state machine: a top-level "
                    <code class="inline-code">"AppState"</code>
                    " (Startup → MainMenu → InGame → Shutdown) with a nested "
                    <code class="inline-code">"GameState"</code>
                    " (Playing ↔ Paused). Invalid transitions are unrepresentable by design —
                    you cannot call "
                    <code class="inline-code">"pause()"</code>
                    " unless the game is already in the Playing sub-state."
                </p>
            </section>

            <hr class="divider"/>

            // ── Determinism ───────────────────────────────────────
            <section class="project-section">
                <span class="eyebrow">"Design Principle"</span>
                <h2>"Determinism First"</h2>
                <p>
                    "Every subsystem is designed to be a pure function of its inputs, with all
                    randomness fed through seeded RNGs. This makes multiplayer possible without a
                    dedicated authoritative server — both clients run the same simulation, and
                    a single binary serves as either a peer or a headless dedicated server
                    depending on startup flags."
                </p>
                <p style="margin-top: 1rem;">
                    "A "
                    <code class="inline-code">"DETERMINISM_ANALYSIS.md"</code>
                    " file lives at the root of the simulation crate, tracking every known
                    source of nondeterminism (Bevy query order, floating-point variance,
                    HashMap iteration) and the mitigation applied to each."
                </p>
            </section>

            <hr class="divider"/>

            // ── Build ─────────────────────────────────────────────
            <section class="project-section">
                <span class="eyebrow">"Build"</span>
                <h2>"Targets & Profiles"</h2>
                <p>
                    "The dev profile uses the Cranelift codegen backend for near-instant
                    recompilation, with dependencies compiled by LLVM so hot-reload stays
                    fast without sacrificing dependency performance. The release profile
                    enables full LTO and codegen-unit merging for maximum runtime speed.
                    A dedicated WASM release profile strips debug info and optimises for
                    binary size, targeting deployment in the browser via "
                    <code class="inline-code">"wasm-bindgen"</code>
                    "."
                </p>
            </section>

            <hr class="divider"/>

            // ── Status ────────────────────────────────────────────
            <section class="project-section">
                <span class="eyebrow">"Status"</span>
                <h2>"Foundation Complete"</h2>
                <p>
                    "The underlying libraries — procedural planet generation, camera, input binding,
                    and GPU shaders — are all functional. The game application has a working state
                    machine, plugin architecture, and build pipeline. The next phase is writing the
                    gameplay systems that connect them, building on a solid, tested foundation
                    rather than prototyping and rewriting later."
                </p>
            </section>
        </div>
    }
}