This website requires JavaScript.
Explore
Help
Sign In
meleki
/
feuerwerk
Watch
1
Star
0
Fork
0
Code
Issues
38
Actions
Projects
1
Wiki
Activity
Files
5ba796a2b61415151f79099351a0fd3a6e718e30
feuerwerk
/
tests
/
core
T
History
admin
and
Claude Opus 5
5ba796a2b6
game-maker / gate (push)
Successful in 3m32s
Details
game-maker / suite (push)
Failing after 8m21s
Details
Plugins belong to the project, and they load before it: the project file gained the field plugins: ["demo-plugin.js"] (default empty, no formatVersion bump), the Plugins tab's switch writes into it as an ordinary undo step (SetPluginActiveCommand) instead of into a server-wide plugins.json, and the start order is turned around - startPlugins only fetches the list of files, then editor.boot() runs and ProjectStore.load(id, prepare) hands the raw JSON through before it is deserialized, where pluginsOf(raw) reads the list and PluginManager.syncTo() activates exactly those; that is the point of the issue, because what a plugin registers has to stand there before normalizeGraph would throw it away as unknown (
#126
,
#127
), a project switch first stops what the new project does not name and then starts what it does, a file the server does not have is passed over silently, and after signing out the manager is dead so a late event cannot start anything in a torn-down session; on the server plugins.json, PluginStore::setActive, isActive, the route PUT ?r=plugins/{file} and the 403 for inactive modules are gone and GET ?r=plugins only answers {file,bytes,updatedAt}, which makes every plugin file fetchable - the consequence accepted in
#117
, written down in the wiki for
#115
and
#116
; publishPlugins(root) only copies files now, the seeder switches the demo plugin on in the fixture project, and the Plugins tab carries a puzzle piece as its icon while only a plugin's own tab still goes without one (the knob and the socket are cubic curves, not arcs, which Pixi's parser draws as a spike after an L); 3 new e2e checks in module 38 and 5 new unit tests cover the project as the owner of the switch, its undo, the order, pluginsOf against crude input and an unknown file name (
#119
)
...
Co-Authored-By: Claude Opus 5 <
noreply@anthropic.com
>
2026-09-20 14:24:27 +02:00
..
animation-preview.test.ts
Physics stage 1a runs on Rapier: a new Rigidbody child object (body type, mass, gravity scale, damping, fixed rotation, CCD) makes its parent fall, bounce and come to rest in play, colliders gain friction, bounciness and density, the scene gains gravity (0, 980), the new PhysicsSystem steps at a fixed 60 Hz with interpolation in world coordinates and treats a tilemap as static ground, On collision enter gains normal and impulse, play waits for Rapier and does not start without it, and the editor run keeps the old CollisionSystem; the existing collision tests run against both systems unchanged (
#146
)
2026-09-18 18:11:43 +02:00
animation.test.ts
The scene view and the animation preview share one camera, the three form dialogs one base, and keys are found through one set of helpers (
#85
)
2026-09-17 14:19:53 +02:00
apply.test.ts
Measure a deviation against the base, not the innermost template
2026-09-09 13:45:27 +02:00
aspect.test.ts
Create a sprite asset from a texture's context menu
2026-09-11 09:57:19 +02:00
asset-ref.test.ts
Consolidate duplicated editor code, trim comments, refresh README
2026-09-11 11:00:30 +02:00
auth.test.ts
Changing the password: the Logout button at the far right of the toolbar became an Account menu that names the signed-in account in an entry of its own that cannot be picked, with Change password... above Logout, and the new dialog (src/editor/auth/PasswordDialog.ts) asks for the current password, the new one and its repetition, all three as bullets, and stays standing when the server refuses so that it can say why, unlike the other form dialogs; the rules for empty, too short, new equal to old and a differing repetition sit as the pure function passwordProblem() next to loginProblem(), the API gained POST ?r=auth/password which answers 204, insists on the current password although a session is there, enforces a minimum length of 8 in UserStore::MIN_PASSWORD_LENGTH and again in the client so the mask can answer without asking the server, and the new SessionStore::destroyAllFor($user, $keep) ends every other session of the account while the tab that changed the password keeps its own; the placeholders admin/admin and user/user stay as they are, which the length check does not touch because it only runs when a password is set through the API; e2e 45 grew by 8 checks for the menu, the dialog, both refusals and signing in with the old and the new password, and it sets the e2e account back at the end - a run dying in between leaves it on <password>-tmp, which a make-user.php call repairs (
#182
)
2026-09-20 13:46:40 +02:00
bag-commands.test.ts
Fix findUsages/undo/node-lookup bugs, split Viewport and Editor, share command and inspector helpers
2026-09-08 09:22:49 +02:00
behavior-events.test.ts
Physics stage 1a runs on Rapier: a new Rigidbody child object (body type, mass, gravity scale, damping, fixed rotation, CCD) makes its parent fall, bounce and come to rest in play, colliders gain friction, bounciness and density, the scene gains gravity (0, 980), the new PhysicsSystem steps at a fixed 60 Hz with interpolation in world coordinates and treats a tilemap as static ground, On collision enter gains normal and impulse, play waits for Rapier and does not start without it, and the editor run keeps the old CollisionSystem; the existing collision tests run against both systems unchanged (
#146
)
2026-09-18 18:11:43 +02:00
camera.test.ts
Play through the first camera that is switched on
2026-09-09 16:13:30 +02:00
collapsed-node.test.ts
Add the Variable node and show the variable name in node titles
2026-09-11 13:34:09 +02:00
collider.test.ts
Move with collision reacts along the contact normal: it travels to the surface, stays flush and slides the rest of the move along it with Coulomb friction (the mean of both colliders, a tile counts as 0.5), a circle now rolls over an edge instead of catching on it, pushed dynamic bodies move off along the normal, Move gains the outputs hit, normal x and normal y, an object without its own collider moves freely, and editor run and play share the same path through Solids; contact point and normal come from our own f64 geometry (contactBetween), because Rapier's castShape lands 3e-6 px inside the wall in f32 (
#150
)
2026-09-18 21:52:11 +02:00
collision-stay.test.ts
One-way platforms, raycast and collision stay with contact data: a collider can be one-way with a side it blocks from (turning with its object, drawn thick in the scene view) and a tile can be one-way from above, one-way cells never merge with solid tiles, a contact blocks only when its normal is within 45 degrees of the blocking side, the new node Ignore one-way lets an object drop through for a while, and it all holds for Move and for dynamic bodies in Rapier, where the decision is made before each step because the hook may not touch the engine (
#155
); the new Raycast node answers hit, object, collider, point, normal and distance in our own f64 geometry, the same in editor run and play, and the editor run draws each ray for 0.25 s (
#153
); On collision stay gains an interval with its own clock per pair, and stay and enter gain the contact point next to normal and impulse (
#149
); fixes that every Rapier collider of a tilemap had the shape of its last cell
2026-09-19 11:36:11 +02:00
commands.test.ts
Transform: scale, rotation and mirror as properties, world transform as a matrix chain, oriented colliders (
#76
)
2026-09-13 17:25:06 +02:00
container.test.ts
Remove exports and methods nothing uses any more
2026-09-11 20:15:49 +02:00
deviation.test.ts
Shader assets: graph-built shaders, the Shader tab and sprite rows from the graph (
#62
)
2026-09-12 22:41:14 +02:00
dynamic-ports.test.ts
State machines: asset, tab, State branch and Set state nodes (
#51
)
2026-09-12 18:00:23 +02:00
enabled.test.ts
Shader assets: graph-built shaders, the Shader tab and sprite rows from the graph (
#62
)
2026-09-12 22:41:14 +02:00
folded-edge.test.ts
Give the three asset tabs one base, and move the viewports into the editor
2026-09-10 07:14:38 +02:00
fonts.test.ts
Fonts: a new asset type, picked from the server or dropped in, worn by text objects (
#74
)
2026-09-13 20:09:59 +02:00
frame-commands.test.ts
A frame with borders tiles unless told to stretch
2026-09-16 18:13:11 +02:00
ghost-ports.test.ts
An edge to a vanished port needs a handle, so the port stays as a ghost (
#60
)
2026-09-14 11:50:36 +02:00
graph-annotations.test.ts
A graph that grew past one screen needs somewhere to say what a part of it is for (
#38
)
2026-09-16 11:24:34 +02:00
graph.test.ts
A state change is something the graph can react to, so the machine announces it (
#53
,
#54
,
#55
,
#57
)
2026-09-15 06:18:20 +02:00
hierarchy.test.ts
Transform: scale, rotation and mirror as properties, world transform as a matrix chain, oriented colliders (
#76
)
2026-09-13 17:25:06 +02:00
holders.test.ts
Plugins belong to the project, and they load before it: the project file gained the field plugins: ["demo-plugin.js"] (default empty, no formatVersion bump), the Plugins tab's switch writes into it as an ordinary undo step (SetPluginActiveCommand) instead of into a server-wide plugins.json, and the start order is turned around - startPlugins only fetches the list of files, then editor.boot() runs and ProjectStore.load(id, prepare) hands the raw JSON through before it is deserialized, where pluginsOf(raw) reads the list and PluginManager.syncTo() activates exactly those; that is the point of the issue, because what a plugin registers has to stand there before normalizeGraph would throw it away as unknown (
#126
,
#127
), a project switch first stops what the new project does not name and then starts what it does, a file the server does not have is passed over silently, and after signing out the manager is dead so a late event cannot start anything in a torn-down session; on the server plugins.json, PluginStore::setActive, isActive, the route PUT ?r=plugins/{file} and the 403 for inactive modules are gone and GET ?r=plugins only answers {file,bytes,updatedAt}, which makes every plugin file fetchable - the consequence accepted in
#117
, written down in the wiki for
#115
and
#116
; publishPlugins(root) only copies files now, the seeder switches the demo plugin on in the fixture project, and the Plugins tab carries a puzzle piece as its icon while only a plugin's own tab still goes without one (the knob and the socket are cubic curves, not arcs, which Pixi's parser draws as a spike after an L); 3 new e2e checks in module 38 and 5 new unit tests cover the project as the owner of the switch, its undo, the order, pluginsOf against crude input and an unknown file name (
#119
)
2026-09-20 14:24:27 +02:00
http-store.test.ts
Plugins belong to the project, and they load before it: the project file gained the field plugins: ["demo-plugin.js"] (default empty, no formatVersion bump), the Plugins tab's switch writes into it as an ordinary undo step (SetPluginActiveCommand) instead of into a server-wide plugins.json, and the start order is turned around - startPlugins only fetches the list of files, then editor.boot() runs and ProjectStore.load(id, prepare) hands the raw JSON through before it is deserialized, where pluginsOf(raw) reads the list and PluginManager.syncTo() activates exactly those; that is the point of the issue, because what a plugin registers has to stand there before normalizeGraph would throw it away as unknown (
#126
,
#127
), a project switch first stops what the new project does not name and then starts what it does, a file the server does not have is passed over silently, and after signing out the manager is dead so a late event cannot start anything in a torn-down session; on the server plugins.json, PluginStore::setActive, isActive, the route PUT ?r=plugins/{file} and the 403 for inactive modules are gone and GET ?r=plugins only answers {file,bytes,updatedAt}, which makes every plugin file fetchable - the consequence accepted in
#117
, written down in the wiki for
#115
and
#116
; publishPlugins(root) only copies files now, the seeder switches the demo plugin on in the fixture project, and the Plugins tab carries a puzzle piece as its icon while only a plugin's own tab still goes without one (the knob and the socket are cubic curves, not arcs, which Pixi's parser draws as a spike after an L); 3 new e2e checks in module 38 and 5 new unit tests cover the project as the owner of the switch, its undo, the order, pluginsOf against crude input and an unknown file name (
#119
)
2026-09-20 14:24:27 +02:00
key-repeat.test.ts
Type a repeat delay as whole milliseconds
2026-09-10 05:59:39 +02:00
kinds.test.ts
State machines: asset, tab, State branch and Set state nodes (
#51
)
2026-09-12 18:00:23 +02:00
list-item-kind.test.ts
An animation is a timeline of rows over one asset, played on an object rather than worn as a picture (
#97
)
2026-09-16 20:02:25 +02:00
list-of-structs.test.ts
Describe every value kind in one table instead of spreading it over the code
2026-09-12 14:47:17 +02:00
list-value.test.ts
Shader assets: graph-built shaders, the Shader tab and sprite rows from the graph (
#62
)
2026-09-12 22:41:14 +02:00
list.test.ts
The tab headers are one TabHeader, the node board and the tile board pan and zoom through one helper, reordering tile pictures and tilemap layers goes through one moveItem, and a tilemap cell is one named type (
#85
)
2026-09-18 16:01:12 +02:00
live-values.test.ts
State machines: asset, tab, State branch and Set state nodes (
#51
)
2026-09-12 18:00:23 +02:00
load-scene.test.ts
Physics stage 1a runs on Rapier: a new Rigidbody child object (body type, mass, gravity scale, damping, fixed rotation, CCD) makes its parent fall, bounce and come to rest in play, colliders gain friction, bounciness and density, the scene gains gravity (0, 980), the new PhysicsSystem steps at a fixed 60 Hz with interpolation in world coordinates and treats a tilemap as static ground, On collision enter gains normal and impulse, play waits for Rapier and does not start without it, and the editor run keeps the old CollisionSystem; the existing collision tests run against both systems unchanged (
#146
)
2026-09-18 18:11:43 +02:00
nested-behavior.test.ts
State machines: asset, tab, State branch and Set state nodes (
#51
)
2026-09-12 18:00:23 +02:00
node-catalog.test.ts
One-way platforms, raycast and collision stay with contact data: a collider can be one-way with a side it blocks from (turning with its object, drawn thick in the scene view) and a tile can be one-way from above, one-way cells never merge with solid tiles, a contact blocks only when its normal is within 45 degrees of the blocking side, the new node Ignore one-way lets an object drop through for a while, and it all holds for Move and for dynamic bodies in Rapier, where the decision is made before each step because the hook may not touch the engine (
#155
); the new Raycast node answers hit, object, collider, point, normal and distance in our own f64 geometry, the same in editor run and play, and the editor run draws each ray for 0.25 s (
#153
); On collision stay gains an interval with its own clock per pair, and stay and enter gain the contact point next to normal and impulse (
#149
); fixes that every Rapier collider of a tilemap had the shape of its last cell
2026-09-19 11:36:11 +02:00
nodes.test.ts
Replace the five variable nodes with one Variables node
2026-09-11 16:56:24 +02:00
one-way-angle.test.ts
The one-way tolerance angle is a field: a one-way collider and a one-way tile gain One-way angle (0 to 90 degrees, default 45), a contact blocks when its normal is within that angle of the blocking side, without a value the limit is bit-identical to before, and the rule holds for Move, Raycast and dynamic bodies in Rapier; tiles with different angles never merge into one rectangle, the scene view draws the angle as a cone in the middle of the thick side, and the inspector shows Blocks from and One-way angle only while One-way is on, through the new schema option shownWith (
#159
)
2026-09-19 13:13:29 +02:00
one-way.test.ts
One-way platforms, raycast and collision stay with contact data: a collider can be one-way with a side it blocks from (turning with its object, drawn thick in the scene view) and a tile can be one-way from above, one-way cells never merge with solid tiles, a contact blocks only when its normal is within 45 degrees of the blocking side, the new node Ignore one-way lets an object drop through for a while, and it all holds for Move and for dynamic bodies in Rapier, where the decision is made before each step because the hook may not touch the engine (
#155
); the new Raycast node answers hit, object, collider, point, normal and distance in our own f64 geometry, the same in editor run and play, and the editor run draws each ray for 0.25 s (
#153
); On collision stay gains an interval with its own clock per pair, and stay and enter gain the contact point next to normal and impulse (
#149
); fixes that every Rapier collider of a tilemap had the shape of its last cell
2026-09-19 11:36:11 +02:00
parallel-transitions.test.ts
Several transitions between the same pair of states: make transition onto a state that is already connected in that direction adds another transition, which gets its own name right away (Transition 2, Transition 3, skipping names that already leave the state), so two unnamed transitions between one pair never exist; renaming is refused when another transition between the same pair in the same direction already carries the name, the empty name included, while equal names to other targets are only warned about as before; the behavior graph keeps Already connected; self transitions may repeat too, each further loop drawn as a ring around the previous one with the preview showing the next ring, and transition labels that would cover another one slide along their own edge until they are free (pure function freeLabelSpot); test hook transitionLabelAt also returns width and height, e2e 26e6 (
#162
)
2026-09-19 16:30:52 +02:00
particles.test.ts
Three stores, three importers and three pickers that differ only in their type are one of each (
#85
)
2026-09-16 17:38:54 +02:00
physics-engine.test.ts
Rapier 2D (@dimforge/rapier2d-compat 0.20) comes in as the physics engine: the editor loads it once in the background right after opening a project from its own chunk, so the main bundle grows by 0.19 KB gzip and the first frame does not wait; loadPhysics, physicsStatus and the 100 px = 1 m conversion live in src/runtime/physics/engine.ts, __gm.physics() reports the state, unit tests pin free fall and a box resting on a box, and e2e module 41 pins that Rapier is ready from its own chunk without console noise (
#145
)
2026-09-18 16:56:47 +02:00
physics-system.test.ts
One-way platforms, raycast and collision stay with contact data: a collider can be one-way with a side it blocks from (turning with its object, drawn thick in the scene view) and a tile can be one-way from above, one-way cells never merge with solid tiles, a contact blocks only when its normal is within 45 degrees of the blocking side, the new node Ignore one-way lets an object drop through for a while, and it all holds for Move and for dynamic bodies in Rapier, where the decision is made before each step because the hook may not touch the engine (
#155
); the new Raycast node answers hit, object, collider, point, normal and distance in our own f64 geometry, the same in editor run and play, and the editor run draws each ray for 0.25 s (
#153
); On collision stay gains an interval with its own clock per pair, and stay and enter gain the contact point next to normal and impulse (
#149
); fixes that every Rapier collider of a tilemap had the shape of its last cell
2026-09-19 11:36:11 +02:00
placement.test.ts
Place assets by dragging them from the panel into the view
2026-09-09 13:09:13 +02:00
polygon.test.ts
The scene view outlines a tilemap's collision only along its outer edges: where two pieces meet, their shared stretch runs once in each direction and is not drawn, so an autotile lake is one outline without cross strokes at the quarters, merged rectangles of plain tiles and one-way tiles follow the same rule, the bridges from splitting concave outlines disappear and a piece doubled on two layers is outlined once; fill and collision stay as they were, and the result is cached per tilemap and rebuilt only when its collision data changes (
#173
)
2026-09-19 12:54:53 +02:00
property-ports.test.ts
State machines: asset, tab, State branch and Set state nodes (
#51
)
2026-09-12 18:00:23 +02:00
raycast.test.ts
One-way platforms, raycast and collision stay with contact data: a collider can be one-way with a side it blocks from (turning with its object, drawn thick in the scene view) and a tile can be one-way from above, one-way cells never merge with solid tiles, a contact blocks only when its normal is within 45 degrees of the blocking side, the new node Ignore one-way lets an object drop through for a while, and it all holds for Move and for dynamic bodies in Rapier, where the decision is made before each step because the hook may not touch the engine (
#155
); the new Raycast node answers hit, object, collider, point, normal and distance in our own f64 geometry, the same in editor run and play, and the editor run draws each ray for 0.25 s (
#153
); On collision stay gains an interval with its own clock per pair, and stay and enter gain the contact point next to normal and impulse (
#149
); fixes that every Rapier collider of a tilemap had the shape of its last cell
2026-09-19 11:36:11 +02:00
resolve.test.ts
Transform: scale, rotation and mirror as properties, world transform as a matrix chain, oriented colliders (
#76
)
2026-09-13 17:25:06 +02:00
scope.test.ts
A shared value belongs to no behavior, so it becomes an asset of its own (
#91
)
2026-09-14 18:05:36 +02:00
self-transition.test.ts
Several transitions between the same pair of states: make transition onto a state that is already connected in that direction adds another transition, which gets its own name right away (Transition 2, Transition 3, skipping names that already leave the state), so two unnamed transitions between one pair never exist; renaming is refused when another transition between the same pair in the same direction already carries the name, the empty name included, while equal names to other targets are only warned about as before; the behavior graph keeps Already connected; self transitions may repeat too, each further loop drawn as a ring around the previous one with the preview showing the next ring, and transition labels that would cover another one slide along their own edge until they are free (pure function freeLabelSpot); test hook transitionLabelAt also returns width and height, e2e 26e6 (
#162
)
2026-09-19 16:30:52 +02:00
serialize.test.ts
Plugins belong to the project, and they load before it: the project file gained the field plugins: ["demo-plugin.js"] (default empty, no formatVersion bump), the Plugins tab's switch writes into it as an ordinary undo step (SetPluginActiveCommand) instead of into a server-wide plugins.json, and the start order is turned around - startPlugins only fetches the list of files, then editor.boot() runs and ProjectStore.load(id, prepare) hands the raw JSON through before it is deserialized, where pluginsOf(raw) reads the list and PluginManager.syncTo() activates exactly those; that is the point of the issue, because what a plugin registers has to stand there before normalizeGraph would throw it away as unknown (
#126
,
#127
), a project switch first stops what the new project does not name and then starts what it does, a file the server does not have is passed over silently, and after signing out the manager is dead so a late event cannot start anything in a torn-down session; on the server plugins.json, PluginStore::setActive, isActive, the route PUT ?r=plugins/{file} and the 403 for inactive modules are gone and GET ?r=plugins only answers {file,bytes,updatedAt}, which makes every plugin file fetchable - the consequence accepted in
#117
, written down in the wiki for
#115
and
#116
; publishPlugins(root) only copies files now, the seeder switches the demo plugin on in the fixture project, and the Plugins tab carries a puzzle piece as its icon while only a plugin's own tab still goes without one (the knob and the socket are cubic curves, not arcs, which Pixi's parser draws as a spike after an L); 3 new e2e checks in module 38 and 5 new unit tests cover the project as the owner of the switch, its undo, the order, pluginsOf against crude input and an unknown file name (
#119
)
2026-09-20 14:24:27 +02:00
shaders.test.ts
Three stores, three importers and three pickers that differ only in their type are one of each (
#85
)
2026-09-16 17:38:54 +02:00
shapes.test.ts
The scene view outlines a tilemap's collision only along its outer edges: where two pieces meet, their shared stretch runs once in each direction and is not drawn, so an autotile lake is one outline without cross strokes at the quarters, merged rectangles of plain tiles and one-way tiles follow the same rule, the bridges from splitting concave outlines disappear and a piece doubled on two layers is outlined once; fill and collision stay as they were, and the result is cached per tilemap and rebuilt only when its collision data changes (
#173
)
2026-09-19 12:54:53 +02:00
sounds.test.ts
A game that is more than one scene needs a way from one to the next, so the graph can load one (
#39
)
2026-09-15 13:24:26 +02:00
state-machine.test.ts
A machine that arrives as a value can still be commanded, so a name may name its state (
#58
)
2026-09-16 09:08:57 +02:00
struct-shape-ports.test.ts
State machines: asset, tab, State branch and Set state nodes (
#51
)
2026-09-12 18:00:23 +02:00
struct-variable.test.ts
Drop the per-list item declaration; every item carries its own kind
2026-09-12 13:35:02 +02:00
text-and-pointer.test.ts
Replace the property nodes with one Properties node
2026-09-11 18:40:47 +02:00
texture-commands.test.ts
A border drawn in pixels is as wide as the texture says a pixel is, so a small sheet can frame a large sprite (
#96
)
2026-09-16 18:09:43 +02:00
texture-kind.test.ts
State machines: asset, tab, State branch and Set state nodes (
#51
)
2026-09-12 18:00:23 +02:00
texture.test.ts
The texture field only offers pictures: each texture with its frames, no animations any more; an animation id left in an older project shows as a missing reference (
#143
)
2026-09-18 12:14:01 +02:00
tile.test.ts
The loader keeps no migrations any more: an asset of the old type autotile (before
#131
) is an unknown type and dropped, and a tilemap layer with the cell map of the first version (before
#134
) loads empty; every project is saved in the current format, and the two tests now pin that the old shapes are not read (
#137
)
2026-09-18 15:12:07 +02:00
tilemap-cells.test.ts
The loader keeps no migrations any more: an asset of the old type autotile (before
#131
) is an unknown type and dropped, and a tilemap layer with the cell map of the first version (before
#134
) loads empty; every project is saved in the current format, and the two tests now pin that the old shapes are not read (
#137
)
2026-09-18 15:12:07 +02:00
tilemap-collision.test.ts
Move with collision reacts along the contact normal: it travels to the surface, stays flush and slides the rest of the move along it with Coulomb friction (the mean of both colliders, a tile counts as 0.5), a circle now rolls over an edge instead of catching on it, pushed dynamic bodies move off along the normal, Move gains the outputs hit, normal x and normal y, an object without its own collider moves freely, and editor run and play share the same path through Solids; contact point and normal come from our own f64 geometry (contactBetween), because Rapier's castShape lands 3e-6 px inside the wall in f32 (
#150
)
2026-09-18 21:52:11 +02:00
tilemap-fill.test.ts
The tilemap panel gains Fill and Pick: Fill floods the connected cells of the active layer that carry the same tile (edge neighbours only, bounded by the grid) as one undo step, Pick takes the tile of the clicked cell on the active layer, and holding Alt picks while any tool is active (
#133
)
2026-09-18 12:31:19 +02:00
tilemap-resize.test.ts
A placed tilemap grows and shrinks at every edge: the new GRID EDGES block in the inspector adds or removes one column or row at Left, Top, Right or Bottom as one undo step, shifting the cells of all layers and moving the placement through its own matrix so the content stays in place on screen; removed painted cells are kept outside the grid and return when the edge grows again, and the Columns and Rows fields of a placement keep the content in place too (
#136
)
2026-09-18 13:58:03 +02:00
tilemap.test.ts
The active tilemap layer can be renamed from the painting section, and a Show setting fades or hides the other layers in the scene view while the tilemap is selected (
#138
)
2026-09-18 10:56:32 +02:00
time.test.ts
One clock under everything that moves by itself (
#90
)
2026-09-14 09:31:53 +02:00
transform.test.ts
A source wears an icon without becoming decoration (
#89
)
2026-09-14 08:25:49 +02:00
variable-node.test.ts
State machines: asset, tab, State branch and Set state nodes (
#51
)
2026-09-12 18:00:23 +02:00
variable-ports.test.ts
A shared value belongs to no behavior, so it becomes an asset of its own (
#91
)
2026-09-14 18:05:36 +02:00
walk.test.ts
Move with collision reacts along the contact normal: it travels to the surface, stays flush and slides the rest of the move along it with Coulomb friction (the mean of both colliders, a tile counts as 0.5), a circle now rolls over an edge instead of catching on it, pushed dynamic bodies move off along the normal, Move gains the outputs hit, normal x and normal y, an object without its own collider moves freely, and editor run and play share the same path through Solids; contact point and normal come from our own f64 geometry (contactBetween), because Rapier's castShape lands 3e-6 px inside the wall in f32 (
#150
)
2026-09-18 21:52:11 +02:00
world-sync.test.ts
Remove exports and methods nothing uses any more
2026-09-11 20:15:49 +02:00