Files
feuerwerk/src/core/commands/projectCommands.ts
T
adminandClaude Opus 5 4f55f85ad4
game-maker / gate (push) Successful in 2m41s
game-maker / suite (push) Failing after 8m21s
Collision layers and masks: a collider carries a layer and a mask of the layers it meets, and the pair only meets when both masks name the other's layer - the rule is one pure module (src/core/model/collisionLayers.ts) with layerBit, layersMeet and the names a project starts with, so the three places that have to agree read the same function: the editor run through CollisionSystem, the Solids sweep per pair and Rapier, where the mask becomes the collider's interaction groups; the project file gained collisionLayers: ["Default"] (default one layer, no formatVersion bump), the collider schema two new kinds - layer as a dropdown of the project's layers and layerMask as a menu of tickboxes that stays open while it is ticked (Menu.ts learned rows that do not close on a pick) - and the names are edited through "Collision layers..." in the toolbar's Project menu, not a Project tab, which is the decision I made myself because the question ran into the MCP timeout: the dialog (src/editor/CollisionLayersDialog.ts) holds up to 16 names, Add layer appends "Layer <n>" and Apply writes all of them as one undo step (SetCollisionLayersCommand); a mask read from a file goes through a check that refuses anything that is not a finite number, because Number(null) is 0 and a collidesWith: null would silently have meant "meets nothing"; 9 new e2e checks in module 8 cover the menu entry, the dialog, Add layer, Apply and its undo, both inspector rows, the tickbox menu, and the mover walking straight through the crate that 8c blocked on once their layers no longer meet, and 21 new unit tests cover the rule, the schema and the command (#152)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 15:31:22 +02:00

41 lines
1.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { collisionLayersOf } from '../model/collisionLayers';
import type { Project } from '../model/Project';
import type { Command } from './Command';
export class RenameProjectCommand implements Command {
readonly label = 'Rename project';
private previous = '';
constructor(private readonly name: string) {}
execute(project: Project): void {
this.previous = project.name;
project.name = this.name;
}
undo(project: Project): void {
project.name = this.previous;
}
}
/**
* The named collision layers of the project (#152). Colliders name a layer by number, so removing
* one shifts what every collider below it points at – which is why the dialog only ever hands over
* a whole list, and why the list is read through `collisionLayersOf` here as well.
*/
export class SetCollisionLayersCommand implements Command {
readonly label = 'Collision layers';
private previous: string[] = [];
constructor(private readonly names: readonly string[]) {}
execute(project: Project): void {
this.previous = project.collisionLayers;
project.collisionLayers = collisionLayersOf({ collisionLayers: this.names });
}
undo(project: Project): void {
project.collisionLayers = this.previous;
}
}