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 7×7 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:
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:
The source and destination BEs both receive:
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:
Interior detection:
local X is projected onto the gate right vector
local depth is projected onto the gate facing vector
valid area is approximately:
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:
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:
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:
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.