- drop per-guide Validation sections; manual gates stay in MANUAL_CHECKS - drop audit/provenance lines (reference checkouts, dated refreshes, commit pins) - state version status and Scala-free compile check once in API.md - replace API.md status prose with link to migration status - fix RELEASE_NOTES dangling sentence - rewrite README for GTNH fork and Java port
4.3 KiB
Registered part factory lookup
MultiPartRegistry.getPartFactory(String) returns the registered IPartFactory2 for an exact part type name, or
null when no factory is mapped.
IPartFactory2 factory = MultiPartRegistry.getPartFactory("mcr_face");
Lookup is case-sensitive, uses string equality and reads the current registration map. It neither constructs a part, logs unknown names, waits for registration nor changes registry state. It does not depend on the numeric network ID map. Look up after the owning mod has registered its types, on the initialization/game thread; no synchronization is added. Use published, non-null type names.
The result is the exact registered factory instance, not a copy or a mutable registry view. Do not modify its state.
Registration remains the job of registerPartFactory; lookup does not expose a replacement,
removal or enumeration operation. An earlier lookup result does not update itself if registry state later changes.
Choose the construction path
Most consumers should continue using loadPart(name, nbt) or readPart(input). Those choose the registered factory's
NBT/server or packet/client method. Their caller still invokes part.load(nbt) or part.readDesc(input), respectively,
and later binds/places the part. See factory and payload contracts.
Factory lookup is useful when a supported factory subtype provides a specialized construction method. Older Schematica
looks up a MicroblockClass and calls create(client, materialId) before loading the saved microblock NBT. Calling
loadPart instead would select the server/NBT construction path, even for a client preview. Passing a null packet or
using deprecated createPart(name, true) is also unsuitable: microblock packet factories read a material ID from it.
New preview integrations should use the complete client preview helper. See microblock creation when a caller specifically needs an unbound microblock.
The compiling Java example
checks for MicroblockClass and creates a fresh unbound microblock. The caller must resolve a valid material ID,
load the part's NBT, prepare the correct composite tile and complete its existing lifecycle. This example only covers
factory selection and construction, not a complete schematic loader. Its null result for an unsupported type must
cause the whole preview to be rejected when matching Schematica's all-parts-required policy.
Migrating Schematica's optional reflection
Prefer direct MultiPartRegistry.getPartFactory(partID) calls, as in the compiling example above. Isolate typed
optional integration code behind mod-presence/version checks; see the direct-call policy.
The following is only a legacy interoperability option for a consumer retaining reflection temporarily. It replaces
the companion singleton/private-field lookup and Scala Map.get / Option handling:
Class<?> registry = Class.forName("codechicken.multipart.MultiPartRegistry");
Method lookup = registry.getMethod("getPartFactory", String.class);
Object factory = lookup.invoke(null, partID);
if (factory == null) {
return null; // Keep the caller's missing-part rejection.
}
Cache the Method during integration initialization as Schematica already does. Continue resolving
MicroblockClass.create(boolean.class, int.class) with its exact parameter types and invoking it on this factory.
Not every registered factory is a microblock class: keep the existing rejection of an unsupported factory, or check
the reflected microblock class's isInstance(factory) explicitly before invoking. Do not silently produce a partial preview.
This removes only the registry-map Scala dependency. The client preview helper replaces the complete Schematica reconstruction path when the minimum FMP version can require it.
The private MultiPartRegistry$.codechicken$multipart$MultiPartRegistry$$typeMap field keeps its exact name, modifiers,
Scala mutable-map type and live backing, so existing binary/reflection callers keep working.
Client microblock creation only works on a physical client: a dedicated server strips clientTrait().