Skip to content

Refactor property value retrieval in DynmapPlugin - #4273

Open
filipkober wants to merge 1 commit into
webbukkit:v3.0from
filipkober:v3.0
Open

Refactor property value retrieval in DynmapPlugin#4273
filipkober wants to merge 1 commit into
webbukkit:v3.0from
filipkober:v3.0

Conversation

@filipkober

Copy link
Copy Markdown

Use serialized property names when building block state names

Problem

Modded blocks with enum properties whose Java constant names differ from their
serialized names are silently rendered as air. No warning is logged, no texture is
reported missing, and no amount of renderdata will reach them.

DynmapPlugin.initializeBlockStates() records a name for every block state:

statename += p.getName() + "=" + bs.getValue(p).toString();

For an enum property, Object#toString() returns the Java constant name. The chunk
NBT palette stores the serialized name. GenericMapChunkCache builds its lookup key
from the NBT and matches it against the recorded name in
DynmapBlockState.getStateByNameAndState(), which lowercases and compares.

Vanilla survives this because vanilla enum constants are just uppercased serialized names
(NORTH / "north", NORTH_SOUTH / "north_south"). Any mod enum where they diverge
does not match.

The failure is silent and permanent for the session:

rslt = AIR;  // Assume miss
...
blk.lookup.put(statename, rslt);  // Cache the lookup

getStateByNameAndState returns AIR rather than null on a miss, so the
if (palette[pi] == null) palette[pi] = getBaseStateByName(pname); fallback in the
palette loop never fires, and the miss is cached. The block is gone before anything
consults a texture map, which is why it never shows up in the dump-missing-blocks
report or the verbose no texture mapping output.

Reproduction

TerraFirmaCraft's Flow enum, used by tfc:fluid/river_water:

EEE("e"), NEE("nee"), N_E("ne"), NNE("nne"), NNN("n"), NNW("nnw"), N_W("nw"), NWW("nww"),
WWW("w"), SWW("sww"), S_W("sw"), SSW("ssw"), SSS("s"), SSE("sse"), S_E("se"), SEE("see"), ___("none");

Lowercased constant name vs serialized name:

resolves fails
NEEnee, NNEnne, NNWnnw, NWWnww EEEeeee
SWWsww, SSWssw, SSEsse, SEEsee N_En_ene
NNNnnnn
______none

Exactly the eight three-letter flow values render. Every one-letter, two-letter and
none value becomes air, producing holes in the middle of rivers that follow the flow
field rather than any obvious terrain feature. TFC leaves were affected too, via a
separate enum property, which went unnoticed until this was fixed.

Fix

Use the property's own name-for-value method, which resolves to the serialized name for
enum properties and to toString() for boolean and integer properties, where the old
behaviour was already correct.

  • Forge (official / MCP mappings): Property#getName(T)
  • Fabric (Yarn mappings): Property#name(T)

A small generic helper is needed because bs.getProperties() yields Property<?>, and
two separate uses of the same wildcard in one expression capture independently. The
helper binds the capture once. net.minecraft.Util#getPropertyName in vanilla exists for
the same reason.

The Bukkit helpers are unaffected. They already derive state names by parsing
IBlockData#toString(), which goes through StateHolder#toString() and therefore uses
serialized names.

Scope

20 files, forge-1.14.4 through forge-1.21.11 and fabric-1.14.4 through
fabric-1.21.9-10. forge-1.14.4 and forge-1.15.2 iterate a raw IProperty, so no
helper is required there and the call is inlined.

Verification

forge-1.20 (Minecraft 1.20.1, Forge 47.4.13) built from v3.7-beta-6 and run on a
TerraFirmaGreg-Modern server. All river water flow states render after a full render;
previously only eight of seventeen did. Other TFC blocks that were silently missing also
came back.

The remaining 19 modules are the same edit against their respective mappings and have not
been individually built. CI coverage on those would be welcome.

- Added a new method `getPropertyValueName` to retrieve the serialized name of a property's value within a block state, ensuring compatibility with modded enums.
- Updated instances where property values are appended to state names to use the new method instead of directly calling `toString()`, improving accuracy in rendering block states.
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