Go to file
Sasha Baranov 81672a3465
Build Papyrus / Build Papyrus (${{ matrix.mc }}) (21, 1.21.10, papyrus/1.21.10) (push) Failing after 2m44s Details
Build Papyrus / Build Papyrus (${{ matrix.mc }}) (21, 1.21.11, papyrus/1.21.11) (push) Failing after 1s Details
Build Papyrus / Build Papyrus (${{ matrix.mc }}) (21, 1.21.4, papyrus/1.21.4) (push) Failing after 1s Details
Build Papyrus / Build Papyrus (${{ matrix.mc }}) (21, 1.21.8, papyrus/1.21.8) (push) Failing after 2s Details
Build Papyrus / Build Papyrus (${{ matrix.mc }}) (25, 26.1.2, main) (push) Failing after 2s Details
Build Papyrus / release (push) Has been skipped Details
Fix 1.21.8/1.21.10 anticheat compile and restore split Gradle CI build.
Use CraftNamespacedKey for registry and plugin channel lookups so backports
with ResourceLocation compile alongside main's Identifier mappings. Keep
applyPatches and build as separate Gradle invocations to satisfy task ordering.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-16 15:14:37 -04:00
.github Fix 1.21.8/1.21.10 anticheat compile and restore split Gradle CI build. 2026-06-16 15:14:37 -04:00
build-data Add counting ops 2026-05-11 08:56:48 +02:00
gradle/wrapper Implement new version schema: `<mcver>.build.<paper_build_no>-<paper_status>` / `<mcver>.local-SNAPSHOT` 2026-04-10 14:39:00 +02:00
licenses [ci skip] add missing final newline (#8659) 2022-12-13 05:16:45 -08:00
papyrus-api Implement integrated anticheat system and client integrity checks in Papyrus. Update README with new features and configuration options. Enhance server-side handling for anticheat checks during player actions and packet processing. Introduce new configuration settings for anticheat engine and client integrity requirements. 2026-06-15 14:32:50 -04:00
papyrus-generator Fix paperweight patch application after papyrus-server rename. 2026-06-14 07:42:18 -04:00
papyrus-server Fix 1.21.8/1.21.10 anticheat compile and restore split Gradle CI build. 2026-06-16 15:14:37 -04:00
scripts Fix backport CI: drop incompatible branding overlays and unify Gradle build. 2026-06-16 15:02:23 -04:00
test-plugin Add performance and XP orb config options and refresh API docs for v1.0.2. 2026-06-14 08:32:03 -04:00
.editorconfig Rename project from Paper to Papyrus by SushiMC, update configuration paths and documentation, and enhance build scripts. Adjusted Gradle settings and improved entity randomization options for better performance and configurability. 2026-06-14 06:56:15 -04:00
.gitattributes [ci skip] update editorconfig and gitattributes (#9608) 2023-08-21 19:16:03 -07:00
.gitignore Rename project from Paper to Papyrus by SushiMC, update configuration paths and documentation, and enhance build scripts. Adjusted Gradle settings and improved entity randomization options for better performance and configurability. 2026-06-14 06:56:15 -04:00
CONTRIBUTING.md Add performance and XP orb config options and refresh API docs for v1.0.2. 2026-06-14 08:32:03 -04:00
LICENSE.md Rename project from Paper to Papyrus by SushiMC, update configuration paths and documentation, and enhance build scripts. Adjusted Gradle settings and improved entity randomization options for better performance and configurability. 2026-06-14 06:56:15 -04:00
README.md Implement integrated anticheat system and client integrity checks in Papyrus. Update README with new features and configuration options. Enhance server-side handling for anticheat checks during player actions and packet processing. Introduce new configuration settings for anticheat engine and client integrity requirements. 2026-06-15 14:32:50 -04:00
SECURITY.md Add performance and XP orb config options and refresh API docs for v1.0.2. 2026-06-14 08:32:03 -04:00
SUPPORTED_VERSIONS.txt Fix 1.21.x patch hooks and build from papyrus/* branches. 2026-06-15 20:56:35 -04:00
build.gradle.kts [ci skip] Move paperweight and mache to non snapshots 2026-06-02 20:08:53 +02:00
gradle.properties Rename project from Paper to Papyrus by SushiMC, update configuration paths and documentation, and enhance build scripts. Adjusted Gradle settings and improved entity randomization options for better performance and configurability. 2026-06-14 06:56:15 -04:00
gradlew Implement new version schema: `<mcver>.build.<paper_build_no>-<paper_status>` / `<mcver>.local-SNAPSHOT` 2026-04-10 14:39:00 +02:00
gradlew.bat Update Gradle wrapper to 9.1.0 2025-09-29 17:36:09 -07:00
paper-server Fix paperweight patch application after papyrus-server rename. 2026-06-14 07:42:18 -04:00
settings.gradle.kts Fix paperweight patch application after papyrus-server rename. 2026-06-14 07:42:18 -04:00

README.md

Papyrus

Papyrus is a Minecraft server software fork of Paper. It keeps full compatibility with the Paper plugin ecosystem (io.papermc.paper API, Paper plugins, and existing configs) while adding first-class options for vanilla parity and performance tuning.

Repository: github.com/codingsushi79/Papyrus

Documentation: docs.sushii.dev/papyrus


Table of contents


What Papyrus adds

Paper optimizes Minecraft in ways that sometimes diverge from vanilla behavior. Papyrus makes those trade-offs explicit and configurable instead of fixed.

Area Paper behavior Papyrus change
Entity RNG Shared random source across all entities (faster) Configurable: SHARED or VANILLA per-entity RNG
Redstone Vanilla by default; optional fast engines Same engines, documented presets for vanilla vs tech servers
Experience orbs Paper defaults Configurable despawn, pickup radius, merge radius, and merge disable
Performance defaults Paper defaults Tuned defaults for chunk I/O, explosions, hoppers, idle worlds, JVM/Netty
Update checker Checks PaperMC Disabled by default (fork-specific builds)
Anticheat External plugins (GrimAC, etc.) Built-in configurable engine (x-ray heuristics, reach, rates)

Everything else — Moonrise chunk system, incremental saves, hopper optimizations, plugin API, and the patch-based build — comes from upstream Paper unchanged.


Requirements

Running a server

  • Java 21+ to run the server jar (Java 25 recommended)
  • 2 GB RAM minimum for small servers; 8 GB+ recommended for production
  • A machine capable of running a Paper-based server (same as Paper)

Building from source

  • Git — you must clone the repository; zip downloads will not build
  • Java 25 JDK to compile (Gradle can auto-provision this via toolchains if you only have JRE 21+)
  • ~4 GB RAM for Gradle during compilation

Current Minecraft version: 26.1.2 (see gradle.properties).


Quick start

1. Get the jar

From releases: Download Papyrus-<mcVersion>.jar (e.g. Papyrus-26.1.2.jar) from GitHub Releases or see Documentation → Download.

From CI: Download the papyrus-server artifact from the latest successful GitHub Actions build.

From source:

git clone https://github.com/codingsushi79/Papyrus.git
cd Papyrus
./gradlew applyPatches createPaperclipJar syncPapyrusPaperclipJar

The runnable jar is at:

papyrus-server/build/distributions/papyrus-paperclip-<version>.jar

2. First run

mkdir papyrus-server && cd papyrus-server
cp ../Papyrus/papyrus-server/build/distributions/papyrus-paperclip-*.jar .
java -jar papyrus-paperclip-*.jar

Accept the EULA by editing eula.txt, then start again. Papyrus generates configs on first boot:

config/
  paper-global.yml          # Global server settings
  paper-world-defaults.yml  # Defaults for all worlds
world/
  paper-world.yml           # Per-world overrides (optional)
spigot.yml                  # Spigot settings (activation ranges, etc.)
bukkit.yml
server.properties

Running in production

Start script

Papyrus includes a production start script with recommended G1GC flags:

# Copy the jar into your server directory first
cp /path/to/papyrus-paperclip-*.jar ./papyrus-paperclip.jar

# From the repo (or copy scripts/start.sh into your server dir)
JAR=papyrus-paperclip.jar ./scripts/start.sh

Environment variables:

Variable Default Purpose
JAVA java Path to Java binary
JAR papyrus-paperclip.jar Server jar filename

Edit -Xms8G -Xmx8G in the script to match your host. Always set -Xms equal to -Xmx to avoid heap resize pauses during gameplay.

Manual JVM flags

If you prefer not to use the script:

java -Xms8G -Xmx8G \
  -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 \
  -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch \
  -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 \
  -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 \
  -XX:InitiatingHeapOccupancyPercent=15 -XX:MaxTenuringThreshold=1 \
  -jar papyrus-paperclip.jar nogui

Paper's Aikar flags documentation remains a good reference for tuning beyond these defaults.

Moonrise system properties

Optional JVM flags for advanced tuning:

Property Example Effect
Papyrus.WorkerThreadCount -DPapyrus.WorkerThreadCount=4 Override Moonrise worker thread count
Papyrus.NumaScheduling -DPapyrus.NumaScheduling=true NUMA-aware threading on multi-socket hosts
Papyrus.MaxViewDistance -DPapyrus.MaxViewDistance=32 Hard cap on view distance

Configuration

Papyrus uses Paper's layered config system. Files are YAML; keys use kebab-case.

File Scope
config/paper-global.yml Server-wide settings
config/paper-world-defaults.yml Defaults applied to every world
<world>/paper-world.yml Overrides for a specific world
spigot.yml Entity activation/tracking ranges, hopper rates, Netty threads
bukkit.yml Spawn limits, chunk settings
server.properties Port, gamemode, difficulty, etc.

After editing configs, restart the server or use /paper reload where supported (some settings require a full restart).

For Papyrus-specific options and presets, see docs.sushii.dev/papyrus. For the full Paper config reference, see docs.papermc.io. The sections below cover Papyrus-specific behavior and recommended values.


Papyrus-specific options

Entity random source

File: config/paper-global.yml

performance:
  entity-random-source: SHARED   # or VANILLA
  apply-runtime-jvm-defaults: true # Netty buffer caps, JNA nosys
  netty-threads: -1                # -1 = auto (48 based on CPU)
Value Behavior Use when
SHARED All entities share one random source (Paper default, faster) Performance matters; enchantment seed manipulation is not needed
VANILLA Each entity gets RandomSource.create() like vanilla Speedrunners, enchantment seed manipulation, or any vanilla-like RNG dependency

Experience orbs

File: config/paper-world-defaults.yml or <world>/paper-world.yml

environment:
  experience-orb-despawn-rate: 6000   # ticks (vanilla: 6000)
  experience-orb-pickup-radius: 8.0   # blocks (vanilla: 8)

entities:
  spawning:
    experience-orb-merge-radius: 1.0    # merge search radius in blocks
  behavior:
    disable-experience-orb-merge: false

Lower experience-orb-pickup-radius to reduce orb lag on grinder servers. Set disable-experience-orb-merge: true if you want orbs to stay separate.

Lower experience-orb-pickup-radius to reduce orb lag on grinder servers. Set disable-experience-orb-merge: true if you want orbs to stay separate.

Redstone implementation

File: config/paper-world-defaults.yml or <world>/paper-world.yml

misc:
  redstone-implementation: VANILLA   # VANILLA | EIGENCRAFT | ALTERNATE_CURRENT
  alternate-current-update-order: HORIZONTAL_FIRST_OUTWARD   # only for ALTERNATE_CURRENT
Engine Speed Vanilla parity
VANILLA Baseline Full — same update order as Minecraft
EIGENCRAFT ~95% fewer wire updates on depower Different update order; fixes MC-11193
ALTERNATE_CURRENT Fastest in most benchmarks Different update order; configurable direction

Default is VANILLA. Switch to EIGENCRAFT or ALTERNATE_CURRENT only on redstone-heavy technical servers where speed matters more than vanilla timing.

Chunk system I/O threads

File: config/paper-global.yml

chunk-system:
  io-threads: -1      # auto-detect from CPU count (recommended)
  worker-threads: -1  # auto-detect from CPU count (recommended)

Papyrus auto-scales I/O threads to min(4, max(1, cpu_cores / 4)) when set to -1 or 0. Paper previously pinned this to a single I/O thread.


Integrated anticheat

Papyrus ships a built-in anticheat engine under config/paper-global.yml. It runs at packet level (before actions apply) and does not require a plugin. Disable external anticheat plugins if you use this to avoid duplicate kicks.

anticheat:
  engine:
    enabled: true
    alerts:
      console: true
      notify-ops: false
    punishments:
      kick-enabled: true
      kick-violation-level: 40
      violation-decay-per-second: 2.0
    checks:
      xray:
        enabled: true
        window-seconds: 300
        suspicious-ore-count: 14
        tracked-ores:
          - minecraft:diamond_ore
          - minecraft:deepslate_diamond_ore
      fast-place:
        max-per-second: 12
        cancel-action: true
      fast-break:
        max-per-second: 8
      inventory:
        max-clicks-per-second: 25
      hand-swap:
        max-swaps-per-second: 8
      reach:
        block-extra-distance: 0.35
      movement:
        max-horizontal-blocks-per-tick: 0.85
        setback: true
      timer:
        max-packets-per-second: 140
Check What it detects
xray Valuable ores mined unusually fast or with suspicious ore-to-stone ratios
fast-place / fast-break Block place/break rates above human limits
inventory / hand-swap Inventory click and offhand swap spam (autoclickers, quick swap macros)
reach Block interactions beyond vanilla interaction range
movement Horizontal/vertical movement per tick above configured limits
timer Incoming packet rate spikes

Bypass permission: papyrus.anticheat.bypass

Plugin hook: PlayerAnticheatViolationEvent — cancel the event to ignore a flag.

Item component obfuscation (anticheat.obfuscation) and per-world Anti-Xray (anticheat.anti-xray in world config) remain separate features and complement the engine.


Performance tuning

Papyrus performance defaults

These defaults apply to new config files. Existing servers keep their saved values until you change them manually.

Global (config/paper-global.yml)

Key Papyrus default Effect
chunk-system.io-threads auto Scales chunk load/save throughput with CPU
performance.entity-random-source SHARED Fast entity RNG
performance.apply-runtime-jvm-defaults true Sets Netty buffer caps and jna.nosys at startup
performance.netty-threads -1 (auto) Scales Netty event-loop threads (48) when not set in spigot.yml
spark.enabled false No Spark profiler overhead
misc.region-file-cache-size 512 Larger region file cache (uses more RAM)
update-checker.enabled false No PaperMC update checks

World (config/paper-world-defaults.yml)

Key Papyrus default Effect
misc.update-pathfinding-on-block-update false Mobs don't repath on every nearby block change
environment.optimize-explosions true Faster TNT/creeper blast processing
environment.experience-orb-despawn-rate 6000 Ticks until XP orbs despawn (vanilla: 6000)
environment.experience-orb-pickup-radius 8.0 Player pickup range in blocks
entities.spawning.experience-orb-merge-radius 1.0 Radius for orb merge search
entities.behavior.disable-experience-orb-merge false When true, orbs never merge
unsupported-settings.disable-world-ticking-when-empty true Worlds with no players stop ticking
hopper.ignore-occluding-blocks true Hoppers skip entity scans under solid blocks
entities.armor-stands.tick false Armor stands don't tick (display/map servers)
entities.markers.tick false Marker entities don't tick
scoreboards.allow-non-player-entities-on-scoreboards false Skips scoreboard team lookups for non-players
chunks.entity-per-chunk-save-limit.* capped Limits arrow/orb/pearl buildup per chunk

Spigot (spigot.yml)

Key Papyrus default Effect
commands.log false No disk I/O logging every command
settings.netty-threads auto Scales Netty I/O threads with CPU when unset

Spigot entity ranges (manual tuning)

For mob-heavy servers, lower tracking and activation ranges in spigot.yml:

world-settings:
  default:
    entity-tracking-range:
      animals: 48
      monsters: 48
      misc: 32
    entity-activation-range:
      animals: 24
      monsters: 24
      water: 8
      villagers: 16

Tracking controls network packets; activation controls server-side AI ticks. Lower both before touching game rules.


Vanilla compatibility preset

Use this when vanilla behavior matters more than peak performance (speedrunning, strict survival, enchantment seed work):

# config/paper-global.yml
performance:
  entity-random-source: VANILLA

# config/paper-world-defaults.yml
misc:
  redstone-implementation: VANILLA
  update-pathfinding-on-block-update: true   # restore Paper-like mob repathing
environment:
  optimize-explosions: false
entities:
  armor-stands:
    tick: true
  markers:
    tick: true

Also set entity-random-source: VANILLA if players use enchantment table seed manipulation — this is the setting that restores per-entity RNG.


Redstone presets

Vanilla survival (default)

misc:
  redstone-implementation: VANILLA

Technical / farm server

misc:
  redstone-implementation: EIGENCRAFT

Maximum wire performance

misc:
  redstone-implementation: ALTERNATE_CURRENT
  alternate-current-update-order: HORIZONTAL_FIRST_OUTWARD

Test contraptions after switching engines. Timing and update order will differ from vanilla.


Building from source

git clone https://github.com/codingsushi79/Papyrus.git
cd Papyrus

# Apply Minecraft patches and compile
./gradlew applyPatches build

# Create the runnable paperclip jar (copied to papyrus-paperclip-*.jar)
./gradlew createPaperclipJar syncPapyrusPaperclipJar

Common Gradle tasks:

Task Purpose
./gradlew applyPatches Apply all Minecraft source patches
./gradlew build Compile and run tests
./gradlew createPaperclipJar Build the downloadable server jar
./gradlew syncPapyrusPaperclipJar Copy paperclip output to papyrus-paperclip-*.jar
./gradlew rebuildPatches Regenerate patch files after editing papyrus-server/src/minecraft
./gradlew fixupSourcePatches Fix patch context after manual edits

Windows: use gradlew instead of ./gradlew.

Development requires cloning with Git — the build system applies patches against a generated git tree inside papyrus-server/src/minecraft. Downloading a zip from GitHub will not work.

See CONTRIBUTING.md for patch workflow details (inherited from Paper).


Project structure

Papyrus/
├── papyrus-api/          Public Bukkit/Paper plugin API (Gradle project :paper-api)
├── papyrus-server/       Server implementation (Gradle project :paper-server)
├── paper-server/         Symlink → papyrus-server (required by Paperweight patch tooling)
│   ├── patches/          Minecraft source patches (sources/, features/, resources/)
│   └── src/main/java/    Papyrus/Paper Java code (io.papermc.paper.*)
├── build-data/           Access wideners and mapping data
├── scripts/
│   └── start.sh          Production JVM start script
├── gradle.properties     MC version, apiVersion, Maven group
└── .github/workflows/    CI build, tests, and release uploads

Gradle project names stay :paper-api and :paper-server so upstream Paperweight and plugin examples keep working. Physical directories use the papyrus-* prefix.

Maven coordinates remain io.papermc.paper:paper-api for plugin compatibility. The API jar embeds apiVersioning.json (from apiVersion in gradle.properties) for runtime version checks.


Plugin development

Papyrus is API-compatible with Paper plugins. Use the same dependency and plugin metadata format.

Dependencies

Gradle (Kotlin DSL):

repositories {
    maven("https://repo.papermc.io/repository/maven-public/")
}

dependencies {
    compileOnly("io.papermc.paper:paper-api:26.1.2-R0.1-SNAPSHOT")
}

java {
    toolchain.languageVersion.set(JavaLanguageVersion.of(21))
}

Maven:

<repository>
    <id>papermc</id>
    <url>https://repo.papermc.io/repository/maven-public/</url>
</repository>

<dependency>
    <groupId>io.papermc.paper</groupId>
    <artifactId>paper-api</artifactId>
    <version>26.1.2-R0.1-SNAPSHOT</version>
    <scope>provided</scope>
</dependency>

Replace the version with the current apiVersion from gradle.properties. Papyrus does not publish its own Maven repository; the API matches Paper's published artifact.

paper-plugin.yml

name: MyPlugin
version: 1.0.0
main: com.example.myplugin.MyPlugin
api-version: '26.1.2'   # must match gradle.properties apiVersion

Use api-version matching gradle.properties. Paper plugins use paper-plugin.yml; legacy Bukkit plugins use plugin.yml instead.

Detecting Papyrus at runtime

import io.papermc.paper.ServerBuildInfo;
import net.kyori.adventure.key.Key;

ServerBuildInfo info = ServerBuildInfo.buildInfo();
if (info.brandId().equals(ServerBuildInfo.BRAND_PAPYRUS_ID)) {
    // Running on Papyrus (sushimc:papyrus)
}
if (info.isBrandCompatible(ServerBuildInfo.BRAND_PAPER_ID)) {
    // true on both Paper and Papyrus — use for generic Paper-targeted plugins
}

Local development against this repo

dependencies {
    compileOnly(project(":paper-api"))
}

Run ./gradlew publishToMavenLocal to install paper-api locally, then add mavenLocal() above the PaperMC repository in your plugin project. See CONTRIBUTING.md for running the included test-plugin module.

More plugin guides: docs.sushii.dev/papyrus and docs.papermc.io/paper/dev.


Continuous integration

GitHub Actions builds on every push and pull request to main:

  1. Apply Minecraft patches
  2. Compile and run tests
  3. Build the paperclip jar
  4. Upload CI artifacts (papyrus-server jar + test results)

Releases: Pushing a version tag (e.g. v1.0.1) creates a GitHub Release with Papyrus-<mcVersion>.jar attached automatically. No external secrets are required.

Download CI builds from the Actions tab on github.com/codingsushi79/Papyrus.


Contributing

Papyrus inherits Paper's patch-based development workflow. To contribute:

  1. Fork codingsushi79/Papyrus
  2. Clone your fork and create a feature branch from main
  3. Make changes — Java code in papyrus-server/src/main/java/ directly, Minecraft changes via the patch system
  4. Run ./gradlew build to verify
  5. Open a pull request against main

See CONTRIBUTING.md for the full patch workflow. SECURITY.md covers vulnerability reporting.


License

Papyrus inherits licensing from Paper, Spigot, and CraftBukkit. See LICENSE.md for details.


Credits


FAQ

Is Papyrus compatible with Paper plugins?
Yes. Same API package (io.papermc.paper), same Maven artifact (io.papermc.paper:paper-api), same config file names, same paper-plugin.yml format. Gradle modules are named :paper-api / :paper-server but live in papyrus-* directories. Use ServerBuildInfo.BRAND_PAPYRUS_ID only if you need Papyrus-specific behavior.

What's the difference between performance.netty-threads and spigot.yml Netty settings?
performance.netty-threads in paper-global.yml sets io.netty.eventLoopThreads when spigot.yml does not override Netty thread count. Set either one, not both, unless you know you need different values.

Will my existing Paper config work?
Yes. Drop in your existing config/, spigot.yml, and worlds. Papyrus-specific defaults only apply to keys that aren't already set.

How do I restore enchantment seed manipulation?
Set performance.entity-random-source: VANILLA in config/paper-global.yml and restart.

How do I get vanilla redstone behavior?
Set misc.redstone-implementation: VANILLA in your world config. This is already the default.

Why is the jar named papyrus-paperclip?
The bootstrap tool (paperclip) comes from upstream Paper. Papyrus copies the build output to papyrus-paperclip-*.jar.

Can I use GrimAC or another anticheat plugin alongside Papyrus?
You can, but Papyrus includes a built-in engine (anticheat.engine in paper-global.yml). Running both may cause duplicate flags — disable one or set anticheat.engine.enabled: false if you prefer an external plugin.

Where do I report bugs?
Open an issue at github.com/codingsushi79/Papyrus/issues. Specify whether the bug exists in upstream Paper or is Papyrus-specific.

Can I redistribute the built jar?
Yes, under the terms of the GPL/MIT licenses described in LICENSE.md.