Add crafting plan progress and duration estimation API - #211
Merged
Conversation
Adds the total crafting quantity and the estimated total and remaining tick durations to crafting plans, together with their (de)serialization and aggregation during plan flattening. These values are not filled in or displayed yet, so everything reports an unknown value for now. Refs #145 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186zEXrjMNMVXQC7wcoSiMR
rubensworks
commented
Sep 2, 2026
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186zEXrjMNMVXQC7wcoSiMR
Estimates the duration of a crafting plan by walking its dependency graph: a job takes the measured duration of its recipe times its amount, plus the longest estimation of the jobs it depends on, as dependencies have to finish first, while dependencies of the same job are crafted simultaneously. Running jobs subtract the time that their current crafting operation has been going on already. The crafting plan guis show the estimated total duration before a job is started, and the estimated remaining duration while it is running. The crafting jobs gui additionally shows the percentage of crafting operations that are finished. Refs #145 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186zEXrjMNMVXQC7wcoSiMR
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186zEXrjMNMVXQC7wcoSiMR
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186zEXrjMNMVXQC7wcoSiMR
The progress and remaining duration that were added to the crafting job list are drawn in a second column, which the status and duration of the first column ran into: at half scale "Status: Queueing" and "Duration: 0:00:00" are both wider than the 40 pixels that separated the two columns, so their last characters were overwritten. Widen both columns to fit their longest strings, the "Pending Dependencies" status and a two-digit hour duration. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016gX5ZToD5ApLBXQkKW2QGj
The longest status, "Pending Dependencies", is the one that nested jobs spend most of their time in, and it ended right against the progress column next to it. Widen the status column so the two are separated. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016gX5ZToD5ApLBXQkKW2QGj
The crafting job terminal listed the status, size, channel, duration, progress and remaining time as six separate pieces of text per job. Replace the duration, progress and remaining time with a progress bar that carries all three: the time the job has been running on the left, how far it has come in the middle, and what is left on the right. The labelled values, along with the total estimate and the owner, now show up in a tooltip when hovering a job. An estimate that is not known yet was left out entirely, which made it indistinguishable from a job that had no line to show. Show a question mark for it instead, for any job that is not in an error state. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016gX5ZToD5ApLBXQkKW2QGj
…aftingplan-progress-api # Conflicts: # gradle.properties
The crafting jobs gui was still on the overload that master deprecated when it gained a tooltip component parameter. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016gX5ZToD5ApLBXQkKW2QGj
Hovering a craftable in the storage terminal now says how long one crafting operation of it is expected to take. The client had no notion of recipe durations, and asking for a whole crafting plan per hovered item would be far too expensive. The duration of a single operation is only a lookup in the crafting network though, so the server can attach it to the crafting option it already sends. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016gX5ZToD5ApLBXQkKW2QGj
Every line was plain white, which made the tooltip a wall of text to read through. Give the status the same color that the plan guis paint it in, dim the labels so that the durations stand out from them, put the remaining time in a color of its own, and push the values that are only occasionally interesting to the back. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016gX5ZToD5ApLBXQkKW2QGj
The numbers inside the bar sat on a track that was close in brightness to the line behind it. Give the bar a border and a darker track, so that the times and the percentage read over both the track and the fill. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016gX5ZToD5ApLBXQkKW2QGj
The operations of a job are added to the estimation of its dependencies. An unknown duration for them counted as zero, so a job on a crafting interface that had never crafted anything reported the duration of its dependencies as if that were the whole answer. Report an unknown estimation instead, which the guis already show as a question mark. Unknown dependencies keep being skipped: they only lower a maximum that the other dependencies can still win. The recipe duration is now passed in rather than looked up, so that the estimation itself can be tested without a crafting network, instead of through the network being absent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016gX5ZToD5ApLBXQkKW2QGj
The question mark on its own does not say whether the estimate is missing, zero, or broken. Hovering it now explains that the crafting interfaces have not crafted these recipes before. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016gX5ZToD5ApLBXQkKW2QGj
rubensworks
commented
Sep 3, 2026
Make getEstimatedTickDuration a regular interface method, deprecate the constructor that does not take a duration, and drop a comment that does not carry its weight. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016gX5ZToD5ApLBXQkKW2QGj
Crafting interfaces only measure how long a recipe takes to produce its outputs after being started. Regular crafting recipes are done within the tick they are started in, so they measure as taking no time at all, and their average drags every other recipe on the interface to zero as well. Multiplied by the operations of a job, that reported a plan for 100 chests as taking no time, and left the remaining time of a running job at zero. An interface performs at most one operation per update though, so no recipe can go faster than that. Take the update interval as a lower bound. The durations are also no longer formatted as H:mm:ss throughout, which rounded everything below a minute away. Seconds are shown with the decimals that are meaningful at their magnitude, minutes as m:ss, and only durations of an hour and over as H:mm:ss. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016gX5ZToD5ApLBXQkKW2QGj
Recipes that are crafted within the tick they are started in were measured as taking no time, which was worked around here by taking the crafting interface update interval as a lower bound. CyclopsMC/IntegratedCrafting#223 moved that bound to where the numbers come from, where it also knows that non-blocking interfaces start as many operations as their target accepts, and that an interface can be configured to update less often than the configured minimum. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016gX5ZToD5ApLBXQkKW2QGj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of the work towards #145 (showing estimated/remaining time and completion percentage for crafting jobs).
This is the API groundwork only: it adds the fields that the gui will later render, and the plumbing to keep them alive across (de)serialization and plan flattening. Nothing is computed or displayed yet, so this change is inert on its own.
Added
ITerminalCraftingPlan#getCraftingQuantityTotal(): the number of crafting operations of a job, including the ones that finished already.getCraftingQuantity()keeps its current meaning (the operations that still have to happen), sototal - remaininggives the completion of a job.ITerminalCraftingPlan#getEstimatedTickDurationTotal()and#getEstimatedTickDurationRemaining(): estimations, as opposed togetTickDuration(), which is the time a job has been running already.-1means unknown.ITerminalCraftingPlanFlat, plusgetCraftingQuantityTotal()andgetCraftingQuantityRemaining(), which are aggregated over all jobs of a plan during flattening.These are regular interface methods rather than
defaultones, so implementations outside of this repository have to implement them. The existing constructors ofTerminalCraftingPlanStatic,TerminalCraftingPlanFlatStaticandTerminalCraftingPlanCraftingJobDependencyGraphare kept next to the new ones.Notes
isPlanHandledso that both traversals share it.craftingQuantityand-1), so plans serialized by an older version still load.craftingQuantityTotalequalscraftingQuantity, and both estimations are-1.src/test/javasources of this repository, covering the flattening aggregation (nested jobs, jobs shared through job splitting, and invalid jobs).Heads-up: I could not build this locally, as all
org.cyclopsdependencies resolve to GitHub Packages, which returns 401 in my environment. The changed files parse cleanly, but compilation and the new unit tests are only verified by CI here.Next steps for #145 are measuring per-recipe crafting durations in IntegratedCrafting (CyclopsMC/IntegratedCrafting#220), filling in these values in
TerminalStorageTabIngredientCraftingHandlerCraftingNetwork, and rendering them in the crafting plan and crafting jobs guis.🤖 Generated with Claude Code
https://claude.ai/code/session_0186zEXrjMNMVXQC7wcoSiMR