Skip to content

Fix/Rotatable Shutter Placement#116

Open
rebaserHEAD wants to merge 6 commits into
Triad-Sector:mainfrom
rebaserHEAD:fix/rotatable-shutter-placement
Open

Fix/Rotatable Shutter Placement#116
rebaserHEAD wants to merge 6 commits into
Triad-Sector:mainfrom
rebaserHEAD:fix/rotatable-shutter-placement

Conversation

@rebaserHEAD
Copy link
Copy Markdown
Contributor

About the PR

So we had a few small but annoying shutter bugs piling up, and the blast door frames had the same shape of problem... bundled the fixes so it's one review instead of four.

Shutters

  • Rotation now applies at placement (was locked to default facing).
  • Frame snaps anchored on creation so it can't drift off-tile mid-build.
  • Frames + finished shutters can share a tile with windows/grilles, which is the whole point of a shutter anyway.

Blast door frames (BlastDoorFrame, BlastDoorXenoFrame)

  • Removed noRot: true so the frame keeps placement rotation and the finished door inherits it.
  • Added WallMount arc 360 so construction steps (cables, etc.) and interactions still work when a window shares the tile.
  • NO change to buildability rules. Blast doors still don't build over windows like shutters do. Only the interaction/rotation parity got pulled across.

Why no anchor fix on the blast door side: the BlastDoor construction graph's frame1 node already runs SnapToGrid + SetAnchor on creation, and both frame entities are static bodies. They don't drift, so no fix needed.

Why / Balance

Pure QoL/bugfix, no balance impact. Shutters being non-rotatable and refusing window tiles made the whole "shutter for a window" use case impossible without console hacks. Blast door frames just inherited the same rotation lockout and lost interactivity any time a window shared the tile, so cabling them up was a coin flip.

Media

Small fix, exempt.

Requirements

  • I have read relevant guidelines/documentation to this PR found on our devwiki.
  • I have added media to this PR or it does not require an ingame showcase.
  • I can confirm this PR contains either no AI-generated content, or AI-generated content that meets our guidelines.

How to test

  1. Place a shutter rotated 90/180/270 in placement preview, confirm the finished shutter matches.
  2. Build a shutter frame on a window tile, finish construction, confirm it operates.
  3. Same drill for BlastDoorFrame and BlastDoorXenoFrame, including the cable step on a tile that already has a window.
  4. Confirm blast doors STILL refuse to build on bare window tiles from scratch (no regression on the buildability rule).

Breaking changes

None.

Changelog

🆑

  • tweak: Shutters can now be rotated at placement.
  • fix: Shutter frames anchor on creation, so they no longer drift off-tile mid-build.
  • tweak: Shutters can be built on tiles that already hold a window or grille.
  • tweak: Blast door frames keep their placement rotation, so the finished door faces the way you placed it.
  • fix: Blast door frames remain interactable (cable step, etc.) when a window shares the tile.

rebaserHEAD and others added 5 commits May 21, 2026 23:19
ShuttersFrame had `noRot: true` on its Transform, which made Robust
silently drop the placement rotation when the construction frame was
spawned. Since the construction graph copies LocalRotation forward to
each subsequent node, the finished shutter always ended up at the
default facing regardless of how the player rotated the ghost.

Commenting out `noRot: true` lets the frame keep its placement angle,
which then propagates to the completed shutter.
The Shutters construction graph's frame1 node had no actions, so the
freshly-spawned ShuttersFrame - an unanchored Dynamic body inherited
from BaseStructureDynamic - was never anchored. When a shutter was
built on an impassable tile (e.g. over a window, which the recipe
allows via canBuildInImpassable), physics ejected the loose frame off
the tile during the first construction step.

The BlastDoor graph already does this correctly: its frame1 node runs
SnapToGrid + SetAnchor actions on creation. Mirror that on the Shutters
graph so the frame is snapped and anchored the moment it spawns.
Interaction reach checks raycast from the user to the target and treat
any anchored entity in the way as an obstruction. A reinforced window
sharing the shutter's tile blocked that ray, so construction steps
(e.g. adding cables to the frame) and later interactions silently
failed when a shutter was built over a window.

The engine already solves this for windows and firelocks with a
WallMount component, whose only effect is to exempt intersecting
anchored entities from interaction obstruction checks. BaseFirelock
uses `arc: 360` for exactly this reason ("interact despite grilles").

Add the same WallMount (arc 360) to BaseShutter and ShuttersFrame so
the whole construction lifecycle - frame, cable step, and finished
shutter - is reachable when a window or grille shares the tile.
Bring BlastDoorFrame and BlastDoorXenoFrame in line with the shutter
fixes:

- Remove `noRot: true` so the frame keeps its placement rotation,
  which then propagates to the finished blast door.
- Add WallMount (arc 360) so construction steps and interactions work
  when a window or grille shares the frame's tile.

No anchor fix is needed here: the BlastDoor construction graph's
frame1 node already runs SnapToGrid + SetAnchor on creation, and both
frames are static bodies, so neither drifts.
@github-actions github-actions Bot added S: Untriaged YML No C# Doesn't contain any C# code size/S and removed S: Untriaged labels May 23, 2026
@Triad-Sector Triad-Sector changed the title Fix/rotatable shutter placement Fix/Rotatable Shutter Placement May 23, 2026
The Shutters construction graph's frame1 node now runs SetAnchor on
ComponentStartup (a706bcc), which flips Transform.Anchored to true and
the Physics body from Dynamic to Static. PrototypeSaveTest diffs the
spawned Physics component against the prototype yaml (Transform is
skipped, Physics is not), so the Dynamic -> Static delta failed CI.

Mirror BlastDoorFrame and declare bodyType: Static on the prototype.
Prototype and runtime now agree, and the static body also prevents the
unanchored frame from being shoved off impassable tiles.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

No C# Doesn't contain any C# code size/S YML

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant