Skip to content

Conversation

@illuciaz23
Copy link
Contributor

What

Add components to machines to show why recipes fail to setup, they are displayed in:

  1. simple machine's sidebar
  2. multiblock machine's UI
  3. all machine's Jade Tooltip
f5e99c514fbb17d8c98659e65e979dcc recipe waiting reasons will also be displayed

Implementation Details

  1. add failReasonMap field in RecipeLogic to memroize fail reasons, and failReasons that is used to synchronize components with the client.
  2. add getFailReason() to ModifierFunction so recipeModifier can convey info about why recipes fail.
  3. add fail reason component for some frequent occurrences.

Outcome

Players now can easily know why their machines do not work (in most cases).

Additional Information

Also add more info to AdjacentFluidCondition's tooltip to show specific fluid.
Add TODO about replacing ModifierFunction.NULL with cancel(reason).

Potential Compatibility Issues

This feature is all about info display, did not change the original logic or api. failReasonMap and failReasons are not persisted so
data errors will not occur.

@illuciaz23 illuciaz23 requested a review from a team as a code owner January 20, 2026 15:27
@illuciaz23 illuciaz23 force-pushed the luckyblock/recipe-fail-reason branch from 551eabe to cee5381 Compare January 20, 2026 15:43
@jurrejelle jurrejelle added type: feature New feature or request bundled for a 0.X.0 Update Release: Major - 0.X.0 Releases focused on Content, changes to gameplay; While maintaining mostly API stability. labels Jan 21, 2026
Copy link
Contributor

@jurrejelle jurrejelle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add docs to docs/content/modpack/changes/v7.5.0.md and the recipe modifiers page about this existing? the recipe modifiers page doesn't have java examples yet, up to you if you wanna add those too or just add it to the existing kjs examples

@FunctionalInterface
public interface ModifierFunction {

// TODO: Add reasons for any NULL ModifierFunction (replace them with cancel)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this finished within this codebase?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet. There are still multiple usages of ModifierFunction.NULL in the codebase. Some of them were not replaced because I am not sure about reasons. I have only replaced the more common cases where the fail reason is explicit.

@illuciaz23
Copy link
Contributor Author

I hava added docs to v7.5.0.md. I am not familiar with KubeJS, so I did not touch that part.

@illuciaz23 illuciaz23 force-pushed the luckyblock/recipe-fail-reason branch from b1d184a to 1a4ab22 Compare January 23, 2026 04:28
You are supposed to replace `ModifierFunction.NULL` with `ModifierFunction.cancel(reason)` to tell the machine why the recipe fail to start.
```patch
- return ModifierFunction.NULL;
+ return ModifierFunction.cancel(Component.translate("gtceu.recipe_modifier.xxx"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't it Component.translateable and not Component.translate?

Comment on lines +16 to +21
provider.add("gtceu.recipe_logic.insufficient_fuel", "Insufficient Fuel");
provider.add("gtceu.recipe_logic.insufficient_in", "Insufficient Inputs");
provider.add("gtceu.recipe_logic.insufficient_out", "Insufficient Outputs");
provider.add("gtceu.recipe_logic.condition_fails", "Condition Fails");
provider.add("gtceu.recipe_logic.no_contents", "Recipe has no Contents");
provider.add("gtceu.recipe_logic.no_capabilities", "Machine has no Capabilities");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add failure_reason. to all of these keys:

Suggested change
provider.add("gtceu.recipe_logic.insufficient_fuel", "Insufficient Fuel");
provider.add("gtceu.recipe_logic.insufficient_in", "Insufficient Inputs");
provider.add("gtceu.recipe_logic.insufficient_out", "Insufficient Outputs");
provider.add("gtceu.recipe_logic.condition_fails", "Condition Fails");
provider.add("gtceu.recipe_logic.no_contents", "Recipe has no Contents");
provider.add("gtceu.recipe_logic.no_capabilities", "Machine has no Capabilities");
provider.add("gtceu.recipe_logic.failure_reason.insufficient_fuel", "Insufficient fuel");
provider.add("gtceu.recipe_logic.failure_reason.insufficient_in", "Insufficient inputs");
provider.add("gtceu.recipe_logic.failure_reason.insufficient_out", "Insufficient outputs");
provider.add("gtceu.recipe_logic.failure_reason.condition_fails", "Condition fails");
provider.add("gtceu.recipe_logic.failure_reason.no_contents", "Recipe has no contents");
provider.add("gtceu.recipe_logic.failure_reason.no_capabilities", "Machine has no I/O");

Do also edit all the uses of these

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, most of these don't seem to be used anywhere?

Comment on lines +25 to +29
provider.add("gtceu.recipe_modifier.default_fail", "Recipe Modifier Fail");
provider.add("gtceu.recipe_modifier.insufficient_voltage", "Voltage Tier Too Low");
provider.add("gtceu.recipe_modifier.insufficient_eu_to_start_fusion",
"Insufficient Energy to Initiate Fusion Reaction");
provider.add("gtceu.recipe_modifier.coil_temperature_too_low", "Coil Temperature Too Low");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
provider.add("gtceu.recipe_modifier.default_fail", "Recipe Modifier Fail");
provider.add("gtceu.recipe_modifier.insufficient_voltage", "Voltage Tier Too Low");
provider.add("gtceu.recipe_modifier.insufficient_eu_to_start_fusion",
"Insufficient Energy to Initiate Fusion Reaction");
provider.add("gtceu.recipe_modifier.coil_temperature_too_low", "Coil Temperature Too Low");
provider.add("gtceu.recipe_modifier.failure_reason.default_fail", "Recipe modifier failure");
provider.add("gtceu.recipe_modifier.failure_reason.insufficient_voltage", "Voltage too low");
provider.add("gtceu.recipe_modifier.failure_reason.insufficient_eu_to_start_fusion",
"Insufficient energy to initiate fusion reaction");
provider.add("gtceu.recipe_modifier.failure_reason.coil_temperature_too_low", "Coil temperature too low");

provider.add("gtceu.recipe_logic.insufficient_out", "Insufficient Outputs");
provider.add("gtceu.recipe_logic.condition_fails", "Condition Fails");
provider.add("gtceu.recipe_logic.no_contents", "Recipe has no Contents");
provider.add("gtceu.recipe_logic.no_capabilities", "Machine has no Capabilities");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
provider.add("gtceu.recipe_logic.no_capabilities", "Machine has no Capabilities");
provider.add("gtceu.recipe_logic.failure_reason.no_capabilities", "Machine has no %s capabilities");

Comment on lines +120 to +122
Component.translatable("gtceu.recipe_logic.no_capabilities")
.append(Component.literal(": "))
.append(Component.translatable(io.tooltip)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To match my suggested change in RecipeLogicLang:

Suggested change
Component.translatable("gtceu.recipe_logic.no_capabilities")
.append(Component.literal(": "))
.append(Component.translatable(io.tooltip)),
Component.translatable("gtceu.recipe_logic.failure_reason.no_capabilities", Component.translatable(io.tooltip)),

if (!reasons.isEmpty()) {
textList.add(Component.translatable("gtceu.recipe_logic.setup_fail").withStyle(ChatFormatting.RED));
for (var reason : reasons) {
textList.add(Component.literal(" - " + reason.getString()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't use getString and string concatenation to join components, as you'll lose all formatting information by doing that.

Suggested change
textList.add(Component.literal(" - " + reason.getString()));
textList.add(Component.literal(" - ").append(reason));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1.20.1 Release: Major - 0.X.0 Releases focused on Content, changes to gameplay; While maintaining mostly API stability. type: feature New feature or request bundled for a 0.X.0 Update

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants