# 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.