====== Current Systems ====== This document describes the current LanteaCraft rewrite state as implemented in the source tree. It is intentionally descriptive, not aspirational: sections call out what is working, what is prototype-quality, and what still needs testing. ===== Stargate Multiblock Lifecycle ===== ==== Implemented ==== The Stargate frame is implemented as a 7x7 block multiblock centered on a ''stargate_base'' at the bottom middle. The base stores horizontal facing; the frame is resolved relative to ''base.FACING.getClockWise()''. The accepted pattern is defined in ''StargateMultiblock.buildPattern()'': * ''x = -3..3'', ''y = 0..6'' * frame positions are every block on the bottom row, top row, left side, and right side * bottom center ''x=0,y=0'' must be ''stargate_base'' * chevrons are at: * top: ''(-2,6)'', ''(0,6)'', ''(2,6)'' * upper sides: ''(-3,4)'', ''(3,4)'' * lower sides: ''(-3,1)'', ''(3,1)'' * bottom: ''(-2,0)'', ''(2,0)'' * all other frame positions must be ''stargate_ring'' Placement flow: * Placing a ''stargate_base'' calls ''StargateMultiblock.tryAssembleAtBase''. * Placing a ''stargate_ring'' or ''stargate_chevron'' calls ''StargateMultiblock.tryAssembleFrom'', which searches nearby candidate bases. * Successful assembly sets the ''assembled=true'' blockstate on all frame blocks. * Successful server-side assembly registers a ''StargateEntry'' in ''StargateNetworkSavedData''. Interaction flow: * Right-clicking an assembled base/component with no item sends the address chat message. * The chat address is clickable and copies the gate address to clipboard. * Right-clicking the assembled bottom row with a valid solid block applies bottom-row camouflage via the base block entity. Disassembly flow: * Breaking the assembled base calls ''disassembleAtBase''. * Breaking an assembled component calls ''disassembleFrom'', which searches nearby bases. * Disassembly sets ''assembled=false'' on all existing frame blocks found for the base. * Server-side disassembly removes the gate from saved data and attempts to release chunk tickets for active outgoing/incoming connections. ==== Prototype Quality ==== * Assembly/debug logging is very verbose and currently logs every pattern match/mismatch. * Disassembly depends on finding the existing frame from the base. Partial destruction cases need more testing. * The assembled visual is currently a BER-driven ring plus simple assembled block models, not final block replacement logic. * Bottom camouflage is stored as a single block type on the base BE and rendered across all seven bottom-row positions. ==== Needs Testing ==== * Breaking each possible frame block while the gate is active. * Reassembling after partial break/replace. * Base facing for all four horizontal directions. * Applying camouflage from each bottom-row block. * Whether existing worlds with old saved addresses behave acceptably after the new address scheme. ===== Address Generation And Saved Data ===== ==== Implemented ==== Addresses are generated by ''StargateAddress''. Current format: 6 generated gate glyphs + 1 dimension glyph The glyph alphabet is the legacy 38-character set: ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-+ The first six glyphs are generated from the gate chunk coordinates. The dimension is no longer mixed into the six generated glyphs. Instead, the seventh glyph represents the dimension. Reserved/preferred dimension glyphs: * ''A'': ''minecraft:overworld'' * ''N'': ''minecraft:the_nether'' * ''E'': ''minecraft:the_end'' Other dimensions are assigned the first available legacy glyph. These assignments are persisted in ''StargateNetworkSavedData.dimensionGlyphs''. Saved data is global and stored from the overworld data storage under: lanteacraft_stargate_network Persisted data includes: * registered gates: * address * dimension resource location * base position * facing * dimension glyph assignments * active one-way connections: * source address * destination address * connection start game time Lookup maps maintained in memory: * ''gatesByAddress'' * ''addressesByLocation'' * ''activeConnections'' * ''connectionStartTimes'' * ''dimensionGlyphs'' Collision handling: * If the generated address already belongs to another gate, ''uniqueAddress'' salts the six generated glyphs. * The final dimension glyph is preserved during salting. ==== Prototype Quality ==== * Dimension glyph assignment supports 38 dimensions. If all glyphs are exhausted, the code logs a warning and reuses ''+''. * There is no user-facing dimension glyph registry or display yet. * Existing saved gates from the previous 7-symbol hash format are loaded as-is; there is no migration pass. * The first six glyphs are chunk-derived, so multiple gates in the same chunk rely on collision salting. ==== Needs Testing ==== * New gate generation in Overworld, Nether, End, and at least one modded dimension. * Stability of dimension glyphs after save/reload. * Collision behavior for multiple gates in one chunk. * Behavior when old saved gates exist from before the dimension-glyph format. ===== DHD Dialing Flow ===== ==== Implemented ==== The DHD block opens a client-side ''DhdScreen'' on right-click. The GUI: * renders the legacy DHD texture * accepts typed glyphs from the legacy 38-character set * supports paste from clipboard * supports backspace/delete * caps input to ''StargateAddress.ADDRESS_LENGTH'' currently 7 * plays the DHD button sound locally when buttons/backspace/dial are pressed * sends ''DialStargatePayload'' to the server when the center button/Enter is pressed Server payload handling: - Validates that the DHD block still exists. - Finds the nearest assembled Stargate within radius 8. - Blank address means disconnect the local outgoing connection. - Nonblank address must be exactly 7 valid glyphs. - Looks up the destination by address. - Rejects dialing the same local gate. - Forces source/destination chunks. - Stores a one-way active connection. - Starts dialing animation/sound state on both source and destination base block entities. ==== Prototype Quality ==== * The DHD is not a menu/container; it is a custom screen opened from client hooks. * The DHD searches for the nearest assembled gate, not an explicitly linked gate. * There is no power, crystal, ownership, iris, or address book system. * Blank address is overloaded as disconnect. * Receiving gates cannot close incoming connections; this is intentional current behavior. ==== Needs Testing ==== * DHD behavior when multiple gates are within radius. * Paste behavior with lowercase, invalid chars, and overlong strings. * Cross-dimensional dialing after dimension glyph overhaul. * DHD disconnect when source/destination chunks are loaded or unloaded. ===== Connection Model ===== ==== Implemented ==== Connections are one-way and stored as: sourceAddress -> destinationAddress The source gate is the dialing/outgoing gate. The destination gate is incoming. Connection state lives in two places: * ''StargateNetworkSavedData.activeConnections'' for authoritative server routing. * ''StargateBaseBlockEntity.connectedAddress'' for rendering/sound state. The source and destination BEs both receive: * ''startDialing(otherAddress)'' * ''setConnectedAddress(otherAddress)'' Disconnect behavior: * Only the source/outgoing gate can disconnect via DHD. * Disconnect removes the active connection and clears both BEs if their dimensions are loaded. * Disassembly removes connections involving the removed gate and releases chunk tickets. Timeout behavior: * ''StargateTeleportHandler'' enforces a one-minute timeout (''20 * 60'' ticks). * Timeout is checked on the source gate's dimension tick. * On timeout, chunk tickets are released, saved connection is removed, and both BEs are cleared when accessible. ==== Prototype Quality ==== * There is no connection conflict protection beyond overwriting ''activeConnections.put(source, destination)''. * There is no check that the destination is already busy. * No persistence repair pass validates that active connections still point to valid assembled gates. * BE visual state and saved network state can potentially drift if a target dimension is unavailable during cleanup. ==== Needs Testing ==== * Dialing from a gate that already has an outgoing connection. * Dialing a gate that is already receiving. * Save/reload while a connection is active. * Timeout across dimensions. * Disassembly during active dialing/open wormhole. ===== Teleport Behavior ===== ==== Implemented ==== ''StargateTeleportHandler'' subscribes to server level post-tick events. For each active source address: * it only processes the source in the level matching the source gate dimension * it checks wormhole timeout * it scans players in that level against the source gate interior For each active destination address: * it only processes incoming behavior in the destination gate dimension * it scans players in that level against the destination gate interior Interior detection: * local X is projected onto the gate right vector * local depth is projected onto the gate facing vector * valid area is approximately: * width: ''abs(localX) <= 2.35'' * height: ''0.1..5.9'' * depth: ''abs(localDepth) <= 0.7'' Outgoing source behavior: * entering the front side teleports to the destination gate's front side * local X and local Y are preserved * player yaw/pitch are preserved * teleport cooldown is applied Back side of outgoing gate: * entering from the back does not traverse the wormhole * player is moved to the front side of the same source gate * player is pushed outward Incoming destination behavior: * entering an incoming wormhole rejects the player * player is moved to the front side of the destination gate * player is pushed outward at a speed derived from entry velocity, with a minimum rejection speed Cross-dimensional safety: * player iteration uses ''List.copyOf(level.players())'' so cross-dimension teleport does not mutate the list being iterated. ==== Prototype Quality ==== * Teleport volume is a simple rectangular slab inside the gate, not a true circular portal test. * Orientation is mostly "preserve player yaw/pitch", not "walk out facing relative to entry direction". * Entity support is player-only. * No mount, projectile, item, mob, or vehicle traversal. * Cooldowns are held in an in-memory map and are not persisted. ==== Needs Testing ==== * Nether to Overworld and Overworld to Nether travel after the snapshot iteration fix. * Walking through at angles and high speed. * Back-side entry on source gates. * Incoming-side rejection at different velocities. * Multiple players traversing the same gate in the same tick. ===== Chunk Loading Behavior ===== ==== Implemented ==== ''StargateChunkLoading'' registers a NeoForge ''TicketController'' named: lanteacraft:stargate When a connection is opened: * source chunk is force-loaded in the source level * destination chunk is force-loaded in the destination level if that level exists * tickets are ticking tickets * ticket owner is the source base position When a connection disconnects, times out, or disassembles: * the same source/destination chunks are force-unloaded using the same owner where possible ==== Prototype Quality ==== * Only the base chunk is loaded, not nearby DHD/player arrival chunks. * Destination chunk loading depends on ''server.getLevel(destination.dimension())'' returning a loaded level. * Ticket ownership always uses source base position, including destination-level tickets. * There is no startup repair/reassertion for persisted active connections. ==== Needs Testing ==== * Whether destination chunks remain ticking for the entire active wormhole. * Disconnect and timeout release behavior across dimensions. * World reload with an active connection. * Breaking source or destination gate while chunk tickets are active. ===== Known Risks And TODOs ===== ==== Current Risks ==== * Existing saved gate addresses may not match the new 6+1 address scheme. * Active connection state can outlive visual BE state if a dimension or chunk is unavailable during cleanup. * Destination busy/source busy rules are not implemented. * The DHD nearest-gate search may pick the wrong gate in dense builds. * The debug logging volume is high enough to be noisy during normal construction. * Renderer and gameplay state are tightly coupled to the base block entity. * Only players teleport. ==== TODO Candidates ==== * Add address/data migration for old saved addresses or document world reset requirements during development. * Add connection validation and busy checks. * Add explicit DHD-to-gate linking. * Add non-player entity traversal when safe. * Add a proper circular portal volume test. * Add config values for wormhole timeout, DHD search radius, and debug logging. * Add a command/debug screen for listing registered gates and dimension glyphs. * Add tests/manual QA checklist for cross-dimensional dialing and chunk ticket lifecycle.