-
-
Notifications
You must be signed in to change notification settings - Fork 11
Update to java 25 #478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Update to java 25 #478
Conversation
|
Warning Rate limit exceeded@Sheikah45 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 0 minutes and 13 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThis PR removes the Pipeline instance parameter across masks, generators, and related APIs; refactors Pipeline into a thread-scoped/static facility with run/add/isAccepting; updates mask constructors and inflate/deflate signatures to use ints; upgrades toolchain to Java 25/Gradle 9.2.1 and adds jlink/AOT packaging steps and script templates. Changes
Sequence Diagram(s)mermaid Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Poem
Pre-merge checks❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
shared/src/main/java/com/faforever/neroxis/mask/OperationsMask.java (4)
238-248: Pre-existing bug:multiply(BooleanMask, T)callssubtractValueAtinstead ofmultiplyValueAt.Line 244 incorrectly calls
subtractValueAtwhen it should callmultiplyValueAt. This appears to be a pre-existing copy-paste error, not introduced by this PR.🔎 Proposed fix
public U multiply(BooleanMask other, T value) { assertCompatibleMask(other); return enqueue(dependencies -> { BooleanMask source = (BooleanMask) dependencies.getFirst(); apply((x, y) -> { if (source.getPrimitive(x, y)) { - subtractValueAt(x, y, value); + multiplyValueAt(x, y, value); } }); }, other); }
258-270: Pre-existing bug:multiply(BooleanMask, U)callssubtractValueAtinstead ofmultiplyValueAt.Line 266 incorrectly calls
subtractValueAtwhen it should callmultiplyValueAt. Same copy-paste issue as the previous method.🔎 Proposed fix
public U multiply(BooleanMask other, U values) { assertCompatibleMask(other); assertCompatibleMask(values); return enqueue(dependencies -> { BooleanMask source = (BooleanMask) dependencies.get(0); U vals = (U) dependencies.get(1); apply((x, y) -> { if (source.getPrimitive(x, y)) { - subtractValueAt(x, y, vals.get(x, y)); + multiplyValueAt(x, y, vals.get(x, y)); } }); }, other, values); }
322-332: Pre-existing bug:divide(BooleanMask, T)callssubtractValueAtinstead ofdivideValueAt.Line 328 incorrectly calls
subtractValueAtwhen it should calldivideValueAt.🔎 Proposed fix
public U divide(BooleanMask other, T value) { assertCompatibleMask(other); return enqueue(dependencies -> { BooleanMask source = (BooleanMask) dependencies.getFirst(); apply((x, y) -> { if (source.getPrimitive(x, y)) { - subtractValueAt(x, y, value); + divideValueAt(x, y, value); } }); }, other); }
342-354: Pre-existing bug:divide(BooleanMask, U)callssubtractValueAtinstead ofdivideValueAt.Line 350 incorrectly calls
subtractValueAtwhen it should calldivideValueAt.🔎 Proposed fix
public U divide(BooleanMask other, U values) { assertCompatibleMask(other); assertCompatibleMask(values); return enqueue(dependencies -> { BooleanMask source = (BooleanMask) dependencies.get(0); U vals = (U) dependencies.get(1); apply((x, y) -> { if (source.getPrimitive(x, y)) { - subtractValueAt(x, y, vals.get(x, y)); + divideValueAt(x, y, vals.get(x, y)); } }); }, other, values); }
🧹 Nitpick comments (5)
.github/workflows/release.yml (1)
60-63: Consider breaking the AOT command into multiple lines for readability.The AOT cache generation command on line 62 is extremely long (over 200 characters), making it difficult to read and maintain. Consider using YAML's multiline syntax for better readability.
🔎 Suggested refactoring
- name: Package with Gradle run: | ./gradlew -x test --stacktrace jlink --parallel -PgeneratorVersion="${{ github.event.inputs.version }}" - ./generator/build/image/bin/java -XX:AOTCacheOutput=generator/build/image/bin/neroxis-generator.aot -XX:+UseCompactObjectHeaders -m com.faforever.neroxis.generator/com.faforever.neroxis.generator.MapGenerator --out-path ./GeneratedMaps + ./generator/build/image/bin/java \ + -XX:AOTCacheOutput=generator/build/image/bin/neroxis-generator.aot \ + -XX:+UseCompactObjectHeaders \ + -m com.faforever.neroxis.generator/com.faforever.neroxis.generator.MapGenerator \ + --out-path ./GeneratedMaps ./gradlew -x test --stacktrace jpackage --parallel -PgeneratorVersion="${{ github.event.inputs.version }}"buildSrc/src/main/kotlin/com.faforever.neroxis.conventions-application.gradle.kts (1)
28-31: Consider simplifying path resolution.The nested
resolve()calls work correctly, but could be more concise:🔎 Proposed simplification
- val templatesDir = - rootDir.resolve("buildSrc").resolve("src").resolve("main").resolve("resources").resolve("templates") + val templatesDir = rootDir.resolve("buildSrc/src/main/resources/templates") unixScriptTemplate = templatesDir.resolve("unixScriptTemplate.txt") windowsScriptTemplate = templatesDir.resolve("windowsScriptTemplate.txt")shared/src/main/java/com/faforever/neroxis/util/Pipeline.java (1)
209-217: Entry.write() method may throw unchecked exception for algorithm availability.The
NoSuchAlgorithmExceptionis wrapped inRuntimeException, which is acceptable since MD5 should always be available. However, consider logging the error or using a more specific exception type for clarity.shared/src/main/java/com/faforever/neroxis/mask/NormalMask.java (1)
14-20: Constructor ignoressymmetrySettingsparameter.The constructor at lines 18-20 accepts a
SymmetrySettingsparameter but ignores it, always delegating to the constructor that usesSymmetry.NONE. This is misleading for callers who might expect their symmetry settings to be applied.If
NormalMaskshould always useSymmetry.NONE, consider either:
- Removing this constructor overload, or
- Adding a comment explaining why symmetry settings are intentionally ignored for normal masks
🔎 Option 1: Remove misleading constructor
public NormalMask(int size, Long seed, String name) { super(size, seed, new SymmetrySettings(Symmetry.NONE), name); } -public NormalMask(int size, Long seed, SymmetrySettings symmetrySettings, String name) { - this(size, seed, name); -}🔎 Option 2: Document the behavior
+/** + * Creates a NormalMask. Note: symmetrySettings is ignored as normal masks + * always use {@link Symmetry#NONE}. + */ public NormalMask(int size, Long seed, SymmetrySettings symmetrySettings, String name) { this(size, seed, name); }shared/src/main/java/com/faforever/neroxis/mask/VectorMask.java (1)
635-653: Type change reduces compile-time safety but is functionally correct.The change from
FloatMask[]toMask<?, ?>[]at line 644 loses some type information, requiring the explicit cast at line 647. Since thecomponentsarray passed toenqueueis guaranteed to beFloatMask[], the cast is safe at runtime. The class-level@SuppressWarnings("unchecked")already covers this pattern.Consider retaining the stronger typing if possible:
🔎 Optional: Retain FloatMask[] typing
enqueue(dependencies -> { - Mask<?, ?>[] sources = dependencies.subList(0, dimension).toArray(Mask[]::new); + FloatMask[] sources = dependencies.subList(0, dimension).toArray(FloatMask[]::new); apply((x, y) -> { for (int i = 0; i < dimension; ++i) { - ((FloatMask) sources[i]).setPrimitive(x, y, get(x, y).get(i)); + sources[i].setPrimitive(x, y, get(x, y).get(i)); } }); }, components);
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (78)
.github/workflows/release.yml.github/workflows/tests.yml.idea/codeStyles/Project.xmlbuildSrc/build.gradle.ktsbuildSrc/src/main/kotlin/com.faforever.neroxis.conventions-application.gradle.ktsbuildSrc/src/main/kotlin/com.faforever.neroxis.conventions-java.gradle.ktsbuildSrc/src/main/resources/templates/unixScriptTemplate.txtbuildSrc/src/main/resources/templates/windowsScriptTemplate.txtgenerator/src/main/java/com/faforever/neroxis/generator/GeneratedMapNameEncoder.javagenerator/src/main/java/com/faforever/neroxis/generator/decal/DecalGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/prop/BasicPropGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/prop/BoulderFieldPropGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/prop/EnemyCivPropGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/prop/LargeBattlePropGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/prop/NavyWrecksPropGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/prop/NeutralCivPropGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/prop/PropGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/prop/RockFieldPropGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/prop/SmallBattlePropGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/resource/HighMexLandLowMexWaterResourceGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/resource/ResourceGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/style/StyleGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/BasicLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/BasicTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/BigIslandsTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/CenterLakeLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/CenterLakeTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/DropPlateauLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/DropPlateauTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/FloodedTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/FractalLandLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/FractalNavyLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/FractalNoiseLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/FractalPlateauLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/FractalUpsideDownLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/LandBridgeTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/LittleMountainLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/LittleMountainTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/MountainRangeLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/MountainRangeTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/MultiLevelLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/OneIslandTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/PathedLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/PathedPlateauLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/PathedPlateauTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/PathedTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/RiversAndOceansTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/RiversTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/SmallIslandsTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/SpawnFirstTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/SpawnLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/TerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/ValleyLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/ValleyTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/texture/LegacyTextureGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/texture/PbrTextureGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/texture/TextureGenerator.javagenerator/src/test/java/com/faforever/neroxis/generator/MapGeneratorTest.javagradle/wrapper/gradle-wrapper.propertiesshared/build.gradle.ktsshared/src/main/java/com/faforever/neroxis/lua/LuaParserVisitorImpl.javashared/src/main/java/com/faforever/neroxis/map/placement/HydroPlacer.javashared/src/main/java/com/faforever/neroxis/map/placement/SpawnPlacer.javashared/src/main/java/com/faforever/neroxis/mask/BooleanMask.javashared/src/main/java/com/faforever/neroxis/mask/ComparableMask.javashared/src/main/java/com/faforever/neroxis/mask/FloatMask.javashared/src/main/java/com/faforever/neroxis/mask/IntegerMask.javashared/src/main/java/com/faforever/neroxis/mask/Mask.javashared/src/main/java/com/faforever/neroxis/mask/NormalMask.javashared/src/main/java/com/faforever/neroxis/mask/OperationsMask.javashared/src/main/java/com/faforever/neroxis/mask/PrimitiveMask.javashared/src/main/java/com/faforever/neroxis/mask/Vector2Mask.javashared/src/main/java/com/faforever/neroxis/mask/Vector3Mask.javashared/src/main/java/com/faforever/neroxis/mask/Vector4Mask.javashared/src/main/java/com/faforever/neroxis/mask/VectorMask.javashared/src/main/java/com/faforever/neroxis/util/Pipeline.javatoolsuite/src/main/java/com/faforever/neroxis/toolsuite/MapInfoTextureExporter.javautilities/src/main/java/com/faforever/neroxis/utilities/TestingGround.java
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-12-27T19:00:16.091Z
Learnt from: clivepaterson
Repo: FAForever/Neroxis-Map-Generator PR: 0
File: :0-0
Timestamp: 2025-12-27T19:00:16.091Z
Learning: In the Neroxis Map Generator codebase, StrictMath should always be used instead of Math to ensure deterministic behavior across different JVM implementations for procedural map generation.
Applied to files:
generator/src/main/java/com/faforever/neroxis/generator/terrain/FractalNavyLastTerrainGenerator.java
📚 Learning: 2025-12-27T17:01:57.927Z
Learnt from: clivepaterson
Repo: FAForever/Neroxis-Map-Generator PR: 477
File: shared/src/main/java/com/faforever/neroxis/mask/BooleanMask.java:817-819
Timestamp: 2025-12-27T17:01:57.927Z
Learning: In the Neroxis Map Generator codebase: X symmetry means the top half of the map mirrors the bottom half (requires a horizontal line at halfY), and Z symmetry means the left half mirrors the right half (requires a vertical line at halfX).
Applied to files:
generator/src/main/java/com/faforever/neroxis/generator/terrain/MultiLevelLastTerrainGenerator.javashared/src/main/java/com/faforever/neroxis/mask/Vector3Mask.javashared/src/main/java/com/faforever/neroxis/mask/ComparableMask.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/SmallIslandsTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/DropPlateauTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/BigIslandsTerrainGenerator.javashared/src/main/java/com/faforever/neroxis/mask/Vector4Mask.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/RiversAndOceansTerrainGenerator.javashared/src/main/java/com/faforever/neroxis/mask/VectorMask.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/RiversTerrainGenerator.javashared/src/main/java/com/faforever/neroxis/mask/Vector2Mask.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/DropPlateauLastTerrainGenerator.javagenerator/src/main/java/com/faforever/neroxis/generator/terrain/OneIslandTerrainGenerator.javashared/src/main/java/com/faforever/neroxis/mask/IntegerMask.javashared/src/main/java/com/faforever/neroxis/mask/FloatMask.javashared/src/main/java/com/faforever/neroxis/mask/NormalMask.java
📚 Learning: 2025-12-27T17:01:49.688Z
Learnt from: clivepaterson
Repo: FAForever/Neroxis-Map-Generator PR: 477
File: shared/src/main/java/com/faforever/neroxis/mask/BooleanMask.java:817-819
Timestamp: 2025-12-27T17:01:49.688Z
Learning: In shared/src/main/java/com/faforever/neroxis/mask/BooleanMask.java, define/clarify symmetry handling: - X symmetry means the top half of the map mirrors the bottom half, achieved by a horizontal reflection across the line y = halfY. - Z symmetry means the left half mirrors the right half, achieved by a vertical reflection across the line x = halfX. Ensure the implementation computes halfX and halfY, applies the appropriate reflection to affected cells, and that tests cover both symmetry cases with boundary checks.
Applied to files:
shared/src/main/java/com/faforever/neroxis/mask/BooleanMask.java
📚 Learning: 2025-12-19T12:43:23.824Z
Learnt from: clivepaterson
Repo: FAForever/Neroxis-Map-Generator PR: 477
File: generator/src/main/java/com/faforever/neroxis/generator/terrain/MultiLevelLastTerrainGenerator.java:153-156
Timestamp: 2025-12-19T12:43:23.824Z
Learning: The fillRect method in the Mask class has the signature: fillRect(int x, int y, int width, int height, T value), where x and y are the starting coordinates, and width and height are the dimensions (not ending coordinates).
Applied to files:
shared/src/main/java/com/faforever/neroxis/mask/BooleanMask.java
🧬 Code graph analysis (3)
shared/src/main/java/com/faforever/neroxis/mask/Mask.java (1)
shared/src/main/java/com/faforever/neroxis/util/Pipeline.java (1)
Pipeline(27-223)
shared/src/main/java/com/faforever/neroxis/mask/BooleanMask.java (1)
shared/src/main/java/com/faforever/neroxis/util/SymmetryUtil.java (1)
SymmetryUtil(13-335)
generator/src/main/java/com/faforever/neroxis/generator/style/StyleGenerator.java (3)
shared/src/main/java/com/faforever/neroxis/map/placement/SpawnPlacer.java (1)
SpawnPlacer(17-134)shared/src/main/java/com/faforever/neroxis/util/DebugUtil.java (1)
DebugUtil(6-124)shared/src/main/java/com/faforever/neroxis/util/Pipeline.java (1)
Pipeline(27-223)
🪛 actionlint (1.7.9)
.github/workflows/tests.yml
20-20: the runner of "actions/setup-java@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue
(action)
.github/workflows/release.yml
50-50: the runner of "actions/setup-java@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue
(action)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Package windows-latest
- GitHub Check: Package macOS-latest
- GitHub Check: build
| val lombokVersion = "1.18.42" | ||
| compileOnly("org.projectlombok:lombok:$lombokVersion") | ||
| annotationProcessor("org.projectlombok:lombok:$lombokVersion") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
Lombok 1.18.42 Java 25 support compatibility
💡 Result:
Short answer: Lombok 1.18.42 adds JDK 25 compatibility (release dated Sep 20, 2025), but there are still active/closed issues reporting JDK 25-related breakages — test your code (and consider newer Lombok releases if problems appear). [1][2][3][4]
Sources:
- 1.18.42 release entry. [1]
- Feature/compatibility discussion for JDK 25. [2]
- Reported "Unable to compile using java 25" issue against 1.18.42. [3]
- Reported "val can be used only once with JDK25" bug (1.18.42). [4]
Test Lombok 1.18.42 thoroughly with JDK 25 before merging.
While Lombok 1.18.42 adds JDK 25 compatibility support, there are known issues reported including compilation failures and val usage restrictions with JDK 25. Test your codebase with this version, and consider upgrading to a newer Lombok release if you encounter compatibility problems.
🤖 Prompt for AI Agents
In buildSrc/src/main/kotlin/com.faforever.neroxis.conventions-java.gradle.kts
around lines 18 to 20, you've set lombokVersion to "1.18.42" which may have JDK
25 compatibility issues; run the entire project build and test suite using JDK
25 to verify compilation, annotation processing and 'val' usage; if you
encounter failures, either bump lombokVersion to a newer release that fixes JDK
25 issues or revert to the previous known-good Lombok version, update the
version string accordingly and re-run tests, and document the chosen version in
the file header or project README for future reference.
| this.slope = terrainGenerator.getSlope(); | ||
| this.passableLand = new BooleanMask(1, random.nextLong(), symmetrySettings, "passableLand", pipeline); | ||
| this.slope = new FloatMask(1, random.nextLong(), symmetrySettings, "passableLand", pipeline); | ||
| this.passableLand = new BooleanMask(1, random.nextLong(), symmetrySettings, "passableLand"); | ||
| this.slope = new FloatMask(1, random.nextLong(), symmetrySettings, "passableLand"); | ||
| passableLand.init(terrainGenerator.getPassableLand()); | ||
| slope.init(terrainGenerator.getSlope()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incorrect mask name and redundant assignment.
There are two issues here:
- Line 32 assigns
this.slope = terrainGenerator.getSlope(), but line 34 immediately overwrites it with a newFloatMask - Line 34 creates a
FloatMaskwith the name"passableLand"when it should be"slope"
This appears to be a copy-paste error where the mask name wasn't updated.
🔎 Proposed fix
- this.slope = terrainGenerator.getSlope();
this.passableLand = new BooleanMask(1, random.nextLong(), symmetrySettings, "passableLand");
- this.slope = new FloatMask(1, random.nextLong(), symmetrySettings, "passableLand");
+ this.slope = new FloatMask(1, random.nextLong(), symmetrySettings, "slope");
passableLand.init(terrainGenerator.getPassableLand());
slope.init(terrainGenerator.getSlope());📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| this.slope = terrainGenerator.getSlope(); | |
| this.passableLand = new BooleanMask(1, random.nextLong(), symmetrySettings, "passableLand", pipeline); | |
| this.slope = new FloatMask(1, random.nextLong(), symmetrySettings, "passableLand", pipeline); | |
| this.passableLand = new BooleanMask(1, random.nextLong(), symmetrySettings, "passableLand"); | |
| this.slope = new FloatMask(1, random.nextLong(), symmetrySettings, "passableLand"); | |
| passableLand.init(terrainGenerator.getPassableLand()); | |
| slope.init(terrainGenerator.getSlope()); | |
| this.passableLand = new BooleanMask(1, random.nextLong(), symmetrySettings, "passableLand"); | |
| this.slope = new FloatMask(1, random.nextLong(), symmetrySettings, "slope"); | |
| passableLand.init(terrainGenerator.getPassableLand()); | |
| slope.init(terrainGenerator.getSlope()); |
🤖 Prompt for AI Agents
In
generator/src/main/java/com/faforever/neroxis/generator/decal/DecalGenerator.java
around lines 32 to 36, there is a redundant assignment to this.slope and a wrong
mask name: remove the early assignment this.slope = terrainGenerator.getSlope()
(it is immediately overwritten), instantiate the FloatMask with the correct name
"slope" instead of "passableLand", and keep the BooleanMask for passableLand
named "passableLand"; then ensure
passableLand.init(terrainGenerator.getPassableLand()) and
slope.init(terrainGenerator.getSlope()) remain as the initializations.
| public void initialize(SCMap map, long seed, GeneratorParameters generatorParameters, | ||
| SymmetrySettings symmetrySettings, Pipeline pipeline) { | ||
| super.initialize(map, seed, generatorParameters, symmetrySettings, pipeline); | ||
|
|
||
| spawnLandMask = new BooleanMask(map.getSize() + 1, random.nextLong(), symmetrySettings, "spawnLandMask", | ||
| pipeline); | ||
| spawnPlateauMask = new BooleanMask(map.getSize() + 1, random.nextLong(), symmetrySettings, "spawnPlateauMask", | ||
| pipeline); | ||
| land = new BooleanMask(1, random.nextLong(), symmetrySettings, "land", pipeline); | ||
| mountains = new BooleanMask(1, random.nextLong(), symmetrySettings, "mountains", pipeline); | ||
| plateaus = new BooleanMask(1, random.nextLong(), symmetrySettings, "plateaus", pipeline); | ||
| ramps = new BooleanMask(1, random.nextLong(), symmetrySettings, "ramps", pipeline); | ||
| hills = new BooleanMask(1, random.nextLong(), symmetrySettings, "hills", pipeline); | ||
| valleys = new BooleanMask(1, random.nextLong(), symmetrySettings, "valleys", pipeline); | ||
| connections = new BooleanMask(1, random.nextLong(), symmetrySettings, "connections", pipeline); | ||
| heightmapValleys = new FloatMask(1, random.nextLong(), symmetrySettings, "heightmapValleys", pipeline); | ||
| heightmapHills = new FloatMask(1, random.nextLong(), symmetrySettings, "heightmapHills", pipeline); | ||
| heightmapPlateaus = new FloatMask(1, random.nextLong(), symmetrySettings, "heightmapPlateaus", pipeline); | ||
| heightmapMountains = new FloatMask(1, random.nextLong(), symmetrySettings, "heightmapMountains", pipeline); | ||
| heightmapLand = new FloatMask(1, random.nextLong(), symmetrySettings, "heightmapLand", pipeline); | ||
| heightmapOcean = new FloatMask(1, random.nextLong(), symmetrySettings, "heightmapOcean", pipeline); | ||
| heightMapNoise = new FloatMask(1, random.nextLong(), symmetrySettings, "heightmapNoise", pipeline); | ||
| SymmetrySettings symmetrySettings) { | ||
| super.initialize(map, seed, generatorParameters, symmetrySettings); | ||
|
|
||
| spawnLandMask = new BooleanMask(map.getSize() + 1, random.nextLong(), symmetrySettings, "spawnLandMask"); | ||
| spawnPlateauMask = new BooleanMask(map.getSize() + 1, random.nextLong(), symmetrySettings, "spawnPlateauMask"); | ||
| land = new BooleanMask(1, random.nextLong(), symmetrySettings, "land"); | ||
| mountains = new BooleanMask(1, random.nextLong(), symmetrySettings, "mountains"); | ||
| plateaus = new BooleanMask(1, random.nextLong(), symmetrySettings, "plateaus"); | ||
| ramps = new BooleanMask(1, random.nextLong(), symmetrySettings, "ramps"); | ||
| hills = new BooleanMask(1, random.nextLong(), symmetrySettings, "hills"); | ||
| valleys = new BooleanMask(1, random.nextLong(), symmetrySettings, "valleys"); | ||
| connections = new BooleanMask(1, random.nextLong(), symmetrySettings, "connections"); | ||
| heightmapValleys = new FloatMask(1, random.nextLong(), symmetrySettings, "heightmapValleys"); | ||
| heightmapHills = new FloatMask(1, random.nextLong(), symmetrySettings, "heightmapHills"); | ||
| heightmapPlateaus = new FloatMask(1, random.nextLong(), symmetrySettings, "heightmapPlateaus"); | ||
| heightmapMountains = new FloatMask(1, random.nextLong(), symmetrySettings, "heightmapMountains"); | ||
| heightmapLand = new FloatMask(1, random.nextLong(), symmetrySettings, "heightmapLand"); | ||
| heightmapOcean = new FloatMask(1, random.nextLong(), symmetrySettings, "heightmapOcean"); | ||
| heightMapNoise = new FloatMask(1, random.nextLong(), symmetrySettings, "heightmapNoise"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
LGTM! Comprehensive Pipeline removal.
The initialize method signature and all Mask constructors (BooleanMask and FloatMask) have been correctly updated to remove Pipeline dependency. This is a clean refactoring across 14 mask instances.
🤖 Prompt for AI Agents
In
generator/src/main/java/com/faforever/neroxis/generator/terrain/BasicTerrainGenerator.java
around lines 62 to 81, the initialize method and all BooleanMask/FloatMask
constructor calls were refactored to remove the Pipeline dependency and now use
the new signatures; there is no issue to fix — keep the current changes as-is
(approved).
| protected void plateausSetup() { | ||
| int mapSize = map.getSize(); | ||
| float maxStepSize = mapSize / 128f; | ||
| int maxStepSize = mapSize / 128; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find pathInCenterBounds method signature and its usage
rg -n 'pathInCenterBounds' --type java -A5 -B2Repository: FAForever/Neroxis-Map-Generator
Length of output: 12166
🏁 Script executed:
#!/bin/bash
# Also check the full PathedPlateauTerrainGenerator.java file around the flagged lines
wc -l generator/src/main/java/com/faforever/neroxis/generator/terrain/PathedPlateauTerrainGenerator.javaRepository: FAForever/Neroxis-Map-Generator
Length of output: 176
🏁 Script executed:
#!/bin/bash
# Look at the full context of lines around 9 and 17
head -50 generator/src/main/java/com/faforever/neroxis/generator/terrain/PathedPlateauTerrainGenerator.javaRepository: FAForever/Neroxis-Map-Generator
Length of output: 931
🏁 Script executed:
#!/bin/bash
# Check if there are minimum map size constraints in the codebase
rg -n "getSize|mapSize.*=" generator/src/main/java/com/faforever/neroxis/generator/terrain/PathedPlateauTerrainGenerator.javaRepository: FAForever/Neroxis-Map-Generator
Length of output: 113
🏁 Script executed:
#!/bin/bash
# Check inflate method signature to understand its parameter type
rg -n "inflate.*{" --type java -A3 | grep -A3 "float\|int"Repository: FAForever/Neroxis-Map-Generator
Length of output: 158
🏁 Script executed:
#!/bin/bash
# Search for inflate method signature properly
rg -n 'inflate' --type java | grep 'public\|inflate(' | head -20Repository: FAForever/Neroxis-Map-Generator
Length of output: 3254
🏁 Script executed:
#!/bin/bash
# Find the inflate method definition in BooleanMask or MapMask classes
fd -e java -path '*/mask/*' | xargs grep -l 'inflate' | head -5Repository: FAForever/Neroxis-Map-Generator
Length of output: 243
🏁 Script executed:
#!/bin/bash
# Find the BooleanMask class and search for inflate method definition
find . -name "BooleanMask.java" -o -name "*Mask.java" | xargs grep -l "public.*inflate"Repository: FAForever/Neroxis-Map-Generator
Length of output: 141
🏁 Script executed:
#!/bin/bash
# Search for inflate method definition in the mask directory
rg 'public.*inflate' --type java -A2Repository: FAForever/Neroxis-Map-Generator
Length of output: 390
🏁 Script executed:
#!/bin/bash
# Check if there are any minimum map size validations in the codebase
rg -n "mapSize.*<|mapSize.*>|MIN.*MAP|minimum.*map" --type java generator/src/main/java/com/faforever/neroxis/generator/ | head -20Repository: FAForever/Neroxis-Map-Generator
Length of output: 972
🏁 Script executed:
#!/antml:thinking
Let me verify if there are any minimum map size constraints that would prevent the truncation issue from occurring in practice.Repository: FAForever/Neroxis-Map-Generator
Length of output: 118
🏁 Script executed:
#!/bin/bash
# Look for typical map sizes used in the codebase
rg -n "getSize\|mapSize.*[0-9]" --type java generator/src/main/java/com/faforever/neroxis/generator/ | grep -E "[0-9]{3,}" | head -20Repository: FAForever/Neroxis-Map-Generator
Length of output: 57
🏁 Script executed:
#!/bin/bash
# Confirm the learned context about StrictMath usage in this codebase
rg -n 'StrictMath' --type java generator/src/main/java/com/faforever/neroxis/generator/ | head -10Repository: FAForever/Neroxis-Map-Generator
Length of output: 1922
Integer division truncates step size for small maps.
Changed from float maxStepSize = mapSize / 128f to int maxStepSize = mapSize / 128. Integer division loses precision before conversion to float—for maps smaller than 128 pixels, this produces 0 instead of a fractional value. Similarly, line 17 uses inflate(mapSize / 256), truncating values below 256. Given the emphasis on StrictMath for deterministic procedural generation, verify that pathInCenterBounds handles zero or reduced step sizes gracefully.
🤖 Prompt for AI Agents
In
generator/src/main/java/com/faforever/neroxis/generator/terrain/PathedPlateauTerrainGenerator.java
around line 9, the change from float to int causes integer division and
truncation (mapSize / 128 -> 0 for small maps) and similarly for the inflate
call at line 17; restore fractional precision by using floating-point division
(e.g., use float or double: mapSize / 128f or (double) mapSize / 128) for
maxStepSize and the inflate argument, and if downstream code expects integers,
explicitly round or clamp values (e.g., Math.max(1, Math.round(...)) or preserve
as float if supported); also review pathInCenterBounds usage to ensure it
handles zero or very small step sizes—if it cannot, clamp to a minimum positive
step (e.g., 1 or a small fraction) before calling.
| distributionBase=GRADLE_USER_HOME | ||
| distributionPath=wrapper/dists | ||
| distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip | ||
| distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
Gradle 9.2.1 Java 25 compatibility support requirements
💡 Result:
Short answer — Gradle 9.2.1 supports Java 25, but you must meet the usual JVM/toolchain requirements and be aware of some known edge cases:
- Required JVM to run Gradle: any JVM between Java 17 and Java 25 (Gradle 9.2.1 is tested to run on up to Java 25). Use a supported JDK for the Gradle daemon or configure a toolchain for build tasks. [1]
- Java 25 support introduced in Gradle 9.1.0 — so Java 25 is supported for running Gradle and as a toolchain in 9.2.1 (Gradle ≥ 9.1.0). [2]
- If you use the Tooling API / native JNI clients you may need to enable native access at JVM startup per the release notes (see JEP/JNI notes). Also some plugins (e.g., Kotlin/Android toolchain integrations) have reported issues; check plugin compatibility if you see “incompatible Java 25” errors. [2][3]
- Practical checklist:
- Run Gradle with a JVM in the 17–25 range (set GRADLE_JAVA_HOME / wrapper JVM). [1]
- Configure Java toolchains in build if you need to compile/test with Java 25 while running Gradle on a different JVM. [1]
- Verify third‑party plugin compatibility (Kotlin, Android Gradle Plugin, IDE tooling) and update them if needed. [2][3]
Sources: Gradle compatibility matrix and docs (Java 17–25, Java‑25 support added in 9.1.0) and reported plugin/IDE issues. [1] [2] [3]
References
[1] Gradle Compatibility Matrix (Java versions supported).
[2] Gradle 9.1.0 release notes (introduces Java 25 support).
[3] gradle/gradle GitHub issue reporting Kotlin/IDE problems when using Java 25.
Verify Gradle 9.2.1 Java 25 compatibility and plugin support before upgrade.
Gradle 9.2.1 supports Java 25 (support introduced in 9.1.0) and can run on JVM versions 17–25. However, verify that your project's plugins (Kotlin, Android, IDE tooling) are compatible with Java 25, as some plugins have reported issues. Also ensure the Gradle JVM is configured correctly (via GRADLE_JAVA_HOME or toolchain) and, if using the Tooling API or JNI, enable native access as required by Java 25.
🤖 Prompt for AI Agents
In gradle/wrapper/gradle-wrapper.properties around line 3, the upgrade to Gradle
9.2.1 may require verification of Java 25 compatibility and plugin support;
confirm that all project plugins (Kotlin, Android Gradle Plugin, IDE tooling and
any third‑party plugins) support Java 25 and Gradle 9.2.1, update plugin
versions if needed, ensure the build uses the correct Gradle JVM by setting
GRADLE_JAVA_HOME or configuring the toolchain in gradle.properties/build.gradle,
and if your build uses the Tooling API or JNI enable the required native access
flags for Java 25; run local and CI builds/tests and fix any plugin or
configuration issues before merging.
| .inflate(teamSeparation / spawnMask.getSymmetrySettings() | ||
| .spawnSymmetry() | ||
| .getNumSymPoints())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Integer division may cause incorrect spawn placement.
The change from float to int division will truncate the result, which can significantly affect the inflate operation:
- Before:
teamSeparation / numSymPointsproduced a float (e.g.,32 / 4 = 8.0,2 / 4 = 0.5) - After: Integer division truncates (e.g.,
32 / 4 = 8,2 / 4 = 0)
When teamSeparation < numSymPoints, this produces 0 instead of a fractional value, which may cause:
- No inflation of symmetry lines (inflate(0))
- Incorrect spawn separation boundaries
- Potential spawn placement failures or clustering
🔎 Proposed fix
Either restore float division or use explicit rounding:
- .inflate(teamSeparation / spawnMask.getSymmetrySettings()
- .spawnSymmetry()
- .getNumSymPoints()))
+ .inflate((int) Math.ceil((float) teamSeparation / spawnMask.getSymmetrySettings()
+ .spawnSymmetry()
+ .getNumSymPoints())))Or verify that inflate() now accepts int and handles small values appropriately.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .inflate(teamSeparation / spawnMask.getSymmetrySettings() | |
| .spawnSymmetry() | |
| .getNumSymPoints())) | |
| .inflate((int) Math.ceil((float) teamSeparation / spawnMask.getSymmetrySettings() | |
| .spawnSymmetry() | |
| .getNumSymPoints()))) |
🤖 Prompt for AI Agents
In shared/src/main/java/com/faforever/neroxis/map/placement/SpawnPlacer.java
around lines 91-93, integer division is being used for the inflate argument
which truncates fractional values (e.g. 2/4 -> 0) and can cause no inflation and
incorrect spawn placement; change the expression to perform floating-point
division (cast one operand to float/double) so fractional results are preserved,
or explicitly compute a safe non-zero inflate value (e.g. Math.max(minValue,
(float)teamSeparation / numSymPoints) or similar) and ensure inflate receives
the correct type expected by the method.
| BooleanMask realWater = realLand.copy().invert(); | ||
| BooleanMask shadowsMask = heightMap | ||
| .copyAsShadowMask(map.getBiome().lightingSettings().sunDirection()).inflate(0.5f); | ||
| .copyAsShadowMask(map.getBiome().lightingSettings().sunDirection()).inflate(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
cat -n toolsuite/src/main/java/com/faforever/neroxis/toolsuite/MapInfoTextureExporter.java | sed -n '40,60p'Repository: FAForever/Neroxis-Map-Generator
Length of output: 1476
🏁 Script executed:
git log --oneline -20 toolsuite/src/main/java/com/faforever/neroxis/toolsuite/MapInfoTextureExporter.javaRepository: FAForever/Neroxis-Map-Generator
Length of output: 102
🏁 Script executed:
git diff HEAD~5 toolsuite/src/main/java/com/faforever/neroxis/toolsuite/MapInfoTextureExporter.java | head -100Repository: FAForever/Neroxis-Map-Generator
Length of output: 261
🏁 Script executed:
find . -name "*.java" -type f | xargs grep -l "class BooleanMask" | head -5Repository: FAForever/Neroxis-Map-Generator
Length of output: 141
🏁 Script executed:
rg "def inflate|inflate\(" --type java -A 2 | head -80Repository: FAForever/Neroxis-Map-Generator
Length of output: 8969
🏁 Script executed:
rg "\.inflate\(" --type java | grep -E "(0\.5|1|inflate)" | head -20Repository: FAForever/Neroxis-Map-Generator
Length of output: 3397
🏁 Script executed:
cat -n shared/src/main/java/com/faforever/neroxis/mask/BooleanMask.java | head -100Repository: FAForever/Neroxis-Map-Generator
Length of output: 4636
🏁 Script executed:
rg "inflate" shared/src/main/java/com/faforever/neroxis/mask/BooleanMask.java -A 5Repository: FAForever/Neroxis-Map-Generator
Length of output: 1172
🏁 Script executed:
git log --all --oneline -- "*MapInfoTextureExporter*" | head -10Repository: FAForever/Neroxis-Map-Generator
Length of output: 150
🏁 Script executed:
git show 7e725ca:toolsuite/src/main/java/com/faforever/neroxis/toolsuite/MapInfoTextureExporter.java | sed -n '40,60p'Repository: FAForever/Neroxis-Map-Generator
Length of output: 1329
🏁 Script executed:
git show fa04454:toolsuite/src/main/java/com/faforever/neroxis/toolsuite/MapInfoTextureExporter.java | sed -n '40,60p'Repository: FAForever/Neroxis-Map-Generator
Length of output: 1347
The shadow mask inflation change from 0.5f to 1 effectively enables shadow spread that was previously disabled.
The old code inflate(0.5f) was compiled as inflate(0) due to implicit float-to-int truncation in the inflate(int radius) method signature, meaning no inflation occurred. The new code inflate(1) enables actual 1-pixel inflation. This is a behavioral change that will affect shadow rendering in the generated map info texture. Confirm this is intentional.
🤖 Prompt for AI Agents
In
toolsuite/src/main/java/com/faforever/neroxis/toolsuite/MapInfoTextureExporter.java
around line 48, the call .copyAsShadowMask(...).inflate(1) changes behavior by
enabling a 1-pixel shadow spread that previously did not occur (inflate(0.5f)
was truncated to 0); decide whether this was intentional and either revert to
the previous no-inflate behavior by calling inflate(0) (or keep the prior
literal 0.5f but change the API to accept floats), or if the spread is desired
keep inflate(1) and add a comment explaining the deliberate change; update the
code accordingly and add a short comment stating the intended shadow-inflation
behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (1)
.github/workflows/release.yml (1)
48-54: Updateactions/checkoutfrom v2 to v4.
actions/checkout@v2is outdated. Theactions/setup-java@v3issue was already flagged in a previous review.🔎 Proposed fix
- - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up JDK 25 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
.github/workflows/release.yml
🧰 Additional context used
🪛 actionlint (1.7.9)
.github/workflows/release.yml
19-19: the runner of "actions/setup-java@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue
(action)
50-50: the runner of "actions/setup-java@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue
(action)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
| - uses: actions/checkout@v2 | ||
| - name: Set up JDK 21 | ||
| - name: Set up JDK 25 | ||
| uses: actions/setup-java@v3 | ||
| with: | ||
| distribution: "temurin" | ||
| java-version: 21 | ||
| java-version: 25 | ||
| cache: 'gradle' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update outdated GitHub Actions in the build job.
actions/checkout@v2is outdated; current major version is v4.actions/setup-java@v3is outdated; current version is v4.x (static analysis confirms this).
🔎 Proposed fix
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Set up JDK 25
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: 25
cache: 'gradle'📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - uses: actions/checkout@v2 | |
| - name: Set up JDK 21 | |
| - name: Set up JDK 25 | |
| uses: actions/setup-java@v3 | |
| with: | |
| distribution: "temurin" | |
| java-version: 21 | |
| java-version: 25 | |
| cache: 'gradle' | |
| - uses: actions/checkout@v4 | |
| - name: Set up JDK 25 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: "temurin" | |
| java-version: 25 | |
| cache: 'gradle' |
🧰 Tools
🪛 actionlint (1.7.9)
17-17: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue
(action)
19-19: the runner of "actions/setup-java@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue
(action)
🤖 Prompt for AI Agents
.github/workflows/release.yml around lines 17 to 23: the workflow uses outdated
action versions (actions/checkout@v2 and actions/setup-java@v3); update
actions/checkout to the current major (v4) and actions/setup-java to v4.x, keep
the existing inputs (distribution: "temurin", java-version: 25, cache: 'gradle')
intact, and run/validate the workflow after updating to ensure no syntax or
input changes are required by the new major versions.
| run: | | ||
| ./gradlew -x test --stacktrace jlink --parallel -PgeneratorVersion="${{ github.event.inputs.version }}" | ||
| ./generator/build/image/bin/java -XX:AOTCacheOutput=generator/build/image/bin/neroxis-generator.aot -XX:+UseCompactObjectHeaders -m com.faforever.neroxis.generator/com.faforever.neroxis.generator.MapGenerator --out-path ./GeneratedMaps | ||
| ./gradlew -x test --stacktrace jpackage --parallel -PgeneratorVersion="${{ github.event.inputs.version }}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
find . -name "release.yml" -path "*/.github/workflows/*" | head -5Repository: FAForever/Neroxis-Map-Generator
Length of output: 106
🏁 Script executed:
cat -n ./.github/workflows/release.yml | sed -n '50,75p'Repository: FAForever/Neroxis-Map-Generator
Length of output: 1468
🏁 Script executed:
cat -n ./.github/workflows/release.yml | sed -n '1,50p'Repository: FAForever/Neroxis-Map-Generator
Length of output: 1776
🌐 Web query:
jlink output Windows java.exe executable extension GitHub Actions
💡 Result:
Short answer: jlink produces a platform-specific runtime image that includes the java launcher with the normal OS filename — on Windows that is java.exe in the image's bin\ directory. A Windows-targeted jlink image will contain bin\java.exe; a Linux-targeted image will contain bin/java (no .exe) and will not run on Windows. When using GitHub Actions build matrix, generate the Windows jlink image on a Windows runner (or use Windows JDK jmods when cross-building) and invoke the runtime via /bin/java.exe (or add that bin dir to PATH). Ensure you run the Windows image on a Windows runner — Linux/macOS runners will not execute .exe binaries. [1][2][3]
Sources
- jlink runtime image description (shows bin/java and platform-specific images). [1]
- Microsoft doc: jlink image contains ./bin/java; Windows images use java.exe. [2]
- Example GitHub Actions + jlink (JReleaser) showing Windows target images and Actions configuration. [3]
🌐 Web query:
GitHub Actions Windows shell bash git bash java.exe extension resolution
💡 Result:
Short answer: On Windows runners GitHub Actions’ shell: bash runs the Git-for-Windows bash (bash.exe). That bash still relies on Windows PATH/PATHEXT behavior and the MSYS/MSYS2 emulation layer — so executable lookup can differ from native cmd/powershell. If a program isn’t found when you call its bare name (java) but exists as java.exe, call java.exe or use the full path or fix PATH so bash can see the Windows location. You can also switch the step to a Windows-native shell (pwsh or cmd) where PATHEXT resolution behaves like normal Windows. Examples and links below.
Actionable options
- Call java.exe explicitly: run: java.exe -version.
- Use full Windows path: run: "/c/Program Files/Java/jdk.../bin/java.exe" -version (or quoted Windows path).
- Ensure the Java bin directory is on PATH (export PATH="/c/Program Files/Java/…/bin:$PATH") in bash.
- Use shell: pwsh or shell: cmd if you need native Windows command resolution.
- Or set a custom shell to a different bash (Cygwin/MSYS2) if required. (docs.github.com)
If you want, tell me which runner image and workflow step (example run block) and I’ll give the exact syntax to fix it.
Citations:
🏁 Script executed:
cat -n ./.github/workflows/release.yml | sed -n '59,64p'Repository: FAForever/Neroxis-Map-Generator
Length of output: 858
AOT generation will fail on Windows runners due to missing .exe extension.
When jlink runs on Windows, it produces java.exe, not java. The AOT command at line 62 uses ./generator/build/image/bin/java, which Git Bash on Windows runners cannot resolve. Use ./generator/build/image/bin/java.exe or implement platform-agnostic logic (e.g., shell conditional or a Gradle task to handle the invocation).
The workflow matrix includes windows-latest, so this will cause builds to fail on Windows.
🤖 Prompt for AI Agents
.github/workflows/release.yml around lines 60 to 63: the workflow invokes the
jlink-generated Java binary as ./generator/build/image/bin/java which fails on
Windows where the runtime is java.exe; update the step to use a platform-aware
invocation — either call ./generator/build/image/bin/java.exe when runner.os ==
'Windows' (use a conditional job/step), or implement a small cross-platform
wrapper/Gradle task that resolves the correct binary name and runs the AOT
command so Linux/macOS use ./generator/build/image/bin/java and Windows uses
./generator/build/image/bin/java.exe.
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.