RetailTooltipPresenter.UpdateWorldHoverTooltip only called RemovePopup()
on the found-object-LOST edge (found == 0u). An A->B found-object CHANGE
(walking past a run of NPCs/doors/lifestones with no intervening "nothing
found" frame) skipped straight to TryBuildAndMountPopup with the previous
popup still mounted as a child of _host -- only the _popupRoot reference
got overwritten, so every earlier popup was orphaned in the tree and never
removed. Matches the user's screenshot of 15+ stacked name boxes.
Fix: clear any showing world popup on ANY found-object edge -- change or
loss -- before evaluating whether to mount a new one, mirroring
OnTooltipShow's own unconditional RemovePopup() at its top.
Live-verified against local ACE (testaccount/+Acdream, session-config
launch): a temporary probe logged 103 mount/102 remove events across many
direct object-to-object transitions (Silver Tusker, Armored Tusker,
+Acdream); hostChildren never exceeded baseline+1 and popupSkinChildren
never exceeded 1 -- confirmed at most one tooltip ever exists. Probe
stripped before landing; two new fixture regressions
(WorldHover_FoundObjectChangesDirectly_ReplacesThePopupWithoutStacking,
WorldHover_ThenUiDwellTooltip_ReplacesRatherThanStacks) both fail pre-fix.
fix#409 (follow-on)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>