Changelog
All notable changes to the SPC Addon API, listed by version.
1.1.6 Latest
April 19, 2026
New Features
-
Custom PNG icons for addon function blocks.
SpcNodeSchemagains an optionaliconTexturefield (10th record component) accepting aResourceLocationpath string (e.g."mymod:textures/gui/nodes/rotation_input.png"). When set, the programming editor renders the texture inside the block body and inside the palette glyph instead of falling back to theshortLabeltext. Recommended texture size: 16×16 or 32×32 PNG in the addon’s resource namespace. -
Custom Python builtins for the Embedded Python block.
New
com.hypernova.spc.api.pythonpackage lets addons register named callables that become available to every Embedded Python block in every program. Use this for Create speed/stress sensors, Mekanism gas readouts, config-aware math helpers, or any read-only world inspection.
Code Examples
Adding a custom block icon:
SpcNodeSchema schema = new SpcNodeSchema(
typeId,
SpcExecutionPhase.LOGIC_EVAL,
inputPorts,
outputPorts,
parameters,
/* requiresDisplay */ false,
"Rotation Input", // displayName
"RIN", // shortLabel
"Reads Create rotation speed.", // description
"RI", // labelPrefix
"createspc:textures/gui/nodes/rotation_input.png" // iconTexture (NEW in 1.1.6)
);
Backwards compatible: the existing 5-arg, 8-arg, and 9-arg
SpcNodeSchema constructors continue to work unchanged
(iconTexture defaults to null). Use
schema.hasIcon() to check whether a custom texture was provided.
Registering a custom Python builtin:
// In your @Mod constructor or FMLCommonSetupEvent:
SpcPythonBuiltinRegistry.register("create_speed", args -> {
if (args.isEmpty()) return SpcPythonValue.ofFloat(0.0);
long shaftId = args.get(0).asLong();
double rpm = MyCreateBridge.lookupSpeed(shaftId);
return SpcPythonValue.ofFloat(rpm);
});
SpcPythonBuiltinRegistry.register("clamp01", args -> {
double v = args.isEmpty() ? 0.0 : args.get(0).asDouble();
return SpcPythonValue.ofFloat(Math.max(0.0, Math.min(1.0, v)));
});
Players can then call these from any Embedded Python block:
# Inside an Embedded Python block in the LOGO editor:
rpm = create_speed(101)
duty = clamp01(rpm / 256.0)
print("duty:", duty)
API Surface
| Class / Field | Package | Purpose |
|---|---|---|
SpcNodeSchema.iconTexture |
com.hypernova.spc.api.node |
Optional String ResourceLocation path for the block’s PNG icon. |
SpcNodeSchema.hasIcon() |
com.hypernova.spc.api.node |
Helper returning true when iconTexture is non-null and non-empty. |
SpcPythonBuiltinRegistry |
com.hypernova.spc.api.python |
Static, thread-safe, freezable registry for custom Python callables. |
SpcPythonBuiltin |
com.hypernova.spc.api.python |
@FunctionalInterface taking List<SpcPythonValue> and returning SpcPythonValue. |
SpcPythonValue |
com.hypernova.spc.api.python |
Boundary value type covering None, Bool, Int, Float, String. Factories: none(), ofBool, ofInt, ofFloat, ofString. Coercions: asBool, asLong, asDouble, asString. |
Reserved Builtin Names
These names are reserved for the Embedded Python runtime and cannot be registered
by addons (registration throws IllegalArgumentException):
input, print, bool, int,
float, str, abs, min,
max, len, set_signal_type.
Identifier validation also rejects names that aren’t valid Python identifiers,
and registering the same name twice throws IllegalStateException.
The registry freezes during FMLCommonSetupEvent — late
registration also throws IllegalStateException.
Bug Fixes (runtime jar 0.3.0)
-
Fixed “
doneis not defined”NameError(and relatedNameErrors) in Embedded Python blocks where aglobaldeclaration referenced a matching Bool/Int/Float/String Variable node on the same program. Variable defaults are now seeded into the committed marker maps at program-load time, so Python sees a defined value on tick 1. NBT-restored state is preserved (putIfAbsentsemantics). - Variable nodes with disconnected inputs no longer overwrite a matching Python global’s same-tick write — the pending-value write is now gated on input presence.
Upgrade Steps
- Replace
storedprogramcontrols-1.1.5-api.jarwithstoredprogramcontrols-1.1.6-api.jarin yourlibs/folder. - Update
build.gradle:compileOnly files('libs/storedprogramcontrols-1.1.6-api.jar') - Update
neoforge.mods.toml:versionRange="[1.1.6,)"(only if you actually useiconTextureor the Python builtin API — older addons keep working against the 1.1.6 runtime jar). - Replace the runtime jar in
run/mods/withstoredprogramcontrols-0.3.0.jar.
1.1.5
April 17, 2026
New Features
-
Guide Book API (Patchouli integration).
Addons can register categories and entries that appear in the in-game LOGO
Guide Book without having to ship Patchouli JSON files. Content is served via
an in-memory resource pack injected through
AddPackFindersEvent. - Multi-addon safety. Duplicate category/entry IDs are handled gracefully — first registration wins, subsequent duplicates log a warning and are skipped. Unknown category references are logged as warnings at freeze time but do not prevent entries from being included.
Code Example
// In your @Mod constructor:
SpcGuideBookRegistry.registerCategory(new SpcBookCategory(
ResourceLocation.parse("createspc:rotation"),
"Create Integration",
"Rotation, stress, speed sensors and outputs.",
"createspc:textures/gui/book/rotation_icon.png",
100,
null // no parent
));
SpcGuideBookRegistry.registerEntry(new SpcBookEntry(
ResourceLocation.parse("createspc:rotation_input"),
"Rotation Input",
"createspc:textures/gui/nodes/rotation_input.png",
ResourceLocation.parse("createspc:rotation"),
10,
false,
List.of(
SpcBookPage.text("Reads RPM from a Create rotation shaft beneath the block."),
SpcBookPage.spotlight("createspc:rotation_input_block", "Place this block on a shaft.")
)
));
API Surface
| Class | Package | Purpose |
|---|---|---|
SpcGuideBookRegistry |
com.hypernova.spc.api.book |
Thread-safe static registry for addon book categories and entries. |
SpcBookCategory |
com.hypernova.spc.api.book |
Record: categoryId, name, description, icon, sortnum, optional parent. |
SpcBookEntry |
com.hypernova.spc.api.book |
Record: entryId, name, icon, category, sortnum, priority, list of SpcBookPage. |
SpcBookPage |
com.hypernova.spc.api.book |
Immutable page data with factories: text(), spotlight(), crafting(), image(), entity(), custom(). |
Upgrade Steps
- Replace
storedprogramcontrols-1.1.4-api.jarwithstoredprogramcontrols-1.1.5-api.jarin yourlibs/folder. - Update
build.gradle:compileOnly files('libs/storedprogramcontrols-1.1.5-api.jar') - Update
neoforge.mods.toml:versionRange="[1.1.5,)"(only if you use the Guide Book API).
1.1.4
April 11, 2026
New Features
-
Custom node label prefixes for addon nodes.
SpcNodeSchemanow accepts an optionallabelPrefixfield. When set, the programming editor displayslabelPrefix + channel(e.g. “RI1”, “RQ2”) instead of the generic “B001” label. This gives addon I/O nodes proper PLC-style labels.
Bug Fixes
- Port signal type mismatch no longer blocks simulation. If an addon changes a port’s signal type between versions, existing saved programs would fail validation with a blocking error. This is now a warning with an actionable message (“Re-place the node to update”).
API Changes
| Class | Change | Details |
|---|---|---|
SpcNodeSchema |
New field | labelPrefix — nullable, 1-3 char prefix for editor block labels |
Upgrade Steps
- Replace
storedprogramcontrols-1.1.3-api.jarwithstoredprogramcontrols-1.1.4-api.jarin yourlibs/folder. - Update
build.gradle:compileOnly files('libs/storedprogramcontrols-1.1.4-api.jar') - Update
neoforge.mods.toml:versionRange="[1.1.4,)" - Replace the runtime jar in
run/mods/with the lateststoredprogramcontrols-0.2.0.jar.
1.1.3
April 11, 2026
New Features
-
Full multiblock connected textures for addon blocks.
The
MultiblockPositionenum (with itsMB_POSblock state property) is now included in the API jar. Addon blocks that registerMB_POSin theircreateBlockStateDefinition()will automatically receive position-aware connected textures when the LOGO multiblock forms — borders are removed on internal seams, just like built-in blocks. Provide blockstate JSON variants for each(facing, mb_pos)combination and matching models.
New API Exports
| Class | Package | Purpose |
|---|---|---|
MultiblockPosition |
com.hypernova.spc.multiblock.model |
Enum of 10 grid positions + MB_POS property for connected textures |
Upgrade Steps
- Replace
storedprogramcontrols-1.1.2-api.jarwithstoredprogramcontrols-1.1.3-api.jarin yourlibs/folder. - Update
build.gradle:compileOnly files('libs/storedprogramcontrols-1.1.3-api.jar') - Update
neoforge.mods.toml:versionRange="[1.1.3,)" - Replace the runtime jar in
run/mods/with the lateststoredprogramcontrols-0.2.0.jar.
1.1.2
April 11, 2026
New Features
-
Connected texture API for addon display blocks.
New
ISpcConnectedDisplayinterface allows addon blocks to participate in the LOGO multiblock connected texture system. Implement this on your block class and return the display facing direction viagetDisplayFacing(BlockState). SPC’s built-in display blocks (and other addons) will recognize your block as a valid texture neighbor and connect accordingly. -
Live Diagnostics Panel API for addon modules.
New
ISpcDiagnosticsProviderinterface allows addon block entities to contribute custom entries to the Live Diagnostics Panel. Implement this on yourBlockEntityand returnSpcDiagnosticEntryinstances with a label, value, and active flag. Entries appear in a dedicated “Addon” section of the diagnostics overlay.
New API Classes
| Class | Package | Purpose |
|---|---|---|
ISpcConnectedDisplay |
com.hypernova.spc.api.multiblock |
Declare addon blocks as connected texture neighbors |
ISpcDiagnosticsProvider |
com.hypernova.spc.api.multiblock |
Contribute entries to the Live Diagnostics Panel |
SpcDiagnosticEntry |
com.hypernova.spc.api.multiblock |
Data record for a single diagnostic label + value |
Upgrade Steps
- Replace
storedprogramcontrols-1.1.1-api.jarwithstoredprogramcontrols-1.1.2-api.jarin yourlibs/folder. - Update
build.gradle:compileOnly files('libs/storedprogramcontrols-1.1.2-api.jar') - Update
neoforge.mods.toml:versionRange="[1.1.2,)" - Replace the runtime jar in
run/mods/with the lateststoredprogramcontrols-0.2.0.jar.
1.1.1
April 11, 2026
Bug Fixes
-
Addon blocks now recognized by multiblock validator.
LogoMachineBlocks.isMachineBlock()andgetModuleType()previously only checked for the internalLogoModuleProviderinterface. Blocks implementing the public API interfaceISpcMultiblockModulewere invisible to both BFS structure discovery and type validation. The multiblock always reported “Missing Input Block” / “Missing Output Block” even when addon blocks were placed correctly.
Details
Both isMachineBlock() and getModuleType() now have a fallback
path: if a block is not a built-in LogoModuleProvider, the methods check for
ISpcMultiblockModule, look up the registered SpcModuleType from
SpcModuleTypeRegistry, and map the declared SpcMultiblockPosition
to the corresponding internal LogoModuleType.
No addon-side code changes are required. Just update your dependency
version range to [1.1.1,) and replace the API jar.
Upgrade Steps
- Replace
storedprogramcontrols-1.1.0-api.jarwithstoredprogramcontrols-1.1.4-api.jarin yourlibs/folder. - Update
build.gradle:compileOnly files('libs/storedprogramcontrols-1.1.4-api.jar') - Update
neoforge.mods.toml:versionRange="[1.1.1,)" - Replace the runtime jar in
run/mods/with the lateststoredprogramcontrols-0.2.0.jar.
1.1.0
April 11, 2026 — Initial public release
Features
-
Custom function block nodes —
Register addon nodes via
SpcNodeSchema,ISpcCompiledNode, andSpcNodeRegistry. - Six signal types — DIGITAL, INTEGER, DECIMAL, TEXT, ITEM, ITEM_ID with automatic type conversion.
- Four-phase execution model — Input Read → Logic Evaluation → State Update → Output Apply.
- Persistent node state — Slot-based storage that survives across ticks and world saves.
-
Palette customization —
displayName,shortLabel, anddescriptionfields onSpcNodeSchemafor controlling how addon nodes appear in the editor. -
Multiblock module API —
ISpcMultiblockModule,SpcModuleType,SpcModuleTypeRegistry,ISpcPhysicalIoHandlerfor addon blocks that participate in the LOGO multiblock structure. -
Network device API —
ISpcNetworkDevice,ISpcNetworkActivation,ISpcCableTraversable,SpcNetworkRegistry. -
Runtime event API —
ISpcRuntimeEventListener,SpcRuntimeEventRegistryfor hooking into program lifecycle events. -
Context extensions —
ISpcExecutionContextExtensionfor injecting custom world interaction capabilities into the execution context. - Custom palette categories — Organize addon nodes under named categories in the Programming Block editor.