Skip to content

A feature on ground below the sea level casts no shadow - #54

Merged
CubeB merged 1 commit into
revivalfrom
9-shadows-on-water
Sep 15, 2026
Merged

CubeB merged 1 commit into
revivalfrom
9-shadows-on-water

Conversation

@HectorBailey

Copy link
Copy Markdown
Collaborator

For #9, the third item (shadows on water, upstream #25), as answered: match the original.

The decode. The gate list in §3 read the water test at 0x4592D5-0x4592F1 as "a building below the water line casts none unless [unit+0xA6] is set". unit+0xA6 is the unit's type index (§18), and the test is skipped when it is non-zero, so the rule is on type index zero only: the Feature Unit that draws map features. A feature whose ground (0x485070) is below the sea level byte casts nothing. A real building is never tested. And the water cut on a mobile unit's copied shadow (0x4BA1B0) lives only in the block taken when the bitmap carries a height plane, which a finished unit's does not (#40), so a finished unit driving through the shallows keeps its whole silhouette.

What changed.

  • featureCastsShadow(groundHeight, seaLevel) in GameScene_util, used by the model-feature shadow loop: ground below the sea level, no shadow. RWE used to draw every feature's shadow and lift a floating one to the surface.
  • Buildings and units unchanged: they already matched.
  • Notes: the §3 gate list corrected and the finished-unit cut clarified; a §100 subsection records the upstream request as considered and declined, with the reason, per your answer. Nothing in §88 or compatibility.md, since nothing departs from the original.

Verified. noshadow.test.cpp pins the strict-below rule; rwe_test: all 594 test cases pass (71755 assertions), Linux gcc-14 Debug.

The other two items of #9 (3DO texture distortion, GAF off-by-one) are untouched here.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PJCbwC9MGZnM6erMDKptun

The only water test in the original's shadow pass turns out to be on
map features. At 0x4592D5 the test is skipped for any unit whose type
index is non-zero, and type index zero is the Feature Unit that draws
the map's features: for those, and only those, ground below the sea
level byte casts nothing. A real building is never tested, and a
finished unit's copied shadow is not cut at the water line either --
the cut at 0x4BA1B0 needs a height plane a finished bitmap does not
carry. So a wreck on the sea bed or a rock in the shallows has no
shadow, and everything else is as it is on land.

RWE drew every feature's shadow, lifting a floating one to the surface.
It now skips a feature whose ground is below the sea level. The notes'
reading of that test as a building-on-water rule is corrected, and the
upstream request to cast shadows on the water surface is recorded in
S:100 as considered and declined: it is not what the original does.

Issue: #9

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJCbwC9MGZnM6erMDKptun
@CubeB

CubeB commented Sep 15, 2026

Copy link
Copy Markdown
Owner

Merging. It builds and passes on MinGW Debug and Release merged onto current revival, and the §3 correction reads right: a zero type index skips past the water test, so only the Feature Unit is tested.

One thing for a later look, not this PR. A floating building's shadow is still lifted to the water surface by groundHeight = rweMax(groundHeight, seaLevel) in the unit shadow loop (GameScene_render.cpp, under unitDefinition.floater || unitDefinition.canHover). Mobile hover and float units never get that far, so the line only touches buildings. The new §100 paragraph says a building's projection is "drawn flat at the ground under it wherever that ground is". For a floating building those two disagree. Either the line should go, or the paragraph should say which height the projected pass really uses (the unit's own Y would give the surface). If you read 0x45A790's caller for which height it passes, that settles it.

🤖 Generated with Claude Code

https://claude.ai/code/session_018moxVoyHDBoHqkw8uqS3HX

@CubeB
CubeB merged commit e11e1ef into revival Sep 15, 2026
5 checks passed
@CubeB

CubeB commented Sep 15, 2026

Copy link
Copy Markdown
Owner

Settled, in favour of your reading: the shadow goes at the ground under the building, wherever that ground is. The projected pass has no water test in it, and the one water test in the shadow pass is the Feature Unit's, which withholds a shadow rather than moving one.

So the lift is gone. rweMax(groundHeight, seaLevel) is out of the unit shadow loop, and a floating building's shadow now lands on the sea bed under it. A floating unit is unchanged and still casts nothing, 0x45957F skipping canhover and floater alike. I added a paragraph to your §100 subsection saying what RWE had been doing and that it stopped.

Committed locally on revival (not pushed yet). Nothing for you to do here; #53 is the one waiting on you.

🤖 Generated with Claude Code

https://claude.ai/code/session_018moxVoyHDBoHqkw8uqS3HX

CubeB added a commit that referenced this pull request Sep 16, 2026
Left over from the shadows-on-water work in #54. The unit shadow loop
lifted a floating building's ground height to the sea level before
placing its shadow, so a floating structure's shadow sat on the water
under it.

Nothing in the original does that. The projected pass a building takes
has no water test in it at all: the one water test in the whole shadow
pass is on the Feature Unit (section 3), which gives a map feature below
the sea level no shadow rather than moving its shadow. So the shadow
belongs at the ground under the building, wherever that ground is.

A floating unit is a different case and is unchanged: it casts no shadow
at all, the copied pass skipping canhover and floater alike (0x45957F).

Recorded in the section 100 subsection #54 added.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018moxVoyHDBoHqkw8uqS3HX
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.

2 participants