Content format

Jobs, research nodes, housing tiers, export entries and blueprints are all datapack JSON. Adding a job, a research branch, a trade good or a whole structure needs no Java at all.

Where files go

data/<namespace>/nerocolonies/jobs/<path>.json
data/<namespace>/nerocolonies/research/<path>.json
data/<namespace>/nerocolonies/housing/<path>.json
data/<namespace>/nerocolonies/exports/<path>.json
data/<namespace>/nerocolonies/blueprints/<path>.json

Blueprints — the structures a colony builds for itself — follow every rule on this page, but their schema is documented with the system that uses it: see Construction.

The id is the file path. data/mypack/nerocolonies/research/mining/drills.json is the node mypack:mining/drills. Subdirectories are part of the id, which is how the shipped research tree gets its habitation/, industry/, life_support/ and trade/ grouping.

Every schema accepts an id field, and every schema ignores it — it exists only so a file that was written out by a generator still loads. The path always wins.

A pack overrides a definition by shipping the same id. Drop your own data/nerocolonies/nerocolonies/jobs/farm.json into a datapack and it replaces the shipped farm job entirely; ordinary datapack precedence decides which pack wins.

Content is re-read whenever the server's datapacks are reloaded, so /reload applies changes immediately. Nothing is migrated and nothing needs to be: what a colony stores is a set of ids, and every number is derived from the currently loaded definitions on demand.

Item targets and item amounts

Two small shapes appear throughout.

An item target (job inputs, export targets) selects exactly one of a single item id or an item tag, plus a count:

{ "item": "minecraft:wheat", "count": 4 }
{ "tag":  "c:crops",         "count": 4 }
FieldTypeDefaultNotes
itemitem id—mutually exclusive with tag
tagitem tag id, written without a leading #—mutually exclusive with item
countinteger1minimum 1

Declaring both, or neither, is a decode error and drops the owning definition with a warning.

Tags are the preferred form throughout the shipped content: a tag lets a farming mod, a planet mod or any third party satisfy a colony job with its own produce, and needs no compat code on either side. Hard item ids are used only where the item is unmistakably vanilla.

An item amount (job outputs, research costs) is always a concrete item:

{ "item": "minecraft:iron_ingot", "count": 8 }
FieldTypeDefaultNotes
itemitem id—required
countinteger1minimum 1

Jobs

data/<namespace>/nerocolonies/jobs/<path>.json

The shipped nerocolonies:fabricate:

{
  "station": "nerocolonies:fabricator_station",
  "inputs": [
    { "item": "minecraft:iron_ingot", "count": 1 },
    { "item": "minecraft:redstone", "count": 2 }
  ],
  "outputs": [
    { "item": "minecraft:repeater", "count": 1 }
  ],
  "ticks": 400,
  "colonists": 2,
  "morale_floor": 35.0,
  "research": "nerocolonies:industry/fabrication",
  "export": true
}
FieldTypeDefaultRangeMeaning
stationblock id— (required)—the block this job runs on
inputslist of item targets[]—consumed from colony storage, all or nothing
outputslist of item amounts[]—placed in colony storage, or in the export buffer
ticksinteger2001–72,000progress needed for one craft
colonistsinteger10–64workers wanted; 0 is fully automated
morale_floordouble20.00–100below this colony morale the job will not run
researchnode idnone—research prerequisite, if any
exportbooleanfalse—route the output to the export buffer

Every magnitude here is scaled at runtime by jobBaseRateMultiplier and by the colony's morale multiplier, so the JSON expresses shape — what turns into what, and roughly how fast — not balance.

A job is dropped when it has no outputs, when its station block is not registered, when one of its inputs resolves to nothing in this launch, or when one of its outputs names an unregistered item. A recipe missing an ingredient is not a cheaper recipe, it is a broken one.

Research nodes

data/<namespace>/nerocolonies/research/<path>.json

The shipped nerocolonies:habitation/pressurised_modules:

{
  "branch": "habitation",
  "title": "research.nerocolonies.habitation.pressurised_modules",
  "requires": [ "nerocolonies:habitation/shelter" ],
  "cost": [
    { "item": "minecraft:iron_ingot", "count": 8 },
    { "item": "minecraft:glass", "count": 4 }
  ],
  "effects": [
    { "type": "nerocolonies:housing_tier", "tier": "nerocolonies:habitat_module" },
    { "type": "nerocolonies:morale_bonus", "amount": 2.0 }
  ]
}
FieldTypeDefaultMeaning
branchstring"general"presentational grouping in the research screen only
titletranslation keyderivedfalls back to research.<namespace>.<path with dots>
requireslist of node ids[]the actual graph
costlist of item amounts[]paid from colony storage, all or nothing
effectslist of effects[]see below

Costs are paid from colony storage, and unlocks are written to the colony record — research is colony-local and is not personal data.

Research effects

Effects are a dispatched type keyed on type:

typeFieldDefaultRangeEffect
nerocolonies:housing_tiertier (housing id)— (required)—makes a housing tier countable in this colony
nerocolonies:job_unlockjob (job id)— (required)—makes a job assignable in this colony
nerocolonies:job_slotsamount (integer)1—adds simultaneously worked job slots
nerocolonies:oxygen_efficiencymultiplier (double)0.90.05–4.0multiplies life-support oxygen burn; below 1.0 is an improvement, and every unlocked node compounds
nerocolonies:export_unlockexport (export id)— (required)—makes an export entry sellable from this colony
nerocolonies:morale_bonusamount (double)1.0-100–100flat addition to the morale target

An unregistered type is not an error. It decodes to an inert Unknown effect: the node still loads, that one effect does nothing, and the id is logged once per session. A datapack written for a newer NeroColonies therefore degrades rather than bricking an older jar. An add-on mod may register its own effect types the same way the built-ins are registered; ids are namespaced, so a collision is the registering mod's own doing.

How the research graph is validated

Three passes, in order:

  1. Effects that point at content which did not load are reported and kept. They simply match nothing. Keeping them means removing one mod does not silently reshape a tree.
  2. Dangling prerequisites are pruned and the node stays. A node that requires an id no longer in any pack loses that one requirement rather than the whole node.
  3. Cycles are dropped. The graph is peeled from its roots; anything left is in — or behind — a prerequisite cycle and can never be unlocked, so it is removed.

Housing tiers

data/<namespace>/nerocolonies/housing/<path>.json

The shipped nerocolonies:habitat_module:

{
  "block": "nerocolonies:habitat_module",
  "tier": 2,
  "capacity": 4,
  "comfort": 0.65,
  "research": "nerocolonies:habitation/pressurised_modules"
}
FieldTypeDefaultRangeMeaning
blockblock id— (required)—the block that counts as this housing
tierinteger11–16ranking; used to break ties between two tiers naming one block
capacityinteger10–256colonists this block seats
comfortdouble0.50–1weight in the morale housing term
researchnode idnone—research prerequisite, if any

Housing is matched by block, not by block entity: one block-state comparison during the sweep, no block entity needed, and a pack can declare any block in the game — vanilla beds, another mod's crew module — as colony housing.

A tier is dropped when its block is not registered or when its capacity is zero. If two tiers claim the same block, the one with the higher tier wins, deterministically.

Export entries

data/<namespace>/nerocolonies/exports/<path>.json

The shipped nerocolonies:refined_metals:

{
  "target": { "item": "minecraft:iron_ingot", "count": 1 },
  "base_value": 4.0,
  "stack_size": 64,
  "research": "nerocolonies:trade/manifest"
}
FieldTypeDefaultRangeMeaning
targetitem target— (required)—what this entry values
base_valuedouble1.00–1,000,000credits per item, before exportValueMultiplier
stack_sizeinteger641–64reserved; accepted and validated, but not yet read by the sale path
researchnode idnone—research prerequisite, if any

An entry is dropped when its target resolves to no item in this launch — an empty tag sells nothing.

Bad content is never fatal

This is a hard rule. Every malformed file, unknown effect type, dangling reference, cycle and unregistered id is logged at warning level against its resource id, and the offending entry is dropped or pruned — the rest of the pack still loads. Even a load that fails outright leaves the server running with no colony content rather than crashing it.

The same complaints are collected as a report so an operator can see what a pack got wrong without reading the server log:

/nerocolonies reload-check

Issues come in two severities: DROPPED (the definition is not loaded at all) and IGNORED (the definition loaded, but part of it was skipped). Nothing in the report is player data — resource ids and codec messages only, and never a filesystem path.

See also

Search across every Nero mod wiki.