7.8 KiB
title, type, weight
| title | type | weight |
|---|---|---|
| Portal Systems | docs | 2 |
Portal systems handle the runtime logic for portal tracking, void events, and instance management.
Package: com.hypixel.hytale.builtin.portals.systems
Portal Tracker Systems
TrackerSystem
Tracks players entering and leaving portal worlds:
public class TrackerSystem extends RefSystem<EntityStore> {
// Called when player enters portal world
@Override
public void onEntityAdded(Ref<EntityStore> ref, AddReason reason,
Store<EntityStore> store,
CommandBuffer<EntityStore> commandBuffer) {
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
if (!portalWorld.exists()) return;
// Send portal UI to player
PlayerRef playerRef = commandBuffer.getComponent(ref, PlayerRef.getComponentType());
UpdatePortal packet = portalWorld.createFullPacket(world);
playerRef.getPacketHandler().write(packet);
}
// Called when player leaves portal world
@Override
public void onEntityRemove(Ref<EntityStore> ref, RemoveReason reason,
Store<EntityStore> store,
CommandBuffer<EntityStore> commandBuffer) {
// Clear UI state
playerRef.getPacketHandler().write(new UpdatePortal(null, null));
portalWorld.getSeesUi().remove(playerRef.getUuid());
}
@Override
public Query<EntityStore> getQuery() {
return Query.and(Player.getComponentType(), PlayerRef.getComponentType());
}
}
UiTickingSystem
Updates portal UI every second:
public class UiTickingSystem extends DelayedEntitySystem<EntityStore> {
public UiTickingSystem() {
super(1.0f); // Tick every 1 second
}
@Override
public void tick(float dt, int index, ArchetypeChunk<EntityStore> archetypeChunk,
Store<EntityStore> store, CommandBuffer<EntityStore> commandBuffer) {
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
if (!portalWorld.exists()) return;
// Send updated time to player
UpdatePortal packet = portalWorld.createUpdatePacket(world);
playerRef.getPacketHandler().write(packet);
}
}
Portal Destination Systems
PortalInvalidDestinationSystem
Handles portals with invalid destinations:
public class PortalInvalidDestinationSystem {
// Turns off portals when destination world closes
public static void turnOffPortalsInWorld(World world, World closedWorld) {
// Find all portals pointing to closedWorld
// Set their destination to null
// Update block state to "off"
}
}
CloseWorldWhenBreakingDeviceSystems
Handles portal device destruction:
// When portal device component is removed
public class ComponentRemoved extends System<ChunkStore> {
// Close the destination world
}
// When portal block entity is removed
public class EntityRemoved extends System<ChunkStore> {
// Close the destination world
}
Void Event Systems
VoidEventRefSystem
Manages void event entity references:
public class VoidEventRefSystem extends System<EntityStore> {
// Tracks void event entity lifecycle
// Updates PortalWorld.voidEventRef
}
VoidEventStagesSystem
Progresses through void event stages:
public class VoidEventStagesSystem extends System<EntityStore> {
// Checks elapsed time
// Activates next stage when time threshold reached
// Updates VoidEvent.activeStage
}
VoidInvasionPortalsSpawnSystem
Spawns invasion portals during void events:
public class VoidInvasionPortalsSpawnSystem extends System<EntityStore> {
// Creates void spawner entities
// Uses spatial hash grid to maintain minimum distance
}
VoidSpawnerSystems.Instantiate
Instantiates void spawner entities:
public class Instantiate extends System<EntityStore> {
// Creates spawner entity from config
// Adds to VoidEvent's spatial grid
}
StartVoidEventInFragmentSystem
Initiates void events in portal fragments:
public class StartVoidEventInFragmentSystem extends System<EntityStore> {
// Checks if void invasion should start
// Creates VoidEvent entity
// Sets up first stage
}
Curse Systems
DiedInPortalSystem
Tracks player deaths in portal worlds:
public class DiedInPortalSystem extends System<EntityStore> {
// On player death in portal world:
// - Add player UUID to diedInWorld set
// - Prevents re-entry
}
CurseItemDropsSystem
Marks dropped items as cursed:
public class CurseItemDropsSystem extends System<EntityStore> {
// Items dropped in portal world become cursed
// Cursed items are lost on death
}
DeleteCursedItemsOnSpawnSystem
Removes cursed items when player spawns:
public class DeleteCursedItemsOnSpawnSystem extends System<EntityStore> {
// When player respawns after dying in portal
// Remove all cursed items from inventory
}
Portal Interactions
EnterPortalInteraction
Handles entering a portal:
public class EnterPortalInteraction extends SimpleBlockInteraction {
// Minimum time before allowing portal use
public static final Duration MINIMUM_TIME_IN_WORLD = Duration.ofMillis(3000L);
@Override
protected void interactWithBlock(...) {
// Check portal device exists
// Verify destination world is alive
// Check player hasn't died in target world
// Teleport player to instance
}
}
Target world states:
OKAY- Can enterWORLD_DEAD- Destination closedDIED_IN_WORLD- Player died thereNO_SPAWN_AVAILABLE- No spawn point
ReturnPortalInteraction
Handles returning from a portal world:
public class ReturnPortalInteraction extends SimpleBlockInteraction {
// Minimum time before allowing return
public static final Duration MINIMUM_TIME_IN_WORLD = Duration.ofSeconds(15L);
// Warning shown before timer expires
public static final Duration WARNING_TIME = Duration.ofSeconds(4L);
@Override
protected void interactWithBlock(...) {
// Check minimum time elapsed
// Uncurse all items
// Exit instance
}
}
System Registration
All systems are registered in PortalsPlugin setup:
// ChunkStore systems
this.getChunkStoreRegistry().registerSystem(new PortalInvalidDestinationSystem());
this.getChunkStoreRegistry().registerSystem(new CloseWorldWhenBreakingDeviceSystems.ComponentRemoved());
this.getChunkStoreRegistry().registerSystem(new CloseWorldWhenBreakingDeviceSystems.EntityRemoved());
// EntityStore systems
this.getEntityStoreRegistry().registerSystem(new PortalTrackerSystems.TrackerSystem());
this.getEntityStoreRegistry().registerSystem(new PortalTrackerSystems.UiTickingSystem());
this.getEntityStoreRegistry().registerSystem(new DiedInPortalSystem());
this.getEntityStoreRegistry().registerSystem(new CurseItemDropsSystem());
this.getEntityStoreRegistry().registerSystem(new DeleteCursedItemsOnSpawnSystem());
this.getEntityStoreRegistry().registerSystem(new VoidEventRefSystem());
this.getEntityStoreRegistry().registerSystem(new VoidInvasionPortalsSpawnSystem());
this.getEntityStoreRegistry().registerSystem(new VoidSpawnerSystems.Instantiate());
this.getEntityStoreRegistry().registerSystem(new StartVoidEventInFragmentSystem());
this.getEntityStoreRegistry().registerSystem(new VoidEventStagesSystem());
Interaction Registration
Portal interactions are registered as codec types:
this.getCodecRegistry(Interaction.CODEC)
.register("Portal", EnterPortalInteraction.class, EnterPortalInteraction.CODEC)
.register("PortalReturn", ReturnPortalInteraction.class, ReturnPortalInteraction.CODEC);