name5566/leaf
A game server framework in Go (golang)
Stale — last commit 2y ago
weakest axislast commit was 2y ago; top contributor handles 93% of recent commits…
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
last commit was 2y ago; no CI workflows detected
- ✓8 active contributors
- ✓Apache-2.0 licensed
- ✓Tests present
Show all 6 evidence items →Show less
- ⚠Stale — last commit 2y ago
- ⚠Single-maintainer risk — top contributor 93% of recent commits
- ⚠No CI workflows detected
What would change the summary?
- →Use as dependency Mixed → Healthy if: 1 commit in the last 365 days; diversify commit ownership (top <90%)
- →Deploy as-is Mixed → Healthy if: 1 commit in the last 180 days
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/name5566/leaf)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/name5566/leaf on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: name5566/leaf
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/name5566/leaf 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 — Stale — last commit 2y ago
- 8 active contributors
- Apache-2.0 licensed
- Tests present
- ⚠ Stale — last commit 2y ago
- ⚠ Single-maintainer risk — top contributor 93% of recent commits
- ⚠ No CI workflows 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 name5566/leaf
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/name5566/leaf.
What it runs against: a local clone of name5566/leaf — 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 name5566/leaf | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 744 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of name5566/leaf. If you don't
# have one yet, run these first:
#
# git clone https://github.com/name5566/leaf.git
# cd leaf
#
# 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 name5566/leaf and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "name5566/leaf(\\.git)?\\b" \\
&& ok "origin remote is name5566/leaf" \\
|| miss "origin remote is not name5566/leaf (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "leaf.go" \\
&& ok "leaf.go" \\
|| miss "missing critical file: leaf.go"
test -f "module/skeleton.go" \\
&& ok "module/skeleton.go" \\
|| miss "missing critical file: module/skeleton.go"
test -f "gate/gate.go" \\
&& ok "gate/gate.go" \\
|| miss "missing critical file: gate/gate.go"
test -f "chanrpc/chanrpc.go" \\
&& ok "chanrpc/chanrpc.go" \\
|| miss "missing critical file: chanrpc/chanrpc.go"
test -f "network/processor.go" \\
&& ok "network/processor.go" \\
|| miss "missing critical file: network/processor.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 744 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~714d)"
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/name5566/leaf"
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
Leaf is a pragmatic game server framework written in Go that provides a modular, multicore-capable foundation for building scalable multiplayer game backends. It bundles network I/O (TCP, WebSocket), message serialization (Protocol Buffers, JSON), clustering, MongoDB integration, and a timer system into a cohesive framework designed to minimize boilerplate while handling concurrent connections reliably. Monolithic single-package structure: core framework logic sits in leaf.go and module/skeleton.go; networking stack is contained in network/ (tcp_server.go, tcp_conn.go, ws_server.go, json/, protobuf/); distributed features in cluster/; supporting tools (timer, log, console, recordfile, db) as separate directories. Each subsystem is independently testable via *_test.go files.
👥Who it's for
Game server developers and backend engineers building multiplayer game services in Go who need a pre-architected framework with built-in networking, clustering, and persistence layers rather than assembling these components individually.
🌱Maturity & risk
Moderately mature but showing signs of age: the repo contains working example tests across core modules (timer, log, recordfile, mongodb, chanrpc), suggesting stability, but lacks visible recent CI/CD configuration files or signs of active 2024 maintenance. The existence of both English and Chinese tutorials (TUTORIAL_EN.md, TUTORIAL_ZH.md) indicates prior investment. Overall: production-ready for stable use cases but possibly not actively developed.
Single-maintainer risk (name5566 appears to be sole owner), no visible open issues or PRs in the file list to assess activity level. The framework has hard dependencies on external services (MongoDB for db/mongodb) and specific network protocols, so upgrades to those libraries could introduce breaking changes. No lock file visible in the listing, making Go dependency versions uncertain.
Active areas of work
Activity status unclear from file list alone; no visible recent commits, PR boards, or milestone data provided. The repo appears stable and complete rather than actively developing new features. Chinese and English documentation suggest past user engagement.
🚀Get running
git clone https://github.com/name5566/leaf.git
cd leaf
go mod download
go test ./...
Daily commands: No traditional 'dev server' start command visible in the file list. Instead, examine examples: chanrpc/example_test.go, go/example_test.go, timer/example_test.go show how to initialize modules and message handlers. Typically: create a module, register it via skeleton, call Start() on the module.
🗺️Map of the codebase
leaf.go— Entry point and root module initialization—defines the framework's main API and startup sequence.module/skeleton.go— Core module lifecycle and message routing abstraction—every game module must understand this contract.gate/gate.go— Gateway server that multiplexes client connections and routes messages—critical for understanding how clients interact with the server.chanrpc/chanrpc.go— Channel-based RPC mechanism for inter-module communication—the backbone of distributed module coordination.network/processor.go— Message encoding/decoding abstraction layer—defines how different protocol types (JSON, Protobuf) are handled.timer/timer.go— Timer and cron scheduling system—enables time-based events and background tasks across modules.cluster/cluster.go— Multi-server clustering support—essential for scaling game servers horizontally.
🧩Components & responsibilities
- Gate Module (TCP/WebSocket server, Processor (JSON/Protobuf), chanrpc to route messages) — Multiplexes all client connections, creates agents, routes incoming messages to game modules, broadcasts updates back to clients
- Failure mode: Gate crash disconnects all clients; message queue overflow drops messages; no failover in single-server mode
- Module (with Skeleton) (Message queue, chanrpc, Go routines, optional MongoDB/timers) — Encapsulates game logic, message handlers, timers, and local state; communicates via chanrpc RPC calls
- Failure mode: Module panic crashes server; blocking calls in handler
🛠️How to make changes
Add a New Game Module
- Create a new struct that embeds module.Skeleton to inherit lifecycle management and message handling. (
module/skeleton.go) - Implement the Module interface (OnInit, OnDestroy) and register message handlers via Skeleton methods. (
module/module.go) - Add your module to the main entry point and call leaf.Run() after registration. (
leaf.go) - Use chanrpc.Call() or Go() for RPC communication with the gate or other modules. (
chanrpc/chanrpc.go)
Add a New Network Protocol
- Create a new file in network/ (e.g., network/myproto/myproto.go) implementing the Processor interface. (
network/processor.go) - Implement Marshal() and Unmarshal() methods to encode/decode messages. (
network/processor.go) - Create a corresponding tcp_server (or ws_server variant) that uses your processor. (
network/tcp_server.go) - Configure the gate to use your new processor and server in leaf.go or conf/conf.go. (
conf/conf.go)
Add a Timer or Scheduled Task
- In your module's OnInit hook, create a timer.Timer instance. (
module/skeleton.go) - Call AddTimer() or CronFunc() to schedule one-off or recurring tasks. (
timer/timer.go) - Use Go() to run the task asynchronously, or call a chanrpc method from the timer callback. (
go/go.go)
Persist Data to MongoDB
- Initialize a MongoDB client in your module's OnInit using db/mongodb/mongodb.go. (
db/mongodb/mongodb.go) - Define your data structure and call Insert(), Find(), Update(), Delete() on the MongoDB connection. (
db/mongodb/mongodb.go) - Wrap database calls in Go() or use chanrpc to avoid blocking the module's message queue. (
go/go.go)
🔧Why these technologies
- Go/Goroutines — Lightweight concurrency model enables handling thousands of concurrent player connections with minimal memory overhead; natural fit for game server I/O multiplexing.
- Channel-based RPC (chanrpc) — Go channels provide safe, synchronization-free inter-goroutine communication; simplifies module coordination and eliminates lock contention.
- TCP + WebSocket — TCP for reliable game server communication; WebSocket for browser-based clients. Both pluggable via Processor interface.
- Protocol Buffers + JSON — Protocol Buffers for compact, fast serialization in high-throughput scenarios; JSON for debugging and flexibility. Framework abstracts via Processor.
- MongoDB — Flexible schema for player data, inventory, and game state; eventual consistency acceptable for game servers; scaling via sharding.
⚖️Trade-offs already made
-
Message queues per module (Skeleton) instead of global queue
- Why: Isolates module processing, allows independent scaling, simplifies debugging
- Consequence: Inter-module calls must go through chanrpc; adds latency vs. shared memory (typically <1ms per hop).
-
Processor abstraction for protocol encoding
- Why: Allows swapping protocols (JSON ↔ Protobuf) without rewriting routing logic
- Consequence: Slight runtime overhead from interface indirection; requires careful implementation for high-throughput servers.
-
Cluster mode routes RPC calls, not shared memory
- Why: Prevents distributed lock/consistency nightmares; clean failover semantics
- Consequence: Cluster adds network latency; not suitable for sub-millisecond latency requirements; requires location awareness in client code.
-
No built-in authentication or encryption
- Why: Keeps framework lightweight; game developers can layer custom auth in gate or agent
- Consequence: Developers must implement TLS/auth separately; potential security pitfall if overlooked.
🚫Non-goals (don't propose these)
- Real-time synchronization guarantees—framework does not provide strict ordering or consensus across distributed modules
- Built-in player authentication or session management—responsibility of game application layer
- Network encryption or TLS termination at framework level—must be implemented separately
- Web UI or admin dashboard—framework provides console CLI only
- Automatic load balancing or failover—cluster routing is manual and application-aware
🪤Traps & gotchas
No visible go.mod or go.sum in file list: dependency versions are undefined; you must initialize go mod init or check if the repo root has these files not listed. MongoDB hardcoded in db/mongodb/mongodb.go: connection string and database selection may require environment variables or config file changes (check conf/conf.go structure). Network protocol frames in tcp_msg.go: the TCP wire format (framing, length prefixes) is custom; ensure client/server frame parsers match exactly. Protobuf code generation: regenerating .pb.go files requires protoc compiler installed; no visible build script or Makefile provided. No explicit shutdown order: modules are destroyed but resource cleanup (DB connections, listener closes) depends on correct implementation in each module's Destroy() method.
🏗️Architecture
💡Concepts to learn
- Channel-based RPC (chanrpc) — Leaf's concurrency model relies on goroutines communicating via typed Go channels rather than traditional function calls; understanding chanrpc/chanrpc.go is essential to writing non-blocking game logic.
- Processor Pattern — Network messages are routed through Processor implementations (network/processor.go) that abstract serialization; you must implement or extend Processor for custom message types.
- Timer Wheel — Leaf's timer/timer.go uses a hierarchical timer wheel algorithm instead of naive heap-based timers; critical for efficient scheduling of thousands of game ticks and events.
- Module Skeleton Pattern — All game logic in Leaf extends module.Skeleton with Init/Start/Destroy lifecycle hooks; understanding this pattern is required to structure any custom game system.
- Protocol Buffers (protobuf) — Leaf uses Protocol Buffers for efficient binary message serialization in network/protobuf/; you must define .proto files and regenerate code when adding new message types.
- Cron Expression Parsing — Leaf's timer/cronexpr.go parses cron-like schedule strings for recurring tasks (e.g., daily resets, maintenance windows); useful for game scheduling without external job queues.
- TCP Framing — Network messages are framed with length prefixes (network/tcp_msg.go); understanding the frame format is mandatory when debugging client/server protocol mismatches.
🔗Related repos
lonng/nano— Similar Go game server framework with actor-model concurrency and clustering; direct alternative to Leaf with more recent maintenance.topfreegames/pitaya— Another Go-based game server framework with RPC, clustering, and multi-protocol support; comparison point for feature completeness.go-kit/kit— Go microservices toolkit providing RPC, logging, and service discovery patterns that Leaf's architecture borrows from.protocolbuffers/protobuf— Official Protocol Buffers repository; essential for Leaf's network/protobuf serialization; required for code generation.mongodb/mongo-go-driver— Official MongoDB Go driver that Leaf's db/mongodb module wraps; needed to understand connection pooling and query patterns.
🪄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 comprehensive unit tests for network/processor.go and message handling pipeline
The network package has JSON and Protobuf processors but lacks unit tests. The processor.go file is critical for message serialization/deserialization. Adding tests for both JSON and Protobuf message encoding/decoding would catch regressions and help contributors understand the message flow architecture.
- [ ] Create network/processor_test.go with tests for Processor interface methods
- [ ] Add network/json/json_test.go testing JSON marshaling/unmarshaling edge cases
- [ ] Add network/protobuf/protobuf_test.go for Protobuf message handling
- [ ] Test error cases (malformed messages, type mismatches)
- [ ] Reference existing example_test.go patterns in the codebase
Add integration tests for cluster communication in cluster/cluster.go
The cluster package enables distributed game server architecture but has no visible test coverage. Given that cluster.go likely handles node-to-node RPC and state synchronization, integration tests would validate core distributed features and prevent breaking changes to the clustering protocol.
- [ ] Create cluster/cluster_test.go with multi-node cluster setup tests
- [ ] Test node discovery and registration workflows
- [ ] Test RPC message passing between cluster nodes using chanrpc
- [ ] Test node failure/disconnection scenarios
- [ ] Validate that cluster integrates properly with module/skeleton.go actor model
Add middleware/hook system tests and expand gate/agent.go test coverage
The gate package (gate/gate.go, gate/agent.go) is the entry point for client connections but lacks example tests. Adding comprehensive tests for agent lifecycle (connect, authenticate, message routing, disconnect) and documenting the agent-to-module message pipeline would help contributors extend the framework and catch protocol-level bugs.
- [ ] Create gate/agent_test.go testing agent connection lifecycle
- [ ] Test message routing from agent through skeleton to modules
- [ ] Test agent cleanup on disconnect and resource leaks
- [ ] Add gate/gate_test.go for concurrent client connection handling
- [ ] Document and test the integration between gate/agent and network/conn.go
🌿Good first issues
- Add example tests for cluster/cluster.go (currently no *_test.go file visible) demonstrating multi-node communication and failover scenarios.
- Document the exact config.json / conf/conf.go schema with defaults and all required fields; currently only conf/conf.go exists with no example config file visible.
- Create a runnable end-to-end example in examples/ showing a minimal game server with gate, a game module, MongoDB persistence, and Protocol Buffer messages; the repo has separate small examples but no integrated demo.
⭐Top contributors
Click to expand
Top contributors
- @name5566 — 93 commits
- @karllynnn — 1 commits
- @pconcepcion — 1 commits
- @zsai001 — 1 commits
- @lonng — 1 commits
📝Recent commits
Click to expand
Recent commits
af71eb0— Update README.md (name5566)8592b1a— Update LICENSE (name5566)deca553— Update LICENSE (name5566)1364c17— Update LICENSE (name5566)2495f8a— Merge pull request #132 from karllynnn/master (name5566)f62d591— update version to 1.1.3 (karllynnn)bfe2943— Merge pull request #94 from pconcepcion/patch-1 (name5566)e443aee— Updated TUTORIAL_EN.md to fix a little mistake (pconcepcion)09f6b6d— update TUTORIAL (name5566)bf8ad34— cluster version (name5566)
🔒Security observations
- High · Potential SQL Injection in MongoDB Module —
db/mongodb/mongodb.go. The db/mongodb/mongodb.go module handles database operations. Without reviewing the actual code, MongoDB operations using user input without proper parameterization or using legacy query syntax could be vulnerable to NoSQL injection attacks. Fix: Ensure all database queries use parameterized queries or the MongoDB driver's built-in safe query methods. Validate and sanitize all user inputs before using them in database operations. - High · Potential XSS in JSON/Protobuf Message Processing —
network/json/json.go, network/protobuf/protobuf.go. The network layer includes JSON (network/json/json.go) and Protobuf (network/protobuf/protobuf.go) processors. If JSON data is rendered in web contexts without proper escaping, or if the framework processes user-supplied data without validation, XSS vulnerabilities could occur. Fix: Implement strict input validation for all incoming messages. Ensure proper output encoding when rendering any user-supplied data. Use Content Security Policy headers if used in web contexts. - High · Missing Input Validation Framework —
network/processor.go, network/agent.go. The codebase includes network/processor.go which handles message processing, but there is no visible input validation or sanitization framework. Game servers receive untrusted input from clients that could be exploited for injection attacks or DoS. Fix: Implement comprehensive input validation for all network messages. Define strict schemas for acceptable data types, sizes, and formats. Reject malformed messages immediately. - Medium · Potential Unencrypted Network Communication —
network/tcp_server.go, network/tcp_conn.go, network/ws_server.go, network/ws_conn.go. TCP connections (network/tcp_conn.go, network/tcp_server.go) and WebSocket connections (network/ws_conn.go, network/ws_server.go) are implemented but the framework does not explicitly enforce TLS/SSL encryption. Game servers may transmit sensitive data over unencrypted channels. Fix: Implement mandatory TLS 1.2+ for all TCP connections. Use WSS (WebSocket Secure) instead of WS for WebSocket connections. Provide configuration options to enforce encryption and reject unencrypted connections. - Medium · Insufficient Error Handling and Information Disclosure —
log/log.go, module/skeleton.go. The log module (log/log.go) and error handling throughout the framework could potentially expose sensitive information through verbose error messages, stack traces, or debug logs in production environments. Fix: Implement different logging levels for different environments. Ensure production logs do not contain sensitive information, stack traces, or internal system details. Configure appropriate log redaction for error messages. - Medium · Missing Authentication and Authorization Framework —
gate/gate.go, gate/agent.go. The gate module (gate/gate.go, gate/agent.go) appears to handle client connections but there is no visible authentication or authorization mechanism. The framework may lack built-in security controls for verifying client identity. Fix: Implement a robust authentication system (token-based, session-based, or certificate-based). Add authorization checks before processing sensitive operations. Validate all client connections and maintain secure session management. - Medium · Potential Race Conditions and Concurrency Issues —
chanrpc/chanrpc.go, network/agent.go, module/skeleton.go. While the framework advertises 'multicore support', the concurrent handling of network messages and shared state across modules (chanrpc/chanrpc.go) could introduce race conditions if proper synchronization primitives are not consistently used. Fix: Use Go's race detector during testing (go test -race). Ensure all shared state is protected with appropriate synchronization mechanisms (mutexes, channels). Implement comprehensive concurrent testing. - Low · Hardcoded Configuration and Magic Values —
conf/conf.go. The conf/conf.go module handles configuration, but without reviewing the code, there may be hardcoded values, default credentials, or configuration options that expose security settings. Fix: Externalize all configuration from code. Use environment variables or secure configuration management systems. Never hardcode credentials, API keys, or security-sensitive defaults. Implement configuration
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.