Using an item
Verified against Minecraft 26.3 · Part VII · A player holds the use key on a piece of cooked beef, then holds it on a bow — one countdown, two endings.
You hold the use button on cooked beef and thirty-two ticks later you have
eaten it. You hold the same button on a bow and nothing happens at all until
you let go. These are the same machine: Item.use starts both,
LivingEntity.useItemRemaining counts down on the client and the server
for both, ItemStack.onUseTick runs every tick on both sides, and
LivingEntity.stopUsingItem ends both. What differs is whether the countdown ever reaches zero, and in play only the
meal’s does: a meal is
thirty-two ticks long and a bow is set to 72000, an hour. And the client’s
countdown does not stop at zero on either. The meal ends because one byte
arrives from the server — a ClientboundEntityEventPacket carrying
EntityEvent.USE_ITEM_COMPLETE, which is the byte 9, the number this page
uses for it from here on. The bow’s shot lives only in its release, so it is fired by a
ServerboundPlayerActionPacket instead: the same packet, carrying the
same action, that the meal would read as the player changed their mind.
The cast
| class | what it decides | thread |
|---|---|---|
Minecraft | which key edge starts a use, and which one ends it | Render |
MultiPlayerGameMode | the client’s own copy of the use, and the packet that reports it | Render |
ServerGamePacketListenerImpl | which handler each packet reaches, and whether the rotation is snapped first | Server |
LivingEntity | the countdown, the synched flags, and both endings | both |
ItemStack | the dispatch into the item, and the after-use side effects | both |
Item | Item.use, Item.getUseDuration, Item.releaseUsing, Item.useOnRelease | both |
Consumable | everything the meal does, on both sides | both |
ProjectileWeaponItem | ammo, spread and the arrow — the counting on both sides, the spawning only on the server | both, but only the server’s counts |
The block-target branch of a use — right-clicking a chest rather than the
air — leaves at MultiPlayerGameMode.useItemOn and belongs to
block interaction;
the stack itself is items and
stacks.
The two paths, side by side
| the meal | the bow | |
|---|---|---|
what Item.use does | the default body finds DataComponents.CONSUMABLE and calls Consumable.startConsuming | BowItem.use overrides it, checks Player.getProjectile, calls LivingEntity.startUsingItem |
| the refusal | Consumable.canConsume asks Player.canEat, for food only | no arrow anywhere and no infinite materials — InteractionResult.FAIL |
Item.getUseDuration | Consumable.consumeTicks, 32 for Consumables.DEFAULT_FOOD | 72000 — an hour, and BowItem’s own override |
what ItemStack.onUseTick does | particles and the chew sound, on both sides | nothing — BowItem does not override Item.onUseTick |
| how it ends | the count reaches zero on the server | the use key comes up on the client |
| the packet that ends it | ClientboundEntityEventPacket, downward | ServerboundPlayerActionPacket, upward |
| is the ending answered | yes — that is the answer | no, nothing answers a release |
Item.releaseUsing | not overridden, returns false, so letting go simply abandons the meal | BowItem.releaseUsing is where the whole shot lives |
ItemStack.useOnRelease | false | also false |
| what the client predicts | the start and every tick of the meal, then the ending replayed when event 9 arrives | the animation, and the release on its own copy, which shoots nothing |
ItemStack.useOnRelease is not the row that decides it
The ItemStack.useOnRelease row is the one that looks wrong. It is the
obvious name for “this item is finished by letting go” — but it only
delegates, and the hook it
delegates to, Item.useOnRelease, has exactly one override in the tree,
CrossbowItem’s. The bow and the trident take the default false. They are
release-ended not because a predicate says so, but because their
Item.getUseDuration is an hour long and their Item.releaseUsing does the
work. The spyglass takes the default too and is not release-ended at all: at
1200 ticks its countdown really can run out.
What the meal’s component holds, and what it does not
Consumable (DataComponents.CONSUMABLE) is the component the meal column
hangs off, and it holds the whole of the use half: Consumable.consumeSeconds,
with Consumable.consumeTicks derived from it; the ItemUseAnimation the
arm plays; the sound; the particles; and a list of ConsumeEffects to apply
at the end — ApplyStatusEffectsConsumeEffect,
RemoveStatusEffectsConsumeEffect, ClearAllStatusEffectsConsumeEffect,
TeleportRandomlyConsumeEffect and PlaySoundConsumeEffect, whose types are registered in
BuiltInRegistries.CONSUME_EFFECT_TYPE. What it does not hold is what the
food is worth, which is a second component and Part VIII’s (hunger and
experience).
Where the hour comes from
Duration is one base method and eight overrides. Item.getUseDuration’s base
body reads Consumable.consumeTicks off the stack if there is a Consumable
on it, and otherwise answers the hour for anything carrying
DataComponents.BLOCKS_ATTACKS or DataComponents.KINETIC_WEAPON — so a
shield and a spear get their long draw from the base method and no override of
their own. BowItem, CrossbowItem and TridentItem override it to return
the same 72000, the number Item.APPROXIMATELY_INFINITE_USE_DURATION names. At the other end EnderEyeItem returns
zero, which makes it the one item in the game whose use is instant by
declaration rather than by having no Consumable at all. The remaining four
overrides are ordinary finite numbers: the spyglass’s 1200, two hundred each
for BrushItem and BundleItem, and InstrumentItem’s, which is the goat
horn’s own sounded length in ticks.
Starting: the client finishes before it speaks
Minecraft.handleKeybinds sees the press and calls Minecraft.startUseItem,
which sets the four-tick Minecraft.rightClickDelay itself, refuses while
LocalPlayer.isHandsBusy, and walks both hands for a target. With nothing
under the crosshair it reaches MultiPlayerGameMode.useItem, which, once any
pending hotbar change has been sent, opens a prediction window
(MultiPlayerGameMode.startPrediction,
prediction and acks) and does the rest
inside it: it builds the ServerboundUseItemPacket — hand, sequence
number and both rotations — then consults the client’s own ItemCooldowns,
and runs ItemStack.use locally first only if the item is off cooldown.
The packet goes up either way; the cooldown suppresses the prediction, not the
report of it. The prediction is complete before the use packet leaves the client, for
the meal and the bow alike. Both answer InteractionResult.CONSUME, whose
InteractionResult.SwingSource.NONE is why neither swings the arm, although
FirstPersonHandsAndItems.itemUsed still runs — the small dip the item makes as
the use begins. An instant use, one whose ItemStack.getUseDuration is
zero, returns its outcome the other way instead, through
InteractionResult.Success.heldItemTransformedTo, which both game modes
unwrap and write back into the hand.
On the server, ServerGamePacketListenerImpl.handleUseItem acknowledges the
sequence number, snaps the player’s rotation to the one in the packet,
and calls ServerPlayerGameMode.useItem. That snap is what makes the
release strange later, because the release packet does no such thing. And
ServerPlayerGameMode.useItem ends on a deliberate omission: it normally
re-sends the player’s inventory with
AbstractContainerMenu.sendAllDataToRemote
(containers and
menus), but not when the use it
just ran started a multi-tick one. While you are eating or drawing, the
server declines to correct your inventory.
While it runs: the flag on the wire and the flag the client believes
LivingEntity.startUsingItem writes two bits of
LivingEntity.DATA_LIVING_ENTITY_FLAGS
(synched entity
data) — bit one for
using, bit two assigned the hand, so a main-hand use clears it — and
only on the server. LivingEntity.isUsingItem and
LivingEntity.getUsedItemHand read those bits, which is how every other
client knows your arm is up.
Your own client does not read them. LocalPlayer.isUsingItem overrides the
base and returns a private local flag set by LocalPlayer.startUsingItem;
LocalPlayer.getUsedItemHand likewise answers from a local field.
Reconciliation happens afterwards, in both directions:
LocalPlayer.onSyncedDataUpdated compares the arriving bits with the local
flag and will start a use the client never predicted, or stop one it did.
The base LivingEntity.onSyncedDataUpdated makes the matching repair on
every other entity’s copy — it adopts the held stack and re-derives
LivingEntity.useItemRemaining from ItemStack.getUseDuration, which is why
a remote player drawing a bow animates correctly although your client never
saw the press.
One abandonment rule is shared, and it lives a level above the countdown.
LivingEntity.tick calls the private LivingEntity.updatingUsingItem,
which compares the hand’s current stack with the remembered one using
ItemStack.isSameItem and calls LivingEntity.stopUsingItem if they
differ; only on a match does it call LivingEntity.updateUsingItem, the
countdown proper. The comparison is item identity, not components, so
swapping a bowl for a stew aborts the meal while a durability tick on the
bow does not abort the draw.
Every tick, and what the bow does instead
LivingEntity.updateUsingItem offers ItemStack.onUseTick the count
before it decrements, so on the server a thirty-two-tick meal is offered 32
down to 1 and never 0; the client, waiting for its byte, goes on to 0 and
below. For the meal that one call is the whole visible experience:
Consumable.shouldEmitParticlesAndSounds is true once more than
Consumable.CONSUME_EFFECTS_START_FRACTION of the duration has elapsed and
the remaining count is a multiple of Consumable.CONSUME_EFFECTS_INTERVAL,
and Consumable.emitParticlesAndSounds then spawns five item particles
through LivingEntity.spawnItemParticles — behind
Consumable.hasConsumeParticles, which drinks turn off — and plays the chew
sound, which they do not. Level.addParticle does nothing on the server, so
the crumbs are pure client simulation.
For the bow the call does nothing whatever: BowItem does not override
Item.onUseTick, and the base body is empty. Everything you see while
drawing is the renderer reading the same counter the logic is decrementing.
FirstPersonHandsAndItemsRenderer computes the draw curve for
ItemUseAnimation.BOW from a per-frame copy of
LivingEntity.getUseItemRemainingTicks, and the three-stage bow texture is
not code at all: items/bow.json is a condition on using_item wrapping
a range_dispatch on the use_duration property (UseDuration), scaled so
its thresholds are fractions of BowItem.MAX_DRAW_DURATION.
The crossbow is the exception that makes the rule legible. It does
override Item.onUseTick, and that body is entirely server-side: it plays
the start, middle and end sounds a CrossbowItem.ChargingSounds holds (Quick
Charge’s has no middle) at fixed fractions of
CrossbowItem.getChargeDuration and, on reaching one, writes
DataComponents.CHARGED_PROJECTILES onto the stack. Its client half is a
Render-thread computation — CrossbowPull and FirstPersonHandsAndItems both
call CrossbowItem.getChargeDuration, which calls
EnchantmentHelper.modifyCrossbowChargingTime
(enchantments
owns the two enchantment values a client is allowed to compute). An
enchantment hook, evaluated on the Render thread every frame, to pose an arm and
pick one of three textures.
Moving while you use
Neither path slows you through movement code — both read one component.
LocalPlayer.modifyInput scales the movement input by
LocalPlayer.itemUseSpeedMultiplier, which reads
UseEffects.speedMultiplier off the stack, unless the player is riding, and
LocalPlayer.isSlowDueToUsingItem blocks sprinting because
UseEffects.canSprint is false. The number is a multiplier and not a
subtraction: UseEffects.DEFAULT carries 0.2, so the input is scaled to a
fifth of what you pressed. That default sits in
DataComponents.COMMON_ITEM_COMPONENTS, so every item has one — and neither
cooked beef nor the bow overrides it, which is why drawing a bow slows you
by exactly as much as eating does, through exactly the same field.
Item.Properties.spear is the definition that overrides it outright, with a
UseEffects that permits sprinting, suppresses vibrations and multiplies
speed by one; the hits that use makes need no packet at all, coming from the
server’s use tick itself (the spear).
The component’s remaining field is not about movement at all, and it is the half
that runs on the server. UseEffects.interactVibrations is what
ItemStack.causeUseVibration consults before letting a use emit a game
event, so an item whose component clears the flag starts and finishes
silently as far as a sculk sensor is concerned. LivingEntity calls it at
both ends of a use — GameEvent.ITEM_INTERACT_START when the timer opens and
GameEvent.ITEM_INTERACT_FINISH when it closes — and FishingRodItem and
BoneMealItem call it for themselves, because neither ends through the use
timer (game events and
vibrations).
The two endings
There are two, and they are separate machines that share a last step. The first is the countdown reaching zero, which is the meal.
flowchart TD
T["LivingEntity.updateUsingItem, both sides, every tick"]
T --> A["ItemStack.onUseTick, with the count before the decrement"]
A --> B["decrement LivingEntity.useItemRemaining"]
B --> C{"reached zero"}
C -- no --> T
C -- yes --> D{"on the server"}
D -- "no, this is the client" --> W["keep counting into the negatives and wait"]:::client
D -- yes --> E{"ItemStack.useOnRelease"}
E -- "true, a crossbow" --> T
E -- "false, everything else" --> F["LivingEntity.completeUsingItem"]:::server
F --> G["ServerPlayer.completeUsingItem sends ClientboundEntityEventPacket 9 first"]:::server
G --> H["ItemStack.finishUsingItem, then LivingEntity.stopUsingItem"]:::server
G -. "the byte lands" .-> X["Player.handleEntityEvent replays LivingEntity.completeUsingItem"]:::client
W --> X
The client’s arm of the branch reaches nothing on its own. The dotted edge is the whole of what ends a meal on the client — a byte from the server, arriving at a branch that was otherwise waiting for ever.
The second is the key coming up, which is the bow, and nothing in it waits for a reply at all.
flowchart TD
R["the use key comes up, Minecraft.handleKeybinds"]:::client
R --> S["MultiPlayerGameMode.releaseUsingItem sends RELEASE_USE_ITEM"]:::client
S --> P["ServerGamePacketListenerImpl.handlePlayerAction, no ack, no sequence"]:::server
S --> Q2["LivingEntity.releaseUsingItem on the client's own copy"]:::client
P --> Q["LivingEntity.releaseUsingItem on the server's"]:::server
Q --> K["ItemStack.releaseUsing, then LivingEntity.stopUsingItem either way"]
Q2 --> K
K -- "Item.releaseUsing returned true" --> L["the shot, then the after-use side effects"]
K -- "returned false" --> M["the meal is simply abandoned"]
One method run twice, once per copy, and the split at the top is the
point — the client releases locally without waiting, and only the server’s
run reaches a ServerLevel and so an arrow.
The client’s branch has no exit. Nothing on the client ever reaches
LivingEntity.completeUsingItem from the countdown — it is called from
Player.handleEntityEvent when event 9 arrives, and nowhere else on that
side. The counter meanwhile keeps falling past zero and only the renderer
notices: FirstPersonHandsAndItemsRenderer draws a use pose solely while
LivingEntity.getUseItemRemainingTicks is positive, so the arm drops at
tick 32 whether or not the packet has landed.
And ItemStack.useOnRelease does not mean “ends on release”. It means
do not let the countdown finish this, and give it one more tick when the
key comes up: LivingEntity.releaseUsingItem calls
LivingEntity.updatingUsingItem again when it is true, so a crossbow gets a
final CrossbowItem.onUseTick in which it can still latch the charge. No
other item asks for that. Release is also not only a key-up: besides the
client’s and the server’s key-up paths, LivingEntity.releaseUsingItem is
called from five other places — once by LivingEntity.completeUsingItem
itself, when the stack turned out not to match the hand; once each by
CrossbowAttack and RangedCrossbowAttackGoal, which is how a piglin and a pillager finish loading; and twice by BrushItem.onUseTick, which ends its own use from inside
the tick.
The meal, tick by tick
The whole of it is one press, thirty-one ticks in which the meal sends its eater nothing, and one byte, and the three bands below are those three.
sequenceDiagram
participant LP as LocalPlayer
participant MPGM as MultiPlayer<br/>GameMode
participant Wire as the network
participant SGPL as ServerGamePacket<br/>ListenerImpl
participant SP as ServerPlayer
participant Cons as Consumable
rect rgba(0, 0, 0, 0.04)
Note over LP,Cons: tick 0, the press
MPGM->>Cons: startConsuming, reached from Minecraft.startUseItem through Item.use
Cons->>LP: startUsingItem, once canConsume has asked Player.canEat
MPGM->>Wire: ServerboundUseItemPacket, hand and sequence and both rotations
Wire->>SGPL: handleUseItem acks the sequence and snaps the rotation
SGPL->>SP: the same Item.use, remaining = 32, the two flag bits written
end
rect rgba(0, 0, 0, 0.04)
Note over LP,Cons: ticks 1 to 31, both sides
LP->>LP: ItemStack.onUseTick, particles and the chew sound once the delay is past
SP->>SP: the same call, particles discarded, sound broadcast to everyone else
end
rect rgba(0, 0, 0, 0.04)
Note over LP,Cons: tick 32, the count at zero, and only the server ending it
SP->>Wire: ClientboundEntityEventPacket, EntityEvent.USE_ITEM_COMPLETE
SP->>Cons: Consumable.onConsume, from ItemStack.finishUsingItem, FoodData.eat inside it
Wire->>LP: handleEntityEvent replays LivingEntity.completeUsingItem locally
SP->>Wire: ClientboundSetHealthPacket, same tick, overwrites the prediction
end
Note over Wire,SP: a later tick: AbstractContainerMenu.broadcastChanges corrects the count
Three bands, and the count reaches zero in only one of them. Watch the third — the client is told the meal is over by a single byte, and its own countdown had nothing to do with it.
The stack’s own count is the last thing to agree: the menu’s
AbstractContainerMenu.broadcastChanges corrects it a tick or more later,
which is a container’s business rather than the meal’s.
The replay is the interesting half. Consumable.onConsume runs on both
sides and three parts of it do not: the Stats.ITEM_USED award and
CriteriaTriggers.CONSUME_ITEM need a ServerPlayer, the ConsumeEffects
in Consumable.onConsumeEffects sit behind a server-side guard, and
GameEvent.EAT is a no-op because ClientLevel.gameEvent has an empty
body. Particles, sound, the ConsumableListener walk that finds
FoodProperties, and the ItemStack.consume shrink all run on both — and
every one of those client mutations is then overwritten. That is why a
chorus fruit’s teleport is never predicted while the hunger bar’s jump is
(hunger and
experience).
One meal, two exactly-once sound strategies. The chew sound goes through
Player.playSound, which on the server names the eater as the entity to exclude, so the
server broadcasts it to everyone else; on the eater’s client LocalPlayer.playSound plays it
locally without the test. The FoodProperties eat and burp sounds pass no exclusion at all —
and ClientLevel.playSeededSound plays a sound only when the excluded
entity is the local player — so those reach the eater as the server’s
broadcast alone.
The bow, tick by tick
The same lanes, the same opening, and then a release that nobody waits for.
sequenceDiagram
participant LP as LocalPlayer
participant MPGM as MultiPlayer<br/>GameMode
participant Wire as the network
participant SGPL as ServerGamePacket<br/>ListenerImpl
participant SP as ServerPlayer
rect rgba(0, 0, 0, 0.04)
Note over LP,SP: tick 0, the press
MPGM->>LP: startUsingItem, remaining = 72000, once BowItem.use has a projectile
MPGM->>Wire: ServerboundUseItemPacket, hand and sequence and both rotations
Wire->>SGPL: handleUseItem acks the sequence and snaps the rotation
SGPL->>SP: startUsingItem too, remaining = 72000, the two flag bits written
end
rect rgba(0, 0, 0, 0.04)
Note over LP,SP: every tick after that, both sides
LP->>LP: the count falls, onUseTick is empty, the model reads the use duration
SP->>SP: the count falls, and only the using-item trigger fires
end
rect rgba(0, 0, 0, 0.04)
Note over LP,SP: the tick the key comes up
MPGM->>Wire: ServerboundPlayerActionPacket, RELEASE_USE_ITEM, sequence zero
MPGM->>LP: releaseUsingItem, and BowItem.releaseUsing on the client's copy
LP->>LP: no ServerLevel, so a phantom stack, no ammo, no arrow, then stopUsingItem
Wire->>SGPL: handlePlayerAction, with whatever rotation the server last heard
SGPL->>SP: releaseUsingItem, the identical call on the server's copy
SP->>SP: BowItem.releaseUsing, then<br/>ProjectileWeaponItem.<br/>draw and shoot
SP->>Wire: Projectile.spawnProjectile, then the add-entity packet
SGPL-->>MPGM: nothing acknowledges the release itself
end
Note over Wire,SP: a later tick: the container sync corrects the arrows and the damage
The same method twice, once per copy — the two self-messages in the
third band are BowItem.releaseUsing on each machine, and only the lower one
has a ServerLevel to shoot into. The dashed line is the only reply, and it
is empty.
BowItem.releaseUsing runs on both sides and gets nowhere on one of them.
It measures the draw as BowItem.getUseDuration minus the remaining count,
puts it through BowItem.getPowerForTime — a curve on the draw time in
seconds, clamped at one after BowItem.MAX_DRAW_DURATION ticks — and
returns false below a tenth of full power, which is why a tap of the button
neither shoots nor costs durability. Above it, ProjectileWeaponItem.draw
decides how many arrows leave the string
(EnchantmentHelper.processProjectileCount) and
ProjectileWeaponItem.useAmmo decides whether an arrow is spent
(EnchantmentHelper.processAmmoUse). Both consult a ServerLevel and fall
back to one and zero otherwise, and ProjectileWeaponItem.shoot is itself
inside a ServerLevel test — so on the client the draw produces a single
phantom arrow marked DataComponents.INTANGIBLE_PROJECTILE, spends nothing
and shoots nothing.
On the server it is six enchantment hooks and one ordering worth
remembering. Two have already run inside ProjectileWeaponItem.draw; the
third, EnchantmentHelper.processProjectileSpread, fans a multishot
volley, and each arrow is aimed by BowItem.shootProjectile through
Projectile.shootFromRotation using the server’s rotation — which the
release packet never updated, so the shot goes where the last movement
packet said you were looking. Projectile.spawnProjectile aims, adds the
entity to the level, and only afterwards calls
Projectile.applyOnProjectileSpawned, which runs
EnchantmentHelper.onProjectileSpawned twice when ammo and weapon are
different items: once for the arrow’s stack and once for the bow’s. The fifth
is out of sight in the arrow itself — the AbstractArrow constructor asks
EnchantmentHelper.getPiercingCount off the weapon it was fired from
(enchantments).
ItemStack.hurtAndBreak takes the durability after each arrow, through the
sixth, EnchantmentHelper.processDurabilityChange, and the volley breaks off
if the bow dies mid-flight.
Only when Item.releaseUsing returns true does ItemStack.releaseUsing run
ItemStack.applyAfterUseComponentSideEffects — the same private step
ItemStack.finishUsingItem runs for the meal, converting
DataComponents.USE_REMAINDER into the empty bowl and starting
DataComponents.USE_COOLDOWN. (For an instant use it runs from
ItemStack.use instead, and only for a zero-duration success.) Cooldowns
are grouped rather than per-item: ItemCooldowns.getCooldownGroup returns
UseCooldown.cooldownGroup when the component names one and the item’s
Identifier otherwise, both sides own an ItemCooldowns — the client’s is
a real prediction, consulted before it will even predict a use — and
ServerItemCooldowns.onCooldownStarted mirrors the server’s as one
ClientboundCooldownPacket naming a group.
What the ending never carries
The release is the least-answered packet in the pipeline.
ServerGamePacketListenerImpl.handlePlayerAction treats
ServerboundPlayerActionPacket.Action.RELEASE_USE_ITEM in one line — call
LivingEntity.releaseUsingItem, return — with no ack, no sequence number
consumed, not even a spectator check. Everything the client learns about its
own shot arrives as ordinary world traffic. The arrow is the quick one: adding
it to the level starts its tracking inside the same call, so the spawn packet
leaves on that tick. The spent ammo and the bow’s damage wait for a container
slot update (containers and
menus) and the cleared
using-flag for entity data it has already acted on, both a tick or more
later. The shoot sound is broadcast with no
exclusion, so — by the same rule as the burp — the shooter hears the
server’s copy and never their own.
The completion is barely richer. There is no you ate this packet: event 9
tells the client to re-derive the outcome from components it already holds,
and ClientboundSetHealthPacket corrects the hunger it got wrong, the
container sync the count. The single
override of Item.finishUsingItem in the whole tree is
SpyglassItem.finishUsingItem, which plays a sound — the spyglass being the
one item whose completion is worth a sound of its own.
That override is reached only by the countdown running out, all 1200 ticks of
it. Letting go takes the other door: SpyglassItem also overrides
Item.releaseUsing — the fourth and last override of it in the tree, after
the bow, the crossbow and the trident — plays the same sound there through the same private SpyglassItem.stopUsing,
and returns true. So the spyglass gets its sound either way, through two
overrides that meet only in that helper. That is the last thing this page has to say about the
two endings: they are not one path with a switch on it. They are two.
For a 1.21-era reader. There is no bow-pull item property class left to hunt for. The old pulling / pull pair is now the shared
UseDurationrange-select property plus a using_item condition, both declared in the item’s JSON. The crossbow keeps a bespoke property,CrossbowPull, only because its denominator is enchantable. ItemInHandRenderer is gone;FirstPersonHandsAndItemsandFirstPersonHandsAndItemsRendererdo its work.
Where to look
LivingEntity is the whole machine, and four of its methods in this order are
the page: LivingEntity.startUsingItem, the private
LivingEntity.updatingUsingItem that decides whether to keep going,
LivingEntity.updateUsingItem that counts, and LivingEntity.releaseUsingItem
for the other ending. LivingEntity.completeUsingItem beside them is the one
the client never reaches from its own countdown.
For where a use begins, read down: Minecraft.startUseItem, then
MultiPlayerGameMode.useItem for the prediction window, then
ServerGamePacketListenerImpl.handleUseItem for the rotation snap, then
ServerPlayerGameMode.useItem for the inventory re-send it declines to do.
ItemStack.use is where both sides dispatch into the item.
Consumable is the meal in one class. BowItem is the bow, and
ProjectileWeaponItem above it holds the two methods that decide how many
arrows leave and whether any is spent; CrossbowItem is the one ranged
weapon that uses the tick hook and the one item that sets
ItemStack.useOnRelease. UseEffects shapes the use while it runs and UseCooldown outlives it, and FirstPersonHandsAndItems and
FirstPersonHandsAndItemsRenderer between them are everything you see.
Rules: names, never code · how the system works, not how the code reads ·
newest version only · every backticked name passes tools/verify_names.py.