Description
Regenerating Ore Veins
A configurable NeoForge mod for Minecraft 1.21.1 that allows you to generate ore veins that regenerate over time.
Regenerator Block
This mod centres around the regenerator block which is a repurposed glass block. It is translucent and non-colliding and marks the location of an ore that will be regenerated after an interval. Each time the ore is destroyed, the regenerator block will replace it and begin the countdown until it generates the ore again.
Behavior of the regenerator block:
- players and entities can walk through it
- sneaking + right click shows the target block and remaining time
- creative players can sneak-right-click it to open a configuration screen
- the config screen sets target block, interval seconds, and jitter min/max seconds
- players in creative mode use middle-click to copy a regenerator block with its block entity data so it can be placed elsewhere
- players in creative mode can break regenerator blocks even when
allow_breakingis false - players in survival mode can break the block (if
allow_breakingis set to true) by sneaking and mining the block - breaking can be disabled entirely in
global.jsonusing theallow_breakingconfiguration option - regenerator blocks ignore explosions by default, while managed ores destroyed by explosions still enter regeneration
- managed ores removed by modded block breakers are detected and moved into the regeneration cycle
- the regenerator block is tagged as non-movable/non-breakable for Create and non-movable for Create Aeronautics/Simulated contraptions
- what this effectively means is that contraptions will move the ore but not the placement of the regenerator block and drills will destroy the ore but not the regenerator block
- regeneration timing is stored with persistent data, so unloaded chunks still count down
- when regeneration finishes, smoke particles are emitted and the target block is restored (this can be turned off in
global.jsonusing theregeneration_smoke_particlesconfiguration option
Setting A Manual Regenerator Interval In Game
In creative mode, sneak-right-click a regenerator block and edit:
Target block, for exampleminecraft:diamond_oreInterval seconds, for example3600Jitter minandJitter max, for example-300and300
The jitter is applied when the block enters its regenerating state. An interval of 3600 with jitter -300..300 produces a real interval from 3300 to 3900 seconds.
For commands or automation, the same values are stored as block entity data:
/data merge block <x> <y> <z> {IntervalSeconds:60,EffectiveIntervalSeconds:60,JitterRangeMinSeconds:-10,JitterRangeMaxSeconds:10}
Example for the block you are standing on:
/data merge block ~ ~-1 ~ {IntervalSeconds:60,EffectiveIntervalSeconds:60,JitterRangeMinSeconds:-10,JitterRangeMaxSeconds:10}
IntervalSeconds is the base number of real-time seconds before that regenerator restores its target block. EffectiveIntervalSeconds is the currently active countdown value: set it too when editing with /data.
Global config values live in:
config/regenerating_ore_veins/global.json
{
"allow_breaking": true,
"break_hardness": 5.0,
"default_regeneration_seconds": 3600,
"default_jitter_interval": {
"range_min": 0,
"range_max": 0
},
"regeneration_smoke_particles": true,
"destroyed_by_explosives": false,
"default_fill_factor": 1.0
}
On a dedicated server or multiplayer world, the server's global.json is authoritative for gameplay behavior. A local client copy only affects that client's own singleplayer/integrated server and does not override the server.
Important values:
allow_breakingdefaults totruebreak_hardnessdefaults to5.0default_regeneration_secondsdefaults to3600(1 hour)default_jitter_intervaldefaults to no jitterregeneration_smoke_particlesdefaults totruedestroyed_by_explosivesdefaults tofalse: when false, explosions do not destroy regenerator blocksdefault_fill_factordefaults to1.0: used by veins that do not set their ownfill_factor
JSON Configuration
The mod creates these files under:
config/regenerating_ore_veins/areas.jsonconfig/regenerating_ore_veins/veins.jsonconfig/regenerating_ore_veins/global.jsonconfig/regenerating_ore_veins/vein_locator.json
areas.json
The following example shows how you can create an area (note this is heavily inspired by the mod, In Control!).
[
{
"dimension": "minecraft:overworld",
"name": "frontier_0",
"type": "box",
"x": 0,
"y": 128,
"z": 0,
"dimx": 8192,
"dimy": 512,
"dimz": 8192
}
]
type supports In Control!-style area shapes:
box: rectangular prism.dimx,dimy, anddimzare half-extents from the center.sphere: ellipsoid.dimx,dimy, anddimzare the X/Y/Z radii from the center.cylinder: vertical elliptical cylinder.dimxanddimzare horizontal radii, anddimyis vertical half-height.
circle is not supported. Area dimensions follow In Control! semantics and are radius/half-size values, not full dimensions. For example, a box centered at x: 0, y: 128, z: 0 with dimx: 8192, dimy: 512, dimz: 8192 covers roughly x=-8192..8192, y=-384..640, and z=-8192..8192.
veins.json
The following example shows how you can configure a vein.
[
{
"id": "gold_ore_unusual",
"blocks": [
"minecraft:gold_ore",
"minecraft:deepslate_gold_ore",
"minecraft:nether_gold_ore"
],
"weights": [
1,
2,
4
],
"dimension_whitelist": [
"minecraft:overworld",
"minecraft:the_nether"
],
"biome_whitelist": [
"minecraft:badlands",
"#c:is_jungle",
"minecraft:nether_wastes"
],
"area_whitelist": [
"frontier_0"
],
"area_blacklist": [],
"shape": "sphere",
"min_radius": 2,
"max_radius": 3,
"fill_factor": 1.0,
"attempts": 1,
"min_y": -64,
"max_y": 32,
"chunk_minimum_generation_separation": 0.5,
"regeneration_interval_seconds": 3600,
"regeneration_interval_jitter": {
"range_min": -240,
"range_max": 240
}
}
]
Supported/optional fields:
area_whitelistaccepts a string or list of area names. If provided, the vein only generates inside those areas.area_blacklistaccepts a string or list of area names. If provided, the vein never generates inside those areas.dimension_whitelistaccepts a string or list. If provided, the vein only generates in those dimensions.dimension_blacklistaccepts a string or list. If provided, the vein never generates in those dimensions. Blacklist wins if it overlaps the whitelist.biome_whitelistaccepts a string or list. If provided, the vein only generates in those biomes.biome_blacklistaccepts a string or list. If provided, the vein never generates in those biomes. Blacklist wins if it overlaps the whitelist.weightsdefaults to1for each blockshapesupportssphereandboxmin_radiusandmax_radiuschoose a random radius in blocks for each vein. Forsphere, this is the radius of a sphere-like vein. Forbox, this is the half-extent of a cube from the center.fill_factoris a0.0..1.0probability applied to each candidate block in the vein shape.0places none of the selected positions,1places all selected positions. Defaults toglobal.jsonvaluedefault_fill_factor.chunk_minimum_generation_separationdefaults to8. Values>= 1space candidate chunks apart. Values below1multiply generation in each chunk, so0.5means two attempts per chunk and0.25means four.regeneration_interval_secondsdefaults toglobal.jsonvaluedefault_regeneration_secondsregeneration_interval_jitterdefaults toglobal.jsonvaluedefault_jitter_interval
Regarding the filters:
- Dimension and biome filters support exact ids and namespace wildcards such as
biomeswevegone:*. The vanilla Nether id isminecraft:the_nether, thoughminecraft:netheris accepted as an alias for dimensions. - Biome filters also support tags prefixed with
#, such as#c:is_jungle. - Empty whitelist/blacklist lists are treated as omitted.
- The old vein-level
area,dimension, andbiomefields are no longer supported. The mod logs a warning if it sees them.
If whitelist and blacklist overlap, blacklists win. Dimension, area, biome, and Y-level filters are combined, so admins can make a vein generate only where all configured filters match. The default veins.json examples are not area-constrained and include Overworld and Nether examples. Vanilla Minecraft does not have separate Overworld quartz ore or netherite ore blocks, so the default examples use minecraft:quartz_block for the quartz example and minecraft:ancient_debris for netherite.
Expected blocks generated with fill_factor: 1.0:
| Radius | sphere |
box |
|---|---|---|
| 1 | 7 | 27 |
| 2 | 33 | 125 |
| 3 | 123 | 343 |
| 4 | 257 | 729 |
| 5 | 515 | 1,331 |
| 6 | 925 | 2,197 |
| 7 | 1,419 | 3,375 |
| 8 | 2,109 | 4,913 |
| 9 | 3,071 | 6,859 |
| 10 | 4,169 | 9,261 |
| 12 | 7,153 | 15,625 |
With fill_factor: 0.5, you can expect the number of blocks to roughly half.
vein_locator.json
{
"allow_crafting": true,
"allow_use": true,
"crafting_recipe": [
"minecraft:netherite_ingot",
"minecraft:ender_eye"
],
"craft_any_order": true,
"chance_to_break": 0.75,
"use_durability": false,
"durability": 2,
"stack_size": 64
}
The Vein Locator is crafted from the configured recipe. Because the recipe is generated as a normal server datapack recipe, JEI can display it after recipes reload.
Tune a locator by crafting it with any block item. The output locator stores that block as its target. When used, it flies like an eye of ender toward the nearest tracked regenerating vein block in the current dimension with the same target block.
allow_craftingcontrols the base locator recipeallow_usedisables locator usage server-sidecrafting_recipeis a list of item ids.minecraft:netheriteis accepted as an alias forminecraft:netherite_ingot.craft_any_orderuses a shapeless recipe when true and a shaped row recipe when falsechance_to_breakis a0.0..1.0chance to remove one locator from the held stack, used only whenuse_durabilityis falseuse_durabilityswitches the item to configured durability loss instead of random break chance. In this mode the thrown locator signal always shows the break effect, and the held locator loses durability.durabilitycontrols how many successful uses the locator has whenuse_durabilityis truestack_sizecontrols the max stack size whenuse_durabilityis false and defaults to64
When use_durability is true, vein locators are not stackable. If this is turned on while players already have stacked locators, the mod splits those stacks safely during inventory updates or when a player uses a stack. If use_durability is later turned off, durability data is removed from existing locators during inventory updates or use and they can stack again using stack_size.
Manual Placement
Each vein id is also exposed as a generated structure id:
/place structure regenerating_ore_veins:diamond_ore
This uses the current veins.json ids that were available when the datapacks loaded. Manual placement ignores the vein's area whitelist and blacklist so you can test a vein at your current location.
The mod also provides its own placement command:
/rov place diamond_ore
/regenerating_ore_veins place diamond_ore
Use this command when testing config changes. It reads the mod config directly and places the vein at the command source position.
Updating Existing Veins
After changing veins.json, update tracked existing placements without regenerating whole chunks:
/rov update_existing
/rov update_existing id diamond_ore
/rov update_existing area frontier_0
/rov update_existing id diamond_ore area frontier_0
/rov update_existing area frontier_0 id diamond_ore
/rov update_existing regenerate
/rov update_existing regenerate id diamond_ore
/rov update_existing regenerate area frontier_0
/rov update_existing regenerate id diamond_ore area frontier_0
The full command prefix also works:
/regenerating_ore_veins update_existing id diamond_ore
This updates the mod's saved vein entries to the current configuration: interval seconds, jitter, stored vein id, and target block if the old target is no longer part of the configured vein. It does not force-load chunks. For unloaded chunks, saved data is updated immediately and any needed block-state correction happens later when the chunk naturally loads and the mod validates the tracked entry.
The main safety rule is that the command only touches loaded world blocks when the block is still the exact old tracked target or the regenerator block entity is present. This avoids overwriting unrelated player edits. Old saved entries created before vein ids were stored can still be updated when the target block uniquely identifies the vein, or when an explicit id is provided and that vein contains the target block.
Adding regenerate rebuilds already tracked vein groups using the current shape, min_radius, max_radius, and fill_factor. The command reconstructs groups from nearby tracked blocks with the same vein id, removes old tracked positions, creates new tracked positions around the group's center, and queues cleanup/placement work for unloaded chunks. It still avoids force-loading chunks. When those chunks load later, queued cleanup removes old generated ore/regenerator blocks only if they still look like the old tracked blocks, and queued placement writes new ore only into safe replaceable/natural blocks. If a player has built something else there, the queued placement is skipped and that new saved entry is removed instead of overwriting the build.
Reloading Config
Reload the mod's JSON config without restarting the server:
/rov reload
/regenerating_ore_veins reload
This reloads global.json, areas.json, veins.json, and vein_locator.json for runtime generation, /rov place, /rov update_existing, locator use, locator durability, and locator stack size. If these files have syntax errors, or if areas.json/veins.json has unsupported values such as type: "circle" in an area, the problem is logged to latest.log and the command sender is told that the config has warnings or errors. Players are also warned when they join the world if config issues were found.
Vanilla /place structure regenerating_ore_veins:<id> and generated crafting recipes use datapack resources, so adding or removing vein ids or changing recipes may still require Minecraft's /reload or a world restart for those resources to refresh.
Note that this reload will not change the crafting recipe immediately, and you will need to restart the world (save and quit then open the world again) for the recipe changes to take effect.
Natural generation does respect area_whitelist and area_blacklist. The default frontier_0 example is centered at x=0, z=0 with dimx: 8192 and dimz: 8192, so it covers roughly x=-8192..8192 and z=-8192..8192.
Notes
- natural generation is processed once for newly generated chunks
- managed vein blocks are tracked per-dimension in saved data
- when a managed ore block is mined, it is replaced on the next server tick by a
Regenerator Block
License
MIT


