ChipiMod/CONTRIBUTING.md

271 lines
4.8 KiB
Markdown

# 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:
```java
int sum(int a, int b) {
int r = a + b;
return r;
}
```
❌ Bad:
```java
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:
```java
if (value == null) {
return;
}
```
❌ Bad:
```java
if (value == null)
{
return;
}
```
## Imports (Strict Rules)
### Never use fully-qualified class names inline
❌ Forbidden:
```java
net.minecraft.util.math.BlockPos pos = new net.minecraft.util.math.BlockPos(0, 0, 0);
```
✅ Required:
```java
import net.minecraft.util.math.BlockPos;
BlockPos pos = new BlockPos(0, 0, 0);
```
### Import grouping and ordering
1) Imports from external/other packages first.
2) Blank line.
3) Imports from this project (net.Chipperfluff.*) next.
Inside each block, order by:
1) Classes
2) Functions (static method imports)
3) Variables/constants (static field imports)
4) 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:
```java
void processUser(User user, int flags, boolean force, long timeout) {
...
}
```
❌ Bad:
```java
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:
```java
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):
```java
BiomeModifications.addFeature(
BiomeSelectors.foundInOverworld(),
GenerationStep.Feature.UNDERGROUND_ORES,
RegistryKey.of(
RegistryKeys.PLACED_FEATURE,
new Identifier("chipi", "chipper_ore")
)
);
```
❌ Bad (no semantic gain):
```java
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:
```java
builder
.withColor(theme.getPrimaryColor())
.withSize(32)
.enableShadow()
.build();
```
❌ Bad:
```java
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:
```java
void handle(User user) {
if (user == null) return;
if (!user.isActive()) return;
process(user);
}
```
❌ Bad:
```java
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:
```java
if (value == null) return;
```
❌ Not allowed:
```java
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:
```java
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:
```java
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:
```java
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.