====== 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.