Thank you for your interest in contributing to HyperPerms! This guide covers the development setup and contribution workflow for HyperPerms and the broader HyperSystems ecosystem.
- Java 25 (build and runtime)
- Gradle 9.3.0+ (included via wrapper — no manual install needed)
- Git for version control
HyperPerms compiles against one optional mod. Download the JAR and place it in HyperPerms/libs/:
| JAR | Required | Download |
|---|---|---|
| VaultUnlocked-Hytale | Yes (compile) | CurseForge |
The Hytale Server API is resolved automatically from maven.hytale.com — no local JAR needed.
HyperPerms lives inside the HyperSystems multi-project workspace:
HyperSystems/
├── HyperPerms/ # This plugin
├── HyperHomes/ # Home teleportation
├── HyperFactions/ # Faction management
├── HyperWarp/ # Warps, spawns, TPA
├── HyperSpawns/ # Mob spawn zone control
├── servers/ # Dev and prerelease servers
├── settings.gradle # Multi-project configuration
└── build.gradle # Root build with shared properties
Each plugin has its own Git repository with independent versioning.
# Clone the HyperPerms repository
git clone git@github.com:HyperSystemsDev/HyperPerms.gitAll builds use the root Gradle wrapper. Never use subproject wrappers.
# Build HyperPerms only
./gradlew :HyperPerms:shadowJar
# Build all plugins
./gradlew buildAll
# Clean and rebuild (recommended after branch switches)
./gradlew :HyperPerms:clean :HyperPerms:shadowJar --no-build-cacheOutput JAR: HyperPerms/build/libs/HyperPerms-<version>.jar
Dependencies are relocated into the JAR to avoid conflicts:
com.google.gson->com.hyperperms.lib.gsoncom.github.benmanes.caffeine->com.hyperperms.lib.caffeineorg.yaml.snakeyaml->com.hyperperms.lib.snakeyaml
The jar task has archiveClassifier = 'plain' to prevent it from overwriting the shadow JAR in multi-project builds.
# Build all plugins and deploy to test server
./gradlew buildAndDeploy
# Deploy already-built JARs only
./gradlew deployMods# Start the test server (uses screen)
cd servers/dev && ./start.sh
# Attach to server console
screen -r hytale-server
# Stop the server
screen -S hytale-server -X stuff "stop\n"- Use records for immutable data models
- Use pattern matching where it improves clarity
- Use sealed interfaces for closed type hierarchies
Message.join()for message formatting — never.then()or legacy color codes@NotNull/@Nullableannotations on all public API parameters and return typesConcurrentHashMapfor thread-safe collectionsCompletableFuturefor all async storage operations- No raw types — always specify generic parameters
- Package-private by default — only
publicwhat needs to be accessed externally
- Manager classes in
com.hyperperms.manager - Data records in
com.hyperperms.data - Commands follow
<Action>Commandnaming (e.g.,CheckCommand) - Integration classes in
com.hyperperms.integration
We use Conventional Commits:
feat: add context-aware permission resolution
fix: wildcard matching ignores negated nodes
docs: update permission node reference
refactor: extract caching logic into CacheManager
chore: bump Caffeine to 3.1.8
- Add specific files by name — never use
git add -Aorgit add . - Write meaningful messages — focus on "why" not "what"
- One logical change per commit — don't mix features with refactors
| Branch | Purpose |
|---|---|
main |
Stable releases only |
dev/phase1 |
Primary development branch |
feat/<name> |
Feature branches (branch from dev/phase1) |
fix/<name> |
Bug fix branches |
- Branch from
dev/phase1:git checkout -b feat/my-feature dev/phase1 - Make changes, commit with conventional commit messages
- Push and open a PR against
dev/phase1 - After review, merge into
dev/phase1 dev/phase1merges intomainfor releases
# Run all tests
./gradlew testAll
# Run HyperPerms tests only
./gradlew :HyperPerms:testTests use JUnit Jupiter 5.10.2. Place test files in src/test/java/.
- Bug reports: Use the Bug Report template on GitHub
- Feature requests: Use the Feature Request template on GitHub
- Discord: Join our server for discussion
By contributing, you agree that your contributions will be licensed under the GPLv3.