Thank you for your interest in contributing! This document explains the process.
- Code of Conduct
- Development Lifecycle
- How to Contribute
- Development Setup
- Design Principles
- Commit Style
- Pull Request Process
- Testing
- Release Process
- Continuous Improvement
This project follows the Contributor Covenant. Be respectful and constructive.
Every change 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.
| 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 |
# 1. Fork and clone
git clone https://github.com/oxidized-mc/mc-types.git
cd mc-types
# 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 warningscargo install cargo-deny # licence + advisory checks
cargo install cargo-nextest # faster test runner
cargo install cargo-watch # auto-rebuild on save
cargo install cargo-fuzz # fuzz testing (requires nightly)oxidized-mc-types is a foundational library crate used across the Oxidized MC
ecosystem. Key principles:
- API stability matters — public types are consumed by many downstream crates. Think carefully before changing public signatures.
- Wire compatibility — types that touch the Minecraft protocol must produce byte-identical output to vanilla Java Edition 26.1.
- Documentation required — all public items must have
///doc comments. The crate enforces#![warn(missing_docs)]. - No unsafe code — the crate enforces
#![deny(unsafe_code)]. - Idiomatic Rust — when implementing logic from the vanilla Java source, rewrite idiomatically rather than transliterating Java line-by-line.
All commits must follow Conventional Commits:
<type>(<scope>): <short description>
| 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 |
Use mc-types as the scope for all changes to this crate.
Use ci for workflow files, deps for dependency updates.
feat(mc-types): add BlockPos::between_closed iterator
fix(mc-types): correct Vec3 lerp clamping at t=1.0
perf(mc-types): use bitwise ops for Direction axis lookup
test(mc-types): add property-based roundtrip tests for all wire types
docs(mc-types): add doc examples for ResourceLocation
chore(deps): bump proptest from 1.5 to 1.6
Breaking changes: add ! after type or add BREAKING CHANGE: footer.
- Create a branch:
git checkout -b feat/block-pos-iterator - Make your changes following the lifecycle
- Commit with conventional commits
- Open a PR targeting
main; fill in the PR template completely - At least one approving review is required before merge
- Squash-merge preferred for feature branches
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?
- Unit tests live next to the code in
#[cfg(test)]modules - Integration tests live in
tests/ - Property-based tests use
proptestfor roundtrips, invariants, and edge cases - All public API must have at least one test
- Test modules use
#[allow(clippy::unwrap_used, clippy::expect_used)] - Reference the Java behaviour when writing expected values:
// BlockPos packing matches net.minecraft.core.BlockPos in the reference assert_eq!(BlockPos::new(1, 2, 3).packed(), 0x0000_0003_0000_8001);
Run with nextest for faster feedback:
cargo nextest runCriterion benchmarks live in
benches/. Run the suite:
cargo benchBenchmark results are written to target/criterion/ with HTML reports.
Fuzz targets live in fuzz/ and use
cargo-fuzz (requires nightly).
List available targets:
cargo +nightly fuzz listRun a fuzz target (runs until stopped with Ctrl-C):
cargo +nightly fuzz run <target>Crash artifacts are stored in fuzz/artifacts/. If a crash is found, add a
regression test in tests/.
This crate uses automated versioning and release management based on conventional commits.
- Commit with conventional prefixes —
feat,fix,perf, etc. - release-please automatically creates and maintains a "Release PR" on GitHub that accumulates changes and proposes the next version bump.
- When a maintainer merges the Release PR, a git tag (
v0.X.Y) and GitHub Release are created automatically. - git-cliff generates the changelog from conventional commit messages.
| 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 |
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