TL;DR โ€” 3 things to do

1. Download the API jar and put it in libs/.
2. Add compileOnly files('libs/storedprogramcontrols-1.1.2-api.jar') to build.gradle.
3. Add a spc_core dependency to neoforge.mods.toml. Done!

On this page

Prerequisites

RequirementVersionNotes
Java JDK21+Oracle or Eclipse Temurin
NeoForge MDK1.21.1 (21.1.x)neoforged.net
Gradle8.x+Bundled with the MDK
Stored Program Controls0.2.0+Installed at runtime; API jar at compile time
โ„น๏ธ Already have a NeoForge mod?
Skip to Obtain the API jar โ€” you just need to add one dependency and one mod descriptor entry.

Obtain the API Jar

The SPC Addon API ships as a small standalone jar file (storedprogramcontrols-*-api.jar, ~28 KB). It contains only the public API classes โ€” interfaces, records, and enums. No implementation code.

Where to get it

  1. Go to the SPC Addon API page on CurseForge
  2. Download the latest storedprogramcontrols-*-api.jar for your Minecraft version

Place the jar in a libs/ folder in your project root:

my-spc-addon/ โ”œโ”€โ”€ build.gradle โ”œโ”€โ”€ libs/ โ”‚ โ””โ”€โ”€ storedprogramcontrols-1.1.2-api.jar โ† API jar goes here โ”œโ”€โ”€ gradle/ โ”œโ”€โ”€ settings.gradle โ””โ”€โ”€ src/

Project Structure

A typical SPC addon has this layout:

my-spc-addon/ โ”œโ”€โ”€ build.gradle โ”œโ”€โ”€ libs/ โ”‚ โ””โ”€โ”€ storedprogramcontrols-1.1.2-api.jar โ””โ”€โ”€ src/main/ โ”œโ”€โ”€ java/com/example/myaddon/ โ”‚ โ”œโ”€โ”€ MyAddon.java โ† @Mod entry point โ”‚ โ”œโ”€โ”€ node/ โ”‚ โ”‚ โ”œโ”€โ”€ MyNodeSchemas.java โ† SpcNodeSchema constants โ”‚ โ”‚ โ”œโ”€โ”€ MySensorNode.java โ† ISpcCompiledNode impl โ”‚ โ”‚ โ””โ”€โ”€ MySensorFactory.java โ† ISpcNodeFactory impl โ”‚ โ””โ”€โ”€ extension/ โ”‚ โ”œโ”€โ”€ IMyExtension.java โ† optional context extension โ”‚ โ””โ”€โ”€ MyExtensionImpl.java โ† extension implementation โ””โ”€โ”€ resources/META-INF/ โ””โ”€โ”€ neoforge.mods.toml โ† mod descriptor
๐Ÿ’ก Keep it organized
Separating node definitions into a node/ sub-package and extensions into extension/ keeps things clean as your addon grows.

Configure build.gradle

Add the API jar as a compile-only dependency. At runtime, the full SPC mod provides everything.

build.gradle
dependencies {
    // ... your existing NeoForge dependencies ...

    // SPC Addon API โ€” compile-only, provided by SPC at runtime
    compileOnly files('libs/storedprogramcontrols-1.1.2-api.jar')
}
โœ… Use compileOnly โ€” here's why
compileOnly makes the API available at compile time but keeps it out of your addon jar. The player's installed SPC mod provides the real classes at runtime โ€” no duplicates, no version conflicts.

Configure neoforge.mods.toml

Your addon must declare a required dependency on spc_core. This ensures NeoForge loads SPC before your addon and shows a helpful error if SPC is missing.

src/main/resources/META-INF/neoforge.mods.toml
# Your mod's main block
modLoader = "javafml"
loaderVersion = "[4,)"
license = "MIT"

[[mods]]
    modId = "my_spc_addon"
    version = "${file.jarVersion}"
    displayName = "My SPC Addon"
    description = "Custom LOGO nodes for Stored Program Controls."

# โ”€โ”€ Required: depend on spc_core โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[[dependencies.my_spc_addon]]
    modId = "spc_core"
    type = "required"
    reason = "Provides the SPC Addon API for custom function block nodes"
    versionRange = "[0.2.0,)"
    ordering = "AFTER"
    side = "BOTH"

# โ”€โ”€ Standard NeoForge dependency โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
[[dependencies.my_spc_addon]]
    modId = "neoforge"
    type = "required"
    versionRange = "[21.1,)"
    ordering = "NONE"
    side = "BOTH"

[[dependencies.my_spc_addon]]
    modId = "minecraft"
    type = "required"
    versionRange = "[1.21.1,)"
    ordering = "NONE"
    side = "BOTH"

Key fields

FieldValueWhy
modId"spc_core"The SPC identifier โ€” note: not storedprogramcontrols
versionRange"[0.2.0,)"Minimum SPC version. [ = inclusive, ) = no upper bound
ordering"AFTER"Load your mod after SPC so registries are available

Create the @Mod Class

This is your addon's entry point. It's where you register all nodes and (optionally) context extensions. Keep this class minimal โ€” just registration calls.

MyAddon.java
package com.example.myaddon;

import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.common.Mod;

@Mod("my_spc_addon")
public class MyAddon {

    public MyAddon(IEventBus modEventBus) {
        // Node registration goes here โ€” see the Tutorial page
        // SpcNodeRegistry.register(schema, factory, category);
    }
}
โ„น๏ธ When to register
Register your nodes in the @Mod constructor. SPC freezes its registries during FMLCommonSetupEvent, so anything registered after that will throw IllegalStateException.

Verify Your Setup

  1. Run ./gradlew build โ€” it should compile without errors
  2. Run ./gradlew runClient with the SPC mod jar in the run/mods/ folder
  3. Open the mod list โ€” you should see both "Stored Program Controls" and your addon
  4. If your addon node registration works, open the Programming Block GUI and check the palette
๐Ÿ’ก Check the API version
You can verify API compatibility at runtime:
if (SpcApi.API_VERSION < 1) {
    LOGGER.error("Incompatible SPC API version!");
}

What's Next?

Now that your project compiles, head to the tutorial to build your first node: