5.4 KiB
Coding Guidelines (Java written C/C++-style)
These rules exist to preserve intent, structure, and mental parseability. Formatting must reflect logic, not arbitrary line limits or formatter preferences.
Java syntax, C/C++ brain.
1. General Philosophy
- Java is written as if it were C/C++
- Formatting must never change perceived control flow
- Readability = how fast the code parses correctly in your head
- Tools must adapt to the codebase, not the other way around
2. Indentation & Whitespace
- Indentation: 4 spaces
- No tabs
- Avoid excessive vertical whitespace
- Blank lines only where 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;
}
3. 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;
}
Rationale: new-line braces create false scope perception and visual ambiguity.
4. Imports (IMPORTANT)
❗ 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);
Why:
- Fully-qualified names destroy readability
- They bloat expressions and hide logic
- Imports exist to solve exactly this problem
Rule:
If you need a class, import it. If imports collide, resolve the collision explicitly — do not inline paths everywhere.
5. Function & Method Definitions
- Method signatures must stay on one line
- Never break parameters across multiple lines
- Length is 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
) {
...
}
Reason: multiline signatures look like scopes and break C/C++ mental parsing.
6. 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();
When multiline calls ARE allowed (and expected)
Multiline calls are allowed only when:
- The call is structural / declarative
- Each argument is conceptually distinct
- Nesting would otherwise hide meaning
Example (correct usage)
BiomeModifications.addFeature(
BiomeSelectors.foundInOverworld(),
GenerationStep.Feature.UNDERGROUND_ORES,
RegistryKey.of(
RegistryKeys.PLACED_FEATURE,
new Identifier("chipi", "chipper_ore")
)
);
Why this is correct:
- Each argument represents a different conceptual layer
- Nested calls are grouped logically
- Visual structure mirrors logical structure
- This reads like a configuration block, not a simple call
❌ Incorrect multiline usage
doThing(
a,
b,
c
);
This adds vertical noise with no semantic gain.
7. 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();
8. 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);
}
}
}
9. 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();
10. Null Handling
nullis a valid, intentional state- Do not over-engineer around it
- Prefer clarity over defensive clutter
✅ Good
User user = findUser(id);
if (user == null) return;
11. Logging & Debug Output
- Logging must be short and readable
- Prefer
System.out.printlnfor quick diagnostics - Verbose logging only when justified
✅ Good
System.out.println("Loaded structure: " + id);
12. 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.
Summary (Non-Negotiable)
- Java written with C/C++ structure
- Compact signatures, explicit layout
- Imports always used
- Multiline only when it adds meaning
- Formatting reflects logic, not fashion
If a tool disagrees with this file, the tool is wrong.