mirror of
https://github.com/GTNewHorizons/ForgeMultipart.git
synced 2026-11-15 17:54:59 +00:00
149 lines
14 KiB
Markdown
149 lines
14 KiB
Markdown
# ForgeMultipart Java API
|
|
|
|
Start here when integrating with ForgeMultipart for **Minecraft 1.7.10 / Forge**. This describes the `algent/java`
|
|
migration branch. Its new APIs are implemented and tested but do not yet have a minimum published dependency version.
|
|
Use a dev artifact containing the methods you need; source Javadocs are packaged with the sources artifact.
|
|
|
|
Consumers can use the Java surface without importing Scala types. FMP still retains Scala storage, runtime and
|
|
compatibility bridges, and some extension contracts still need migration. A Scala-authored mod can adopt the Java API
|
|
without converting the rest of its code to Java.
|
|
|
|
Run `./gradlew compileJavaApiExamples` (or `gradlew.bat compileJavaApiExamples` on Windows) to compile the existing
|
|
Java examples with a Java 8 compiler against the packaged dev jar and dependencies excluding `scala-*` libraries.
|
|
This also runs through `check`. It covers every Java file in the test and functional-test `examples` packages,
|
|
including their supporting types; add new documented examples there to extend coverage. Main/test class outputs,
|
|
annotation processors and source lookup are not used to supply FMP classes. This is a compile-time API check only:
|
|
FMP still needs Scala at runtime, and generated-trait behavior remains covered separately by Forge functional tests.
|
|
|
|
**Rebuilding an existing mod against this branch? Read the [release notes](RELEASE_NOTES.md) first.** Shipped binaries
|
|
keep working, but recompiling has three classes of break, and the trait-composition one compiles cleanly and changes
|
|
behavior at runtime. Use the [consumer migration checklist](api/MIGRATION_CHECKLIST.md) to carry a source change through
|
|
runtime validation, release and target-pack adoption.
|
|
|
|
## Direct calls and optional integration
|
|
|
|
The intended consumer API uses direct typed public calls, without reflection, private-field mixins or Scala
|
|
companion lookup. Reuse existing entry points where they cover the task. For optional support, isolate FMP-typed
|
|
code in a compatibility class loaded only after mod-presence and supported-version checks; test absent and present
|
|
mod loading. Reflection snippets in older guides are legacy interoperability options, not the migration target.
|
|
Existing reflective binaries remain supported until consumer release and pack adoption.
|
|
|
|
## Choose a guide
|
|
|
|
| Task | API and guide |
|
|
| --- | --- |
|
|
| Define, place, persist, synchronize and remove a custom part | `TMultiPart`, `canPlacePart`, `addPart`, `remPart` - [end-to-end custom-part lifecycle](api/CUSTOM_PARTS.md) |
|
|
| Register block converters | `registerConverter(IPartConverter)` - [registration, state ownership and committed lifecycle](api/BLOCK_CONVERTERS.md) |
|
|
| Register part factories during mod initialization | `registerPartFactory(IPartFactory2, String...)` - [factory timing, payload ownership and migration](api/PART_REGISTRATION.md) |
|
|
| Find the factory registered for a part type | `getPartFactory(String)` - [lookup ownership and Schematica reflection migration](api/FACTORY_LOOKUP.md) |
|
|
| Enumerate microblock materials by numeric ID | `materialCount()`, `materialName(int)`, `getMaterial(int)` - [material enumeration](api/MATERIAL_ENUMERATION.md) |
|
|
| Read a microblock material's block and metadata | `BlockMicroMaterial.block()`, `meta()` - [typed GuideNH query, identity and overrides](api/MATERIAL_ACCESS.md) |
|
|
| Create a microblock with the requested material and side | `MicroblockGenerator.create(MicroblockClass, int, boolean)` - [construction, material traits and GuideNH migration](api/MICROBLOCK_CREATION.md) |
|
|
| Call generated tile capabilities from Java | `TileMultipart`, `IRedstoneTile` and ordinary interfaces - [safe compilation and raw-trait pitfalls](api/TILE_TRAIT_ACCESS.md) |
|
|
| Add aggregate or lifecycle behavior to generated multipart tiles | `registerTrait(marker, trait)` - [custom Java tile traits, stable capabilities and transformer constraints](api/CUSTOM_TILE_TRAITS.md) |
|
|
| Refresh slots after a stored part changes shape | `refreshPartSlots(TMultiPart)` - [ownership, equality and notification responsibilities](api/TILE_TRAIT_ACCESS.md#refreshing-a-changed-slot-mask) |
|
|
| Add material-specific behavior to generated microblocks | `registerTrait(String)` and `IGeneratedMaterial` - [illuminated Java extension, compilation and side contracts](api/MICROBLOCK_EXTENSIONS.md) |
|
|
| Change an existing FMP saw's cutting strength | `ItemSaw.setHarvestLevel(int)` - [state, lifecycle and Iguana migration](api/SAW_STRENGTH.md) |
|
|
| Read/index/search a tile's parts | `jPartList()` - [part collection ownership and order](api/PART_TRAVERSAL.md#collection-ownership-and-ordering) |
|
|
| Run callbacks only on parts still owned by the tile | `forEachPart(Consumer)` - [callback and override behavior](api/PART_TRAVERSAL.md#callback-behavior) |
|
|
| Rebuild parts on an already prepared composite tile | `loadPartList(Collection)` - [part loading](api/PART_LOADING.md) |
|
|
| Select client/server tile capabilities before preparing state and loading | `MultipartGenerator.generateCompositeTile(TileEntity, Iterable, boolean)` - [staged generation and reflection migration](api/COMPOSITE_GENERATION.md) |
|
|
| Assign stored parts during reconstruction, without binding or notifications | `setPartList(List)` - [storage assignment](api/PART_LOADING.md#storage-assignment) |
|
|
| Test a candidate against a selected collection of parts | `testOcclusion(Collection, candidate)` - [occlusion queries and generated hooks](api/OCCLUSION.md) |
|
|
| Test two groups of bounding boxes directly | `NormalOcclusionTest.testBoxes(Iterable, Iterable)` - [box-versus-box queries](api/OCCLUSION.md#box-versus-box-queries) |
|
|
| Read FMP's global render registration ID | `TileMultipart.getRenderID()` - [render-ID meaning, lifecycle and setter](api/RENDER_ID.md) |
|
|
| Inspect an existing tile or converted placeholder with a named result | `getOrConvertTileResult(World, BlockCoord)` - [conversion outcomes and placement lifecycle](api/TILE_CONVERSION.md) |
|
|
| Add or remap multipart button attachment orientations | `ButtonPart.setOrientation(int, ForgeDirection)` - [metadata, face mapping and Et Futurum migration](api/BUTTON_ORIENTATIONS.md) |
|
|
|
|
Each guide explains ownership, lifecycle, legacy replacements and limitations, and links to a compiling Java example
|
|
exercised by the test suite. The loading/setter APIs are advanced reconstruction operations; ordinary placement and
|
|
removal should use the existing world APIs below.
|
|
|
|
## Existing Java entry points
|
|
|
|
These entry points already exist. The links lead to their source/Javadocs; detailed migration guides and checks for
|
|
compilation without Scala are still pending in these areas. A Java-typed overload can still require Scala on the
|
|
compile classpath for overload resolution, as the [loading guide](api/PART_LOADING.md#overrides-and-reflection) explains.
|
|
|
|
| Area | Starting points |
|
|
| --- | --- |
|
|
| Construct a server composite tile from parts, or restore saved multipart NBT | [MultipartHelper](../src/main/scala/codechicken/multipart/MultipartHelper.java): `createTileFromParts(Iterable)`, `createTileFromNBT(World, NBTTagCompound)` |
|
|
| Register microblock materials | [MicroMaterialRegistry](../src/main/scala/codechicken/microblock/MicroMaterialRegistry.java) and [BlockMicroMaterial](../src/main/scala/codechicken/microblock/BlockMicroMaterial.java) |
|
|
| Register generated tile traits or pass-through interfaces | [MultipartGenerator](../src/main/scala/codechicken/multipart/MultipartGenerator.java); see [custom tile-trait authoring](api/CUSTOM_TILE_TRAITS.md) and [safe capability access](api/TILE_TRAIT_ACCESS.md) |
|
|
|
|
New API examples use Java 8 language/library features. The source path `src/main/scala` also contains Java classes
|
|
because of the current joint-compilation layout; it does not imply that those APIs require Scala source in a consumer.
|
|
|
|
## Supported API and internal hooks
|
|
|
|
Public visibility alone does not make a method a consumer entry point. Scala's former package-private methods are
|
|
public in bytecode. Source Javadocs now mark the following audited implementation hooks **Internal FMP**; keep
|
|
consumer code on the public operations in the right column. These markers change no visibility, descriptor or
|
|
behavior and do not deprecate or authorize removing a method. Trait callbacks and generated overrides still run.
|
|
|
|
| Internal hooks | Consumer operation or responsibility |
|
|
| --- | --- |
|
|
| `TileMultipart.addPart_impl`, `addPart_do`, `writeAddPart` | Place through `TileMultipart.addPart(world, pos, part)`; use [part loading](api/PART_LOADING.md) for prepared reconstruction |
|
|
| `TileMultipart.remPart_impl` | Remove through `tile.remPart(part)` on the server and retain the returned tile |
|
|
| `TileMultipart.partAdded`, `partRemoved` | Lifecycle callbacks for trait overrides; callers use placement/removal APIs |
|
|
| `TileMultipart.from`, `copyFrom`, `loadFrom`, `setValid` | FMP composite transitions; use [staged generation](api/COMPOSITE_GENERATION.md) and [loading](api/PART_LOADING.md) for consumer reconstruction |
|
|
| `MicroMaterialRegistry.setupIDMap`, `calcMaxCuttingStrength` | FMP initializes IDs and cutting strength; register materials at initialization and read the resulting values |
|
|
| `MicroMaterialRegistry.loadIcons` | FMP dispatches client texture callbacks; override the supported `IMicroMaterial.loadIcons()` material callback |
|
|
| `MicroMaterialRegistry.writeIDMap`, `readIDMap` | FMP's whole-map handshake; part packets use `writeMaterialID` / `readMaterialID` for individual IDs |
|
|
|
|
The registry's matching companion methods carry the same internal marker. This is a bounded consumer audit,
|
|
not a claim that every other public member is a supported API. See [TileMultipart's Javadocs](../src/main/scala/codechicken/multipart/TileMultipart.java)
|
|
and [registry Javadocs](../src/main/scala/codechicken/microblock/MicroMaterialRegistry.java) for method-specific details.
|
|
|
|
Three advanced methods remain supported because consumers use them directly:
|
|
|
|
- **`bindPart(part)`** updates capability caches through generated overrides. It does not insert the part, change
|
|
its tile binding or perform placement/notifications. The legacy OpenComputers integration clears a print part's old
|
|
slot entries before calling it to populate a changed slot mask. A repeated call does not clear obsolete slots and
|
|
may append entries in other trait caches. Use `refreshPartSlots` for that migration; full reconstruction uses
|
|
`loadPartList`.
|
|
- **`refreshPartSlots(part)`** replaces OpenComputers' direct generated-array mutation. Generated slotted tiles clear
|
|
equal cached entries and invoke the virtual bind chain once; base tiles do nothing. It leaves ownership, storage,
|
|
validation and notifications to the caller. See the [slot-refresh contract](api/TILE_TRAIT_ACCESS.md#refreshing-a-changed-slot-mask).
|
|
- **`internalPartChange(part)`** sends local `onPartChanged` callbacks through the retained `operate` hook. The base
|
|
traversal captures list order, visits only parts still bound to the receiving tile, and excludes parts equal to the
|
|
changed part using `part.equals(p)`. Null broadcasts to all eligible parts. Detached or transferred parts are skipped.
|
|
Callback failures stop traversal and propagate. ProjectRed deliberately handles dirty state,
|
|
packets and external neighbors separately; this method does none of those. `notifyPartChange` also performs world
|
|
update/neighbor/lighting notifications when needed.
|
|
|
|
No reflection is needed to call any of these methods. `operate` and `getOrConvertTile2` retain their documented legacy
|
|
contracts and Java replacements; neither receives an internal-only marker. Removing those bridges still requires
|
|
consumer and internal migration gates. The [consumer audit](migration/COMPATIBILITY.md#api-boundary-audit)
|
|
records the checked source calls and validation.
|
|
|
|
## Compatibility and remaining work
|
|
|
|
Deprecated Scala-facing entry points remain callable, with their descriptors and supported override dispatch retained.
|
|
Follow the method-specific guide: a Java sibling is not automatically a replacement override hook, and reflection
|
|
must select the intended parameter types when a method is overloaded.
|
|
|
|
An [illuminated Java microblock extension](api/MICROBLOCK_EXTENSIONS.md) now covers registration, material traits,
|
|
light aggregation and halo geometry, with compiling examples and Forge coverage. Its physical-client rendering and
|
|
ProjectRed adoption remain open. [Converter registration and lifecycle](api/BLOCK_CONVERTERS.md) are documented and
|
|
tested. [Stable tile capability access](api/TILE_TRAIT_ACCESS.md) covers safe Java calls, ProjectRed redstone queries
|
|
and OpenComputers slot refresh. [Custom Java tile-trait authoring](api/CUSTOM_TILE_TRAITS.md) covers registration,
|
|
stable capabilities, lifecycle/state rules and transformer constraints with generated Forge coverage. Supported
|
|
[button orientation mapping](api/BUTTON_ORIENTATIONS.md) replaces Et Futurum's reflective array mutation. Supported
|
|
[saw-strength mutation](api/SAW_STRENGTH.md) replaces Iguana's private-field access. ProjectRed's existing Scala
|
|
traits remain supported until adoption.
|
|
|
|
The audited Scala-typed API gaps have Java replacements linked above; broader extension validation and
|
|
consumer adoption remain open in the [migration status](migration/README.md).
|
|
|
|
FMP-side implementation is separate from consumer releases and target-pack adoption. Retiring legacy bridges or the
|
|
Scala dependency requires those gates and removal of FMP's remaining internal Scala users.
|
|
|
|
| Need | Document |
|
|
| --- | --- |
|
|
| What is complete and what comes next? | [Migration status](migration/README.md) |
|
|
| Which consumers need changes, releases and pack adoption? | [Consumer adoption ledger](migration/COMPATIBILITY.md#java-api-adoption-ledger) |
|
|
| Which binary names, reflective lookups and runtime contracts must survive? | [ABI inventory and consumer audit](migration/COMPATIBILITY.md) |
|
|
| What has been tested and what still needs a client/pack run? | [Migration status](migration/README.md), [manual release checks](migration/MANUAL_CHECKS.md) |
|
|
| Why is some Scala or older Java syntax retained? | [Build boundaries](migration/MAINTAINERS.md#build-and-runtime-boundaries), [compiler constraints](migration/MAINTAINERS.md#retained-compiler-constraints) |
|