Addon development
API 1.0.0 is available in WWPG 0.2.1. Build stationary machines and instruments, add custom CEE panel properties, or connect Power Grid’s native board components to mixed circuits. The mod version and API version are independent.
This guide assumes you know Java, but does not assume you have written a NeoForge mod. Start with the single-device tutorial. The nine-device example and lifecycle contract remain useful references once your first block works.
Documentation update: October 12, 2026. Corrections describe existing API 1.0.0 behavior. Released binaries, source ZIPs and original Javadoc snapshots are unchanged.
Choose your integration
Section titled “Choose your integration”| Route | Contract | Working example |
|---|---|---|
| New stationary device or instrument | org.cha0scollective.wwpg.api and .api.neoforge |
General machine addon: nine devices using immutable models and accepted results. |
| Custom CEE property | Separate org.cha0scollective.wwpg.api.cee contract plus CEE 1.1.3 |
Native addon: a storage-indicator panel attachment with checkpointed numerical state. |
| Power Grid board component | Power Grid 0.6.2’s own component registration and simulation | Native addon: a circuit shunt assembled through PG’s designer. |
A PG-native component already has an electrical owner. Do not register a second WWPG circuit for it. The CEE adapter route and PG’s component route are separate upstream integrations.
Get the released SDK
Section titled “Get the released SDK”Use Java 21 and Minecraft 1.21.1 with NeoForge 21.1.231 / 21.1.248. The released SDK example projects build against 21.1.231. Check the full runtime requirements before testing in game.
- Download and extract the developer SDK bundle, verifying it against the release checksums.
- Extract its
maven/wwpg-api-1.0.0-maven.zipinto a directory such aswwpg-api-maven. The directory containingorg/cha0scollective/wwpgis the repository root. - Point your build at its absolute path and declare the exact version:
repositories { maven { url = uri('/absolute/path/to/wwpg-api-maven') }}dependencies { compileOnly 'org.cha0scollective.wwpg:wwpg-api:1.0.0'}The archive includes both coordinates, POMs, sources, and generated Javadoc. It works without GitHub credentials. Declare 1.0.0 explicitly; this distribution does not provide floating version-discovery metadata.
Build your first integration
Section titled “Build your first integration”Inside the developer SDK bundle, extract examples/wwpg-api-example-1.0.0-source.zip into its own directory. The bundle’s SHA256SUMS.txt also lists the enclosed files. The example includes its own Gradle wrapper and MIT license; no WWPG source checkout is needed.
Run from that extracted project, using the absolute path of your extracted Maven repository:
chmod +x gradlew./gradlew build "-PapiRepository=/absolute/path/to/wwpg-api-maven" --no-daemon.\gradlew.bat build "-PapiRepository=C:/dev/wwpg-api-maven" --no-daemonThe released ZIPs can lose the wrapper’s executable permission on Unix; the chmod step repairs it. Run these commands from the project containing settings.gradle, not from the outer SDK or Maven directory. A repository path containing spaces still works when the entire -PapiRepository=... argument is quoted.
The output is build/libs/wwpg-api-example-1.0.0.jar. Install it alongside WWPG 0.2.1 and every required mod on the server and each client. SDK jars stay in your development environment.
For a visible first circuit, obtain wwpg_api_example:source and wwpg_api_example:load from the Creative Redstone Blocks tab. Connect both matching red/blue terminal pairs with native wiring tools and a complete return path. The enabled load is two 100 Ω resistors in parallel: expect roughly 20 V, 0.4 A, and 8 W, allowing for native wire losses. Empty-hand right-click shows server readings; sneak-right-click changes the setting. These ideal developer devices do not define balanced survival progression.
The release-pinned source is the complete working implementation. Its ElectricalDevice interface is:
public interface ElectricalDevice { String providerId(); default String slotId() { return "main"; } List<Terminal> terminals(); CircuitDescription prepare(TickContext context); void commit(DeviceResults results);}This excerpt describes the contract; use the downloadable wrapped project for the complete imports, registration, device implementation, and resources. See the generated reference for the full signatures.
Registration and lifecycle
Section titled “Registration and lifecycle”Register during NeoForge’s RegisterCapabilitiesEvent using ElectricalProviders.registerBlock or registerBlockEntity. Each block has one declared electrical owner; duplicate claims fail. Registration freezes before worlds tick.
terminals() is a read-only immutable geometry query that can run on either logical side. It must not mutate the world or advance electrical history. Keep factories and geometry queries free of client-only classes.
prepare() must retain exactly the same terminal records returned by terminals(), compared as a set. Keys, native numbers, positions and hit radii all matter; ordering does not. A disabled device with wiring points keeps those terminals and opens a switch. CircuitDescription.empty() requires an empty geometry query too. See constructor limits before accepting configuration values.
prepare() captures immutable topology and parameters on the authoritative server thread. commit() receives one snapshot per participating server tick after PG’s substeps. Apply gameplay only when the status is VALID. NOT_READY, ISOLATED, and SOLVE_FAILED mean unavailable readings, including empty result/history maps; they are not measured zeroes or permission to reuse stale readings.
Use stable namespaced provider IDs, device slots, terminal keys and native numbers, node keys, and independent element IDs. Parallel elements need separate IDs even when their endpoints match. Preserve accepted capacitor voltage and inductor current in versioned native saved data; restore initial values only when reconstructing elements. Invalid results must not overwrite that history.
Call ElectricalDevices.changed(ServerLevel, BlockPos) from server-side placement, loading, and configuration hooks when the device changes. Chunk unload is temporary and preserves wires/history; permanent block replacement retires the old wire identities. Let held native wiring tools reach Item.useOn: the example returns SKIP_DEFAULT_BLOCK_INTERACTION for nonempty stacks and leaves empty-hand interactions to its readout/control.
An addon owns gameplay, rendering, networking, inventory, recipes, and persistence. WWPG owns interoperability and the shared electrical schedule. Do not run an extra solver, mutate topology during solving, or perform gameplay side effects in numerical trials. A throwing commit() is quarantined; repair the cause and explicitly notify ElectricalDevices.changed before retrying preparation.
Extend a CEE property or PG board
Section titled “Extend a CEE property or PG board”The SDK’s examples/wwpg-upstream-api-example-1.0.0-source.zip includes a separate wrapped project. Build it with the same command and Maven repository. It produces wwpg-upstream-api-example-1.0.0.jar and pins CEE 1.1.3, PG 0.6.2, Create, and the other development dependencies.
CEE adapters additionally declare:
compileOnly 'org.cha0scollective.wwpg:wwpg-cee-api:1.0.0'Subscribe to RegisterCeePropertyAdaptersEvent on your mod event bus, registering a namespaced ID and your exact custom property class. WWPG posts this event in the serial enqueued load-complete phase. Do not replace built-in CEE models or assume a superclass adapter owns subclasses.
Static adapters capture CeeElectricalParameters. Dynamic adapters use accepted substep callbacks and must checkpoint every field they can mutate. Restore checkpoints without world access or additional advancement. Use native CEE source polarity; WWPG translates it to PG. Whole-tick rollback covers checkpointed CEE numerical state, not arbitrary gameplay effects or native PG state. These callbacks must remain numerical.
The PG shunt keeps PG’s native component registration, model, damage, schematic identity, and assembly-item workflow. It does not gain a duplicate WWPG device model. Consult the native example implementation and CEE reference for the separate adapter contract.
Develop your own content
Section titled “Develop your own content”Create an adjustable load provides a complete small project and explains its naming, registration, models and saved settings. Build, install and debug explains the edit loop and debugger attachment. Test and troubleshoot gives symptoms, diagnostics and an author checklist.
The existing examples do not define project-managed game runs. Build their jars and install them into a separate client/server instance; the workflow guide makes that route explicit.
Test in the workshop
Section titled “Test in the workshop”The Extension API Workshop demonstrates nine general devices, a CEE storage indicator, and a PG shunt board. Install both example addon jars for this save. Ordinary WWPG factories do not require either example. Downloads and worlds include the base and optional Pinout editions.
Compatibility boundaries
Section titled “Compatibility boundaries”WWPGApi.version() reports API 1.0.0; WWPG’s mod version is 0.2.1. Compatible API additions use minor versions; breaking contract changes require a new major version and migration guidance. WWPG 0.2.1 retains the API 1.0.0 contracts introduced in 0.2.0; the public API jars are unchanged.
Use the supported API artifacts and pinned upstream contracts. WWPG’s bridge, wiring, mixin, gametest, solver internals, network objects, and JNI pointers are implementation details. API 1.0 covers stationary integration; moving contraptions, raw matrix access, replacement Lua APIs, and broad dependency ranges remain outside this release.
The optional Lua integration belongs to Pinout’s upstream API and is separate from this Java SDK. The future Ch4oS player manual will teach the installed pack’s gameplay edition.
Complete release-pinned developer contract · Java reference · General example guide · Native example guide