Updates documentation.
This commit is contained in:
@@ -18,7 +18,7 @@ MODRINTH_TOKEN=
|
|||||||
MODRINTH_PROJECT_ID=metropolis-builder
|
MODRINTH_PROJECT_ID=metropolis-builder
|
||||||
# Optional Markdown override; empty generates notes from commits since the last tag.
|
# Optional Markdown override; empty generates notes from commits since the last tag.
|
||||||
MODRINTH_CHANGELOG=
|
MODRINTH_CHANGELOG=
|
||||||
MODRINTH_GAME_VERSIONS=26.2
|
MODRINTH_GAME_VERSIONS=26.2,26.3
|
||||||
MODRINTH_LOADERS=paper
|
MODRINTH_LOADERS=paper
|
||||||
MODRINTH_VERSION_TYPE=
|
MODRINTH_VERSION_TYPE=
|
||||||
MODRINTH_DEPENDENCIES=
|
MODRINTH_DEPENDENCIES=
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,4 +6,5 @@ bin/
|
|||||||
/backups/
|
/backups/
|
||||||
/server/
|
/server/
|
||||||
.env
|
.env
|
||||||
|
.settings/
|
||||||
|
|
||||||
|
|||||||
35
AGENTS.md
Normal file
35
AGENTS.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Metropolis Working Rules
|
||||||
|
|
||||||
|
Start with [CONTRIBUTING.md](CONTRIBUTING.md) for the first-contribution path,
|
||||||
|
architecture, build/test commands, and operational safety. [README.md](README.md)
|
||||||
|
is the player/server-admin behavior reference. Other files in `docs/` are
|
||||||
|
optional reference material, not competing onboarding guides.
|
||||||
|
|
||||||
|
- Use **Metropolis** in human-facing prose. Preserve machine-facing identifiers,
|
||||||
|
including `Metropolis`, `com.majinnaibu.bukkitplugins.metropolis`, artifact
|
||||||
|
names, plugin IDs, commands, permission nodes, and URLs.
|
||||||
|
- Inspect the current diff before editing and preserve unrelated work. Do not
|
||||||
|
edit generated `build/`, `target/`, or `.gradle/` output. Never read, expose,
|
||||||
|
or commit `.env`, server/player data, or publishing credentials.
|
||||||
|
- Keep claims aligned with source, build configuration, CI, and scripts. State
|
||||||
|
Paper targets separately from versions actually built or tested. Keep
|
||||||
|
implemented behavior, planned work, automated coverage, and manual scenarios
|
||||||
|
distinct.
|
||||||
|
- When editing Java, preserve the existing AGPL header, use Gradle Spotless,
|
||||||
|
and keep Bukkit/Paper state and API access on the main thread. Avoid unrelated
|
||||||
|
gameplay changes.
|
||||||
|
- Before editing `docs/project-description.json`, read
|
||||||
|
`docs/projects.schema.json`. Validate the JSON against that schema without
|
||||||
|
changing the schema to accommodate invalid metadata. Preserve exactly the
|
||||||
|
existing top-level project key, `id`, `title`, `docId`, `image.url`, and
|
||||||
|
`headerImage.url` when present. Preserve `headerImage: null` or its absence.
|
||||||
|
These are fixed consuming-project integration values: do not derive or
|
||||||
|
“correct” their spelling, capitalization, spacing, or slug from repository
|
||||||
|
names. Image paths are relative to the consuming project's root; do not
|
||||||
|
resolve them here, convert them to repository URLs, or replace them with
|
||||||
|
generated/remote URLs. Preserve all other integration fields unless the task
|
||||||
|
requires a change. If schema compliance conflicts with preserving protected
|
||||||
|
values, stop and explain the conflict before editing.
|
||||||
|
- Do not start/stop servers, deploy, restore, publish, tag, or release without
|
||||||
|
explicit authorization. `tools/stop-server.sh` can match unrelated Paper
|
||||||
|
processes; `tools/restore-server.sh` replaces archive top-level items.
|
||||||
@@ -1,18 +1,57 @@
|
|||||||
# Contributing
|
# Contributing to Metropolis
|
||||||
|
|
||||||
## Development Setup
|
This is the single onboarding entry point for new contributors. Shared rules
|
||||||
|
for people and coding agents are in [AGENTS.md](AGENTS.md); read them before
|
||||||
|
editing, especially the scraper-metadata preservation and operational-safety
|
||||||
|
rules.
|
||||||
|
|
||||||
Use Java 25 or newer. The Gradle wrapper downloads Gradle 9.8; dependencies are declared in `build.gradle` and resolved from Maven Central, PaperMC, and EngineHub.
|
## First Contribution
|
||||||
|
|
||||||
```sh
|
1. Read [README.md](README.md) for supported server versions, installation,
|
||||||
./gradlew build
|
configuration, and commands.
|
||||||
```
|
2. Trace the relevant implementation using the source map below and check
|
||||||
|
nearby tests before changing behavior.
|
||||||
|
3. Make a focused change. Add or update automated tests for behavior changes;
|
||||||
|
update the manual pre-release checklist for behavior that needs a real
|
||||||
|
server.
|
||||||
|
4. Run `./gradlew test` and `./gradlew build`. Report any manual scenarios that
|
||||||
|
were not run rather than describing them as passing.
|
||||||
|
5. Update user-facing descriptions if setup, supported versions, commands,
|
||||||
|
dependencies, or behavior changed.
|
||||||
|
|
||||||
The standard build runs JUnit 5 tests without starting Minecraft. Tests use Mockito for Bukkit and external-plugin boundaries. Keep domain and configuration behavior testable without a running server.
|
## Architecture and Source Map
|
||||||
|
|
||||||
## Live Server Tests
|
- `MetropolisPlugin` loads configuration, connects Bukkit to WorldGuard and
|
||||||
|
WorldEdit, allocates plots, generates blocks, and manages regions.
|
||||||
|
- `Plot`, `PlayerHome`, grid/layout/support classes, and home stores implement
|
||||||
|
plot geometry, region ownership, allocation, and selected-home persistence.
|
||||||
|
- `commands/` contains the command handlers; `eventlisteners/` contains join
|
||||||
|
behavior.
|
||||||
|
- `src/main/resources/plugin.yml` declares dependencies, commands, and command
|
||||||
|
permissions. `config.yml` is the bundled configuration template.
|
||||||
|
- `src/test/` contains isolated JUnit/Mockito tests. `src/integrationTest/`
|
||||||
|
contains the opt-in tests that require a running server and RCON.
|
||||||
|
- `build.gradle` defines dependencies, Java/Gradle versions, formatting, and
|
||||||
|
test tasks. `.github/workflows/gradle.yml` runs tests and builds on pushes
|
||||||
|
and pull requests to `develop`.
|
||||||
|
|
||||||
Live tests are opt-in and run separately from `build`:
|
## Prerequisites and Checks
|
||||||
|
|
||||||
|
- JDK 25. The Gradle wrapper uses Gradle 9.8 and can download the required
|
||||||
|
Gradle distribution; dependencies resolve from Maven Central, PaperMC, and
|
||||||
|
EngineHub.
|
||||||
|
- `./gradlew test` runs server-free JUnit tests.
|
||||||
|
- `./gradlew build` runs the normal build and verification lifecycle. The
|
||||||
|
plugin jar is written under `build/libs/`.
|
||||||
|
- CI compiles against Paper API 26.2, runs `test`, then builds. It does not
|
||||||
|
start a Minecraft server or run `integrationTest`.
|
||||||
|
|
||||||
|
The opt-in `integrationTest` source set currently has two tests: checking that
|
||||||
|
Metropolis appears in `/plugins`, and creating a coordinate reservation then
|
||||||
|
checking WorldGuard's `regions.yml`. It mutates the configured server's
|
||||||
|
WorldGuard data and needs a running Paper server with RCON, WorldGuard, and
|
||||||
|
WorldEdit. Use a disposable server, bind RCON to a trusted interface, and use
|
||||||
|
a temporary password:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
METROPOLIS_RCON_HOST=127.0.0.1 \
|
METROPOLIS_RCON_HOST=127.0.0.1 \
|
||||||
@@ -22,12 +61,27 @@ METROPOLIS_SERVER_DIR=/path/to/server \
|
|||||||
./gradlew integrationTest
|
./gradlew integrationTest
|
||||||
```
|
```
|
||||||
|
|
||||||
Use a disposable or backed-up Paper server with compatible WorldGuard and WorldEdit plugin jars installed. Keep RCON local, use a temporary password, and restore the server after tests that modify regions or worlds.
|
Set `METROPOLIS_WORLD` if the test world is not named `world`. These tests do
|
||||||
|
not cover the broader in-game workflows in [human-tests.md](docs/human-tests.md).
|
||||||
|
|
||||||
## Pull Requests
|
## Operational Safety
|
||||||
|
|
||||||
- Keep changes focused and include tests for behavior changes.
|
Use the build/test commands above for ordinary contribution work. The scripts
|
||||||
- Run `./gradlew build` before submitting.
|
under `tools/` also include server start/stop, deployment, backup/restore, and
|
||||||
- Run `integrationTest` only when changing behavior that requires Paper or the external plugins; do not add it to the default build.
|
publishing operations; they are not required for a normal build. Read a
|
||||||
- Update `README.md` and project descriptions when user-facing setup, commands, or dependencies change.
|
script before use and get explicit authorization before running operational
|
||||||
- Keep generated build output, server data, credentials, and local `.env` files out of commits.
|
or release actions. In particular, `stop-server.sh` matches Paper jar
|
||||||
|
processes by command line, and `restore-server.sh` replaces matching top-level
|
||||||
|
server items from an archive. Never commit `.env`, credentials, server state,
|
||||||
|
or generated build output.
|
||||||
|
|
||||||
|
## Optional References
|
||||||
|
|
||||||
|
- [README.md](README.md): player/server-admin usage reference.
|
||||||
|
- [human-tests.md](docs/human-tests.md): manual pre-release checklist, not an
|
||||||
|
automated test report.
|
||||||
|
- [TODO.md](docs/TODO.md): historical backlog; the maintained plan is
|
||||||
|
[modernization-plan.md](docs/modernization-plan.md).
|
||||||
|
- [Modrinth description](docs/modrinth-description.md): hosting copy reference.
|
||||||
|
- [Scraper metadata](docs/project-description.md) and
|
||||||
|
[schema](docs/projects.schema.json): consuming-site project entry.
|
||||||
|
|||||||
11
README.md
11
README.md
@@ -18,7 +18,9 @@ Metropolis expands a protected Minecraft city as players join. Each player can r
|
|||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- Paper 26.2 or 26.3, with Java 25 or newer
|
- Paper 26.2 or 26.3, with Java 25 or newer. The build and CI compile against
|
||||||
|
Paper API 26.2; CI does not launch a server to verify runtime behavior on
|
||||||
|
either version.
|
||||||
- WorldGuard 7.0.19
|
- WorldGuard 7.0.19
|
||||||
- WorldEdit 7.4.5
|
- WorldEdit 7.4.5
|
||||||
|
|
||||||
@@ -114,4 +116,9 @@ Assign these permission nodes to groups or individual users in your permission p
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
GNU General Public License v3.
|
GNU Affero General Public License v3 or later.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for the single developer onboarding
|
||||||
|
path, source map, checks, and operational safety notes.
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
# Modernize Metropolis Plugin: Implementation Tasks
|
# Historical Modernization Backlog
|
||||||
|
|
||||||
|
This file preserves the earlier task list for context. Its status labels and
|
||||||
|
acceptance text are historical and are not the current implementation report.
|
||||||
|
Use the maintained [modernization plan](modernization-plan.md) for current
|
||||||
|
implementation status, pending work, and completion criteria.
|
||||||
|
|
||||||
| ID | Status | Title |
|
| ID | Status | Title |
|
||||||
|:-------:|:--------:|:------|
|
|:-------:|:--------:|:------|
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
# Metropolis Human Testing
|
# Metropolis Manual Pre-release Checklist
|
||||||
|
|
||||||
Use this checklist for behavior that depends on a real Paper world, player interactions, or the installed WorldGuard and WorldEdit plugins. Automated tests cover some isolated logic, but they do not establish that the complete in-game workflows behave correctly.
|
This is a manual checklist of expected behavior that needs a real Paper world,
|
||||||
|
player interaction, or installed WorldGuard/WorldEdit plugins. Checklist items
|
||||||
|
are scenarios to run, not test results; no item is considered passed until a
|
||||||
|
person performs it and records the outcome. Automated coverage is summarized
|
||||||
|
separately below.
|
||||||
|
|
||||||
## Test Environment
|
## Test Environment
|
||||||
|
|
||||||
@@ -10,7 +14,7 @@ Use this checklist for behavior that depends on a real Paper world, player inter
|
|||||||
- Keep a server console open and check it for errors after startup, commands, joins, and restarts.
|
- Keep a server console open and check it for errors after startup, commands, joins, and restarts.
|
||||||
- Record the Metropolis config, world name, test player UUIDs, command output, and any unexpected region bounds or block changes.
|
- Record the Metropolis config, world name, test player UUIDs, command output, and any unexpected region bounds or block changes.
|
||||||
|
|
||||||
## Human Checklist
|
## Manual Scenarios
|
||||||
|
|
||||||
### Startup and world setup
|
### Startup and world setup
|
||||||
|
|
||||||
@@ -78,34 +82,20 @@ Use this checklist for behavior that depends on a real Paper world, player inter
|
|||||||
- Test commands as console, permitted player, and player without the relevant permission. Check player-only commands, target-player arguments, unknown names, malformed arguments, and permission denials for useful feedback and no unintended changes.
|
- Test commands as console, permitted player, and player without the relevant permission. Check player-only commands, target-player arguments, unknown names, malformed arguments, and permission denials for useful feedback and no unintended changes.
|
||||||
- If upgrading an existing server, verify a legacy name-keyed `currentHomes.yml` entry resolves to the right UUID and the player's selected home is retained.
|
- If upgrading an existing server, verify a legacy name-keyed `currentHomes.yml` entry resolves to the right UUID and the player's selected home is retained.
|
||||||
|
|
||||||
## Existing Automated Coverage
|
## Automated Coverage (Separate from This Checklist)
|
||||||
|
|
||||||
Run `./gradlew test` for the server-free JUnit suite. It has 62 tests covering:
|
Run `./gradlew test` for the server-free JUnit suite. It covers isolated plot
|
||||||
|
geometry/allocation rules, road and stair layouts/build plans, WorldGuard
|
||||||
|
region occupancy and reservation lookup, spawn/city bounds, home identity and
|
||||||
|
selection persistence, permission overrides, player lookup, and selected
|
||||||
|
command/event behavior. These unit tests do not load a real Paper server.
|
||||||
|
|
||||||
- `AvenueStairwayLayoutTest`: centered per-segment street and avenue flights, both border directions, independent cadence, top-tread alignment, inverted backing plan, exact-width openings, and invalid-fit rejection.
|
The separate `src/integrationTest` source set currently contains two live
|
||||||
- `PlotLevelSupportTest`: rejection of upper plots with missing logical support cells and complete coverage requirements across all lower levels.
|
checks: Metropolis appears in `/plugins`, and a coordinate reservation is
|
||||||
- `CityRegionBoundsTest`: City bounds expand to include elevated plots and Spawn without shrinking existing protection bounds.
|
persisted in WorldGuard's `regions.yml`. It does not verify restart behavior,
|
||||||
- `PlotGridLayoutTest`: zero-offset compatibility, offsets on X/Y/Z, axis-specific spacing, and negative logical-index recovery.
|
join allocation, WorldEdit-selection reservations, permissions, teleport
|
||||||
- `WorldGuardRegionOccupancyTest`: arbitrary saved-region bounds are excluded while City/global regions are treated as non-occupying envelopes.
|
workflows, generated blocks, or protection behavior. See
|
||||||
- `PlotWorldBorderBoundsTest`: search bounds follow WorldBorder size/center and require the full candidate footprint inside it.
|
[CONTRIBUTING.md](../CONTRIBUTING.md) for prerequisites and safe invocation.
|
||||||
- `SpawnLayoutTest`: default one-cell bounds, independent multipliers, and build-height validation.
|
Those integration checks have not been run as part of this documentation
|
||||||
- `AvenueStairwayBuilderTest`: configured stair material and facing/half data for avenue and street directions, upside-down backing stairs, exact upper-road AIR placements, and no block writes at lower-road Y.
|
update. The manual scenarios above remain unverified until individually run
|
||||||
- `RoadLayoutTest`: independently sized street/avenue bands, correct road-type tagging, non-overlapping corners, and disabled roads at zero width.
|
and recorded against the target server/plugins.
|
||||||
- `RoadBlockWriterTest`: no-op writes for existing roads, filling missing road blocks, and preserving stair treads.
|
|
||||||
- `CuboidTest`: WorldEdit bound conversion, vector ordering/null handling, touching intersections, and point containment.
|
|
||||||
- `CurrentHomesStoreTest`: UUID-based persistence and resolving a legacy player-name key.
|
|
||||||
- `PlayerJoinListenerTest`: the welcome bounds message when a home is supplied by a mock.
|
|
||||||
- `PlayerLookupTest`: case-insensitive full-name matching and rejection of prefix matching.
|
|
||||||
- `PlayerHomeTest`: UUID-based region identity and display-name retention.
|
|
||||||
- `HomePermissionOverrideTest`: dotted permission-node parsing, priority and tie resolution, invalid entries, and username/permission/default precedence.
|
|
||||||
- `HomeNumberAllocatorTest`: choosing the first unused positive home number.
|
|
||||||
- `MetropolisHomeMoveCommandTest`: selecting a sender's home, selecting an offline target's home, and rejecting invalid requests.
|
|
||||||
- `PlotReservationLookupTest`: owner/member matching, exclusion of homes/City/Spawn, legacy reservation markers, and region-name aliases.
|
|
||||||
- `MetropolisPlotGoCommandTest`: self and target teleportation, ambiguous memberships, absent membership, and unsafe-destination feedback.
|
|
||||||
- `MetropolisPlotReserveCommandTest`: parsing six coordinates and rejecting malformed coordinates.
|
|
||||||
- `MetropolisHomeAcquireTest`: acquisition below the limit and refusal at the limit.
|
|
||||||
- `MetropolisDebugGenerateTestHomesCommandTest`: asynchronous tick-queued generation, one home per interval, no overlapping batches, and continuing test-player names across repeated runs.
|
|
||||||
|
|
||||||
The two opt-in tests in `src/integrationTest` require a running Paper server and RCON. They check that Metropolis appears in `/plugins` and that a coordinate reservation is persisted by WorldGuard. They do not currently verify restart persistence, join allocation, WorldEdit-selection reservations, permissions, teleports, generated blocks, protection behavior, or the other command workflows above. Run them with the environment variables documented in `README.md`; use a disposable server because the reservation test changes its WorldGuard data.
|
|
||||||
|
|
||||||
The integration scope described in `TODO.md` is broader than the tests currently present. Treat the scenarios in this guide as unverified until a human has run them on the target Paper and plugin versions.
|
|
||||||
|
|||||||
59
docs/modernization-plan.md
Normal file
59
docs/modernization-plan.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Metropolis Modernization Plan
|
||||||
|
|
||||||
|
This is the maintained status and follow-up plan. Implemented behavior is
|
||||||
|
described in [README.md](../README.md); automated and manual coverage are
|
||||||
|
separated in [human-tests.md](human-tests.md). A feature is not considered
|
||||||
|
runtime-verified merely because its code or an isolated unit test exists.
|
||||||
|
|
||||||
|
## Completed
|
||||||
|
|
||||||
|
- **Build and CI modernization.** Gradle 9.8 builds the Java 25 plugin and
|
||||||
|
expands the version into `plugin.yml`. CI runs `test` and the plugin build
|
||||||
|
for pushes and pull requests to `develop`. Completion check: running
|
||||||
|
`./gradlew test build` succeeds; CI provides the corresponding hosted check.
|
||||||
|
- **Paper/WorldGuard/WorldEdit integration.** The plugin declares Paper API
|
||||||
|
26.2, WorldGuard 7.0.19, and WorldEdit 7.4.5, and uses WorldGuard regions
|
||||||
|
for city, home, and reservation geometry. Paper 26.2/26.3 are project
|
||||||
|
targets; the current build and CI do not perform live server compatibility
|
||||||
|
checks. Completion check for runtime claims: run the applicable manual
|
||||||
|
scenarios in `human-tests.md` on a disposable server.
|
||||||
|
- **Plot, home, and command features.** The implementation includes join-time
|
||||||
|
initial home allocation, explicit additional-home acquisition, UUID-based
|
||||||
|
active-home persistence with legacy name-key loading, user/permission plot
|
||||||
|
overrides, reservations, multi-level support checks, and configured
|
||||||
|
road/stair generation. Isolated tests cover parts of these rules; see
|
||||||
|
`src/test/` and `human-tests.md` for their boundaries.
|
||||||
|
|
||||||
|
## Pending
|
||||||
|
|
||||||
|
- **Expand live-server integration coverage.** The current `integrationTest`
|
||||||
|
suite only checks plugin visibility and persistence of one coordinate-based
|
||||||
|
WorldGuard reservation. Add focused disposable-server checks for join-time
|
||||||
|
home allocation/ownership and selected-home restart persistence. Completion
|
||||||
|
criteria: tests assert the expected region/UUID state before and after a
|
||||||
|
restart, clean up their own test regions, and remain excluded from `build`.
|
||||||
|
- **Choose optional login allocation policies (MET-023/MET-024).** Current
|
||||||
|
behavior allocates the configured initial home count (default one) when a
|
||||||
|
player has no home; later homes require `/metropolis-home-acquire`. Decide
|
||||||
|
whether to offer grant-all-to-limit or one-more-per-login policies before
|
||||||
|
implementing them. Completion criteria: documented config semantics,
|
||||||
|
compatibility defaults, and unit tests for limits, reconnects, and existing
|
||||||
|
home selections.
|
||||||
|
- **Choose an allocation traversal option (MET-025).** The proposal to select
|
||||||
|
a rectangle/cuboid or ring-based traversal remains unimplemented. First
|
||||||
|
document deterministic ordering and how each policy treats occupied regions,
|
||||||
|
levels, and WorldBorder bounds. Completion criteria: configuration and
|
||||||
|
focused allocation tests establish repeatable ordering without overlaps.
|
||||||
|
- **Research conversion of existing worlds (MET-026).** There is no automatic
|
||||||
|
world/config conversion workflow. Document the legacy data/config formats,
|
||||||
|
backups and rollback requirements, and a safe migration strategy before
|
||||||
|
proposing implementation. Completion criteria: a reviewed conversion
|
||||||
|
specification plus disposable-world validation; do not claim migration
|
||||||
|
support before that work is complete.
|
||||||
|
|
||||||
|
## Deferred Ideas
|
||||||
|
|
||||||
|
Economy-based home sales, arbitrary connected plot shapes, and alternate
|
||||||
|
multi-plot footprints remain product ideas, not committed work. Reconsider them
|
||||||
|
only after requirements, compatibility constraints, and acceptance criteria
|
||||||
|
are defined.
|
||||||
@@ -11,6 +11,8 @@ Metropolis grows a protected Minecraft city as players join. It assigns home plo
|
|||||||
WorldGuard and WorldEdit are required dependencies. Install all three plugins in the server's `plugins` directory.
|
WorldGuard and WorldEdit are required dependencies. Install all three plugins in the server's `plugins` directory.
|
||||||
|
|
||||||
Metropolis targets Paper only; Bukkit and Spigot servers are not supported.
|
Metropolis targets Paper only; Bukkit and Spigot servers are not supported.
|
||||||
|
The project targets Paper 26.2 and 26.3, while its build/CI compile against the
|
||||||
|
Paper 26.2 API and do not run a live server compatibility check.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,29 @@
|
|||||||
{
|
{
|
||||||
|
"metropolis": {
|
||||||
"id": "metropolis",
|
"id": "metropolis",
|
||||||
"title": "Metropolis",
|
"title": "Metropolis",
|
||||||
"description": "A Paper 26.2/26.3 city-planning plugin that turns player onboarding into procedural urban growth with protected UUID-owned homes, roads, reservations, and configurable infrastructure.",
|
"description": "City manager that automatically creates protected home plots and roads as players join a Minecraft server.",
|
||||||
"docId": "Metropolis",
|
"docId": "Metropolis",
|
||||||
|
"headerImage": null,
|
||||||
|
"platforms": [
|
||||||
|
{ "name": "Minecraft", "info": "Paper server plugin" }
|
||||||
|
],
|
||||||
"image": {
|
"image": {
|
||||||
"url": "Pixel-art aerial view of a growing Minecraft city planned in a square grid, small player home plots connected by pale roads, a protected central spawn, blocky green landscape, subtle WorldGuard-inspired boundary lines, warm daylight, clean game-plugin thumbnail composition, no words or logos.",
|
"url": "/projects/metropolis/logo.png",
|
||||||
"alt": "Pixel-art aerial view of a Minecraft city with player home plots and connecting roads",
|
"alt": "Metropolis Minecraft plugin logo",
|
||||||
"prompt": "Pixel-art aerial view of a growing Minecraft city planned in a square grid, small player home plots connected by pale roads, a protected central spawn, blocky green landscape, subtle WorldGuard-inspired boundary lines, warm daylight, clean game-plugin thumbnail composition, no words or logos.",
|
"width": 1024,
|
||||||
"width": 0,
|
"height": 1024,
|
||||||
"height": 0,
|
|
||||||
"backgroundClassName": "bg-surface"
|
"backgroundClassName": "bg-surface"
|
||||||
},
|
},
|
||||||
"url": "/projects/metropolis",
|
"url": "/projects/metropolis",
|
||||||
"tags": ["open-source"],
|
"tags": ["Open-Source", "Game", "Minecraft"],
|
||||||
"source": {
|
"source": {
|
||||||
"type": "github",
|
"type": "github",
|
||||||
"url": "https://github.com/headhunter45/Metropolis"
|
"url": "https://github.com/headhunter45/Metropolis"
|
||||||
},
|
},
|
||||||
"feedback": {
|
"feedback": {
|
||||||
|
"type": "github-issues",
|
||||||
"url": "https://github.com/headhunter45/Metropolis/issues"
|
"url": "https://github.com/headhunter45/Metropolis/issues"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
# Metropolis
|
# Metropolis
|
||||||
|
|
||||||
|
The project targets Paper 26.2 and 26.3; Gradle and CI compile against Paper
|
||||||
|
API 26.2, and CI does not run a live server compatibility check.
|
||||||
|
|
||||||
Metropolis turns player onboarding into city planning. As players arrive, the Paper plugin finds the next available plot, builds the surrounding roads and infrastructure, and extends a WorldGuard-protected city that feels designed rather than randomly generated.
|
Metropolis turns player onboarding into city planning. As players arrive, the Paper plugin finds the next available plot, builds the surrounding roads and infrastructure, and extends a WorldGuard-protected city that feels designed rather than randomly generated.
|
||||||
|
|
||||||
The project combines procedural spatial logic, persistent UUID-based ownership, configurable construction rules, WorldEdit-assisted reservations, and a command suite for acquiring and selecting multiple homes. Home limits and plot sizes can be assigned per user or through permission-manager groups using configurable permission tiers. Reservation owners and members can teleport to their reserved plots, with explicit selection when they belong to multiple reservations. Active-home selections persist across reconnects and server restarts. It is also a modernization case study: a legacy plugin brought forward to Paper 26.2 and 26.3 with Gradle, focused unit tests, and opt-in live-server integration tests. Bukkit and Spigot servers are outside the support target.
|
The project combines procedural spatial logic, persistent UUID-based ownership, configurable construction rules, WorldEdit-assisted reservations, and a command suite for acquiring and selecting multiple homes. Home limits and plot sizes can be assigned per user or through permission-manager groups using configurable permission tiers. Reservation owners and members can teleport to their reserved plots, with explicit selection when they belong to multiple reservations. Active-home selections persist across reconnects and server restarts. It is also a modernization case study: a legacy plugin brought forward to Paper 26.2 and 26.3 with Gradle, focused unit tests, and opt-in live-server integration tests. Bukkit and Spigot servers are outside the support target.
|
||||||
|
|||||||
114
docs/projects.schema.json
Normal file
114
docs/projects.schema.json
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"title": "Projects",
|
||||||
|
"description": "Project metadata keyed by the project route slug.",
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
"^[a-z0-9]+(?:-[a-z0-9]+)*$": { "$ref": "#/definitions/project" }
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"definitions": {
|
||||||
|
"image": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["url", "width", "height"],
|
||||||
|
"properties": {
|
||||||
|
"url": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Public asset path or remote image URL. A blank header image URL falls back to image.",
|
||||||
|
"pattern": "^(\\s*|/[^/].*|https?://.+)$"
|
||||||
|
},
|
||||||
|
"alt": { "type": "string" },
|
||||||
|
"prompt": { "type": "string" },
|
||||||
|
"name": { "type": "string" },
|
||||||
|
"width": { "type": "integer", "minimum": 1 },
|
||||||
|
"height": { "type": "integer", "minimum": 1 },
|
||||||
|
"backgroundClassName": { "type": "string" }
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"projectLink": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["url"],
|
||||||
|
"properties": {
|
||||||
|
"type": { "type": "string" },
|
||||||
|
"url": { "type": "string", "pattern": "^(\\s*|https?://.+)$" }
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"platform": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["name"],
|
||||||
|
"properties": {
|
||||||
|
"name": { "type": "string", "pattern": "\\S" },
|
||||||
|
"info": { "type": "string" },
|
||||||
|
"links": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["label", "url"],
|
||||||
|
"properties": {
|
||||||
|
"label": { "type": "string", "pattern": "\\S" },
|
||||||
|
"url": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uri",
|
||||||
|
"pattern": "^https?://.+"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"project": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["id", "title", "description", "tags"],
|
||||||
|
"properties": {
|
||||||
|
"id": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" },
|
||||||
|
"title": { "type": "string", "pattern": "\\S" },
|
||||||
|
"description": { "type": "string", "pattern": "\\S" },
|
||||||
|
"docId": { "type": "string", "minLength": 1 },
|
||||||
|
"image": { "$ref": "#/definitions/image" },
|
||||||
|
"headerImage": {
|
||||||
|
"description": "Optional detail-page logo override. Omit, set to null, or use a blank URL to fall back to image. Listing cards continue to use image.",
|
||||||
|
"anyOf": [{ "$ref": "#/definitions/image" }, { "type": "null" }]
|
||||||
|
},
|
||||||
|
"status": { "type": "string" },
|
||||||
|
"platforms": {
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/platform" }
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^/projects/[a-z0-9]+(?:-[a-z0-9]+)*$"
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"type": "array",
|
||||||
|
"items": { "type": "string", "minLength": 1 },
|
||||||
|
"uniqueItems": true
|
||||||
|
},
|
||||||
|
"source": {
|
||||||
|
"allOf": [
|
||||||
|
{ "$ref": "#/definitions/projectLink" },
|
||||||
|
{ "required": ["type"] }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"feedback": { "$ref": "#/definitions/projectLink" },
|
||||||
|
"repository": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uri",
|
||||||
|
"pattern": "^https?://.+"
|
||||||
|
},
|
||||||
|
"features": {
|
||||||
|
"type": "array",
|
||||||
|
"items": { "type": "string", "minLength": 1 }
|
||||||
|
},
|
||||||
|
"technology": {
|
||||||
|
"type": "array",
|
||||||
|
"items": { "type": "string", "minLength": 1 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user