diff --git a/CLAUDE.md b/CLAUDE.md index 27111ea..3e5f52c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -11,6 +11,7 @@ Reusable single-screen SceneryStack template. Run `npm run rename` to fork it to | File | Purpose | |---|---| | `src/SimColors.ts` | All `ProfileColorProperty` instances | +| `src/SimConstants.ts` | Named numeric constants (layout px, physics SI units) | | `src/SimNamespace.ts` | Namespace for color property names | | `src/i18n/StringManager.ts` | Singleton localized string accessor | | `src/sim-screen/SimScreen.ts` | Screen wrapper | diff --git a/doc/model.md b/doc/model.md new file mode 100644 index 0000000..1e559a0 --- /dev/null +++ b/doc/model.md @@ -0,0 +1,37 @@ +# Model - Sim Template + +This document describes the model (the underlying physics, math, and behavior) for the simulation, in +terms appropriate for an educator. It is the companion to +[implementation-notes.md](./implementation-notes.md), which targets developers. Replace the placeholder +content below with a description of your own sim's model when you fork this template. + +## Overview + +*One or two paragraphs describing what the simulation models and the key ideas a student should take +away. Write for a teacher, not a programmer — avoid code and class names.* + +The template ships with no domain-specific physics; it is a minimal Model-View scaffold. A real sim +replaces this section with its actual conceptual model. + +## Quantities and units + +*List the primary modeled quantities, their symbols, units (SI where applicable), and ranges.* + +| Quantity | Symbol | Units | Range | +|---|---|---|---| +| *(example)* time | t | s | 0 – ∞ | + +## Governing equations + +*State the equations or rules that drive the model, with a sentence explaining each. Use a smaller +fixed time step than the screen default if the integration requires it; the model makes no assumption +about frame rate.* + +## Simplifications and assumptions + +*Note anything intentionally idealized or omitted relative to the real-world phenomenon (e.g. no air +resistance, point masses, instantaneous response), so educators can set expectations.* + +## References + +*Optional: textbook sections, papers, or standards the model is based on.* diff --git a/src/SimConstants.ts b/src/SimConstants.ts new file mode 100644 index 0000000..716f7df --- /dev/null +++ b/src/SimConstants.ts @@ -0,0 +1,37 @@ +/** + * SimConstants.ts + * + * Central repository for every named numeric constant used across the + * simulation. Bare numbers that carry semantic meaning (sizes, margins, + * physics defaults, ranges) belong here rather than inline in model or view + * code, so they are named, documented, and changed in one place. + * + * Conventions + * ─────────── + * - Physics / model values use SI units (metres, seconds, kilograms, …); + * note the unit in a comment on each value. + * - Layout / chrome values are in screen pixels. + * - Colour strings live in SimColors.ts, not here. + * - Computed expressions (e.g. `2 * Math.PI`) may stay inline. + * + * Remove the example constants below and replace them with the sim's own. + */ + +import SimNamespace from "./SimNamespace.js"; + +// ── Layout / chrome (screen pixels) ─────────────────────────────────────────── + +/** Margin between the screen edge and edge-anchored controls (e.g. Reset All). */ +export const SCREEN_VIEW_MARGIN = 20; + +/** Corner radius shared by control panels and dialogs. */ +export const PANEL_CORNER_RADIUS = 6; + +// ── Physics / model defaults (SI units) ─────────────────────────────────────── + +// Example: export const GRAVITY_MPS2 = 9.81; // m/s² + +SimNamespace.register("SimConstants", { + SCREEN_VIEW_MARGIN, + PANEL_CORNER_RADIUS, +}); diff --git a/src/common/SimPanel.ts b/src/common/SimPanel.ts index a9e3365..437c796 100644 --- a/src/common/SimPanel.ts +++ b/src/common/SimPanel.ts @@ -29,13 +29,14 @@ import type { Node } from "scenerystack/scenery"; import type { PanelOptions } from "scenerystack/sun"; import { Panel } from "scenerystack/sun"; import SimColors from "../SimColors.js"; +import { PANEL_CORNER_RADIUS } from "../SimConstants.js"; export class SimPanel extends Panel { public constructor(content: Node, providedOptions?: PanelOptions) { super(content, { fill: SimColors.panelBackgroundColorProperty, stroke: SimColors.panelBorderColorProperty, - cornerRadius: 6, + cornerRadius: PANEL_CORNER_RADIUS, xMargin: 12, yMargin: 10, ...providedOptions, diff --git a/src/sim-screen/view/SimScreenView.ts b/src/sim-screen/view/SimScreenView.ts index 1abaf1c..8c8bb54 100644 --- a/src/sim-screen/view/SimScreenView.ts +++ b/src/sim-screen/view/SimScreenView.ts @@ -25,12 +25,10 @@ import { ResetAllButton } from "scenerystack/scenery-phet"; import type { ScreenViewOptions } from "scenerystack/sim"; import { ScreenView } from "scenerystack/sim"; import SimColors from "../../SimColors.js"; +import { SCREEN_VIEW_MARGIN } from "../../SimConstants.js"; import type { SimModel } from "../model/SimModel.js"; import { SimScreenSummaryContent } from "./SimScreenSummaryContent.js"; -// Margin between screen edges and buttons/panels (in layout-bounds coordinates) -const SCREEN_VIEW_MARGIN = 20; - export class SimScreenView extends ScreenView { public constructor(model: SimModel, options?: ScreenViewOptions) { // ── Accessibility: screen summary ───────────────────────────────────────────