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>
This commit is contained in:
1 parent
5ba796a2b6
commit
4f55f85ad4
19 files changed
+721
-18
No files matched your search
@@ -29,6 +29,7 @@ import type {
|
||||
} from '../model/Asset';
|
||||
import { parseCellKey } from '../model/tilemap';
|
||||
import { pluginsOf } from './projectPlugins';
|
||||
import { collisionLayersOf } from '../model/collisionLayers';
|
||||
import { decodeCells, encodeCells } from './tilemapCells';
|
||||
import { isAssetType } from '../model/AssetTypes';
|
||||
import { isFontFile } from '../model/font';
|
||||
@@ -222,6 +223,7 @@ export function deserializeProject(raw: unknown, fallbackId = ''): Project {
|
||||
// The same reading the editor did before it loaded the plugins (#119), so the model says what
|
||||
// is actually running.
|
||||
plugins: pluginsOf(r),
|
||||
collisionLayers: collisionLayersOf(r),
|
||||
};
|
||||
return project;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user