…er hand check, look up Hand Pick state once
A one-hour Main spark profile at 60 players put SketchService.stampKitsLater
at 8.0 s, TrackerService.pulse at 3.6 s and the Hand Pick HUD pass at 8.6 s
of main-thread time. These changes keep every result the same.
- Sketch kits: markUnstackable checks the item type before copying
metadata (only a filled map has MapMeta); stampInstructions matches a
stack only against a vanilla sheet or pencil, since pack supplies never
get Archaeo lore; several stampKitsLater calls for one player in one
tick scan the bag once, in the newest request.
- Tracker: holdingTracker remembers both hand stacks and the answer, and
matches again when a stack changes (ItemStack equality), after 20
ticks, on reload, or when the pack-plugin matcher is rebound.
- ItemMatcher: the MMOItems id is read only when the type already fits;
type and id are separate reads of the item data.
- Hand Pick: the per-player shortcut state is looked up once per player
per tick and passed to the held-tool match and the mining-lock steps.
The per-tick action-bar send is unchanged: MMOCore redraws its own bar
and Archaeo does not reserve it, so sending less often could let that
bar show through.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Summary
Performance-only fixes for three hot spots in a one-hour Main spark profile at 60 players (72,000 ms/h = 1 ms per tick). Nothing a player sees or does changes.
SketchService.stampKitsLaterunstackCarriedcopied the metadata of every carried item (CraftItemStack.getItemMeta, 5.7 s);stampAllasked the pack plugins about every item (ItemMatcher, 1.6 s)TrackerService.pulseholdingTrackerread both hands' item data through MMOItems for every player on every pulse (3.0 s)HandPickService.tick→syncAndShowHudheldTool2.1 s (DigTools.match0.8 s,state()lookup 0.5 s),aimedNearSite0.85 sWhat changed
Sketch kit pass
markUnstackablechecks the item type first. Only a filled map hasMapMeta, so every other item is skipped without copying its metadata. Filled maps, sketch or not, are handled exactly as before.stampInstructionsonly matches a stack againstsketch.paper/sketch.pencilwhen that entry is a vanilla item. A pack sheet or pencil never gets Archaeo lore (that was already the rule, checked last), so the pack plugin is no longer asked about every item in the bag first.stampKitsLatercalls for one player in the same tick (a pile of drops picked up, a click and a close, fast hotbar scrolling) now scan the bag once. Each call still queues its task; only the newest one for that player does the work, and it runs at the same point as before.Tracker
holdingTrackerremembers each player's two hand stacks and the answer. It matches again only when a stack changes (ItemStack equality against stored copies, so wear, renames and data changes count), after 20 ticks, on/archaeo reload, or when the pack-plugin matcher is rebound. This is the same approachHandPickService.heldToolalready uses.ItemMatcher.matchesMmoItemsreads the MMOItems id only when the type already fits. Type and id are two separate reads of the item data; the answer is the same. This also helps the Hand Pick whitelist match and every other MMOItems check.Hand Pick HUD
heldTool,keepVanillaMineUnlockedandsetVanillaMineLocked, instead of once in each.matchesMmoItemschange above.Not changed, and why
ActionBarHandler, so sending less often would let the MMOCore bar show through. The cost is inside the send itself, so reusing the text or the component object would save nothing. Two options exist but both change behaviour and need a Dev check, so they are left for a separate PR: sending through Paper'ssendActionBar(cheaper, but it is a different packet:action_barinstead of overlaysystem_chat), or reserving the bar through MythicLib and sending only when the text changes.aimedNearSite/hasEstablishedIn. The site status is read live on purpose; remembering the answer per player would not be exact.Behaviour notes
Tests
mvn -B clean verifyon Windows: 825 tests, 2 skipped, 3 failures. The 3 failures are theSiteEstatesTestcases that also fail on unmodifiedmainon Windows (they look forownership/journalswith a forward slash in a Windows path); I ran that class on a clean copy oforigin/mainto confirm. With that class left out, the other 797 tests pass and the jar builds. Linux CI is authoritative.TrackerServiceTest: the hands are matched once per pair, again after 20 ticks, at once on any stack change (new item, same type with different data, item removed), and afteritemChanged,setSettingsandstop.SketchServiceTest: three kit requests in one tick scan the bag once and still stamp the lore; later ticks and other players get their own pass;unstackCarriednever copies the metadata of a non-map item and still caps a plain filled map at one per slot.SketchSuppliesTest: pack-configured supplies are never matched during a bag scan; a vanilla sheet next to a pack pencil is still matched.ItemMatcherPackIT(optionalpack-api-testsprofile, run locally against the ItemsAdder, FastNbt, MMOItems and MythicLib jars: 10 + 7 tests pass): a stack without an MMOItems type is not asked for its id.Test plan
/archaeo reloadwhile holding it keeps it workinggetItemMetagone fromstampKitsLater,matchesMmoItemsgone fromTrackerService.pulse🤖 Generated with Claude Code