4.8 KiB
4.8 KiB
Contributing Guide (Java Style)
This project follows a strict, C/C++-style Java formatting rule set. The goal is to preserve intent, control flow clarity, and fast mental parsing. Please follow these rules for any Java changes.
If a tool or formatter fights these rules, the tool is wrong.
Core Philosophy
- Java is written as if it were C/C++.
- Formatting must never change perceived control flow.
- Readability means fast, correct parsing in your head.
- Tools adapt to the codebase, not the other way around.
Indentation & Whitespace
- Indentation: 4 spaces.
- No tabs.
- Avoid excessive vertical whitespace.
- Blank lines only when they add logical separation.
✅ Good:
int sum(int a, int b) {
int r = a + b;
return r;
}
❌ Bad:
int sum(int a, int b)
{
int r = a + b;
return r;
}
Braces
- Braces are always required.
- Opening brace stays on the same line.
- Never rely on implicit scopes.
✅ Good:
if (value == null) {
return;
}
❌ Bad:
if (value == null)
{
return;
}
Imports (Strict Rules)
Never use fully-qualified class names inline
❌ Forbidden:
net.minecraft.util.math.BlockPos pos = new net.minecraft.util.math.BlockPos(0, 0, 0);
✅ Required:
import net.minecraft.util.math.BlockPos;
BlockPos pos = new BlockPos(0, 0, 0);
Import grouping and ordering
- Imports from external/other packages first.
- Blank line.
- Imports from this project (net.Chipperfluff.*) next.
Inside each block, order by:
- Classes
- Functions (static method imports)
- Variables/constants (static field imports)
- Enums
If there are no project imports, do not add a blank line.
Method Signatures
- Method signatures must stay on one line.
- Do not break parameters across multiple lines.
- Long lines are acceptable; ambiguity is not.
✅ Good:
void processUser(User user, int flags, boolean force, long timeout) {
...
}
❌ Bad:
void processUser(
User user,
int flags,
boolean force,
long timeout
) {
...
}
Function Calls & Argument Layout
Default rule
- Single-line calls are preferred.
- Flat calls stay flat.
- Length alone is not a reason to wrap.
✅ Good:
Color color = user.getProfile().getSettings().getTheme().getPrimaryColor();
Multiline calls are allowed only when:
- The call is structural or declarative.
- Each argument is conceptually distinct.
- Nesting would otherwise hide meaning.
✅ Good (structural/declarative):
BiomeModifications.addFeature(
BiomeSelectors.foundInOverworld(),
GenerationStep.Feature.UNDERGROUND_ORES,
RegistryKey.of(
RegistryKeys.PLACED_FEATURE,
new Identifier("chipi", "chipper_ore")
)
);
❌ Bad (no semantic gain):
doThing(
a,
b,
c
);
Chained Calls
- Flat chains stay on one line.
- Long or builder-style chains may be split vertically.
- Each chained step gets its own line.
✅ Good:
builder
.withColor(theme.getPrimaryColor())
.withSize(32)
.enableShadow()
.build();
❌ Bad:
builder.withColor(
theme.getPrimaryColor()
).withSize(
32
).enableShadow().build();
Control Flow & Returns
- Early returns are encouraged.
- Avoid artificial nesting.
- Single-exit functions are not required.
✅ Good:
void handle(User user) {
if (user == null) return;
if (!user.isActive()) return;
process(user);
}
❌ Bad:
void handle(User user) {
if (user != null) {
if (user.isActive()) {
process(user);
}
}
}
One-Liners
- One-liners allowed for simple guard clauses.
- No complex logic on one line.
✅ Allowed:
if (value == null) return;
❌ Not allowed:
if (a == b && c != d && flag && check()) doThing();
Null Handling
- null is a valid, intentional state.
- Do not over-engineer around it.
- Prefer clarity over defensive clutter.
✅ Good:
User user = findUser(id);
if (user == null) return;
Logging & Debug Output
- Logging must be short and readable.
- Prefer System.out.println for quick diagnostics.
- Verbose logging only when justified.
✅ Good:
System.out.println("Loaded structure: " + id);
Autoformatters & Linters
Autoformatters must not:
- Break method signatures.
- Move braces to new lines.
- Introduce unwanted trailing newlines.
- Rewrap stable code repeatedly.
If a formatter fights these rules: disable or reconfigure it.
Empty Methods
Empty methods or constructors must be written on one line:
public static void register() {}
Summary (Non-Negotiable)
- Java written with C/C++ structure.
- Compact signatures, explicit layout.
- Imports always used (no fully-qualified inline types).
- Multiline formatting only when it adds meaning.
- Formatting reflects logic, not fashion.