Creating a Custom Origin
This guide walks through creating a brand-new origin for your data pack.
Prerequisites
You should have a working data pack. If you're new to data packs, read the Minecraft Wiki tutorial first.
Step 1: Define the Origin File
Create a JSON file at data/<namespace>/origins/origin/<id>.json. For this tutorial we'll use example:supermorph, so the file goes at:
data/example/origins/origin/supermorph.json
Here is a minimal origin that reuses vanilla powers:
{
"powers": [
"#example:supermorph"
],
"icon": {
"id": "minecraft:slime_ball"
},
"order": 4,
"impact": 1
}
{
"replace": false,
"values": [
"origins:fire_immunity",
"origins:elytra",
"origins:throw_ender_pearl",
"origins:fresh_air"
]
}
The powers List can contain both power IDs and tags. In this case, we define a tag example:supermorph that includes several existing powers to create a flying, fire-immune origin.
Using tags are recommeneded for better capability and extensibility.
If you directly list powers in the origin file, other data packs won't be able to add or remove powers from your origin without replacing the whole file. With tags, they can simply add or remove powers from the tag without needing to replace your origin file.
Origin JSON Field reference
| Field | Type | Default | Description |
|---|---|---|---|
name | Text Component | optional | The display name of the origin. Use translation key origin.<namespace>.<path>.name is more recommended |
description | Text Component | optional | The description shown in the origin's tooltip. Use translation key origin.<namespace>.<path>.description is more recommended |
powers | ReferenceOrTagList | [] | Power IDs or tags granted by this origin. Use "origins:xxx" or "#origins:tag_name" |
icon | Item Stack | optional | The item displayed as the origin's icon in the selection screen |
unchoosable | Boolean | false | If true, this origin won't appear in selection screens, but can still be assigned via commands or upgrades |
order | Integer | Integer.MAX_VALUE | Sort order in the selection screen; lower numbers appear first |
impact | Integer | 0 | Impact level: 0 = NONE, 1 = LOW, 2 = MEDIUM, 3 = HIGH |
upgrades | List of Upgrade objects | [] | Origin upgrade configuration list |
Step 2: Add Translations
Names and descriptions are defined in language files. Create a resource pack (or place these in your data pack's assets/ if supported):
// assets/origins/lang/en_us.json
{
"origin.origins.supermorph.name": "Supermorph",
"origin.origins.supermorph.description": "A flying, fire-immune creature that needs fresh air."
}
The pattern is origin.<namespace>.<path>.name / .description.
If you prefer to set the name in the origin file itself, you can use the optional name and description fields (as Text Components), but translation keys are the recommended approach.
Using default translation keys are always recommended. But language files are always put in resource packs, which means you must also include a resource pack with the same namespace.
By default mods have builtin resource packs and data packs, so use translation keys is not a problem for them. For pure data packs, it's up to you whether to create a resource pack for translations or not.
If you don't want to create a resource pack, you can use the name and description fields to directly specify the text, but they won't be localizable.
Step 3: Add the Origin to a Layer
Origins don't appear in-game until they're listed in a Layer. The default layer is origins:origin. To add your origin to it, create:
{
"replace": false,
"values": [
"example:supermorph"
]
}
To create a separate layer that lets players pick a second origin:
{
"order": 1,
"origins": [
"example:supermorph",
"origins:human"
],
"gui_title": {
"choose_origin": "Choose your Second Origin"
}
}
The old replace field from the Fabric version no longer exists. To override an existing layer, create a file with the same ID in your data pack: it will replace the original automatically.
If you don't want to replace the whole file, just use tags. That's the reason why we use tags instead of listing all origins directly in the layer file: it allows other data packs to add their own origins without needing to replace the whole file.
Step 4: Test
Load the data pack into a world and check the origin selection screen. If the origin doesn't appear:
- Run
/datapack listto confirm the pack is loaded. - Check the game log for JSON parsing errors.
- Make sure your origin file is in
origins/origin/, notorigins/.
You cannot use /reload to reload your datapack after making changes since Origins (NeoForge) use vanilla data loading mechanisms, which do not support hot-reloading of data files. You must leave and rejoin the world to see changes.
If you are testing some functions which need frequently reload and know some JavaScript, you can use Origins JS to define your origins in JavaScript instead of JSON. This allows you to reload your datapack with /reload and see changes immediately.