Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
30cba53
docs(demos): redesign the car demo page layout
claude Oct 9, 2026
2491810
docs(demos): add file search and type filter to the demo code explorer
claude Oct 9, 2026
714811a
docs(demos): drop per-type colors from code explorer icons
claude Oct 9, 2026
ff95f9e
docs(demos): show the open file's type as plain text, not a pill
claude Oct 9, 2026
004178a
docs(demos): right-align the open file's type in the code explorer
claude Oct 9, 2026
b529985
docs(demos): split DemoPage into reusable components
claude Oct 9, 2026
1f500ae
docs(demos): move physics and UI demos to DemoPage
claude Oct 9, 2026
42cd3c7
docs(demos): move the remaining UI demos to DemoPage
claude Oct 9, 2026
dc3fca4
docs(demos): fix FullscreenButton style import and move rendering dem…
claude Oct 9, 2026
7591c58
docs(demos): move the last demos to DemoPage and delete the old Demo
claude Oct 9, 2026
e908ca6
docs(demos): fix spelling in the easing functions page
claude Oct 9, 2026
67b084d
docs(demos): rebuild the text demo as one live playground
claude Oct 9, 2026
ca6fe82
docs(demos): keep React page code out of the demo code explorer
claude Oct 10, 2026
1f78207
docs(site): restyle the docs site in the Forge brand
claude Oct 10, 2026
b5ab352
docs(site): add a copy button to the homepage install command
claude Oct 10, 2026
fa85fad
docs(site): use Orbitron for headings and other display text
claude Oct 10, 2026
f3babd6
chore: add Orbitron to the spelling dictionary
claude Oct 10, 2026
8e98448
docs(site): drop the eyebrow labels above the homepage hero and modul…
claude Oct 10, 2026
2a74134
docs(site): retitle the homepage feature grid
claude Oct 10, 2026
a012117
docs(site): describe the particles module by its features, not an exa…
claude Oct 10, 2026
4bfdfdc
docs(site): reword the homepage feature grid's heading and intro
claude Oct 10, 2026
3ce3b06
docs(site): drop the demos section eyebrow and reword its intro
claude Oct 10, 2026
5f28025
docs(site): refine hero and section intros for clarity and conciseness
stormmuller Oct 10, 2026
06ec7ea
docs(site): add math, storage, lifetimes and state machine cards to t…
claude Oct 10, 2026
67a6695
Merge branches 'claude/quirky-babbage-4156mb' and 'claude/quirky-babb…
stormmuller Oct 10, 2026
b602291
docs(site): show Galactic Journey gameplay beside the homepage hero
claude Oct 10, 2026
7573dbb
Merge remote-tracking branch 'origin/claude/quirky-babbage-4156mb' in…
claude Oct 10, 2026
f377383
docs(site): give the demo categories the site's line-icon style
claude Oct 10, 2026
13db7dd
docs(site): use a real Galactic Journey recording for the homepage hero
claude Oct 10, 2026
cb8d1bf
docs(site): credit every asset, font and icon set the site uses
claude Oct 10, 2026
1320ed3
docs(site): credit the car, planet and Kenney space and physics art
claude Oct 10, 2026
57d65f2
docs(site): credit Squaremeapixel's space pack
claude Oct 10, 2026
ab6e49c
docs(site): credit CodeManu's VFX pack for the explosion
claude Oct 10, 2026
75d124a
docs(site): say what OboroPixel's sprite sheets are used for
claude Oct 10, 2026
ac1efe3
docs(site): draw the raycasting hit marker with the in-house circle t…
claude Oct 10, 2026
683da69
style(site): drop the faint background gradients that banded
claude Oct 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 85 additions & 60 deletions .claude/skills/add-feature-demo/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ description: Use this skill when adding a new feature to the engine.
# Add a Demo

`documentation-site/src/pages/demos/<name>/` holds interactive, in-browser
demos of engine features, each rendered through
`documentation-site/src/components/Demo.tsx`. Read `AGENTS.md`'s
demos of engine features, each rendered through `DemoPage`
(`documentation-site/src/components/demo-page/`). Read `AGENTS.md`'s
"Documentation Site Demos" section first for the `file:..`/`dist` gotcha
that governs how demos are verified — it applies to every demo, new or
existing.
Expand Down Expand Up @@ -57,8 +57,8 @@ Follow the existing file split, every demo uses the same shape:
`_create-boundaries.ts` from `_spawn-shapes.ts`, not into one monolithic
file — each file also becomes its own tab in the demo's code viewer (see
step 3).
- `index.tsx` — the page itself, a thin wrapper around `<Demo>` (see step
3).
- `index.tsx` — the page itself, a thin wrapper around `<DemoPage>` (see
step 3).

Demo-only components/systems (input handling for interaction, camera
follow, reset-on-key, etc.) still follow the engine's own component/system
Expand All @@ -71,59 +71,93 @@ instead of `/src` because they're not part of the public API.
import React, { JSX } from 'react';
import { create<PascalName>Game } from './_create-game';
import gameCode from '!!raw-loader!./_create-game';
import someOtherCode from '!!raw-loader!./_some-other-file';
import thingSystemCode from '!!raw-loader!./_thing.system';

import { Demo } from '@site/src/components/Demo';
import { DemoPage } from '@site/src/components/demo-page';

export default function <PascalName>(): JSX.Element {
return (
<Demo
metaData={{
title: '<Human Title> Demo',
description: 'A demo showcasing <what it shows>.',
}}
header="<Human Title>"
blurb="<1-3 sentences: what the demo shows, what the engine feature
does, and how to interact with it (click/drag/keys) if applicable.>"
<DemoPage
slug="<kebab-case-name>"
createGame={create<PascalName>Game}
codeFiles={[
{ name: 'game.ts', content: gameCode },
{ name: 'some-other-file.ts', content: someOtherCode },
controls={[
{ inputs: ['←', 'A'], action: 'Move left' },
{ inputs: [{ device: 'mouse', label: 'Click' }], action: 'Select' },
]}
highlights={[
{
text: '<One short sentence on what the engine does here.>',
file: 'thing.system.ts',
},
]}
docLinks={[{ label: '<Guide>', to: '/docs/docs/<module>/<page>' }]}
fileGroups={[
{
title: 'Start here',
files: [
{
name: 'create-game.ts',
summary: '<One sentence on what the file does.>',
content: gameCode,
},
],
},
{
title: '<Feature>',
files: [
{
name: 'thing.system.ts',
summary: '<One sentence.>',
content: thingSystemCode,
},
],
},
]}
/>
);
}
```

Each `codeFiles` entry drives one tab in the demo's live code viewer, so
list every demo-source file the reader would need to fully understand the
scene, in the order that makes it easiest to follow (usually `game.ts`
first, since it's the entry point). Import each via `!!raw-loader!` exactly
like `gameCode` — this is what pulls the raw source text in at build time,
not the compiled/imported binding.

If the demo needs live interaction controls beyond canvas input (a slider,
a toggle button), pass a React node via `interactions` — see
`space-shooter/index.tsx` and `_BloomControls.tsx` for the pattern of a
small controls component alongside the demo files.

## 4. Wire it into the navbar

Add an entry to the `Demos` dropdown in
`documentation-site/docusaurus.config.ts` (currently around line 114),
alphabetical-ish grouping isn't strictly enforced but new entries are
generally added near thematically similar ones (physics demos are grouped
together, etc.):

```typescript
{
to: 'demos/<kebab-case-name>',
label: '<Human Label>',
},
```

This is the only place demos are registered/linked — there's no separate
index page or sidebar to update.
The page's title and one-line summary come from the demo's entry in
`documentation-site/src/data/demos.ts` (step 4), so the catalogue card and
the page always agree. Write the rest for a reader who has never seen the
feature:

- `controls`: one row per action, with alternative inputs in the same
row. Check each binding against the demo's input code. Leave it out for
a demo you only watch.
- `highlights`: 3-5 "How it works" points, one short sentence each, each
linked to the file that implements it. Clicking the link opens that file
in the code explorer.
- `docLinks`: the guides under `documentation-site/docs/docs` that cover
the feature (`/docs/docs/<path>`, a folder's `index.md` is
`/docs/docs/<folder>`).
- `fileGroups`: every demo-source file a reader needs, grouped by purpose,
with `create-game.ts` alone under "Start here". Name each after its
source file without the leading underscore, and keep the
`.component.ts`/`.system.ts` suffixes: the explorer's type icons and
filter come from them. Import each via `!!raw-loader!` exactly like
`gameCode`, which pulls in the raw source text at build time.
- **Never list React or other framework code** (`.tsx`/`.jsx`) in
`fileGroups`. The explorer shows engine code a reader can reuse in their
own game; a settings panel that only exists to drive this site's page
isn't that. `DemoPage` throws if a `.tsx`/`.jsx` file is listed.

If the demo needs something else beside the game, such as live settings (a
slider, a toggle) or a legend for colors in the scene, pass it as `panels`,
wrapped in `DemoPanel` (with `DemoLegend` for a legend). Build live
settings from `DemoSettings`, `DemoSlider`, `DemoToggle`, `DemoChoice` and
`DemoTextField`. Keep the game-side logic the panel changes in a plain
`.ts` file (shown in the explorer) and the React panel itself out of the
explorer. See `text/index.tsx` and `easing-functions/index.tsx`.

## 4. Add it to the demo catalogue

Add an entry to `documentation-site/src/data/demos.ts` with the demo's
`slug` (its directory name), `title`, a one-sentence `description` (what
you see or do, and which feature it shows; it's the page's summary too) and
the category slugs it belongs to. See AGENTS.md's "Demo Catalogue and
Categories" section.

## 5. Verify

Expand All @@ -138,23 +172,14 @@ verification checklist:
already-built, unchanged API).
2. From `documentation-site/`: `npm run typecheck`, then `npm run build`
(`docusaurus build`) — this is what actually catches a broken import
against the published package surface or an MDX/broken-link error from
the navbar entry.
against the published package surface or a broken `docLinks` entry.
3. `npm run start` in `documentation-site/` (or reuse a running dev
server), open `demos/<kebab-case-name>` in a browser with a full page
reload (fast refresh doesn't guarantee a clean re-init), and confirm it
renders and behaves correctly — click through any interactions the
`blurb` describes.
4. **Also click the entry from the actual "Demos" navbar dropdown** - don't
only visit the URL directly. Adding the array entry in step 4 above is
necessary but not sufficient: the dropdown has grown to ~30 entries and
its `.dropdown__menu` is capped to the viewport height with internal
scrolling (`documentation-site/src/css/custom.css`) specifically so
every entry stays reachable regardless of list length - confirm your new
entry actually scrolls into view and is clickable in a real browser,
since a syntactically-correct array entry can still end up unreachable
if that CSS ever regresses or a future redesign changes the dropdown
markup.
renders and behaves correctly — try every control the page lists and
open each highlight's file link.
4. Open the demo from its card on `/demos` too, to check the catalogue
entry.

If this was prompted by a `/src` change (not a brand-new demo for existing
functionality), also re-run the full root-level `CLAUDE.md` verification
Expand Down
10 changes: 10 additions & 0 deletions .cspell/project-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -394,3 +394,13 @@ Zoltan
rrggbb
rrggbbaa
zstandard
sublist
orbitron
mcinerney
inerney
rasmus
andersson
oxanium
overcrafted
squaremeapixel
manu
18 changes: 13 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,14 @@ e2e/playwright-report` opens the HTML report, which links each test's

`documentation-site/src/pages/demos/<name>/` holds interactive, in-browser
demos of engine features (`physics`, `ecs`, `particles`, `rendering`, ...),
each rendered through `documentation-site/src/components/Demo.tsx`.
each rendered through `DemoPage` (`documentation-site/src/components/demo-page/`):
the running game with its controls and a short "How it works" list beside
it, and a code explorer for the demo's source below. Its title and summary
come from the demo's entry in `documentation-site/src/data/demos.ts`. The
`add-feature-demo` skill shows how to write a page. The code explorer only
shows engine code a reader can reuse: never list React or other framework
code (`.tsx`/`.jsx`) in it, such as a settings panel that only drives the
site's page.

**Critical gotcha**: these demos import the engine as a published package
(e.g. `import { addRigidBodyComponent } from '@forge-game-engine/forge/physics'`),
Expand Down Expand Up @@ -721,8 +728,9 @@ wrapper around the shared `CategoryDemosPage` component.
The catalogue's data lives separately from the demo pages themselves:

- `documentation-site/src/data/demo-categories.ts` - the fixed list of
categories (slug, title, description, card image under
`static/img/demos/categories/`).
categories (slug, title, description, and the line icon its card shows,
from `src/components/ModuleIcon.tsx`, the same set the homepage's feature
grid uses).
- `documentation-site/src/data/demos.ts` - one entry per demo (slug, title,
short description, and the category slugs it belongs to). A demo can
belong to more than one category - e.g. the car demo is tagged both
Expand All @@ -731,8 +739,8 @@ The catalogue's data lives separately from the demo pages themselves:

**When adding a new demo**, also add an entry to `demos.ts` with the
category slugs it belongs to (adding a new category itself means adding to
`demo-categories.ts` and a matching SVG under
`static/img/demos/categories/`, plus a new
`demo-categories.ts` with a `ModuleIcon` name, drawing a new icon in
`ModuleIcon.tsx` in the same style if none fits, plus a new
`src/pages/demos/category/<slug>/index.tsx` wrapper). A demo that combines
many engine features into a complete mini-game (like the space shooter,
brick breaker and car demos) belongs in the `games` category regardless of
Expand Down
84 changes: 71 additions & 13 deletions documentation-site/docs/credits.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,82 @@
title: Credits and attributions
---

## Icons
Forge's demos, documentation and website use art, audio and fonts made by
the people below. Thank you to all of them.

## Sprites and textures

Scroll down icons created by [Smashicons](https://www.flaticon.com/free-icons/scroll-down) from [Flaticon](https://www.flaticon.com/)
- [Kenney](https://kenney.nl), all licensed
[CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/):
- [UI Pack](https://kenney.nl/assets/ui-pack): the buttons, sliders, text
inputs and panels in the UI demos.
- [Fantasy UI Borders](https://kenney.nl/assets/fantasy-ui-borders): the
frames in the nine-slice and masks demos.
- [Particle Pack](https://kenney.nl/assets/particle-pack): the particle
textures in the particles demo.
- [Pattern Pack](https://kenney.nl/assets/pattern-pack): the backgrounds in
the physics demos.
- [Pirate Pack](https://kenney.nl/assets/pirate-pack): the sprites in the
pirate battle demo.
- [Puzzle Pack 2](https://kenney.nl/assets/puzzle-pack-2): the sprites in
the brick breaker demo.
- [Rolling Ball Assets](https://kenney.nl/assets/rolling-ball-assets): the
balls and blocks in the physics demos.
- [Simple Space](https://kenney.nl/assets/simple-space): ships, meteors and
stars in the space demos.
- [Screaming Brain Studios](https://screamingbrainstudios.com/dl-seamless-space-backgrounds/):
the nebula space background.
- [Wenrexa](https://opengameart.org/content/assets-free-laser-bullets-pack-2020):
the laser bullets in the space shooter demo.
- [Squaremeapixel](https://squaremeapixel.itch.io/space-pack): the
spaceships and asteroids in the space shooter demo.
- [CodeManu](https://codemanu.itch.io/vfx-free-pack): the explosion
animation in the space shooter demo.
- [Overcrafted](https://overcrafted.itch.io/free-paid-vehicle-car-sprites-):
the car body and wheels in the car demo.
- [Deep-Fold's Pixel Planet Generator](https://deep-fold.itch.io/pixel-planet-generator):
the pixel-art planet in the rendering demos and blog.
- [OboroPixel](https://oboropixel.itch.io/characters-animations-asset-pack):
the soldier sprite sheets in the sprite animation docs.

## Sprites
## Music and sound effects

- Some assets used in the demos and documentation have been provided by [Screaming Brain Studios - OpenGameArt.org](https://opengameart.org/content/seamless-space-backgrounds)
- Some assets used in the demos and documentation have been provided by [Wenrexa - OpenGameArt.org](https://opengameart.org/content/assets-free-laser-bullets-pack-2020)
- Some assets used in the demos and documentation have been provided by [OboroPixel - itch.io](https://oboropixel.itch.io/characters-animations-asset-pack)
- Music by
[GerardDEP](https://pixabay.com/users/gerarddep-48160304/?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=363808)
from
[Pixabay](https://pixabay.com/?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=363808).
- Sound effects by
[LoLa Joy](https://pixabay.com/users/u_xg7ssi08yr-48039129/?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=381976)
from
[Pixabay](https://pixabay.com/?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=381976).

## Fonts

- The engine's shipped default font atlas, and the text rendering demo's
font, both use [Liberation Sans](https://github.com/liberationfonts)
(Copyright (c) 2012 Red Hat, Inc. with Reserved Font Name Liberation),
licensed under the [SIL Open Font License, Version 1.1](https://scripts.sil.org/OFL).
All licensed under the
[SIL Open Font License, Version 1.1](https://openfontlicense.org):

- [Liberation Sans](https://github.com/liberationfonts) (Copyright (c) 2012
Red Hat, Inc. with Reserved Font Name Liberation): the engine's default
font atlas, used by the text demo.
- [Orbitron](https://github.com/theleagueof/orbitron) by Matt McInerney:
the website's headings.
- [Inter](https://github.com/rsms/inter) by Rasmus Andersson: the website's
body text.
- [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono) by JetBrains:
the website's code.

## Icons

- [Font Awesome Free](https://fontawesome.com) icons, licensed
[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).

## Galactic Journey

## Music
The gameplay video on the home page is from
[Galactic Journey](https://galactic-journey-6517e.web.app), a game made with
Forge. Besides the art credited above, it uses:

- Some music used in the demos and documentation have been provided by [GerardDEP](https://pixabay.com/users/gerarddep-48160304/?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=363808) from [Pixabay](https://pixabay.com//?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=363808)
- Some sound effects used in the demos and documentation have been provided by [LoLa Joy](https://pixabay.com/users/u_xg7ssi08yr-48039129/?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=381976) from [Pixabay](https://pixabay.com//?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=381976)
- The sci-fi UI kit by [Wenrexa](https://wenrexa.itch.io).
- [Oxanium](https://github.com/sevmeyer/oxanium) (Copyright 2019 The Oxanium
Project Authors), licensed under the
[SIL Open Font License, Version 1.1](https://openfontlicense.org).
12 changes: 11 additions & 1 deletion documentation-site/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,16 @@ const config: Config = {
onUntruncatedBlogPosts: 'warn',
},
theme: {
customCss: './src/css/custom.css',
// Self-hosted fonts: Orbitron for headings, Inter for body text and
// JetBrains Mono for code and small eyebrow labels.
customCss: [
require.resolve('@fontsource/orbitron/600.css'),
require.resolve('@fontsource/orbitron/700.css'),
require.resolve('@fontsource-variable/inter/index.css'),
require.resolve('@fontsource/jetbrains-mono/400.css'),
require.resolve('@fontsource/jetbrains-mono/500.css'),
'./src/css/custom.css',
],
},
} satisfies Preset.Options,
],
Expand Down Expand Up @@ -95,6 +104,7 @@ const config: Config = {
// Replace with your project's social card
image: 'img/forge-social-card.jpg',
colorMode: {
defaultMode: 'dark',
respectPrefersColorScheme: true,
},
navbar: {
Expand Down
Loading
Loading