From 109dad1c76aa70f2c4c7f8d2df566d0bdc0dbb78 Mon Sep 17 00:00:00 2001 From: Developer Date: Thu, 29 Oct 2026 19:14:57 -0500 Subject: [PATCH 1/2] feat: the formula box on CHOICES: words, sample value, mistakes with a fix, SHAPE and INSERT (formula box 1) REQUIRES, each modifier's amount and USES now say the formula in words with what it comes to for the sample character (every level at 3), worked out by a new POST /api/systems/preview-formulas on the game's own parser. Mistakes show in red before PUBLISH, stricter than it: a name the system hasn't got, with USE @name for the nearest; an amount reading a formula. A formula button (Fluent math-format icon, MIT) opens SHAPE and INSERT. The remove x is red. Approved mockup docs/mockups/formula-box.html, 2026-10-29. --- CHANGELOG.md | 8 + README.md | 8 + .../system_builder_formula_preview.test.js | 120 +++++++++++++ backend/routes/systems.js | 13 ++ backend/systemBuilder/formulaPreview.js | 103 +++++++++++ e2e/COVERAGE.md | 1 + e2e/README.md | 1 + e2e/tests/builder-clicks.spec.ts | 3 + e2e/tests/builder-formula-box.spec.ts | 72 ++++++++ frontend/src/components/ChoicesPage.tsx | 16 +- frontend/src/components/FeaturesEditor.tsx | 60 +++++-- frontend/src/components/FormulaIcon.tsx | 13 ++ .../hooks/__tests__/useFormulaBox.test.tsx | 118 ++++++++++++ frontend/src/hooks/useFormulaBox.tsx | 170 ++++++++++++++++++ .../src/sheets/__tests__/formulaBox.test.ts | 119 ++++++++++++ frontend/src/sheets/builderHelp.ts | 6 +- frontend/src/sheets/formulaBox.ts | 139 ++++++++++++++ frontend/src/sheets/systemsApi.ts | 4 + 18 files changed, 948 insertions(+), 26 deletions(-) create mode 100644 backend/__tests__/system_builder_formula_preview.test.js create mode 100644 backend/systemBuilder/formulaPreview.js create mode 100644 e2e/tests/builder-formula-box.spec.ts create mode 100644 frontend/src/components/FormulaIcon.tsx create mode 100644 frontend/src/hooks/__tests__/useFormulaBox.test.tsx create mode 100644 frontend/src/hooks/useFormulaBox.tsx create mode 100644 frontend/src/sheets/__tests__/formulaBox.test.ts create mode 100644 frontend/src/sheets/formulaBox.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index c8859d8e..c86c337e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,14 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added +- **Formulas on CHOICES say what they do, and help you write them.** Under a modifier's amount, a + feature's USES and an option's REQUIRES, a line now says the formula in words with what it comes + to for the sample character: "+2 for each level · sample Level 3: +6", "needs Strength 13 or + more · the sample (Strength 16) meets it". A mistake shows in red before you publish, including a + name the system hasn't got: `@lvl` offers USE @level to fix it. The new formula button beside each + box opens SHAPE, which writes common ones for you (A NUMBER, PER LEVEL, PER CLASS LEVEL, HALF + LEVEL; AT LEAST and LEVEL AT LEAST on a requirement), and INSERT, the names the box can read, put + where your cursor is. The × that removes a modifier is now red. - **Features that add to the token's maximum (7a5a3).** A feature whose modifier is on HP MAX (or WOUNDS, under a wound count) now moves the token's real maximum, not just the number the sheet names: a level 3 fighter picking Tough (`2 * @level`) goes from 20 to 26 of 26, the current diff --git a/README.md b/README.md index 58f97a86..58728891 100644 --- a/README.md +++ b/README.md @@ -449,6 +449,7 @@ CITY_NET/ │ │ ├── choices.js # A system's choices (7a1a; approved mockup builder-choices, 2026-10-27): the lists a character picks from (classes, backgrounds, feats), each named one and many, picked once, so many times or any, levelled or not, and MORE THAN ONCE for multiclassing; options with an optional requirement (a formula) and features, each unlocking at a level in a levelled list and doing any of: modifiers on a stat, formula or health field, uses refilled by a rest, rolls it gives, a change it lets a roll take, another list to pick from, or only words. Option and feature ids share one set; an option's level is read as @