Files
Stargate/README.md
T
Michael Burgess b822389387 Fix one-way travel, rework iris to SG-1 mechanics, glowstone chevrons, pin-locked shield
One-way travel bug: the exit point landed players directly inside the
destination gate's own iris footprint. Since dialing opens both ends,
arriving there immediately re-triggered the teleport listener and
bounced them straight back - reading exactly like one-way travel.
GateManager.computeSafeLanding now nudges the landing spot along the
player's travel direction until it clears the destination's iris
blocks, and GateTeleportListener adds a short per-player cooldown as a
second guard against re-trigger. Same-server teleports now also
preserve the player's exact yaw/pitch and velocity instead of forcing
a fixed stored orientation, so entering forward always means exiting
forward; the cross-server plugin-messaging protocol was extended to
carry yaw/pitch through the proxy hop for the same reason.

Iris rework to match SG-1 rather than a binary open/closed gate:
- Idle (not connected): iris-idle-material, default AIR - you see
  straight through an inactive ring, not a wall.
- Connected: iris-open-material (WATER, the event horizon) unless the
  gate's separate iris shield is closed, in which case
  iris-shield-material (IRON_BLOCK) blocks travel even though the
  wormhole is active.
- A button placed directly below the control sign toggles the shield
  (GateIrisButtonListener). Closing needs nothing; opening a gate with
  a pin code set (/sg pin <code>) prompts the player to type it in
  chat within gate.pin-timeout-seconds first.

Also: gate.chevron-lit-material default changed from gilded blackstone
to glowstone per feedback.
2026-08-09 11:36:17 -04:00

5.8 KiB

Stargate

A network-aware Stargate portal plugin for PaperMC, with sign-based dialing and cross-server travel over Velocity or BungeeCord.

Modules

Module What it is
stargate-common Shared models + JDBC storage (SQLite / MySQL) used only by the Paper plugin
stargate-paper The actual gate plugin — install this on every backend server
stargate-velocity Proxy companion for Velocity — install on the proxy only if using cross-server gates
stargate-bungee Same, for BungeeCord/Waterfall

Build everything with ./gradlew build. Jars land in each module's build/libs/.

Building a gate

There's no fixed size or shape - build any single connected ring out of gate.frame-materials (default: obsidian, gold block, gilded blackstone, birch/oak planks) with a fully sealed hollow interior. No gaps; the interior must be enclosed. "Connected" includes the usual diagonal stepping a round/octagonal ring needs at its corners (blocks touching only edge-to-edge or corner-to-corner still count), so a circular build doesn't need every block to share a full face with the next.

Build it free-standing, one block thick, in a single flat plane (a vertical ring facing a direction, like all the examples above) - the plugin figures out which axis is the ring's "thickness" and only looks for the interior within that plane, so it doesn't try to flood-fill out through the open air in front of and behind the gate.

Chevrons aren't a separate material you place. When the gate is linked, the plugin flood-fills the ring, walks it in geometric order, and picks out the blocks that stick further outward than their immediate ring-neighbours - the "elbow" points of the shape, which is where a real Stargate's chevrons sit (an 11-wide octagonal ring like the reference design naturally produces 7 of them: the top apex, the four shoulder elbows, and the two side bumps). Those blocks swap to gate.chevron-lit-material (default glowstone) while dialing/open, and revert to whatever they looked like at rest when the gate closes - so a chevron can rest as plain obsidian and blend invisibly into the frame until it lights up.

  1. Build the ring.
  2. Optionally place a button directly below where you'll put the sign - this becomes the iris shield toggle (see below). Not required; a gate without one just has no shield control.
  3. Place a sign anywhere - it doesn't need to touch the frame, so it can act like a DHD console standing apart from the gate - with:
    • Line 1: [Stargate]
    • Line 2: network name (blank = default network)
    • Line 3: gate name (blank = auto-generated)
    • Line 4: hidden to keep it out of the cycle list, fixed:GateName to lock this gate to always dial GateName (no right-click cycling), or blank
  4. The sign will show "Punch the gate (30s)". Within gate.link-timeout-seconds, left-click (punch) any frame block, within gate.max-link-distance of the sign. The plugin scans out from that block and links the sign to it.

If punching a block doesn't work, the plugin tells you exactly why in chat - wrong material, unsealed interior, too far from the sign, etc.

Using a gate

  • Right-click the sign: cycles the destination shown on line 3 among the other gates on the same network.
  • Left-click the sign: dials the shown destination - chevrons light in sequence, then the interior switches from gate.iris-idle-material (default air - an idle gate is just an empty ring you can see straight through) to either the event horizon (gate.iris-open-material, default water) or, if the iris shield is closed, to gate.iris-shield-material (default iron block) instead, blocking travel even though the gate is actively connected. It auto-closes after dialing.open-seconds, switching back to the idle material either way.
  • Walking into the event horizon teleports you to the connected gate, arriving just clear of its iris (never inside it - that would immediately teleport you right back) and still facing whatever direction you were already walking, so entering forward always means exiting forward.
  • Right-click a button placed directly below the sign toggles the iris shield. Closing it never needs anything extra. If the gate has a pin set (/sg pin <code>), opening a closed shield prompts you to type the code in chat within gate.pin-timeout-seconds before it'll open.

Multi-world

Gates are addressed by network name, not world — a gate on any loaded world can dial any other gate on the same network regardless of world, exactly like same-server cross-world travel in the original Stargate mod.

Cross-server (Velocity / Bungee)

  1. Set storage.type: mysql in every backend server's config.yml and point them at the same database — this is how servers see each other's gates.
  2. Give each backend a unique server-id in config.yml that matches its name in the proxy config (velocity.toml / config.yml servers list).
  3. Set cross-server.enabled: true on every backend.
  4. Drop stargate-velocity (or stargate-bungee) into the proxy's plugin folder.

When a player dials a gate hosted on another backend, the Paper plugin asks the proxy (over the stargate:teleport plugin channel) to connect the player to that server; once they land, the proxy forwards a delivery message so the destination server's Stargate instance teleports them to the gate's exit point.

Permissions

  • stargate.use (default: true) — dial/cycle gates
  • stargate.create (default: op) — build new gates
  • stargate.destroy (default: op) — break your own gates
  • stargate.admin (default: op) — reload, break/manage any gate

Commands

  • /sg list [network]
  • /sg networks
  • /sg destroy (look at a gate's sign)
  • /sg pin <code|clear> (look at a gate's sign) — requires that code in chat before a closed iris shield will open on that gate
  • /sg reload