Skip to content

Migrate to Neoforge 1.21 - #76

Open
lonevox wants to merge 9 commits into
caeruleusDraconis:1.21from
lonevox:1.21
Open

Migrate to Neoforge 1.21#76
lonevox wants to merge 9 commits into
caeruleusDraconis:1.21from
lonevox:1.21

Conversation

@lonevox

@lonevox lonevox commented May 14, 2026

Copy link
Copy Markdown

I cherrypicked the recent commits from the 1.20 branch and made the Neoforge migration on top of that. Originally I had my 1.21 Neoforge migration built on the 1.20.1 branch, and cherrypicked that over, which was a bit of a merge hell so I hope I haven't discarded work that was done towards updating to 1.21 (I think I may have done so for SampleUtils.java). Regardless, this currently works in Neoforge 1.21.

lonevox and others added 9 commits May 15, 2026 03:36
This bug occurs due to `cellHeight`. Depending on the values of the "Higher y-value" heightmap setting and `cellHeight`, the resulting value can undershoot the "Higher y-value" heightmap setting, so the highest y-value allowed isn't actually sampled. With this fix, instead of sometimes undershooting, it will now sometimes overshoot, which is okay because of the added `if (y >= maxY) continue;` line, which stops those overshot values from being sampled.
Due to the compression algorithm, the first real value is flooded to
all block positions. This is intended behavior, however, when values
are not explicitly written to the storage (which is the case for
the "fast" height map generator) the flooded value is also not overwritten.
Thus resulting in invalid data beeing stored. The resulting heightmap
then has blocky artefacts.

This commit fixes this by explicitly setting unsampled positions to
the Short.MIN_VALUE magic value.

fixes caeruleusDraconis#69
The compressed section's single-value optimization caused the first
real value written to flood all unsampled positions, making them
appear sampled. In flat areas (ocean, mushroom islands), adjacent
sections received slightly different flood values, creating visible
rectangular boundaries.

The fix is: expand to level-1 compression on the first write so unsampled
positions correctly remain Short.MIN_VALUE. Replace the
Short.MIN_VALUE sentinel in mapData with an explicit mapDataCount
field, since Short.MIN_VALUE is now a legitimate map entry.

Also fixes a race condition where unsynchronized readers could see
mismatched data/mapData arrays during compression transitions, by
bundling both into a volatile CompressedState record.
I'm not sure how you determine this number, so I just increased it by 1.
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.

1 participant