ultraspace-1.0.71.jar
Curse Maven Snippet
What's new
[1.0.71] — 2026-09-18
NEW ITEMS
ultraspace:potion_of_survival — "Potion of Survival"
- Drinkable, stack size 1, registered through the existing UltraSpace item helper so it appears in the UltraSpace creative tab.
- Uses the vanilla drinking pipeline instead of a custom use path:
UseAnim.DRINK, the vanilla drinking sound, the vanilla 32-tick drink time. The animation and timing are identical to a normal potion. Returns a glass bottle; creative mode does not consume it. - Model is a plain
minecraft:item/generatedwith a 16×16 texture. No custom 3D model, no blockstate, no custom HUD rendering. - Drinking applies
ultraspace:survival. The duration always comes from configuration, never from the item stack. Re-drinking refreshes the single timer instead of stacking a second one. /give @p ultraspace:potion_of_survivalworks for testing.
NEW EFFECT
ultraspace:survival — "Ultra Survival"
- Registered as a vanilla
BENEFICIALmob effect, so it shows up normally in the status-effect HUD and the inventory effect screen with its icon and countdown. No forced custom HUD. - Icon: 18×18 at
assets/ultraspace/textures/mob_effect/survival.png, resolved through the standardmob_effectatlas directory source asultraspace:mob_effect/survival. Matches vanilla's 18×18 mob-effect texture size. - Intentionally inert: no attribute modifiers, no per-tick behaviour, no combat bonus. It exists only as the permission marker the survival requirement reads.
- It does not remove any existing Ultra Space environment effect (water blindness, cactus poison, flower poison/slowness). This is the survival requirement, not a universal immunity potion.
NEW SYSTEM — ULTRA SPACE SURVIVAL REQUIREMENT
- Server-authoritative. The server decides the dimension, the configuration, whether
ultraspace:survivalexists, when it expires, and the damage/death state. A client claim is never trusted. - One central scheduled check for the whole server instead of per-player tasks or timers. Damage is additionally gated per player by
damageIntervalTicks, so the server never scans every player every tick and never spams damage packets. Designed for a few hundred concurrent players. - Expiry warning fires once per effect instance, identified by its expiry tick — a refreshed timer can warn again, a running one cannot repeat.
- Protection is never persisted. It is always derived from the live effect plus the current dimension plus the current configuration, so joining inside the dimension, teleporting in and out, dying, respawning, relogging, dimension changes and server restarts are all correct without a stored "unprotected" flag.
- Applies only inside
ultraspace:ultra_space. Overworld, Nether, End and other mods' dimensions are untouched. enabled: falsedisables the whole system — no requirement, no damage, no warnings — while leaving the item and effect registered.requireSurvivalPotion: falselifts just the restriction with the system still loaded.killWhenUnprotected: falsekeeps applying the configured damage but caps it so it can never be lethal, leaving the player at 1 health.
NEW CONFIG
New ultraSpaceSurvival section in the existing config file — no second configuration framework:
"ultraSpaceSurvival": {
"enabled": true, "requireSurvivalPotion": true,
"potionDurationSeconds": 600, "survivalCheckIntervalTicks": 20,
"damageAmount": 4.0, "damageIntervalTicks": 40, "killWhenUnprotected": true,
"warningEnabled": true, "warningTimeRemainingSeconds": 30,
"messages": {
"survivalEffectApplied": "You are protected by Ultra Survival.",
"survivalWarning": "Warning: your Ultra Survival expires in %seconds% seconds!",
"survivalLost": "Your Ultra Survival has expired!",
"survivalDisabled": "Ultra Space survival requirements are disabled."
}
}
potionDurationSecondsis converted properly:× 20ticks.600→12000,1800→36000,60→1200. Nothing assumes the default of 600.- Existing config files pick the section up automatically on load; user values are never overwritten.
- All four player-facing messages are configurable. None are hard-coded in the code.
NEW RECIPE
data/ultraspace/recipe/potion_of_survival.json— shapeless: glass bottle + glowstone dust + amethyst shard + ender pearl → 1 Potion of Survival.data/ultraspace/advancement/recipes/misc/potion_of_survival.jsonfor recipe-book unlocking.- Every ingredient is obtainable outside Ultra Space on purpose: with the requirement enabled, a player must be able to craft a potion before their first trip in.
- Vanilla potions and vanilla potion recipes untouched.
NEW COMMANDS
/ultraspace survival status— live tuning plus the caller's own protection state./ultraspace survival give <player> [count]/ultraspace survival effect <player> [seconds]— defaults to the configured potion duration./ultraspace survival clear <player>- Added to the existing command tree. No new command framework was created.
CRASH FIX — CHUNK GENERATION CRASH AT ultraspace:desert_pyramid_dungeon
NOT a Potion of Survival regression. The identical crash is already present in the logs from 14–15 September, before this work started, and not a single mod frame appears in the stack trace. It is listed here because 1.0.71 is the version that fixes it.
WHAT YOU SAW
Error executing task on Chunk source main thread executor for ultraspace:ultra_space
net.minecraft.ReportedException: Exception generating new chunk
Caused by: java.lang.IllegalStateException: Requested chunk unavailable during world generation
The game died while generating Ultra Space chunks, most reliably when teleporting to an ultraspace:desert_pyramid_dungeon.
WHAT WAS ACTUALLY HAPPENING
The deobfuscated stack (resolved against the project's own mappings.tiny) ended here:
ChunkGenerator.createStructures
-> StructureStart.placeInChunk
-> PoolElementStructurePiece.place
-> SinglePoolElement.place
-> StructureTemplate.placeInWorld
-> RuleProcessor.processBlock <-- reads the world
-> WorldGenRegion.getBlockState
-> WorldGenRegion.getChunk <-- THROWS
RuleProcessor.processBlock performs an unconditional level.getBlockState(pos) for every single block of the template, before it evaluates any rule. The pyramid is one giant single_pool_element template of 136 × 84 × 157 blocks — 276,411 blocks, roughly 9 × 10 chunks, while every other UltraSpace template is tiny by comparison (largest of the rest: 44 × 111 × 44). Those reads reach chunks outside the world-generation region, and WorldGenRegion.getChunk throws.
THE HOW I FIXED IT
- Read the log you gave me and pulled the full exception block out of
latest.log. - Deobfuscated every stack frame with the project's own intermediary→Mojang mapping file, because the release jar's frames are intermediary (
class_3233etc.). - Confirmed where the two message strings live in the real 1.21.1 jar: "Requested chunk unavailable during world generation" in
WorldGenRegion, "Empty or non-existent pool" inJigsawPlacement$Placer. - Traced the crash path to
RuleProcessor.processBlock, then read its bytecode to prove thegetBlockStatecall is unconditional (it happens before any rule is tested). - Compared all five UltraSpace templates by parsing their
.nbtfiles: the pyramid is the only one big enough to reach outside the region, and it is the only structure whose pool feeds aminecraft:rule. - Removed the
minecraft:ruleprocessor fromultraspace:desert_pyramid_dungeon_clear, keepingultraspace:waterlog_clearing. The pyramid's template pool still references the list by name, so nothing else needed changing. - Proved the removal is behaviour-neutral and sufficient:
- The six rules only matched
water,seagrass,tall_seagrass,kelp,kelp_plant,bubble_column— and parsing all five templates shows no fluid blocks at all, so those rules could never match anything. The processor was dead weight whose only effect was the crash. - Re-checked every remaining read on that path:
StructureTemplate.processBlockInfoshas zero world reads;StructureTemplate.placeInWorld's two reads sit behindFluidState.isSource()branches that can never be entered (no fluids anywhere);ultraspace:waterlog_clearingreads onlycurrentBlockInfo.state(), never the level. Writes were never a problem —WorldGenRegion.setBlockcallsensureCanWrite(pos)first and returnsfalsefor out-of-region positions instead of throwing. - Net result: the pyramid now has no world reads at all during processing.
- The six rules only matched
This mod has no additional files

