Refactor round: ship web/index.html, drop the remote browser, fix stale comments and README

- `.gitignore` said `index.html` unanchored, which also caught the Vite source page;
  a fresh clone could neither `dev` nor `build`. Anchored to `/index.html`, page added.
- Removed GM_REMOTE (tools/remote/gm-browser.ps1 and the ssh/scp branch in browser.mjs):
  the Windows test machine is gone and the only flaky check that lived on it is closed (#37).
- Removed `npm run preview`, undocumented and unused.
- Comments: wrong number in collider.test.ts (250 → 200), the "declarations used to…"
  history in listItems.ts and friends, the 24 px/28 contradiction, section banners in
  nodes/index.ts, node-catalog.test.ts and api/index.php, name paraphrases, and the stale
  step numbers in tools/e2e/11-…23- from the old global count.
- README: asset types include `animation`, kind order Number/Text/Boolean, tagged colour
  and texture items, 6/5 kinds, the `Texture` node, `./build.sh`, PROJECT_FORMAT_VERSION,
  and the file tree (kinds.ts, listItems.ts, propertyPorts.ts, Breadcrumb.ts, beads.ts,
  tools/assets/).
- tests/helpers.ts takes the duplicated `findObject` and `sceneWithCamera`.

Proof: ./check.sh 797 tests, full e2e ALL PASSED 633 checks against this bundle.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Fable 5.1 committed 2026-09-12 15:44:05 +02:00
1 parent d86a655a4d
commit 6471671f7d
44 files changed
+196 -445

No files matched your search

-1
View File
@@ -49,7 +49,6 @@ export interface PointerState {
y: number;
inside: boolean;
down: boolean;
/** Went down / up during this frame. */
pressed: boolean;
released: boolean;
}
-10
View File
@@ -83,7 +83,6 @@ import { Variables } from './variable/Variables';
* the order here is documentation only.
*/
export const BUILT_IN_NODES: readonly NodeDef[] = [
// events
OnStart,
OnUpdate,
OnKeyDown,
@@ -96,15 +95,12 @@ export const BUILT_IN_NODES: readonly NodeDef[] = [
OnClick,
OnAnimationFinished,
BehaviorStart,
// flow
Branch,
Sequence,
Repeat,
RunBehavior,
BehaviorEnd,
// variables
Variables,
// data: references and properties
Self,
Owner,
Parent,
@@ -114,7 +110,6 @@ export const BUILT_IN_NODES: readonly NodeDef[] = [
IsEnabled,
Properties,
GetPosition,
// data: literals and math
NumberLiteral,
BooleanLiteral,
StringLiteral,
@@ -134,7 +129,6 @@ export const BUILT_IN_NODES: readonly NodeDef[] = [
Modulo,
Random,
Time,
// data: text and comparison
ToText,
ToNumber,
Join,
@@ -145,7 +139,6 @@ export const BUILT_IN_NODES: readonly NodeDef[] = [
And,
Or,
Not,
// data: lists
ListLiteral,
Fill,
Count,
@@ -154,10 +147,8 @@ export const BUILT_IN_NODES: readonly NodeDef[] = [
SubList,
Concat,
IndexOf,
// data: structs
PackStruct,
ExpandStruct,
// data: vectors and input
Length,
Distance,
Normalize,
@@ -167,7 +158,6 @@ export const BUILT_IN_NODES: readonly NodeDef[] = [
MouseButton,
IsHovered,
IsTouching,
// actions
Move,
SetPosition,
Spawn,
+1 -4
View File
@@ -1,9 +1,6 @@
import { type Asset, type ContainerAsset, isSceneAsset, type SceneAsset } from './Asset';
/**
* 2 since a placed container stopped copying its template into the scene. Old files are not
* migrated: the loader simply reads no container content from them any more.
*/
/** 2: a placed container carries no copy of its template. */
export const PROJECT_FORMAT_VERSION = 2;
export interface Project {
-1
View File
@@ -47,7 +47,6 @@ export function animationFrameAt(asset: AnimationAsset, time: number): FrameAt {
return frameAt(asset.frames.length, fpsOf(asset), playbackOf(asset), time);
}
/** Seconds for one pass through the frames. */
export function animationDuration(asset: AnimationAsset): number {
const fps = fpsOf(asset);
return fps > 0 ? asset.frames.length / fps : 0;
-1
View File
@@ -116,7 +116,6 @@ export interface SliceOptions {
/** Pixels skipped at the left/top edge of the sheet before the first cell. */
offsetX: number;
offsetY: number;
/** Pixels between neighbouring cells. */
spacingX: number;
spacingY: number;
}
-1
View File
@@ -3,7 +3,6 @@ import { defaultsFor } from './PropertySchema';
const DEFAULTS = defaultsFor('camera');
/** Axis-aligned rectangle in world units. */
export interface WorldRect {
left: number;
top: number;
-1
View File
@@ -17,7 +17,6 @@ type Circle = Extract<ColliderShape, { kind: 'circle' }>;
/** A movement axis in the plane (`z` is draw order, not geometry). */
export type PlaneAxis = 'x' | 'y';
/** Centred on `centre`, a world position. */
export function colliderShape(props: PropertyBag, centre: Vec2): ColliderShape {
if (props.shape === 'circle')
return {
+2 -3
View File
@@ -3,8 +3,7 @@
* value. JSON says what a number, a text, a boolean and a struct are; a tagged kind says so itself
* (`tagOf`), which keeps every list ever stored readable.
*
* Depth is capped the way the declarations used to cap it: a struct item holds flat items, and so
* does a list inside a struct field.
* Depth is capped: a struct item holds flat items, and so does a list inside a struct field.
*/
import {
type FieldValue,
@@ -75,7 +74,7 @@ export function listItemOf(value: PropertyValue | undefined): ListItem {
/**
* A flat position holds a primitive or a tagged item. Anything deeper is dropped rather than
* flattened – the same bound the declarations used to draw, and the one the store writes.
* flattened – the bound the store writes.
*/
export function flatItemOf(value: PropertyValue | undefined): FlatItem | undefined {
if (isList(value) || (isStruct(value) && !isTaggedKind(tagOf(value) ?? ''))) return undefined;
+1 -1
View File
@@ -69,7 +69,7 @@ export interface FieldRow {
/**
* The inspector's one column grid. A variable row is mark + name, a plain row a label spanning
* both, so every value starts at the same x. The mark column holds `≡Aa` (24 px measured).
* both, so every value starts at the same x. The mark column fits `≡Aa` (24 px measured) with air.
*/
export const MARK_WIDTH = 28;
export const NAME_WIDTH = 90;
-1
View File
@@ -208,7 +208,6 @@ export class World {
return this;
}
/** Advances the simulation by `dt` seconds. */
tick(dt: number): void {
this.elapsed += dt;
for (const system of this.systems) system.update(this, dt);
-1
View File
@@ -9,7 +9,6 @@ import type { Popup } from './Popup';
export interface ListItem {
id: string;
label: string;
/** Small secondary text on the right. */
hint?: string;
/** Left indent in levels. */
depth?: number;
-1
View File
@@ -11,7 +11,6 @@ export interface TextFieldOptions {
placeholder?: string;
style?: TextStyleToken;
width?: number;
/** Fires while typing. */
onInput?: (value: string) => void;
/** Fires on Enter / blur when the value changed since editing started. */
onChange?: (value: string) => void;