Skip to content

Latest commit

 

History

History
239 lines (170 loc) · 6.53 KB

File metadata and controls

239 lines (170 loc) · 6.53 KB

Contributing to oxidized-client-headless

Thank you for your interest in contributing! This document explains the process.


Table of Contents


Code of Conduct

This project follows the Contributor Covenant. Be respectful and constructive.


Development Lifecycle

Every change in oxidized-client-headless follows a structured lifecycle:

Identify → Research → Decide → Plan → Test First → Implement → Review → Integrate → Retrospect

The lifecycle ensures that we:

  • Understand the problem before writing code
  • Write tests before implementation (TDD)
  • Actively identify improvements during review

For trivial changes (typo fixes, dependency bumps), an abbreviated lifecycle applies.


How to Contribute

Type How
🐛 Bug report Open a bug report issue
💡 Feature request Open a feature request issue
📖 Docs Edit any .md file and open a PR
🧩 Implementation Pick an open issue and open a PR
🔍 Review Review open PRs and leave constructive feedback
💡 Improvement Found a better approach? Open an issue or PR

Development Setup

# 1. Fork and clone
git clone https://github.com/oxidized-mc/client-headless.git
cd client-headless

# 2. Rust stable (toolchain pinned via rust-toolchain.toml)
rustup update stable

# 3. Build
cargo build

# 4. Run tests
cargo test

# 5. Check formatting and lints
cargo fmt --check
cargo clippy --all-targets -- -D warnings

Useful tools (optional)

cargo install cargo-deny    # licence + advisory checks
cargo install cargo-nextest # faster test runner
cargo install cargo-watch   # auto-rebuild on save

Architecture

oxidized-client-headless is a single crate. Low-level protocol primitives (codec, NBT, types, chat, crypto, compression, transport, auth) are provided by the shared oxidized-mc crate ecosystem. This crate focuses on client-specific logic: connection management, world state, and bot behavior.

Reference code: The decompiled vanilla client/server lives in mc-server-ref/decompiled/ (gitignored). When implementing something, always check the Java reference first. Rewrite idiomatically in Rust — do not transliterate Java line-by-line.


Design Principles

Key principle: the wire protocol is sacred (we can't change what the server sends or expects), but everything client-side uses modern, idiomatic Rust design rather than cloning vanilla Java patterns.


Commit Style

All commits must follow Conventional Commits:

<type>(<scope>): <short description>

Types

Type When Version bump
feat New user-visible feature Minor
fix Bug fix Patch
perf Performance improvement Patch
refactor Restructure, no behaviour change None
test Tests only None
docs Documentation only None
chore Dependencies, CI, tooling None
ci CI/CD workflow changes None

Scopes

Use a descriptive scope when relevant (e.g., client, world, bot). Use ci for workflow files, deps for dependency updates.

Examples

feat(client): implement connection builder
fix: correct session token refresh logic
perf: cache chunk sections to avoid recomputation
test: add NBT round-trip tests for all 13 tag types
chore(deps): bump tokio from 1.43 to 1.44

Breaking changes: add ! after type or add BREAKING CHANGE: footer.


Pull Request Process

  1. Create a branch: git checkout -b feat/varint-codec
  2. Make your changes following the lifecycle
  3. Commit with conventional commits
  4. Open a PR targeting main; fill in the PR template completely
  5. At least one approving review is required before merge
  6. Squash-merge preferred for feature branches

PR Review Standards

Reviews are not just about catching bugs — they actively seek improvements:

  • Does the code follow the project's design principles?
  • Could any existing pattern be improved?
  • Are there learnings to record?

Testing

  • Unit tests live next to the code in #[cfg(test)] modules
  • Integration tests live in tests/
  • All public API must have at least one test
  • Test modules use #[allow(clippy::unwrap_used, clippy::expect_used)] for assertion-like code
  • Reference the Java behaviour when writing expected values:
    // VarInt encoding mirrors net.minecraft.network.VarInt in the reference
    assert_eq!(encode_varint(300), &[0xAC, 0x02]);

Run with nextest for faster feedback:

cargo nextest run --workspace

Benchmarks

Criterion benchmarks live in benches/. Run the full suite:

cargo bench --workspace

Release Process

oxidized-client-headless uses automated versioning and release management based on conventional commits.

How It Works

  1. Commit with conventional prefixesfeat, fix, perf, etc.
  2. release-please automatically creates and maintains a "Release PR" on GitHub that accumulates changes and proposes the next version bump.
  3. When a maintainer merges the Release PR, a git tag (v0.X.Y) and GitHub Release are created automatically.

Version Bump Rules

Commit prefix Bump
feat!: or BREAKING CHANGE: footer Minor (pre-1.0) / Major (post-1.0)
feat(scope): Minor
fix(scope):, perf(scope): Patch
refactor, test, docs, chore, ci No version bump

Continuous Improvement

We believe the codebase should always be getting better.

After every milestone:

  • Conduct a retrospective
  • Record learnings and identify improvements
  • Record any technical debt incurred

During every PR review:

  • Identify outdated patterns or decisions
  • Look for patterns that should be extracted or formalized
  • Suggest improvements (not just catch bugs)

When you find something better:

  • Don't just note it — act on it
  • Open an issue or PR
  • Plan and execute the refactoring