storage.mysql.properties is now a free-form map merged into the JDBC URL as ?key=value&key=value..., letting hosts that require TLS set things like sslMode: REQUIRED, or override the useSSL/autoReconnect defaults, without needing a code change for every possible parameter.
137 lines
7.5 KiB
Markdown
137 lines
7.5 KiB
Markdown
# 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: just obsidian) 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.
|
|
|
|
Add more materials to `gate.frame-materials` if your ring mixes blocks, but keep the
|
|
list to materials used *only* for the ring - anything also used decoratively nearby
|
|
(a backdrop wall, a matching accent elsewhere) risks getting swept into the frame if
|
|
it touches the ring anywhere in the same plane, which is also where stray chevrons
|
|
would show up.
|
|
|
|
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 `gate.chevron-count`
|
|
(default 7) blocks evenly spaced around the ring's actual perimeter. 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 becomes the event horizon (`gate.iris-open-material`, default
|
|
water) and travel opens up. It auto-closes after `dialing.open-seconds`.
|
|
- **Shift + left-click** the sign: destroys the gate on the spot (same permission
|
|
check as `/sg destroy` - owner or `stargate.admin`), breaking the sign as if
|
|
you'd mined it. Quicker than looking at the sign and typing the command.
|
|
- Travel is **one-way**: only the gate you dialed *from* can send anything anywhere.
|
|
Walking (or wandering, or drifting) into its event horizon teleports whatever
|
|
entered to the destination, arriving just clear of its iris (never inside it) and
|
|
still facing whatever direction it was already moving, so entering forward always
|
|
means exiting forward. The destination's horizon is visible but not walkable -
|
|
stepping into it does nothing, same as a real Stargate only running one direction
|
|
at a time.
|
|
- Not just players - mobs, dropped items, minecarts, boats, arrows, anything that
|
|
moves through the event horizon gets sent through too. Non-player entities can
|
|
only travel to a same-server destination, though; there's no way to carry an
|
|
arbitrary entity's state across the Velocity/Bungee plugin-messaging hop, so a
|
|
cross-server gate just won't move anything but players.
|
|
- The **iris shield** is a separate, physical thing from the wormhole connection.
|
|
**Right-click a button placed directly below the sign** to toggle it. Closed means
|
|
closed - `gate.iris-shield-material` (default bedrock), solid, blocking everything -
|
|
whether or not the gate is even connected right now, and travel is refused even if
|
|
something manages to occupy that space anyway (flight, an elytra, a vehicle - not
|
|
just relying on block collision). It blocks in both directions: a closed shield on
|
|
the gate you're dialing *from* stops you from ever stepping in, and a closed shield
|
|
on the *destination* refuses the trip too, matching a real iris stopping anything
|
|
that hits it from either side. With the shield open, the interior just reflects the
|
|
connection state: `gate.iris-idle-material` (default air) if idle, or the event
|
|
horizon if actively dialed. Closing needs nothing 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. Add any
|
|
connection parameters your host requires (TLS, timezone, etc.) under
|
|
`storage.mysql.properties` - each key becomes `?key=value` on the JDBC URL. It
|
|
defaults to `useSSL: false` / `autoReconnect: true`; list a key here to override
|
|
that default (e.g. `useSSL: true` plus `sslMode: REQUIRED`).
|
|
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`
|