--- title: Portal Components type: docs weight: 1 --- Portal components define the data structures for portal devices, portal worlds, and void events. **Package:** `com.hypixel.hytale.builtin.portals.components` ## PortalDevice A chunk-level component representing a portal block device. ```java public class PortalDevice implements Component { // Configuration for portal states private PortalDeviceConfig config; // Block type key for the portal device private String baseBlockTypeKey; // UUID of the destination world (if active) private UUID destinationWorldUuid; } ``` ### Accessing Portal Devices ```java // Get portal device at block position PortalDevice portal = BlockModule.get().getComponent( PortalDevice.getComponentType(), world, x, y, z ); if (portal != null) { // Portal exists at this location BlockType blockType = portal.getBaseBlockType(); World destination = portal.getDestinationWorld(); } ``` ### Destination World ```java // Set destination when activating portal portal.setDestinationWorld(targetWorld); // Get destination (null if inactive or world closed) World destination = portal.getDestinationWorld(); if (destination == null || !destination.isAlive()) { // Portal destination invalid } ``` ## PortalDeviceConfig Configuration for portal device visual states. ```java public class PortalDeviceConfig { // State when instance is being created private String spawningState = "Spawning"; // State when portal is active private String onState = "Active"; // State when portal is inactive private String offState = "default"; // Block placed at spawn point in portal world private String returnBlock; } ``` ### State Validation ```java // Verify all states exist on block type PortalDeviceConfig config = portal.getConfig(); if (config.areBlockStatesValid(baseBlockType)) { // All states (on, off, spawning) are valid } ``` ### State Names | State | Description | Default | |-------|-------------|---------| | `spawningState` | Transition from off to on | "Spawning" | | `onState` | Portal is active | "Active" | | `offState` | Portal is inactive | "default" | ## PortalWorld A resource attached to worlds created by portals. ```java public class PortalWorld implements Resource { // Portal type configuration ID private String portalTypeId; // Time limit in seconds private int timeLimitSeconds; // Removal condition handler private PortalRemovalCondition worldRemovalCondition; // Players who died in this world private Set diedInWorld; // Players currently seeing the UI private Set seesUi; // Spawn point transform private Transform spawnPoint; // Reference to active void event private Ref voidEventRef; } ``` ### Checking Portal World ```java // Get portal world resource PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType()); // Check if this is a valid portal world if (portalWorld.exists()) { PortalType type = portalWorld.getPortalType(); int timeLimit = portalWorld.getTimeLimitSeconds(); } ``` ### Time Management ```java // Get elapsed and remaining time double elapsed = portalWorld.getElapsedSeconds(world); double remaining = portalWorld.getRemainingSeconds(world); // Modify remaining time (e.g., extend timer) portalWorld.setRemainingSeconds(world, 300.0); // 5 minutes ``` ### Death Tracking ```java // Check if player died in this world if (portalWorld.getDiedInWorld().contains(playerUuid)) { // Cannot re-enter - died here } // Track a death portalWorld.getDiedInWorld().add(playerUuid); ``` ### UI State ```java // Track players seeing the portal UI portalWorld.getSeesUi().add(playerUuid); portalWorld.getSeesUi().remove(playerUuid); ``` ## VoidEvent Component for void invasion events in portal worlds. ```java public class VoidEvent implements Component { // Minimum distance between spawners public static final double MIN_BLOCKS_BETWEEN_SPAWNERS = 62.0; // Spatial grid of void spawners private SpatialHashGrid> voidSpawners; // Current active stage private VoidEventStage activeStage; } ``` ### Void Event Access ```java // Check if void event is active Ref voidRef = portalWorld.getVoidEventRef(); if (portalWorld.isVoidEventActive()) { VoidEvent voidEvent = store.getComponent(voidRef, VoidEvent.getComponentType()); VoidEventStage stage = voidEvent.getActiveStage(); } ``` ### Void Spawner Grid ```java // Get spawner grid SpatialHashGrid> spawners = voidEvent.getVoidSpawners(); // Spawners maintain minimum distance of 62 blocks ``` ## VoidEventConfig Configuration for void events. ```java public class VoidEventConfig { // Duration of void event in seconds private int durationSeconds; // Stages of the void event private List stages; } ``` ## VoidEventStage Single stage in a void event progression. ```java public class VoidEventStage { // When this stage starts (seconds from event start) private int startTime; // Spawners to activate private List spawners; } ``` ## VoidSpawner Entity component for void invasion spawners. ```java public class VoidSpawner implements Component { // Spawner configuration // Tracks active spawning state } ``` ## Component Registration Components are registered in PortalsPlugin setup: ```java // In PortalsPlugin.setup() this.portalDeviceComponentType = this.getChunkStoreRegistry() .registerComponent(PortalDevice.class, "Portal", PortalDevice.CODEC); this.voidEventComponentType = this.getEntityStoreRegistry() .registerComponent(VoidEvent.class, VoidEvent::new); this.voidPortalComponentType = this.getEntityStoreRegistry() .registerComponent(VoidSpawner.class, VoidSpawner::new); ``` ## Serialization PortalDevice uses BuilderCodec for persistence: ```java public static final BuilderCodec CODEC = BuilderCodec.builder(...) .append(new KeyedCodec<>("Config", PortalDeviceConfig.CODEC), ...) .append(new KeyedCodec<>("BaseBlockType", Codec.STRING), ...) .append(new KeyedCodec<>("DestinationWorld", Codec.UUID_BINARY), ...) .build(); ```