Grasscutters/Grasscutter
A server software reimplementation for a certain anime game.
Mixed signals — read the receipts
weakest axiscopyleft license (AGPL-3.0) — review compatibility; no tests detected
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2mo ago
- ✓23+ active contributors
- ✓Distributed ownership (top contributor 30% of recent commits)
Show all 7 evidence items →Show less
- ✓AGPL-3.0 licensed
- ✓CI configured
- ⚠AGPL-3.0 is copyleft — check downstream compatibility
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Concerns → Mixed if: relicense under MIT/Apache-2.0 (rare for established libs)
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/grasscutters/grasscutter)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/grasscutters/grasscutter on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: Grasscutters/Grasscutter
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/Grasscutters/Grasscutter shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Mixed signals — read the receipts
- Last commit 2mo ago
- 23+ active contributors
- Distributed ownership (top contributor 30% of recent commits)
- AGPL-3.0 licensed
- CI configured
- ⚠ AGPL-3.0 is copyleft — check downstream compatibility
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live Grasscutters/Grasscutter
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/Grasscutters/Grasscutter.
What it runs against: a local clone of Grasscutters/Grasscutter — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in Grasscutters/Grasscutter | Confirms the artifact applies here, not a fork |
| 2 | License is still AGPL-3.0 | Catches relicense before you depend on it |
| 3 | Default branch development exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 95 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of Grasscutters/Grasscutter. If you don't
# have one yet, run these first:
#
# git clone https://github.com/Grasscutters/Grasscutter.git
# cd Grasscutter
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of Grasscutters/Grasscutter and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "Grasscutters/Grasscutter(\\.git)?\\b" \\
&& ok "origin remote is Grasscutters/Grasscutter" \\
|| miss "origin remote is not Grasscutters/Grasscutter (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(AGPL-3\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"AGPL-3\\.0\"" package.json 2>/dev/null) \\
&& ok "license is AGPL-3.0" \\
|| miss "license drift — was AGPL-3.0 at generation time"
# 3. Default branch
git rev-parse --verify development >/dev/null 2>&1 \\
&& ok "default branch development exists" \\
|| miss "default branch development no longer exists"
# 4. Critical files exist
test -f "build.gradle" \\
&& ok "build.gradle" \\
|| miss "missing critical file: build.gradle"
test -f "src/generated/main/java/emu/grasscutter/net/proto" \\
&& ok "src/generated/main/java/emu/grasscutter/net/proto" \\
|| miss "missing critical file: src/generated/main/java/emu/grasscutter/net/proto"
test -f "settings.gradle" \\
&& ok "settings.gradle" \\
|| miss "missing critical file: settings.gradle"
test -f ".github/workflows/build.yml" \\
&& ok ".github/workflows/build.yml" \\
|| miss "missing critical file: .github/workflows/build.yml"
test -f "Dockerfile" \\
&& ok "Dockerfile" \\
|| miss "missing critical file: Dockerfile"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 95 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~65d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/Grasscutters/Grasscutter"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Grasscutter is a server software reimplementation that allows players to run a private, self-hosted server for an anime game (Genshin Impact) instead of connecting to official servers. Built in Java with MongoDB persistence, it replicates core gameplay: combat, gacha systems, inventory, co-op, teleportation, and character/item progression up to game version REL4.0.1. Gradle-based monolith: core game logic lives in src/main/java under emu.grasscutter packages (inferred); buildSrc/ contains code generators (GenerateActivityConditions.java); Protocol Buffers auto-generate network packets (protobuf-gradle-plugin); TypeScript/JavaScript likely powers optional web dashboards; documentation split across docs/events and docs/quests with language-specific READMEs.
👥Who it's for
Private server enthusiasts and modding communities who want to self-host game servers, developers interested in game server architecture, and players seeking offline/private gameplay experiences without official server dependency.
🌱Maturity & risk
Experimental and maintenance-critical. The project explicitly states (as of January 2025) it is no longer actively maintained and only supports game version REL4.0.1 (Fontaine release). GitHub Actions CI/CD pipelines exist (build.yml, check_code.yml), but the README warns "Grasscutter beyond the latest release will have no handholding" — indicating limited forward compatibility and community support risk.
High maintenance risk: the project is explicitly unmaintained as of January 2025 and lags behind current game versions. Dependency on specific MongoDB versions and Java 17 creates fragility; no visible dependency version pinning in build.gradle. The codebase is 3.4M lines of Java, making contribution friction high. Legal/ethical concerns around game server reimplementation may affect long-term viability.
Active areas of work
Minimal active development. The README explicitly states maintenance ceased; the latest supported version is REL4.0.1 (Fontaine). GitHub Actions workflows exist but recent commit activity is unclear from provided metadata. The project accepts contributions (CODE_OF_CONDUCT.md, CONTRIBUTING.md present) but signals no official support beyond the stable branch.
🚀Get running
git clone https://github.com/Grasscutters/Grasscutter.git && cd Grasscutter && ./gradlew build (Linux/Mac) or gradlew.bat build (Windows). Requires Java 17 and MongoDB Community Server running on localhost:27017. See README for game client version REL4.0.x requirement.
Daily commands: gradlew run (after build), or java -jar build/libs/grasscutter.jar post-compilation. MongoDB must be listening on default port. Consult README quick-start guide for environment setup.
🗺️Map of the codebase
build.gradle— Main build configuration using Gradle with Protocol Buffers support; defines all dependencies, plugins, and compilation pipeline for the entire project.src/generated/main/java/emu/grasscutter/net/proto— Generated Protocol Buffer message classes from the anime game's network protocol; essential reference for understanding all client-server communication structures.settings.gradle— Gradle settings file that defines project structure and module configuration; critical for understanding project layout and dependency resolution..github/workflows/build.yml— GitHub Actions CI/CD pipeline configuration; defines how the project is tested and built, critical for understanding deployment and testing procedures.Dockerfile— Container configuration for deployment; shows how the server is packaged and run in production environments.gradle/wrapper/gradle-wrapper.properties— Gradle wrapper configuration pinning the Gradle version; ensures consistent builds across all environments.
🧩Components & responsibilities
- Protocol Buffer Layer (protobuf 3, protobuf-gradle-plugin) — Defines and serializes all client-server messages (100+ message types); enables cross-platform client implementations
- Failure mode: Message incompatibility; deserialization errors cause client disconnects or silent packet drops
- Build System (Gradle) — Compiles Java sources, generates protobuf classes, packages JAR; orchestrates all build-time code generation
🛠️How to make changes
Add a New Network Protocol Message
- Create or modify the .proto file in the proto definitions (typically in src/main/proto or similar, though not shown in file list) (
build.gradle) - The protobuf-gradle-plugin (defined in build.gradle) will auto-generate Java classes into src/generated/main/java/emu/grasscutter/net/proto/ (
src/generated/main/java/emu/grasscutter/net/proto) - Reference the generated OuterClass in your game logic handler (e.g., NetworkHandler, PacketProcessor) (
build.gradle) - Run 'gradle build' or 'gradlew build' to regenerate and compile all protocol messages (
buildSrc/src/main/java/emu/grasscutter/gen/GenerateActivityConditions.java)
Add a New Game Event or Activity
- Define event data structure using Protocol Buffers (referenced in build.gradle protobuf block) (
build.gradle) - Use GenerateActivityConditions custom task to auto-generate condition handlers (
buildSrc/src/main/java/emu/grasscutter/gen/GenerateActivityConditions.java) - Create event implementation following the Wind Trace pattern documented in docs/events/windtrace/ (
docs/events/windtrace/README.md) - Update plugin-schema.json if the event supports plugin configuration (
plugin-schema.json)
Deploy to Production via Docker
- Ensure build.gradle and all source code are ready (
build.gradle) - GitHub Actions build_container.yml workflow automatically builds the Docker image on push (
.github/workflows/build_container.yml) - Alternatively, manually build using Dockerfile with 'docker build -f Dockerfile -t grasscutter:latest .' (
Dockerfile) - Run container with entrypoint.sh as the startup script (
entrypoint.sh)
🔧Why these technologies
- Protocol Buffers (protobuf) — Efficient binary serialization for high-frequency network traffic; language-agnostic message schema enables multi-client support (game clients, bots, proxies)
- Java + Gradle — Cross-platform JVM runtime; Gradle provides robust build automation, multi-project support, and plugin ecosystem (protobuf-gradle-plugin)
- Docker — Containerization enables reproducible deployments across Linux servers; simplifies dependency isolation and scaling
- GitHub Actions — Native CI/CD integration; automates build, testing, and container registry push on each commit
⚖️Trade-offs already made
-
Auto-generated Protocol Buffer classes (600+ proto files)
- Why: Game protocol is complex and frequently updated; code generation avoids manual maintenance of message definitions
- Consequence: Generated code is read-only and large (src/generated/ folder); changes require modifying .proto files and regenerating
-
Monolithic single Gradle project (vs. microservices)
- Why: Server reimplementation benefits from tight coupling; lower latency and simpler deployment
- Consequence: Vertical scaling only; cannot independently scale individual services (login, world, combat, etc.)
-
Activity condition generation via custom Gradle task
- Why: Game has 100+ activities with complex condition logic; automation reduces boilerplate
- Consequence: Custom build step complexity; developers must understand GenerateActivityConditions to modify activity conditions
🚫Non-goals (don't propose these)
- Not an official game server; is a community-created open-source reimplementation
- Does not store or transmit actual game assets (models, textures, audio); client-side only
- No account persistence with official game servers; isolated from canonical online infrastructure
- Not designed for large-scale production (10,000+ concurrent players); optimized for private/small-group servers
🪤Traps & gotchas
MongoDB must be pre-installed and running before ./gradlew run (no embedded option visible); game client must be specifically version REL4.0.x (newer versions will break); Java 17 is hard-required (Gradle config does not show fallback versions); Protocol Buffer definitions must be regenerated if modified (auto-run by build system but not obvious); the project abandons support post-January 2025, so newer game patches will not be implemented; Docker builds may lag behind source changes (no auto-sync visible in workflows).
🏗️Architecture
💡Concepts to learn
- Protocol Buffers (gRPC serialization) — Grasscutter uses protobuf-gradle-plugin (0.8.18) to auto-generate network packet definitions; understanding protobuf schema evolution is critical for adding new game features without breaking client compatibility
- MongoDB document-oriented persistence — Game state (player inventory, characters, gacha rolls) is persisted in MongoDB collections; contributors must understand document design, indexing, and migration strategies
- Gradle build plugins & code generation — BuildSrc custom tasks (GenerateActivityConditions.java) auto-generate boilerplate during compilation; modifying game data requires understanding Gradle task dependency graphs
- Lombok annotation processing — io.freefair.lombok plugin removes getter/setter/constructor boilerplate; code appears to use @Data, @AllArgsConstructor, @Builder extensively, affecting IDE indexing and debugging
- Game server actor/packet-driven architecture — Grasscutter likely uses actor patterns or packet handlers for concurrent player sessions; understanding how combat packets, movement, and co-op sync is essential for fixing gameplay bugs
- Gacha system probability modeling — One of the listed features; likely uses pity mechanics and weighted randomization similar to official game; modifying pull rates or drop tables requires understanding rate-up windows and hard pity thresholds
- Game client protocol reverse engineering — Grasscutter must decrypt/validate network packets from official game clients; any client update breaks compatibility until protocol changes are reverse-engineered and reimplemented
🔗Related repos
Koko-bbatting/Grasscutter— Alternative community fork maintaining newer game versions and active patches beyond REL4.0.1yuanyan3060/BetterGI— Community enhancement layer and mod framework often paired with Grasscutter servers for extended gameplaytanchinglim/genshin-api— RESTful API wrapper and companion tool for Grasscutter server management and data queriesKoko-batti/Grasscutter-Launcher— Client launcher and patcher designed to work with Grasscutter servers, handling game client setup and version selection3Shain/yet-another-anime-game-server— Competing Rust-based game server reimplementation; architectural alternative approach to same problem space
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add GitHub Actions workflow for automated Spotless code format validation
The repo uses Spotless (v6.11.0) for Java code formatting with specific rules (Google Java Format 1.15.0, tab/space indentation, import ordering), but there's no CI workflow to enforce this on PRs. Currently only build.yml, check_code.yml, and language_lint.yml exist. A dedicated Spotless validation workflow would catch formatting violations before merge and reduce maintainer review burden.
- [ ] Create .github/workflows/spotless_check.yml that runs 'gradle spotlessCheck' on pull requests
- [ ] Configure the workflow to fail if formatting violations are detected
- [ ] Add a comment to failing PRs explaining how to run 'gradle spotlessApply' locally
- [ ] Document the workflow in CONTRIBUTING.md with code style requirements reference
Add missing Gradle/Protobuf build stability documentation and verification task
The build.gradle shows protobuf-gradle-plugin (v0.8.18) is configured, and buildSrc/src/main/java/emu/grasscutter/gen/GenerateActivityConditions.java exists for code generation, but there's no documented build verification workflow or troubleshooting guide for generated code issues. New contributors often struggle with generated proto files. Adding a validation task + documentation would reduce setup friction.
- [ ] Create docs/BUILDING.md with detailed Gradle build steps, protobuf generation explanation, and common errors
- [ ] Add a Gradle task in build.gradle to validate protobuf compilation: 'gradle verifyProto' that checks generated files exist
- [ ] Include troubleshooting section for common issues: stale generated code, protoc version mismatches, buildSrc compilation failures
- [ ] Reference this doc from CONTRIBUTING.md in the development setup section
Add unit test suite for buildSrc code generation (GenerateActivityConditions.java)
The codebase has custom Gradle build source in buildSrc/src/main/java/emu/grasscutter/gen/ but no corresponding test files. This is a critical build component that generates activity conditions, yet it has zero test coverage. A test suite would catch regressions early and document expected generation behavior for contributors modifying game logic generation.
- [ ] Create buildSrc/src/test/java/emu/grasscutter/gen/ directory structure
- [ ] Write unit tests for GenerateActivityConditions.java covering: valid activity condition parsing, edge cases (null inputs, malformed data), output validation
- [ ] Add testImplementation dependency (JUnit 5) to buildSrc/build.gradle if not present
- [ ] Add test task to Gradle configuration and document running 'gradle buildSrc:test' in CONTRIBUTING.md
🌿Good first issues
- Add unit tests for src/main/java/emu/grasscutter/gen/GenerateActivityConditions.java — no test directory visible, making this a critical gap for build-time code generation: Test coverage for auto-generators prevents silent bugs in data-driven features
- Document MongoDB schema and data models in docs/ with example JSON structures, since current docs focus only on events/quests but not persistence layer: New contributors cannot understand entity relationships or add new database features without reverse-engineering the code
- Create a troubleshooting guide in docs/ covering common Java 17 compatibility issues, MongoDB connection failures, and game client version mismatches (REL4.0.x validation): README warns no handholding; a runbook would reduce Discord support burden and improve onboarding
⭐Top contributors
Click to expand
Top contributors
- @github-actions[bot] — 30 commits
- @KingRainbow44 — 15 commits
- @scooterboo — 13 commits
- @longfruit — 10 commits
- @jie65535 — 7 commits
📝Recent commits
Click to expand
Recent commits
f373827— Update README.md for clarity (#2543) (totallynotnochi)74b8de3— Updated korean readme to match with latest changes on main english readme. (#2548) (jwdjk392)9c36daa— Update code of conduct reference (#2535) (emmanuel-ferdman)d340758— Fix cannot stop in dispatch-only mode (#2534) (jie65535)76fd5b2— Update README_ja-JP.md (#2516) (Ign1s-Reiga)4022267— Configuration Update - Shown Email (#2509) (KittenPixel)f1f5b54— (fix:docker) Fix uploading to container registry (KingRainbow44)f871f26— Add Docker Support (#2486) (kashalls)eeaccf3— add some client download link and fix readme (#2475) (Gaobaiawa)6e1913a— Add documentation on 404 error page. (#2463) (root-mega)
🔒Security observations
Failed to generate security analysis.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.