Skip to content

Conversation

@TarLaboratories
Copy link
Contributor

@TarLaboratories TarLaboratories commented Sep 7, 2025

What

Spoilage yay!
Added API to modify item outputs and read item inputs in recipe modifiers.
Also made an event that fires just before a machine is registered to allow modifying it's parameters from addons (most notably add recipe modifiers)

Implementation Details

Stores the creation tick of a spoilable item in its nbt, thus bypassing the need to actively tick it.
Should be noted that the item has to be updated at least once after it finished crafting for it to start spoiling (done by updating items inserted into CustomItemStackHandler)
Basically everything is done via a mixin into ItemStack lols
Doesn't actually make any items spoilable, only adds the functionality to do so.

Outcome

GLEBA

@TarLaboratories TarLaboratories requested a review from a team as a code owner September 7, 2025 11:37
@TarLaboratories TarLaboratories added type: feature New feature or request bundled for a 0.X.0 Update 1.20.1 Release: Major - 0.X.0 Releases focused on Content, changes to gameplay; While maintaining mostly API stability. labels Sep 7, 2025
@github-actions github-actions bot added the Tests: Failed Game Tests have failed on this PR label Sep 7, 2025
@github-actions github-actions bot added Tests: Passed Game Tests have passed on this PR and removed Tests: Failed Game Tests have failed on this PR labels Sep 7, 2025
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.

Very quick review before I have to go do other things, these are my initial thoughts

Comment on lines 137 to 154
@Inject(at = @At("HEAD"), method = "isSameItemSameTags", cancellable = true)
private static void mergeSpoilables(ItemStack stack, ItemStack other, CallbackInfoReturnable<Boolean> cir) {
CompoundTag tag1 = stack.getTagElement("GTCEu_spoilable");
CompoundTag tag2 = other.getTagElement("GTCEu_spoilable");
boolean isSameItem = ItemStack.isSameItem(stack, other) && stack.areCapsCompatible(other);
if (tag1 != null && tag2 != null) {
long tick1 = tag1.getLong("creation_tick");
long tick2 = tag2.getLong("creation_tick");
if (tick1 != tick2) {
long avg = (tick1 * stack.getCount() + tick2 * other.getCount()) /
(stack.getCount() + other.getCount());
tag1.putLong("creation_tick", avg);
tag2.putLong("creation_tick", avg);
}
}
cir.setReturnValue(isSameItem && Objects.equals(stack.getTag(), other.getTag()));
cir.cancel();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this done in isSameItemSameTags? Now, when we e.g. compare two itemstacks for recipe checking but the recipe can't run, it will still assign the average spoil value

Copy link
Contributor

Choose a reason for hiding this comment

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

To be fair, it's very difficult to know when to merge spoilability status and items don't really have a "merge" function. I'm not sure how we would implement this

@jurrejelle
Copy link
Contributor

Some thoughts I had laid out in the discord, ramble style, that I'd like to document here:

  1. The thing with isItemStackEqual being used as a "merge" check when there might be a case that we're just checking without merging, although I have no clue how to solve that, any ideas welcome
  2. The fact that we have to deeply modify GTRecipe and NotifiableItemStackHandler means our API isn't flexible enough to do these things without. Ideally, when implementing content features, we setup API and then use said API instead of messing with internals. Probably this can be done as a RecipeModifier and then we add API to attach to existing machines? then use a new or existing forge event to let users modify all machines to attach the new RecipeModifier? More input needed. But we definitely should do / be able to do this with public API, otherwise we should improve the API until we can.
  3. The fact that when things spoil, the item just gets turned in the spot. Gameplay wise you'd hope it'd get put somewhere else like in the output bus, or at least it's possible to extract them (which is impossible with input busses since the items are inaccessable)
  4. I'm a little worried at the overhead of checking/updating the state at each of the following: method = { "getItem", "getCount", "getTag", "getOrCreateTag", "getTagElement", "getOrCreateTagElement","getItemHolder" }. Maybe we can profile that or have others look at the method when reviewing
  5. (tiny thought) Injecting into ItemStack this heavily might break compatibility with other mods, not 100% sure, I'm not super well known on mixins
  6. With how many internal methods this touches I would not be comfortable having this in this release cycle without it being in testing / snapshot for a while, although that might be mitigated with the "testing release" that we're planning. More input needed by others too

@jurrejelle jurrejelle added Release: API - X.0.0 Major Breaking Refactors that MUST be in a API-Breaking Release and removed Release: Major - 0.X.0 Releases focused on Content, changes to gameplay; While maintaining mostly API stability. labels Sep 8, 2025
TarLaboratories and others added 2 commits November 17, 2025 10:36
Co-authored-by: screret <68943070+screret@users.noreply.github.com>
@github-actions github-actions bot added Tests: Failed Game Tests have failed on this PR and removed Tests: Passed Game Tests have passed on this PR labels Nov 17, 2025
@github-actions github-actions bot added Tests: Passed Game Tests have passed on this PR and removed Tests: Failed Game Tests have failed on this PR labels Nov 17, 2025
@TarLaboratories TarLaboratories changed the base branch from 1.20.1 to 1.20.1-v8.0.0 December 13, 2025 05:42
@github-actions github-actions bot added Tests: Failed Game Tests have failed on this PR and removed Tests: Passed Game Tests have passed on this PR labels Dec 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1.20.1 Release: API - X.0.0 Major Breaking Refactors that MUST be in a API-Breaking Release Tests: Failed Game Tests have failed on this PR 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.

5 participants