Skip to content

fix(common): apply parent rotation and scale to child position offsets - #587

Merged
stormmuller merged 5 commits into
devfrom
claude/github-issue-581-cuo2bu
Aug 7, 2026
Merged

fix(common): apply parent rotation and scale to child position offsets#587
stormmuller merged 5 commits into
devfrom
claude/github-issue-581-cuo2bu

Conversation

@stormmuller

Copy link
Copy Markdown
Member

Summary

composeWithParent in src/common/systems/transform-system.ts inherited a parent's world rotation and scale correctly, but composed a child's world position by plain addition of the parent's world position. The child's local offset was never rotated or scaled by the parent's world transform, so a child of a rotating parent spun in place instead of orbiting it (and a child of a scaled parent kept an un-scaled offset).

  • Split composeWithParent into composePositionWithParent, composeRotationWithParent, and composeScaleWithParent (also fixes a SonarJS cognitive-complexity lint failure the fix would otherwise trigger).
  • composePositionWithParent now rotates and scales the child's local offset by the parent's world rotation/scale before adding it to the parent's world position:
    world.position = parent.world.position + rotate(local.position * parent.world.scale, parent.world.rotation)
  • Deleted parent-position-system.ts, parent-rotation-system.ts, and parent-scale-system.ts (and their tests) - these carried the same additive-position bug, were superseded by createTransformEcsSystem, and were not exported from src/common/systems/index.ts or referenced anywhere outside their own tests.
  • Added tests covering a rotated parent, a scaled parent, a rotated + scaled parent, and a three-deep parent chain.

No demo under /documentation-site/src/pages/demos uses addParentComponent/ParentEcsComponent, so none are affected by this behavior change.

Behaviour change: any existing content that parents a positioned entity to a rotated or scaled one, authored against the previous (incorrect) additive composition, will now render differently (correctly). Flagged in the changelog per the issue's suggestion.

Related issue(s)

Closes #581

Verification checklist

  • npm run check-types passes with 0 errors
  • npm test passes
  • npm run lint passes with 0 errors
  • npm run cspell passes with 0 errors
  • npm run check-exports passes
  • Any new/changed public API is exported from the module's index.ts (and /src/index.ts / package.json exports if it's a new module) — n/a, no public API changed
  • Documentation under /documentation-site/docs/docs is updated if this change affects documented behavior — n/a, no doc describes this composition behavior
  • If this change touches a module with a demo under /documentation-site/src/pages/demos, the demo has been updated and verified — n/a, no demo uses entity parenting

Changelog

  • A bullet has been added under ## [Unreleased] in CHANGELOG.md

Generated by Claude Code

composeWithParent inherited rotation and scale correctly but composed a
child's world position by plain addition, so a child's local offset was
never rotated or scaled by the parent's world transform - a child of a
rotating parent spun in place instead of orbiting it. Rotate and scale the
local offset by the parent's world rotation/scale before adding it to the
parent's world position.

Also deletes parent-position-system.ts, parent-rotation-system.ts, and
parent-scale-system.ts, which carried the same additive-position bug and
were superseded by createTransformEcsSystem but never removed - they were
not exported from src/common/systems/index.ts and referenced only by their
own test files.

Fixes #581

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M42FeAcwfsHYR3btuySY5U
@stormmuller
stormmuller enabled auto-merge (squash) August 6, 2026 21:58

Copy link
Copy Markdown
Member Author

CodeQL analysis passed. However, the CI / Build and Test workflow (.github/workflows/ci.yml) and the Changelog workflow don't appear to have triggered at all for this PR - no run record exists for this branch, and neither workflow has run repo-wide since ~17:46 UTC today (Aug 6), several hours before this PR was opened. The workflow definitions are active/unchanged, so this looks like an infra-side issue (e.g. Actions runner/queue backlog or an account-level quota) rather than something in this PR's diff. Flagging since it's blocking the required status checks for auto-merge - may need a look from someone with access to the org's Actions settings/usage.


Generated by Claude Code

claude added 2 commits August 7, 2026 07:22
Push/pull_request webhook events were dropped during a GitHub Actions
incident (stuck ARC runner pods, resolved 2026-08-07 02:04 UTC), so
CI never ran for this PR. Empty commit to re-fire the trigger per
GitHub's incident notice.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M42FeAcwfsHYR3btuySY5U
"Behaviour" isn't in the project's dictionary; the repo consistently
uses American spelling ("behavior") elsewhere.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M42FeAcwfsHYR3btuySY5U
@codecov

codecov Bot commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

claude added 2 commits August 7, 2026 07:33
…stem

The refactor split into composePositionWithParent/composeRotationWithParent/
composeScaleWithParent added branches for a component present on an entity
but absent on its parent (or vice versa) that weren't exercised by the
existing rotated/scaled/chain tests, dropping patch coverage below the
project's Codecov target.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M42FeAcwfsHYR3btuySY5U
@stormmuller
stormmuller merged commit e3ff3b3 into dev Aug 7, 2026
12 checks passed
@stormmuller
stormmuller deleted the claude/github-issue-581-cuo2bu branch August 7, 2026 07:40
stormmuller pushed a commit that referenced this pull request Aug 7, 2026
…ng on dev

Merges dev, which brings in #587 (the parent-transform fix filed as #581) and
#588 (the AGENTS.md input capability correction filed as #582). Both were
surfaced by the review of this document, and both are now fixed, so the
document's claims about them were stale.

The transform gap row and its explanatory note move to past tense. #587 landed
exactly the composition the note proposed - scale the child's local offset by
the parent's world scale, rotate it by the parent's world rotation, then add -
and deleted the three superseded parent-*-system.ts files along with it. The
note is retained rather than removed, since the design's assumptions were formed
against the broken behavior and it is worth knowing they no longer are.

DL-03's "does this survive the fix" subsection moves to past tense too, and now
records that option (b) is no longer broken while still losing on the
load-bearing arguments.

Open question 2 loses its blocker: world-space canvas mode depended on the
transform fix, since a health bar parented to a rotating ship was exactly the
broken case.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WmVKWzRGU5FPVEwAa2oqVw
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(common): parented position offsets ignore the parent's rotation and scale

2 participants