feat: added parallel face solver#15
Conversation
|
Also @kevinthegreat1 care to have a look if everything looks in place? If so, we can merge. |
|
Haha thanks. I started this like 6 months ago in Python but forgot all about it. Had to use AI to help bring it into Java. Feel free to try it out. |
|
Thanks, I will review this soon. Is the coverage optimal? I think we should guarantee maximum/optimal coverage first and then the number of flying machines. Of course having options for this is fine. Also, I think we should hook this up with the game tests. I might improve the tests as well. |
|
The coverage is not necessarily optimal but the algorithm employs some heuristics to try to find good candidates. It starts by pre-computing all valid islands (between 4 and 12 blocks, containing an L-shape, not covering any obsidian, etc.), then for each pumpkin, it assigns a score that counts the number of possible islands that includes it. Then it just uses backtracking with a heuristic (it tries to cover pumpkins that are part of the least possible islands first). This can still take a long time to find an optimal solution so the algorithm uses a score for each valid solution it finds. The score is simply The score can be changed to optimize for efficiency or coverage. A lower score indicates that the user doesn't mind extra flying machines to cover just a few more pumpkins (more coverage), while a higher score indicates that the user wants to build fewer machines (more efficiency). The algorithm also has a timeout to prevent running forever (it returns best solution it finds in the time). |
|
I have noticed that sometimes it'll return a solution that could easily be improved by just adding one more slime/honey block. This is probably due to the timeout and the algorithm not having enough time to backtrack all the way to replacing that particular island with a larger one. I could probably fix this by adding another pass at the end that takes the best solution and for each island in it, looks for a larger island valid island that encompasses it. |
kevinthegreat1
left a comment
There was a problem hiding this comment.
Thanks for the pr. Please let me know if you have questions for any of these suggestions. I am also happy to implement some of these if you are unfamiliar.
Also, primitive data structures can be replaced with fastutil. I will also work on tests for this.
|
Thanks, will take a look soon. I don't have much fabric experience so this will be good chance to learn more :) |
|
Went ahead and fixed all the issues you found. I went with your suggestions on most of them except the ones I commented on. |
|
I also tried sorting faces by descending clusters covered and then by the cells count, but that actually seemed to give me worse results. |
| ObjectSet<IntSet> seenShapesGlobal = new ObjectOpenHashSet<>(); | ||
|
|
||
| for (int tIdx = 0; tIdx < targets.size(); tIdx++) { | ||
| possibleShapes.put(tIdx, new ObjectRBTreeSet<>(SHAPE_PRIORITY_COMPARATOR)); |
There was a problem hiding this comment.
I think I've found a bug. This could be overwriting existing shapes found for tIdx.

Add
/geodesy solvecommand for automatic flying machine layoutSummary
This PR adds a new
/geodesy solvecommand that automatically calculates optimal slime/honey block placement and mob head markers after running/geodesy project. This eliminates the tedious manual process of figuring out island layouts.Before: Manual placement of sticky blocks and mob heads (Steps 5-6 in the old workflow)
After: Run
/geodesy solveand it's done automaticallyUsage
The cost parameter controls the coverage vs. machine count tradeoff:
cost=1.0→ More machines, higher coveragecost=4.0→ Fewer machines, may skip some pumpkinsAlgorithm Overview
The solver finds optimal "islands" (connected groups of 4-12 blocks) to cover harvest cells.
Constraints
Valid L-Shape Examples
Two-Coloring for Adjacent Islands
Algorithm Steps
harvest_covered - (island_count × cost)Optimization
Files Changed
solver/IslandFaceSolver.javasolver/FaceGrid.javasolver/SolverResult.javasolver/SolverConfig.javaGeodesyCore.javageodesySolve()+ helpersGeodesyFabricMod.javaREADME.mdExample Output