Test scaffolding: client-side Lunge saturation prediction - #456
Open
MrPlankton611 wants to merge 8 commits into
Open
Test scaffolding: client-side Lunge saturation prediction#456MrPlankton611 wants to merge 8 commits into
MrPlankton611 wants to merge 8 commits into
Conversation
…r tick Syncing was driven by a mixin injected at the head of ServerPlayerEntity#tick, which other mods (e.g. spear lunge attacks, attribute swaps) can skip by cancelling that same tick method to freeze movement during their own logic. Drive the sync from ServerTickEvents.END_WORLD_TICK instead, which always fires directly from the server tick loop regardless of what happens in any individual player's tick method.
Renders a second saturation bar predicting the cost of a Lunge jab from client-local state alone, to compare against the real server-synced bar before attempting anything like this on servers that don't run AppleSkin. Not a real feature yet - remove once validated.
AttackEntityCallback only fires when the attack connects with an entity, but piercing weapons (spears) dispatch their jab through ClientPlayerInteractionManager#attackWithPiercingWeapon unconditionally, whether or not it hits anything. Movement-only lunges (no target) never triggered the old hook, which is why the predicted bar never moved in practice on a PvP server where lunges are mostly used for repositioning. Hook the piercing-attack dispatch directly instead via MinecraftClientMixin.
doAttack() returns boolean, and Mixin requires CallbackInfoReturnable for injections into non-void methods - plain CallbackInfo fails mixin apply with "CallbackInfoReturnable is required", which is fatal since this mixin isn't optional and crashed the client on boot. Verified with a runClient smoke test that mixin application now succeeds.
Two compounding bugs: the grace-window design fell back to displaying the real saturation once it expired, but on a server without AppleSkin the real value is stale (only corrected by vanilla's combined health/food packet, which fires on damage, not on Lunge use). And each lunge computed its cost from the real value rather than the shadow, so it could never accumulate - it just dipped from whatever stale number "real" currently was and snapped back. Now the shadow value only resyncs when the real value actually changes, and each lunge subtracts from the shadow itself, so repeated lunges without an intervening correction now accumulate correctly.
The shadow value only ever predicted losses from Lunge, so eating a golden apple never credited it - it just stayed at whatever the last lunge left it at. Turns out food's actual restore is server-only too: ConsumableComponent #finishConsumption gates its onConsumeEffects behind !world.isClient(), so there's no client-side HungerManager.eat() call to piggyback on either. Hook ItemStack#finishUsing (which does run on the client) to detect when consumption completes, and predict the restore ourselves using the same FoodHelper query already used for the held-food preview overlay, mirroring HungerManager#addInternal's exact clamp order (food level first, then saturation clamped against the new food level).
Traced through the eating-doesn't-update-when-full report by hand and couldn't find the bug by inspection - every code path checks out on paper. Logging swing/eat/resync events with their actual values so the next reproduction can be diagnosed from real evidence instead of more guessing. Remove alongside the rest of this test scaffolding.
Author
|
This is all claude code btw, I just wanted to play around with it and it seems to be working. Just wanted your opinion on this. |
Root cause of "ate" never logging: LivingEntity#tickItemStackUsage only calls consumeItem() (which leads to ItemStack#finishUsing) when !world.isClient() - the natural "finished eating" completion is entirely server-only. ItemStack#finishUsing is simply never invoked on the client for a normal timed eat, so that mixin was targeting a dead end. itemUseTimeLeft ticks down identically on both sides though, so hook tickItemStackUsage directly and treat it hitting 0 for the local player as the completion signal. Removes the now-dead ItemStackMixin#onFinishUsing.
Author
|
I added a "prediction" saturation bar since that is the info that we don't get from the server above the actual hunger bar itself. It seems pretty accurate to me. I played a couple of spearmace games with it, and when that prediction bar runs out, the actual hunger bar starts depleting. I would love it if you could double-check it as well, but it seems good to me. |
Author
|
If the prediction bar seems good to you, ill move that logic into the actual hunger bar itself, that is just for testing and debugging. |
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.
Summary
Experimental client-only prediction of Lunge's saturation cost (and food's saturation restore), so the HUD can show a reasonable saturation estimate on servers that don't run AppleSkin server-side.
This is test scaffolding, not a finished feature - explicitly marked for removal/rework once validated:
MinecraftClientMixinhooking the piercing-weapon attack dispatch (works on swing, not just landed hits)ItemStackMixinhookingfinishUsing, since vanilla's actual restore (ConsumableComponent#finishConsumption) is gated server-only[LungeTest]prefix) added while chasing a bug where the eating-prediction hook doesn't appear to fire in practice - still openKnown issues
ItemStackMixin#onFinishUsing) has not been observed firing in real testing despite the call chain checking out by inspection; root cause still under investigationTest plan
runClientwith no mixin errors