Custom Portals
This project depends on , so install that mod before use.
Mods and versions used:
- rhino-forge-2001.2.2-build.18
- architectury-9.2.14-forge
- kubejs-forge-2001.6.5-build.14
- probejs-6.0.1-forge
- customportalapi-0.0.1-forge-1.20
Project Code
This example code should be placed in the startup_scripts folder.
js
const $CustomPortalBuilder = Java.loadClass("net.kyrptonaught.customportalapi.api.CustomPortalBuilder")
const $BuiltinDimensionTypes = Java.loadClass("net.minecraft.world.level.dimension.BuiltinDimensionTypes")
StartupEvents.postInit(e=>{
$CustomPortalBuilder
.beginPortal() // Begin building a custom portal
["frameBlock(net.minecraft.world.level.block.Block)"](Blocks.STONE) // Portal frame block
.destDimID($BuiltinDimensionTypes.NETHER_EFFECTS) // Destination dimension
.tintColor(131, 66, 184) // Portal RGB color
.registerPortal(); // Register custom portal
$CustomPortalBuilder
.beginPortal() // Begin building a custom portal
["frameBlock(net.minecraft.world.level.block.Block)"](Blocks.DIAMOND_BLOCK) // Portal frame block
.destDimID($BuiltinDimensionTypes.NETHER_EFFECTS) // Destination dimension
.lightWithItem(Items.DIAMOND) // Item used to ignite portal
.flatPortal() // Use flat portal style
.tintColor(131, 133, 184) // Portal RGB color
.registerPortal(); // Register custom portal
})CustomPortalBuilder Callable Methods
Open-source reference:
| Method Name | Parameters | Description |
|---|---|---|
| beginPortal() | - | Create a new portal |
| registerPortal() | - | Register the portal after all properties are set |
| frameBlock(ResourceLocation) | Block ID | Set portal frame block |
| frameBlock(Block) | Block type | Set portal frame block |
| destDimID(ResourceLocation) | Dimension ID | Set destination dimension |
| tintColor(int) | Hex color | Set portal color |
| tintColor(int r,int g,int b) | RGB ints | Set portal color |
| lightWithWater() | - | Make portal ignite by water |
| lightWithItem(Item) | Item type | Make portal ignite by item |
| lightWithFluid(Fluid) | Fluid type | Make portal ignite by fluid |
| customIgnitionSource(ResourceLocation) | ~ | a1 |
| customIgnitionSource(PortalIgnitionSource) | ~ | a1 |
| forcedSize(int w,int h) | w width, h height | Force portal dimensions |
| customPortalBlock(CustomPortalBlock) | CustomPortalBlock | Use custom portal block |
| returnDim(ResourceLocation,boolean) | dimension ID, b1 | Set return dimension |
| onlyLightInOverworld() | - | a2 |
| flatPortal() | - | Use flat portal style (like End portal visuals) |
| customFrameTester(ResourceLocation) | ~ | a3 |
| registerBeforeTPEvent(Function<Entity,SHOULDTP>) | ~ | Register a pre-teleport event (can cancel via SHOULDTP) |
| registerInPortalAmbienceSound(Function<PlayerEntity,CPASoundEventData>) | ~ | Register sound while player is in portal |
| registerPostTPPortalAmbience(Function<PlayerEntity,CPASoundEventData>) | ~ | Register sound during/after teleport |
| registerPostTPEvent(Consumer<Entity>) | ~ | Register post-teleport event |
Fabric-Only (Likely)
Based on callable API differences, the following methods appear to be available only in the .
| Method Name | Parameters | Description |
|---|---|---|
| beginPortal(PortalLink) | PortalLink | Create a new portal using a custom PortalLink |
| registerPortalForced() | - | Force-register a portal |
| registerPreIgniteEvent(PortalPreIgniteEvent) | ~ | Pre-ignite event; activation fails if event returns false |
| registerIgniteEvent(PortalIgniteEvent) | ~ | Post-ignite event |
| setPortalSearchYRange(int bottomY,int topY) | - | Set Y-range used for portal search/generation |
| setReturnPortalSearchYRange(int bottomY,int topY) | - | Set Y-range used for return portal search/generation |
Official Notes
a1: Specify a Custom Ignition Source to be used to ignite the portal. You must manually trigger the ignition yourself.
a2: Specify that this portal can only be ignited in the Overworld.Attempting to light it in other dimensions will fail.
a3: Specify a custom portal frame tester to be used.
b1: Should this portal only be ignitable in returnDimID.
About Registering Portal Blocks
js
const $CustomPortalsMod = Java.loadClass("net.kyrptonaught.customportalapi.CustomPortalsMod")
const $CustomPortalBlock = Java.loadClass("net.kyrptonaught.customportalapi.CustomPortalBlock")
const $BlockBehaviourProperties = Java.loadClass("net.minecraft.world.level.block.state.BlockBehaviour$Properties")
const $SoundType = Java.loadClass("net.minecraft.world.level.block.SoundType")
const $EventBuses = Java.loadClass("dev.architectury.platform.forge.EventBuses");
let test;
StartupEvents.init(e => {
test = $CustomPortalsMod.registerOnlyBlock("test",()=>{
return new $CustomPortalBlock(
$BlockBehaviourProperties.copy(Blocks.NETHER_PORTAL)
.lightLevel(() => 11)
.noCollission()
.strength(-1)
.sound($SoundType.GLASS)
)
})
$CustomPortalsMod.BLOCKS.register($EventBuses.getModEventBus("kubejs").get());
})
StartupEvents.postInit(e=>{
$CustomPortalBuilder
.beginPortal()
["frameBlock(net.minecraft.world.level.block.Block)"](Blocks.STONE)
.customPortalBlock(test)
.destDimID($BuiltinDimensionTypes.NETHER_EFFECTS)
.tintColor(131, 66, 184)
.registerPortal();
})Notes
- This project was mainly tested on
1.20.1with . - If errors occur because your mod version differs from this example, adjust the code accordingly.
- This project focuses on the core implementation pattern. For more features, check the open-source project and extend from there.