Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

classwhat it decidesthread
Minecraftwhich key edge starts a use, and which one ends itRender
MultiPlayerGameModethe client’s own copy of the use, and the packet that reports itRender
ServerGamePacketListenerImplwhich handler each packet reaches, and whether the rotation is snapped firstServer
LivingEntitythe countdown, the synched flags, and both endingsboth
ItemStackthe dispatch into the item, and the after-use side effectsboth
ItemItem.use, Item.getUseDuration, Item.releaseUsing, Item.useOnReleaseboth
Consumableeverything the meal does, on both sidesboth
ProjectileWeaponItemammo, spread and the arrow — the counting on both sides, the spawning only on the serverboth, 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 mealthe bow
what Item.use doesthe default body finds DataComponents.CONSUMABLE and calls Consumable.startConsumingBowItem.use overrides it, checks Player.getProjectile, calls LivingEntity.startUsingItem
the refusalConsumable.canConsume asks Player.canEat, for food onlyno arrow anywhere and no infinite materials — InteractionResult.FAIL
Item.getUseDurationConsumable.consumeTicks, 32 for Consumables.DEFAULT_FOOD72000 — an hour, and BowItem’s own override
what ItemStack.onUseTick doesparticles and the chew sound, on both sidesnothing — BowItem does not override Item.onUseTick
how it endsthe count reaches zero on the serverthe use key comes up on the client
the packet that ends itClientboundEntityEventPacket, downwardServerboundPlayerActionPacket, upward
is the ending answeredyes — that is the answerno, nothing answers a release
Item.releaseUsingnot overridden, returns false, so letting go simply abandons the mealBowItem.releaseUsing is where the whole shot lives
ItemStack.useOnReleasefalsealso false
what the client predictsthe start and every tick of the meal, then the ending replayed when event 9 arrivesthe 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 UseDuration range-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; FirstPersonHandsAndItems and FirstPersonHandsAndItemsRenderer do 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.