Refactoring round 9 covers everything since round 8 (14972d0): 62
commits with about 29 000 new lines in src, api, tools and tests.
Behaviour is unchanged. The one fix is in a check: e2e 04 counted 25
asset types, and the shader function from #303 makes 26, so the run
of a526e1b failed there.
Duplicate code (jscpd over src, 50 tokens, without the two licence
texts: 35 clones / 289 lines before, 29 / 232 after):
- ShaderPicture (new, viewport/shaderPicture.ts) is the picture a
camera's shader and a particle field's shader are laid over. It
keeps the render texture while its size holds and frees the
replaced one once the shader holds the new one. CameraShade and
ParticleField.shadeField drew it the same way, line for line.
- CameraShade builds its mesh on the first draw. Before, every redraw
of a view without a camera shader built a mesh and threw it away.
- emptyHost in inspector/host.ts builds the empty host the Inspector,
the Variables tab and the Tilemap panel start from.
- paddedQuad(null) is the plain unit quad. symbols.ts and
shaderPasses.ts each wrote it out by hand.
- In graph/nested.ts, calls of shader functions and On behavior
nodes are followed by one walk, `reaches`, over ids `namedBy` a
node type.
Dead code:
- ShaderEditor.colorFieldOf and the getter CurveCanvas.snapping had
no reader.
- 22 values used only in their own file lose their `export`. Types
and the node catalogues of shaders and particles stay exported.
- Kept on purpose: PhysicsSystem.holdsJoint is read by tests only,
but it is their one view of whether a joint holds.
- A pass with stricter lint rules over every file changed since
round 8 found no bug. PixelArtEditor.started is now readonly.
Comments and docs:
- Ten comments told history ("since #190", "used to", "any more").
They now describe what is. The bundle is md5-identical before and
after, and the four e2e files minify to the same bytes.
- README: joint and shader function in the asset list, joints on the
Physics row, what the Shaders page covers, two CI runners.
- e2e 04 keeps the number of asset types once, as ASSET_TYPE_COUNT.
- screenshot.png in the README is a new picture of the editor
(3840x2160 instead of 1825x1140), taken by the user.
Tests:
- Gate on melektaus-atx: 229 files, 3514 tests, CHECK EXIT 0
(+3 for emptyHost, +1 for the unit quad).
- e2e 1-4, 31, 63 on melektaus-atx: ALL PASSED, 195 checks. That is
the + menu of 04, the field shader of 31 and the camera shader of
63, both through ShaderPicture.
- No new e2e check, so the sum stays 1728.
- Counter-checks, each put back and compared with cmp: reaches that
never goes on fails 1 test, listensTo reading the wrong parameter
fails 1, emptyHost dropping what a panel hands in fails 1, folding
without a relayout fails 1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A shader could only ask its sprites for numbers. A tint, an outline
colour or a glow colour had to be built from three Property nodes.
- New node Color property next to Property: Name and Default (a
colour, white unless picked), output `color`. It becomes a colour
row below the Shader dropdown and a vec3 uniform in the program.
- Number and colour properties share one set of names. A clash is
the existing "Another property is named" problem.
- Like Color it cannot feed the Vertex output.
- Placed from the palette it is called tint, then tint2.
- The preview in the Shader tab shows a colour field for it. Like
the sliders it starts at the sprite's value and never writes into
the project.
- `declaredRows` takes the row builder, so the particle graph keeps
its number rows unchanged.
Tests:
- Gate: 222 files, 3452 tests (3445 + 7)
- e2e 28: 89 checks (28l-v: default colour drawn, then the colour
the sprite sets)
- e2e total 1704, counted (1703 + 1)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Recurring cleanup round over the code since round 6 (056a622), 105
commits. Behaviour is unchanged. Duplicated code in src went from 29
clones with 229 lines (0.32 %) to 14 clones with 109 lines (0.15 %),
measured with jscpd and the same settings as round 6.
- BehaviorSystem.ts shrinks from 941 to 589 lines. Collecting the
pulses (keys, timers, collisions, animations) moved to
behaviorPulses.ts. The NodeContext the nodes receive moved to
behaviorContext.ts. Imports from outside stay the same, TimeScaled
is still exported from BehaviorSystem.ts.
- PointKindButton and drawPointGrip replace the "Point:" button with
its menu and the point and handle drawing that the curve and the
vector art tab each had on their own.
- lerpVec, cubicAt and splitCubic in src/core/util/vec.ts replace four
copies of the cubic curve and two de Casteljau splits.
- mapNested in Properties.ts is the one walk over lists and structs
that liveObjects and objectRefs did separately. withFieldRenamed
and withoutField replace three copies of renaming a struct field
and two of removing one.
- jsonBody and staleRevision build the JSON body and turn a 409 into
StaleRevisionError for all stores. The auth store turns a 401 into
its error in one place.
- Smaller helpers: structAssetFrom for the two "Make struct type"
commands, shownObject in the inspector, selectedItem for the size
gizmo and the polygon corners, solidTiles in the tilemap collision,
requireVariablesAsset and requireBehaviorVariable.
- Left as is on purpose: the plain forwarding from the collision and
physics systems to Solids, the pointer wiring of the canvases and
the identical last lines of the two make commands.
- Removed unused code: tilemapTileIds and tilemapsUsing were never
called since #128 and #131. EditorState.runtimeProject became unused
with GameRun in #266. The assetId getter of the make commands was
read only by a test.
- 60 values used only in their own file lost their export. The shader
and particle node catalogues stay exported as in round 6.
- Five comments that told history now describe the current state. The
doc comment of BehaviorSystem sits on the class again.
- README lists the struct, clip area and curve assets and mentions the
game link from #266.
Findings:
- Deleting a tile that is painted on a tilemap leaves its cells in
place, and they draw nothing. The delete dialog does not mention the
tilemaps. That was probably the job of the unused tilemapsUsing.
Left as is, because fixing it changes behaviour.
- The solid filter for tile surfaces was untested. A bent filter
stayed green. A new test in tests/core/surface.test.ts now fails
against it.
Tests:
- ./check.sh: 195 files, 2815 tests, exit 0 (one test removed with
tilemapsUsing, one added for tile surfaces).
- Full e2e run: ALL PASSED, 1580 checks.
- Smokes jumprun, tetris, actor: 24, 19 and 21 checks, all passed.
The example project files were restored byte for byte afterwards.
- Counter-checks, 12, all fail as expected: 10 in unit tests (among
them mapNested, splitCubic, cubicAt, staleRevision, the stay pulse,
the late timer and the time scale), 2 in the browser (Point button
always enabled fails 47, selectedItem without a hit fails 29).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refactoring round one: HttpFontStore/HttpSoundStore/HttpTextureStore collapse into a generic
HttpFileStore over a FileStore contract; fontImport/soundImport/textureImport share assetImport
with an ImportKind per sort; ImagePicker/FontPicker/SoundPicker sit on FilePicker and describe
only their row. The group/comment drag logic leaves GraphCanvas for annotationDrag.ts (with its
own unit test), declaredRows.ts replaces the duplicated row build in particles.ts and shaders.ts,
and dead code in font/sound/compile/emission/transform/actions is gone. README: asset list,
check count 958, the two-job CI, the Scenes wiki page.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
#63: a shader Property node named "width" quietly took over the sprite
row of the same name. isSpriteProp lives in PropertySchema now and is
derived from FULL_SCHEMAS.sprite instead of being a second list that
drifts. isValidPropertyName rejects those ten names, and the compiler
reports it at the node as its own problem: "width" is a sprite
property, told apart from "not a word" and from a duplicate.
#64: Divide emitted (a / b) and handed NaN to the driver. It emits
divide(a, b) now, with the guard in the prologue next to straight(),
scalar and per channel: zero divided by zero is zero. That was already
the house rule in the behavior and particle graphs - only the shader
had never been told. Clamp comes along as a shader node for the same
reason: the behavior catalog has had it all along.
A shader is an asset carrying a node graph (Texture color, Output, Property,
Color, Add/Subtract/Multiply/Divide, Mix, Luminance) that compiles to the GLSL
fragment of a Pixi filter. The Shader tab reuses the Behavior canvas; a sprite
wears a shader through its Shader picker, and the rows below it are the
graph's Property nodes. Property schema, resolution and deviation take the
project because a sprite's rows now live in another asset. The built-in
registry of the prototype is gone; "Adjust colors" ships as a graph in the
fixture and the three example games.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>