328 lines
5.4 KiB
Markdown
328 lines
5.4 KiB
Markdown
# 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**
|
|
|
|
```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;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 3. 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;
|
|
}
|
|
```
|
|
|
|
> Rationale: new-line braces create **false scope perception** and visual ambiguity.
|
|
|
|
---
|
|
|
|
## 4. Imports (IMPORTANT)
|
|
|
|
### ❗ 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);
|
|
```
|
|
|
|
### 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**
|
|
|
|
```java
|
|
void processUser(User user, int flags, boolean force, long timeout) {
|
|
...
|
|
}
|
|
```
|
|
|
|
❌ **Bad**
|
|
|
|
```java
|
|
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**
|
|
|
|
```java
|
|
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)
|
|
|
|
```java
|
|
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
|
|
|
|
```java
|
|
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**
|
|
|
|
```java
|
|
builder
|
|
.withColor(theme.getPrimaryColor())
|
|
.withSize(32)
|
|
.enableShadow()
|
|
.build();
|
|
```
|
|
|
|
❌ **Bad**
|
|
|
|
```java
|
|
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**
|
|
|
|
```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);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 9. 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();
|
|
```
|
|
|
|
---
|
|
|
|
## 10. 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;
|
|
```
|
|
|
|
---
|
|
|
|
## 11. 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);
|
|
```
|
|
|
|
---
|
|
|
|
## 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.
|