How a Java patch becomes a Horizon hook
fabric.mod.json, every mixin config, and every class file: constant pool, methods, and their annotations.@Mixin targets, then @Inject/@Redirect/@Modify*/@Overwrite with the method and @At they patch.@Inject at HEAD/RETURN/TAIL. A call-site patch needs a hook that replaces the call — those are reported, not guessed.horizon-mixin.toml with one injection per hook, and a helper per injection that names the Java handlers it stands for.horizon-mixins apply puts the helpers into the game's own hook functions; horizon-launcher native-build builds the game with them.The hooks the corpus lands on
net_from_server74hud34tick15client_level_load9screen_init_post9block_changed8client_start8frame8screen_opening8player_logged_in6render_needs6client_disconnecting5key5client_stopping4gui_render_post4render_fog4
What Horizon is missing: moments
net/minecraft/world/level/chunk/PalettedContainer#<init> @RETURN6net/minecraft/world/level/chunk/PalettedContainer#<init> @TAIL6net/minecraft/client/gui/components/debug/DebugScreenEntries#<clinit> @RETURN5net/minecraft/client/renderer/texture/TextureAtlas#upload @RETURN5com/mojang/blaze3d/platform/Window#<init> @TAIL4net/minecraft/client/Options#load @HEAD4net/minecraft/client/gui/GuiGraphicsExtractor#blitSprite @HEAD4net/minecraft/client/renderer/GameRenderer#renderLevel @HEAD4net/minecraft/client/renderer/fog/FogRenderer#setupFog @RETURN4net/minecraft/world/entity/ai/Brain#<init> @RETURN4net/minecraft/world/level/Level#<init> @RETURN4net/minecraft/world/level/ServerExplosion#<init> @RETURN4
What Horizon is missing: call sites
net/minecraft/world/level/Level#getEntities @INVOKE (redirect)12org/apache/commons/lang3/Validate#inclusiveBetween @INVOKE (redirect)12net/minecraft/client/gui/Gui#extractRenderState @INVOKE8net/minecraft/client/renderer/GameRenderer#render @INVOKE8net/minecraft/core/BlockPos#above @OVERWRITE8net/minecraft/core/BlockPos#below @OVERWRITE8net/minecraft/core/BlockPos#east @OVERWRITE8net/minecraft/core/BlockPos#north @OVERWRITE8net/minecraft/core/BlockPos#south @OVERWRITE8net/minecraft/core/BlockPos#west @OVERWRITE8net/minecraft/core/Direction#values @INVOKE (redirect)8net/minecraft/core/particles/ParticleTypes#SMOKE:Lnet/minecraft/core/particles/SimpleParticleType; @FIELD (wrap-operation)8
Run it
cargo run -p horizon-port-pack -- \
fabric mod.jar out/mod
# out/mod/port.json every site + its hook
# out/mod/PORT.md verdict, hooks, gaps
# out/mod/carry/ content mod
# out/mod/native/ the bundle
horizon-mixins apply --workspace . \
--mods out/mod --out /tmp/modded
Every bundle this page counts was applied to
the real Horizon source with horizon-mixins: the helpers land inside the game's own
native_* hook functions.
Every mod, converted as far as it goes
Coverage is the share of a mod's listening patch sites (the ones a hook can stand in for) that found a hook. The bodies of the Java methods are still to port, and each helper names the handler it stands for. Performance mods come out Doesn’t run on purpose: their patches replace a renderer or an allocator, which is code Horizon has its own of.
| Mod | Verdict | Sites | Listening | On a hook | Coverage |
|---|---|---|---|---|---|
| Highlighterhighlighter | Partly | 3 | 1 | 1 | 100% |
| Pick Up Notifierpickupnotifier | Partly | 3 | 1 | 1 | 100% |
| Xaero's World Mapxaeroworldmap | Partly | 28 | 18 | 18 | 100% |
| Xaero's Minimapxaerominimap | Partly | 39 | 28 | 23 | 82% |
| BiomesOPlentybiomesoplenty | Partly | 3 | 3 | 2 | 67% |
| Resourcifyresourcify | Partly | 5 | 3 | 2 | 67% |
| Simple Voice Chatvoicechat | Partly | 11 | 8 | 5 | 62% |
| AppleSkinappleskin | Partly | 10 | 10 | 6 | 60% |
| TCDCommons APItcdcommons | Partly | 10 | 5 | 3 | 60% |
| EnchantmentDescriptionsenchdesc | Partly | 4 | 2 | 1 | 50% |
| EnhancedVisualsenhancedvisuals | Partly | 6 | 2 | 1 | 50% |
| Gamma Utilsgammautils | Partly | 7 | 6 | 3 | 50% |
| Ixerisixeris | Partly | 8 | 2 | 1 | 50% |
| Presence Footstepspresencefootsteps | Partly | 3 | 2 | 1 | 50% |
| Veinminer Clientveinminer_client | Partly | 2 | 2 | 1 | 50% |
| Sound Physics Remasteredsound_physics_remastered | Partly | 16 | 9 | 4 | 44% |
| Explorer's Compassexplorerscompass | Partly | 5 | 5 | 2 | 40% |
| Nature's Compassnaturescompass | Partly | 5 | 5 | 2 | 40% |
| Journeymapjourneymap | Partly | 35 | 20 | 7 | 35% |
| Shoulder Surfing Reloadedshouldersurfing | Partly | 46 | 26 | 9 | 35% |
| Controlifycontrolify | Partly | 67 | 30 | 10 | 33% |
| Crash Assistantcrash_assistant | Partly | 7 | 6 | 2 | 33% |
| Nuitnuit | Partly | 7 | 3 | 1 | 33% |
| Skyboxifyskyboxify | Partly | 11 | 3 | 1 | 33% |
| Roughly Enough Itemsroughlyenoughitems | Partly | 11 | 10 | 3 | 30% |
| Inventory Profiles Nextinventoryprofilesnext | Partly | 37 | 31 | 8 | 26% |
| Falling Leavesfallingleaves | Partly | 12 | 8 | 2 | 25% |
| Litematicalitematica | Partly | 50 | 39 | 8 | 21% |
| Replay Modreplaymod | Partly | 89 | 44 | 9 | 20% |
| Shulker Box Tooltipshulkerboxtooltip | Partly | 16 | 10 | 2 | 20% |
| Chat Headschat_heads | Doesn’t run | 49 | 21 | 4 | 19% |
| Distant Horizonsdistanthorizons | Doesn’t run | 24 | 21 | 4 | 19% |
| Debugifydebugify | Doesn’t run | 62 | 16 | 3 | 19% |
| Not Enough Crashesnotenoughcrashes | Doesn’t run | 18 | 11 | 2 | 18% |
| LambDynamicLightslambdynlights | Doesn’t run | 19 | 13 | 2 | 15% |
| XaeroPlusxaeroplus | Doesn’t run | 163 | 73 | 11 | 15% |
| Bobbybobby | Doesn’t run | 32 | 20 | 3 | 15% |
| ScalableLuxscalablelux | Doesn’t run | 19 | 7 | 1 | 14% |
| Smooth Scrollingsmoothscroll | Doesn’t run | 29 | 7 | 1 | 14% |
| Waystoneswaystones | Doesn’t run | 8 | 7 | 1 | 14% |
| ImmediatelyFastimmediatelyfast | Doesn’t run | 34 | 15 | 2 | 13% |
| ImmediatelyFastimmediatelyfast | Doesn’t run | 33 | 15 | 2 | 13% |
| Soundssounds | Doesn’t run | 38 | 29 | 3 | 10% |
| BetterF3betterf3 | Doesn’t run | 14 | 10 | 1 | 10% |
| Traveler's Backpacktravelersbackpack | Doesn’t run | 25 | 22 | 2 | 9% |
| Freecamfreecam | Doesn’t run | 37 | 34 | 3 | 9% |
| Carry Oncarryon | Doesn’t run | 15 | 12 | 1 | 8% |
| NotEnoughAnimationsnotenoughanimations | Doesn’t run | 15 | 13 | 1 | 8% |
| Irisiris | Doesn’t run | 239 | 144 | 11 | 8% |
| Lootrlootr | Doesn’t run | 32 | 16 | 1 | 6% |
| Polytonepolytone | Doesn’t run | 106 | 64 | 4 | 6% |
| Sodium Extrasodium-extra | Doesn’t run | 67 | 48 | 3 | 6% |
| Friends&Foesfriendsandfoes | Doesn’t run | 33 | 17 | 1 | 6% |
| No Chat Reportsnochatreports | Doesn’t run | 35 | 34 | 2 | 6% |
| ModernFixmodernfix | Doesn’t run | 129 | 53 | 3 | 6% |
| IMBlockerimblocker | Doesn’t run | 107 | 97 | 5 | 5% |
| Sodiumsodium | Doesn’t run | 94 | 48 | 2 | 4% |
| Sodiumsodium | Doesn’t run | 101 | 51 | 2 | 4% |
| Lithiumlithium | Doesn’t run | 419 | 138 | 4 | 3% |
| Lithiumlithium | Doesn’t run | 417 | 140 | 4 | 3% |
| Subtle Effectssubtle_effects | Doesn’t run | 147 | 48 | 1 | 2% |
| Advancement Plaquesadvancementplaques | Works | 0 | 0 | 0 | 0% |
| Alternate Currentalternate-current | Doesn’t run | 8 | 5 | 0 | 0% |
| AttributeFixattributefix | Doesn’t run | 0 | 0 | 0 | 0% |
| BadOptimizationsbadoptimizations | Doesn’t run | 11 | 9 | 0 | 0% |
| Better Advancementsbetteradvancements | Doesn’t run | 1 | 0 | 0 | 0% |
| Better Mount HUDbettermounthud | Doesn’t run | 5 | 0 | 0 | 0% |
| Better Netherbetternether | Doesn’t run | 32 | 27 | 0 | 0% |
| Better Statistics Screenbetterstats | Works | 0 | 0 | 0 | 0% |
| Boat Item Viewboatiview | Doesn’t run | 1 | 0 | 0 | 0% |
| Concurrent Chunk Management Enginec2me | Doesn’t run | 0 | 0 | 0 | 0% |
| Capescapes | Doesn’t run | 5 | 4 | 0 | 0% |
| ChatAnimationchatanimation | Doesn’t run | 8 | 4 | 0 | 0% |
| Cherished Worldscherishedworlds | Doesn’t run | 9 | 5 | 0 | 0% |
| Chunkychunky | Doesn’t run | 4 | 0 | 0 | 0% |
| Clumpsclumps | Doesn’t run | 9 | 6 | 0 | 0% |
| Continuitycontinuity | Doesn’t run | 14 | 6 | 0 | 0% |
| Controllingcontrolling | Doesn’t run | 1 | 0 | 0 | 0% |
| CustomSkinLoader Bootstrapcustomskinloader-bootstrap | Doesn’t run | 0 | 0 | 0 | 0% |
| Cut Throughcutthrough | Doesn’t run | 3 | 0 | 0 | 0% |
| Cubes Without Borderscwb | Doesn’t run | 18 | 4 | 0 | 0% |
| Default Optionsdefaultoptions | Doesn’t run | 5 | 4 | 0 | 0% |
| Drippy Loading Screendrippyloadingscreen | Doesn’t run | 28 | 14 | 0 | 0% |
| Durability Tooltipdurabilitytooltip | Doesn’t run | 0 | 0 | 0 | 0% |
| Dynamic FPSdynamic_fps | Doesn’t run | 1 | 1 | 0 | 0% |
| Dynamic Crosshairdynamiccrosshair | Doesn’t run | 1 | 0 | 0 | 0% |
| e4mce4mc | Doesn’t run | 30 | 8 | 0 | 0% |
| Easy Anvilseasyanvils | Doesn’t run | 2 | 0 | 0 | 0% |
| Easy Magiceasymagic | Doesn’t run | 2 | 2 | 0 | 0% |
| EntityCullingentityculling | Doesn’t run | 4 | 4 | 0 | 0% |
| EntityCullingentityculling | Doesn’t run | 4 | 4 | 0 | 0% |
| Fabric APIfabric-api | Doesn’t run | 0 | 0 | 0 | 0% |
| Fabrishotfabrishot | Doesn’t run | 4 | 1 | 0 | 0% |
| FallingTreefallingtree | Doesn’t run | 3 | 3 | 0 | 0% |
| Farmer's Delightfarmersdelight | Doesn’t run | 26 | 17 | 0 | 0% |
| Fast IP Pingfastipping | Doesn’t run | 1 | 0 | 0 | 0% |
| FastQuitfastquit | Doesn’t run | 25 | 12 | 0 | 0% |
| FerriteCoreferritecore | Doesn’t run | 18 | 9 | 0 | 0% |
| FerriteCoreferritecore | Doesn’t run | 18 | 9 | 0 | 0% |
| FirstPersonfirstperson | Doesn’t run | 19 | 17 | 0 | 0% |
| Global Packsglobalpacks | Doesn’t run | 4 | 1 | 0 | 0% |
| InvMoveinvmove | Doesn’t run | 3 | 2 | 0 | 0% |
| Just Enough Charactersjecharacters | Doesn’t run | 1 | 1 | 0 | 0% |
| Kryptonkrypton | Doesn’t run | 11 | 2 | 0 | 0% |
| Language Reloadlanguagereload | Doesn’t run | 22 | 13 | 0 | 0% |
| Leaves Be Goneleavesbegone | Doesn’t run | 9 | 6 | 0 | 0% |
| LetMeDespawnletmedespawn | Doesn’t run | 14 | 8 | 0 | 0% |
| Make Bubbles Popmake_bubbles_pop | Doesn’t run | 14 | 7 | 0 | 0% |
| Mod Menumodmenu | Doesn’t run | 4 | 0 | 0 | 0% |
| More Chat Historymorechathistory | Doesn’t run | 1 | 0 | 0 | 0% |
| Mouse Tweaksmousetweaks | Doesn’t run | 0 | 0 | 0 | 0% |
| Trekmr_trek | Works | 0 | 0 | 0 | 0% |
| NetherPortalFixnetherportalfix | Works | 0 | 0 | 0 | 0% |
| OptiGUIoptigui | Doesn’t run | 7 | 6 | 0 | 0% |
| Packet Fixerpacketfixer | Doesn’t run | 31 | 2 | 0 | 0% |
| Paginated Advancementspaginatedadvancements | Doesn’t run | 1 | 0 | 0 | 0% |
| Particle Coreparticle_core | Doesn’t run | 17 | 4 | 0 | 0% |
| Particle Rainparticlerain | Doesn’t run | 16 | 8 | 0 | 0% |
| Ping Wheelpingwheel | Doesn’t run | 2 | 0 | 0 | 0% |
| Reese's Sodium Optionsreeses-sodium-options | Doesn’t run | 1 | 1 | 0 | 0% |
| Repurposed Structuresrepurposed_structures | Doesn’t run | 19 | 10 | 0 | 0% |
| Right Click Harvestrightclickharvest | Works | 0 | 0 | 0 | 0% |
| Remove Reloading Screenrrls | Doesn’t run | 42 | 6 | 0 | 0% |
| ServerCoreservercore | Doesn’t run | 64 | 18 | 0 | 0% |
| 3d-Skin-Layersskinlayers3d | Doesn’t run | 12 | 10 | 0 | 0% |
| sparkspark | Doesn’t run | 0 | 0 | 0 | 0% |
| Sodium Shadowy Path Blockssspb | Doesn’t run | 4 | 0 | 0 | 0% |
| Towns and Towerst_and_t | Works | 0 | 0 | 0 | 0% |
| Tectonictectonic | Doesn’t run | 11 | 6 | 0 | 0% |
| Terralithterralith | Works | 0 | 0 | 0 | 0% |
| Tom's Simple Storage Modtoms_storage | Works | 0 | 0 | 0 | 0% |
| Veinminerveinminer | Doesn’t run | 1 | 1 | 0 | 0% |
| Veinminer Enchantmentveinminer_enchantment | Doesn’t run | 0 | 0 | 0 | 0% |
| Villager Namesvillagernames | Doesn’t run | 2 | 1 | 0 | 0% |
| Visualityvisuality | Doesn’t run | 5 | 5 | 0 | 0% |
| Visual Workbenchvisualworkbench | Works | 0 | 0 | 0 | 0% |
| Very Many Playersvmp | Doesn’t run | 52 | 15 | 0 | 0% |
| WaveyCapeswaveycapes | Doesn’t run | 3 | 3 | 0 | 0% |
| Yeetus Experimentusyeetusexperimentus | Doesn’t run | 3 | 0 | 0 | 0% |
| YOSBRyosbr | Doesn’t run | 0 | 0 | 0 | 0% |
| Zoomifyzoomify | Doesn’t run | 4 | 0 | 0 | 0% |