FancyMenu [Fabric] [MOVED TO NEW PROJECT]

FancyMenu [Fabric] [MOVED TO NEW PROJECT]

17M Downloads

Some legacy "deep" elements in the Title screen render after FAPI/Forge events

Johni0702 opened this issue ยท 5 comments

commented

Describe the issue
I'm trying to render an overlay (for e.g. notifications, modals, etc.) on top of all screens but when FancyMenu customizations are enabled for the title screen, some parts of the title screen will unexpectedly render on top of my content.

Minimal fabric-api example:

        ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
            ScreenEvents.afterRender(screen).register((screen1, drawContext, mouseX, mouseY, tickDelta) -> {
                drawContext.draw();
                RenderSystem.clearColor(0.1f, 0.1f, 0.1f, 1f);
                RenderSystem.clear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
            });
        });

I'm expecting this to produce an empty screen of uniform gray (ideally even without the FancyMenu menu bar; though that one I wouldn't necessarily consider a bug), but some of the title screen elements are rendered on top of it (see screenshot below).

Same issue on Forge when using ScreenEvent.Render.Post, and presumably (although I haven't tested this yet) also with the NeoForge equivalent.

Note that to reproduce this in a development environment, -Dfabric.debug.disableModShuffle may be required, as otherwise it is random whether the issue occurs.

Cause

For Fabric, cause of the issue appears to be that FancyMenu's mixin wraps the same target with the same priority as Fabric API's mixin, as such, which one draws first depends on load order.

For Forge, FancyMenu's mixin injects at the top and bottom of ForgeHooksClient.drawScreen, however Forge's events are emitted from drawScreenInternal (which is called in the middle of drawScreen), so FancyMenu's post event always draws on top of the Forge event.

Game Log
N/A

Screenshots

Basic Informations (please complete the following information):

  • OS: Any
  • FancyMenu Version: 3.4.6 (but presumably affects anything 3.4.0+)
  • Forge/Fabric Version: Presumably any (tested Forge 54.1.1, Fabric 0.16.10, FAPI 0.118.0+1.21.4)
  • Fabric Version 0.16.10
  • Minecraft Version: 1.21.4 (though presumably affects all versions which received the 3.4.0 backport)
  • Active Mods: Minimal example above
commented

Well, FancyMenu is made to render after everything else when set to render in front of "Vanilla" elements. This is just how FM works. I can't really make FM know what parts of rendered content are overlays and what are just normal elements.

commented

These events are "after screen rendering" events, they're fired from outside of Screen.render, nothing in there should really be screen elements.
To be clear, I'm not surprised to see FancyMenu's menu bar, that one is arguably some in between thing that's kind of part of the screen but also not really, it is a kind of overlay itself. What I am surprised to see though are the Minecraft logo, the yellow text on its right and the text in the bottom left; all of those are unambiguously part of the screen, so I would expected them to be rendered by the time the "after screen rendering" events are emitted; doubly so given that is exactly what happens when customizations aren't enabled.

commented

Just out of curiosity: What happens if you render your overlay at Z 400 ? Maybe it's more like a Z level thing?

These events are "after screen rendering" events, they're fired from outside of Screen.render, nothing in there should really be screen elements.

Tell that the devs that render their screen elements in Post render events instead of adding them to the screen widgets list. I had to adept.

commented

Maybe it's more like a Z level thing?

It's not, I've initially checked with the debugger and indeed the draw call for the logo happens via FancyMenu's post event after the fabric post event.
The minimal example also rules out that option because I'm not even drawing an overlay in there, I'm straight up clearing the whole screen, and yet the logo still shows.

I unfortunately also can't really even work around the issue by rendering my stuff at a higher z level and relying on the depth test to not show the logo because my stuff includes transparency, so the logo needs to actually be drawn before my stuff.

Tell that the devs that render their screen elements in Post render events instead of adding them to the screen widgets list. I had to adept.

Probably true, though I don't understand how that's relevant since their stuff would already render on top of the logo then anyway.
And I'm not complaining about FancyMenu rendering its own overlay over mine, I understand why its overlay should appear on top of third-party mod content, I'm merely complaining about FancyMenu rendering stuff that's unambiguously screen content, and which is rendered as part of the screen without FancyMenu, after the screen.
Why even are these three elements rendered after the screen when everything else seems to be rendered as part of the screen? I tried to look at the code for a while, and while I can see that it is the case, I can't seem to figure out the underlying reason.

commented

Why even are these three elements rendered after the screen when everything else seems to be rendered as part of the screen? I tried to look at the code for a while, and while I can see that it is the case, I can't seem to figure out the underlying reason.

I don't know anymore. I didn't even know that was an issue until you told me. That part of the code is very old, even pre-v3, so I can't tell you that. Will look into it when I have time, but it's not really a priority right now.