From 33da0f80711fcba21ce414311b08d7e4f6a14646 Mon Sep 17 00:00:00 2001 From: joe Date: Mon, 15 Dec 2025 15:15:31 +0000 Subject: [PATCH 01/48] Add testable events --- build.gradle | 1 + .../fabric/api/event/EventFactory.java | 2 +- .../impl/base/event/ArrayBackedEvent.java | 12 ++++----- .../impl/base/event/EventFactoryImpl.java | 20 ++++++++++++--- .../impl/base/event/EventPhaseData.java | 21 +++++++++++++++- fabric-test-api-v1/build.gradle | 3 +++ .../fabricmc/fabric/api/test/EventScope.java | 9 +++++++ .../fabric/api/test/EventTesting.java | 20 +++++++++++++++ .../fabric/impl/test/EventScopeImpl.java | 22 ++++++++++++++++ .../fabric/impl/test/EventTestingImpl.java | 20 +++++++++++++++ .../impl/test/TestableArrayBackedEvent.java | 25 +++++++++++++++++++ .../impl/test/TestableEventFactoryImpl.java | 17 +++++++++++++ ...mc.fabric.impl.base.event.EventFactoryImpl | 1 + gradle.properties | 1 + settings.gradle | 1 + 15 files changed, 163 insertions(+), 12 deletions(-) create mode 100644 fabric-test-api-v1/build.gradle create mode 100644 fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java create mode 100644 fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventTesting.java create mode 100644 fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java create mode 100644 fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java create mode 100644 fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java create mode 100644 fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java create mode 100644 fabric-test-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl diff --git a/build.gradle b/build.gradle index b81cbd26bca..97fe6234559 100644 --- a/build.gradle +++ b/build.gradle @@ -684,6 +684,7 @@ subprojects.each { def devOnlyModules = [ "fabric-client-gametest-api-v1", "fabric-gametest-api-v1", + "fabric-test-api-v1", ] dependencies { diff --git a/fabric-api-base/src/main/java/net/fabricmc/fabric/api/event/EventFactory.java b/fabric-api-base/src/main/java/net/fabricmc/fabric/api/event/EventFactory.java index 4e452ca6b34..c998276bddd 100644 --- a/fabric-api-base/src/main/java/net/fabricmc/fabric/api/event/EventFactory.java +++ b/fabric-api-base/src/main/java/net/fabricmc/fabric/api/event/EventFactory.java @@ -41,7 +41,7 @@ private EventFactory() { } * @return The Event instance. */ public static Event createArrayBacked(Class type, Function invokerFactory) { - return EventFactoryImpl.createArrayBacked(type, invokerFactory); + return EventFactoryImpl.INSTANCE.createArrayBacked(type, invokerFactory); } /** diff --git a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/ArrayBackedEvent.java b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/ArrayBackedEvent.java index e3c338f46b9..2f3829a696f 100644 --- a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/ArrayBackedEvent.java +++ b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/ArrayBackedEvent.java @@ -30,10 +30,10 @@ import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.impl.base.toposort.NodeSorting; -class ArrayBackedEvent extends Event { +public class ArrayBackedEvent extends Event { private final Function invokerFactory; - private final Object lock = new Object(); - private T[] handlers; + protected final Object lock = new Object(); + protected T[] handlers; /** * Registered event phases. */ @@ -44,7 +44,7 @@ class ArrayBackedEvent extends Event { private final List> sortedPhases = new ArrayList<>(); @SuppressWarnings("unchecked") - ArrayBackedEvent(Class type, Function invokerFactory) { + protected ArrayBackedEvent(Class type, Function invokerFactory) { this.invokerFactory = invokerFactory; this.handlers = (T[]) Array.newInstance(type, 0); update(); @@ -70,7 +70,7 @@ public void register(Identifier phaseIdentifier, T listener) { } } - private EventPhaseData getOrCreatePhase(Identifier id, boolean sortIfCreate) { + protected final EventPhaseData getOrCreatePhase(Identifier id, boolean sortIfCreate) { EventPhaseData phase = phases.get(id); if (phase == null) { @@ -86,7 +86,7 @@ private EventPhaseData getOrCreatePhase(Identifier id, boolean sortIfCreate) return phase; } - private void rebuildInvoker(int newLength) { + protected final void rebuildInvoker(int newLength) { // Rebuild handlers. if (sortedPhases.size() == 1) { // Special case with a single phase: use the array of the phase directly. diff --git a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java index 1d0be4aa530..a07b9e2d865 100644 --- a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java +++ b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java @@ -24,6 +24,7 @@ import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.util.Collections; +import java.util.ServiceLoader; import java.util.Set; import java.util.function.Function; @@ -33,18 +34,29 @@ import net.fabricmc.fabric.api.event.Event; -public final class EventFactoryImpl { +public class EventFactoryImpl { + public static final EventFactoryImpl INSTANCE = ServiceLoader.load(EventFactoryImpl.class).findFirst().orElseGet(EventFactoryImpl::new); private static final Set> ARRAY_BACKED_EVENTS = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap()); - private EventFactoryImpl() { } + protected EventFactoryImpl() { + Class thisClass = getClass(); + + if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals("net.fabricmc.fabric.impl.test.TestableEventFactoryImpl")) { + throw new IllegalStateException("You are not allowed to create a custom EventFactoryImpl!"); + } + } public static void invalidate() { ARRAY_BACKED_EVENTS.forEach(ArrayBackedEvent::update); } - public static Event createArrayBacked(Class type, Function invokerFactory) { - ArrayBackedEvent event = new ArrayBackedEvent<>(type, invokerFactory); + protected ArrayBackedEvent doCreateArrayBacked(Class type, Function invokerFactory) { + return new ArrayBackedEvent<>(type, invokerFactory); + } + + public final Event createArrayBacked(Class type, Function invokerFactory) { + ArrayBackedEvent event = doCreateArrayBacked(type, invokerFactory); ARRAY_BACKED_EVENTS.add(event); return event; } diff --git a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventPhaseData.java b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventPhaseData.java index c11454e4ef3..1b6cbbcab8a 100644 --- a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventPhaseData.java +++ b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventPhaseData.java @@ -26,7 +26,7 @@ /** * Data of an {@link ArrayBackedEvent} phase. */ -class EventPhaseData extends SortableNode> { +public class EventPhaseData extends SortableNode> { final Identifier id; T[] listeners; @@ -42,6 +42,25 @@ void addListener(T listener) { listeners[oldLength] = listener; } + public boolean removeListener(T listener) { + int indexToRemove; + + for (indexToRemove = listeners.length - 1; indexToRemove >= 0; indexToRemove--) { + if (listeners[indexToRemove] == listener) { + break; + } + } + + if (indexToRemove == -1) { + return false; + } + + T[] newListeners = Arrays.copyOf(listeners, listeners.length - 1); + System.arraycopy(listeners, indexToRemove + 1, newListeners, indexToRemove, newListeners.length - indexToRemove); + listeners = newListeners; + return true; + } + @Override protected String getDescription() { return id.toString(); diff --git a/fabric-test-api-v1/build.gradle b/fabric-test-api-v1/build.gradle new file mode 100644 index 00000000000..9ced6ef8b49 --- /dev/null +++ b/fabric-test-api-v1/build.gradle @@ -0,0 +1,3 @@ +version = getSubprojectVersion(project) + +moduleDependencies(project, ['fabric-api-base']) diff --git a/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java new file mode 100644 index 00000000000..0e96b0c679b --- /dev/null +++ b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java @@ -0,0 +1,9 @@ +package net.fabricmc.fabric.api.test; + +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.NonExtendable +public interface EventScope extends AutoCloseable { + @Override + void close(); +} diff --git a/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventTesting.java b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventTesting.java new file mode 100644 index 00000000000..be813cb3d68 --- /dev/null +++ b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventTesting.java @@ -0,0 +1,20 @@ +package net.fabricmc.fabric.api.test; + +import net.fabricmc.fabric.api.event.Event; + +import net.fabricmc.fabric.impl.test.EventTestingImpl; + +import net.minecraft.resources.Identifier; + +public final class EventTesting { + private EventTesting() { + } + + public static EventScope registerScoped(Event event, T listener) { + return registerScoped(event, Event.DEFAULT_PHASE, listener); + } + + public static EventScope registerScoped(Event event, Identifier phase, T listener) { + return EventTestingImpl.registerScoped(event, phase, listener); + } +} diff --git a/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java new file mode 100644 index 00000000000..5df048884f0 --- /dev/null +++ b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java @@ -0,0 +1,22 @@ +package net.fabricmc.fabric.impl.test; + +import net.fabricmc.fabric.api.test.EventScope; + +import net.minecraft.resources.Identifier; + +public class EventScopeImpl implements EventScope { + private final TestableArrayBackedEvent event; + private final Identifier phase; + private final T listener; + + public EventScopeImpl(TestableArrayBackedEvent event, Identifier phase, T listener) { + this.event = event; + this.phase = phase; + this.listener = listener; + } + + @Override + public void close() { + event.unregister(phase, listener); + } +} diff --git a/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java new file mode 100644 index 00000000000..c555789c198 --- /dev/null +++ b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java @@ -0,0 +1,20 @@ +package net.fabricmc.fabric.impl.test; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.test.EventScope; + +import net.minecraft.resources.Identifier; + +public final class EventTestingImpl { + private EventTestingImpl() { + } + + public static EventScope registerScoped(Event event, Identifier phase, T listener) { + if (!(event instanceof TestableArrayBackedEvent testableEvent)) { + throw new IllegalArgumentException("Event is not testable, something has gone very wrong!"); + } + + event.register(phase, listener); + return new EventScopeImpl<>(testableEvent, phase, listener); + } +} diff --git a/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java new file mode 100644 index 00000000000..76f15695386 --- /dev/null +++ b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java @@ -0,0 +1,25 @@ +package net.fabricmc.fabric.impl.test; + +import net.fabricmc.fabric.impl.base.event.ArrayBackedEvent; + +import net.minecraft.resources.Identifier; + +import java.util.Objects; +import java.util.function.Function; + +class TestableArrayBackedEvent extends ArrayBackedEvent { + TestableArrayBackedEvent(Class type, Function invokerFactory) { + super(type, invokerFactory); + } + + public void unregister(Identifier phaseIdentifier, T listener) { + Objects.requireNonNull(phaseIdentifier, "Tried to unregister a listener for a null phase!"); + Objects.requireNonNull(listener, "Tried to unregister a null listener!"); + + synchronized (lock) { + if (getOrCreatePhase(phaseIdentifier, false).removeListener(listener)) { + rebuildInvoker(handlers.length - 1); + } + } + } +} diff --git a/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java new file mode 100644 index 00000000000..c5c3356fb27 --- /dev/null +++ b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java @@ -0,0 +1,17 @@ +package net.fabricmc.fabric.impl.test; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.test.EventScope; +import net.fabricmc.fabric.impl.base.event.ArrayBackedEvent; +import net.fabricmc.fabric.impl.base.event.EventFactoryImpl; + +import net.minecraft.resources.Identifier; + +import java.util.function.Function; + +public class TestableEventFactoryImpl extends EventFactoryImpl { + @Override + protected ArrayBackedEvent doCreateArrayBacked(Class type, Function invokerFactory) { + return new TestableArrayBackedEvent<>(type, invokerFactory); + } +} diff --git a/fabric-test-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl b/fabric-test-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl new file mode 100644 index 00000000000..2211a85aaf6 --- /dev/null +++ b/fabric-test-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl @@ -0,0 +1 @@ +net.fabricmc.fabric.impl.test.TestableEventFactoryImpl diff --git a/gradle.properties b/gradle.properties index d7876d9ff27..9eaf03fc1ee 100644 --- a/gradle.properties +++ b/gradle.properties @@ -52,6 +52,7 @@ fabric-screen-handler-api-v1-version=1.3.160 fabric-serialization-api-v1-version=1.0.5 fabric-sound-api-v1-version=1.0.51 fabric-tag-api-v1-version=1.2.20 +fabric-test-api-v1-version=1.0.0 fabric-transfer-api-v1-version=6.0.24 fabric-transitive-access-wideners-v1-version=7.0.8 fabric-convention-tags-v1-version=2.1.55 diff --git a/settings.gradle b/settings.gradle index ccda40d80ee..064f113edb4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -64,6 +64,7 @@ include 'fabric-screen-handler-api-v1' include 'fabric-serialization-api-v1' include 'fabric-sound-api-v1' include 'fabric-tag-api-v1' +include 'fabric-test-api-v1' include 'fabric-transfer-api-v1' include 'fabric-transitive-access-wideners-v1' From 278ac4c0a677c9a27a0206366e2016b89f657297 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Tue, 13 Jan 2026 01:20:57 -0500 Subject: [PATCH 02/48] feat: Debug API --- fabric-debug-api-v1/build.gradle | 12 ++ .../ClientDebugSubscriptionRegistry.java | 46 +++++++ .../client/renderer/DebugRendererFactory.java | 13 ++ .../renderer/DebugRendererRegistry.java | 42 +++++++ .../ClientDebugSubscriptionRegistryImpl.java | 14 +++ .../renderer/DebugRendererRegistryImpl.java | 43 +++++++ .../client/ClientDebugSubscriberMixin.java | 28 +++++ .../debug/client/DebugRendererMixin.java | 36 ++++++ .../fabric-debug-api-v1.client.mixins.json | 18 +++ .../api/debug/v1/DebugValueFactory.java | 11 ++ .../v1/EntityDebugSubscriptionRegistry.java | 61 ++++++++++ .../EntityDebugSubscriptionRegistryImpl.java | 68 +++++++++++ .../fabric/mixin/debug/EntityMixin.java | 27 +++++ .../fabricmc/fabric/mixin/debug/MobMixin.java | 30 +++++ .../debug/ServerDebugSubscribersMixin.java | 29 +++++ .../assets/fabric-debug-api-v1/icon.png | Bin 0 -> 1555 bytes .../fabric-debug-api-v1.accesswidener | 1 + .../resources/fabric-debug-api-v1.mixins.json | 19 +++ .../src/main/resources/fabric.mod.json | 35 ++++++ .../fabric/test/debug/DebugApiTest.java | 40 +++++++ .../fabric/test/debug/SusDebugInfo.java | 20 ++++ .../src/testmod/resources/fabric.mod.json | 18 +++ .../test/debug/client/DebugApiTestClient.java | 112 ++++++++++++++++++ gradle.properties | 1 + settings.gradle | 1 + 25 files changed, 725 insertions(+) create mode 100644 fabric-debug-api-v1/build.gradle create mode 100644 fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java create mode 100644 fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java create mode 100644 fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererRegistry.java create mode 100644 fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/ClientDebugSubscriptionRegistryImpl.java create mode 100644 fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/renderer/DebugRendererRegistryImpl.java create mode 100644 fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/ClientDebugSubscriberMixin.java create mode 100644 fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/DebugRendererMixin.java create mode 100644 fabric-debug-api-v1/src/client/resources/fabric-debug-api-v1.client.mixins.json create mode 100644 fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/DebugValueFactory.java create mode 100644 fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EntityDebugSubscriptionRegistry.java create mode 100644 fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EntityDebugSubscriptionRegistryImpl.java create mode 100644 fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java create mode 100644 fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java create mode 100644 fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/ServerDebugSubscribersMixin.java create mode 100644 fabric-debug-api-v1/src/main/resources/assets/fabric-debug-api-v1/icon.png create mode 100644 fabric-debug-api-v1/src/main/resources/fabric-debug-api-v1.accesswidener create mode 100644 fabric-debug-api-v1/src/main/resources/fabric-debug-api-v1.mixins.json create mode 100644 fabric-debug-api-v1/src/main/resources/fabric.mod.json create mode 100644 fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/DebugApiTest.java create mode 100644 fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/SusDebugInfo.java create mode 100644 fabric-debug-api-v1/src/testmod/resources/fabric.mod.json create mode 100644 fabric-debug-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/debug/client/DebugApiTestClient.java diff --git a/fabric-debug-api-v1/build.gradle b/fabric-debug-api-v1/build.gradle new file mode 100644 index 00000000000..91ac94ae90f --- /dev/null +++ b/fabric-debug-api-v1/build.gradle @@ -0,0 +1,12 @@ +version = getSubprojectVersion(project) + +moduleDependencies(project, [ + 'fabric-api-base' +]) + +testDependencies(project, [ +]) + +loom { + accessWidenerPath = file("src/main/resources/fabric-debug-api-v1.accesswidener") +} diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java new file mode 100644 index 00000000000..e7d82649bca --- /dev/null +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java @@ -0,0 +1,46 @@ +package net.fabricmc.fabric.api.debug.v1.client; + +import java.util.Objects; + +import net.minecraft.util.debug.DebugSubscription; + +import net.fabricmc.fabric.impl.debug.client.ClientDebugSubscriptionRegistryImpl; + +/// A registry for [debug subscriptions][DebugSubscription] on the client, +/// allowing listening to registered debug subscriptions on the client. +public final class ClientDebugSubscriptionRegistry { + /// Registers a [DebugSubscription] on the client. + /// + /// **Note:** this will register **outside development environments** if it + /// is not checked. Surround calls to this method with + /// [net.fabricmc.loader.api.FabricLoader#isDevelopmentEnvironment] if you + /// do not intend for a debug feature to be present in production. + /// + /// @param the inner type of the [DebugSubscription]. + /// @param debugSubscription the [DebugSubscription] to register. + public static void register(DebugSubscription debugSubscription) { + Objects.requireNonNull(debugSubscription); + ClientDebugSubscriptionRegistryImpl.register(debugSubscription); + } + + /// Registers a [DebugSubscription] on the client if the `isEnabledFlag` + /// parameter is `true`. + /// + /// **Note:** this will register **outside development environments** if it + /// is not checked. Surround calls to this method with + /// [net.fabricmc.loader.api.FabricLoader#isDevelopmentEnvironment] if you + /// do not intend for a debug feature to be present in production. + /// + /// @param the inner type of the [DebugSubscription]. + /// @param debugSubscription the [DebugSubscription] to register. + /// @param isEnabledFlag the flag determining whether to register this + /// [DebugSubscription]. + public static void register( + DebugSubscription debugSubscription, + boolean isEnabledFlag + ) { + if (isEnabledFlag) { + register(debugSubscription); + } + } +} diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java new file mode 100644 index 00000000000..f4985693217 --- /dev/null +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java @@ -0,0 +1,13 @@ +package net.fabricmc.fabric.api.debug.v1.client.renderer; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.debug.DebugRenderer; + +/// A constructor for a +/// [debug subscription][net.minecraft.util.debug.DebugSubscription] renderer. +@FunctionalInterface +public interface DebugRendererFactory { + /// @return a new renderer for a + /// [debug subscription][net.minecraft.util.debug.DebugSubscription]. + DebugRenderer.SimpleDebugRenderer create(Minecraft minecraft); +} diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererRegistry.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererRegistry.java new file mode 100644 index 00000000000..9ef0ddecaae --- /dev/null +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererRegistry.java @@ -0,0 +1,42 @@ +package net.fabricmc.fabric.api.debug.v1.client.renderer; + +import java.util.Objects; + +import net.minecraft.util.debug.DebugSubscription; + +import net.fabricmc.fabric.impl.debug.client.renderer.DebugRendererRegistryImpl; + +/// Registry for custom +/// [debug renderers][net.minecraft.client.renderer.debug.DebugRenderer.SimpleDebugRenderer]. +public final class DebugRendererRegistry { + /// Registers a debug renderer for the given [DebugSubscription]. + /// + /// @param the inner type of the [DebugSubscription]. + /// @param debugSubscription the [DebugSubscription]. + /// @param rendererFactory the factory/constructor for the debug renderer. + public static void register( + DebugSubscription debugSubscription, + DebugRendererFactory rendererFactory + ) { + Objects.requireNonNull(debugSubscription); + DebugRendererRegistryImpl.register(debugSubscription, rendererFactory); + } + + /// Registers a debug renderer for the given [DebugSubscription] if + /// `isEnabledFlag` is `true`. + /// + /// @param the inner type of the [DebugSubscription]. + /// @param debugSubscription the [DebugSubscription]. + /// @param rendererFactory the factory/constructor for the debug renderer. + /// @param isEnabledFlag the flag determining whether to register this debug + /// renderer. + public static void register( + DebugSubscription debugSubscription, + DebugRendererFactory rendererFactory, + boolean isEnabledFlag + ) { + if (isEnabledFlag) { + register(debugSubscription, rendererFactory); + } + } +} diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/ClientDebugSubscriptionRegistryImpl.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/ClientDebugSubscriptionRegistryImpl.java new file mode 100644 index 00000000000..87010fd75f2 --- /dev/null +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/ClientDebugSubscriptionRegistryImpl.java @@ -0,0 +1,14 @@ +package net.fabricmc.fabric.impl.debug.client; + +import java.util.HashSet; +import java.util.Set; + +import net.minecraft.util.debug.DebugSubscription; + +public final class ClientDebugSubscriptionRegistryImpl { + public static final Set> DEBUG_SUBSCRIPTIONS = new HashSet<>(); + + public static void register(DebugSubscription debugSubscription) { + DEBUG_SUBSCRIPTIONS.add(debugSubscription); + } +} diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/renderer/DebugRendererRegistryImpl.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/renderer/DebugRendererRegistryImpl.java new file mode 100644 index 00000000000..d6d8d72bed2 --- /dev/null +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/renderer/DebugRendererRegistryImpl.java @@ -0,0 +1,43 @@ +package net.fabricmc.fabric.impl.debug.client.renderer; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import net.minecraft.util.debug.DebugSubscription; + +import net.fabricmc.fabric.api.debug.v1.client.renderer.DebugRendererFactory; + +public final class DebugRendererRegistryImpl { + public static final Set RENDERERS = new HashSet<>(); + + public static void register( + DebugSubscription debugSubscription, + DebugRendererFactory rendererFactory + ) { + RENDERERS.add(new Entry(debugSubscription, rendererFactory)); + } + + public record Entry( + DebugSubscription debugSubscription, + DebugRendererFactory rendererFactory + ) { + // Ensure DebugSubscriptions with different values don't both + // get into the Set, causing undesirable behavior + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + Entry entry = (Entry) o; + return Objects.equals( + debugSubscription, + entry.debugSubscription + ); + } + + @Override + public int hashCode() { + return Objects.hashCode(debugSubscription); + } + } +} diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/ClientDebugSubscriberMixin.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/ClientDebugSubscriberMixin.java new file mode 100644 index 00000000000..b85c71d3612 --- /dev/null +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/ClientDebugSubscriberMixin.java @@ -0,0 +1,28 @@ +package net.fabricmc.fabric.mixin.debug.client; + +import java.util.Set; + +import com.llamalad7.mixinextras.sugar.Local; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.client.multiplayer.ClientDebugSubscriber; +import net.minecraft.util.debug.DebugSubscription; + +import net.fabricmc.fabric.impl.debug.client.ClientDebugSubscriptionRegistryImpl; + +@Mixin(ClientDebugSubscriber.class) +public abstract class ClientDebugSubscriberMixin { + @Inject( + method = "requestedSubscriptions", + at = @At("RETURN") + ) + private void addSubscribers( + CallbackInfoReturnable>> cir, + @Local(name = "subscriptions") Set> subscriptions + ) { + subscriptions.addAll(ClientDebugSubscriptionRegistryImpl.DEBUG_SUBSCRIPTIONS); + } +} diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/DebugRendererMixin.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/DebugRendererMixin.java new file mode 100644 index 00000000000..b1374722e51 --- /dev/null +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/DebugRendererMixin.java @@ -0,0 +1,36 @@ +package net.fabricmc.fabric.mixin.debug.client; + +import java.util.List; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.debug.DebugRenderer; + +import net.fabricmc.fabric.impl.debug.client.renderer.DebugRendererRegistryImpl; + +@Mixin(DebugRenderer.class) +public abstract class DebugRendererMixin { + @Shadow + @Final + private List renderers; + + private DebugRendererMixin() { + } + + @Inject(method = "refreshRendererList", at = @At("RETURN")) + private void registerRenderers(CallbackInfo ci) { + Minecraft minecraft = Minecraft.getInstance(); + + for (DebugRendererRegistryImpl.Entry entry : DebugRendererRegistryImpl.RENDERERS) { + // a Stream#map would make the most sense here, but they're banned + // so you have to suffer with me now + renderers.add(entry.rendererFactory().create(minecraft)); + } + } +} diff --git a/fabric-debug-api-v1/src/client/resources/fabric-debug-api-v1.client.mixins.json b/fabric-debug-api-v1/src/client/resources/fabric-debug-api-v1.client.mixins.json new file mode 100644 index 00000000000..3e5cfed0580 --- /dev/null +++ b/fabric-debug-api-v1/src/client/resources/fabric-debug-api-v1.client.mixins.json @@ -0,0 +1,18 @@ +{ + "required": true, + "package": "net.fabricmc.fabric.mixin.debug.client", + "compatibilityLevel": "JAVA_25", + "client": [ + "ClientDebugSubscriberMixin", + "DebugRendererMixin" + ], + "injectors": { + "defaultRequire": 1 + }, + "overwrites": { + "requireAnnotations": true + }, + "mixinextras": { + "minVersion": "0.5.0" + } +} diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/DebugValueFactory.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/DebugValueFactory.java new file mode 100644 index 00000000000..27a495ddde6 --- /dev/null +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/DebugValueFactory.java @@ -0,0 +1,11 @@ +package net.fabricmc.fabric.api.debug.v1; + +/// Constructs a debug value of type [T] using data of type [D] +/// +/// @param the data passed for construction +/// (e.g. [net.minecraft.world.entity.Entity]) +/// @param the debug value being constructed +@FunctionalInterface +public interface DebugValueFactory { + T create(D data); +} diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EntityDebugSubscriptionRegistry.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EntityDebugSubscriptionRegistry.java new file mode 100644 index 00000000000..ae69f6d02a3 --- /dev/null +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EntityDebugSubscriptionRegistry.java @@ -0,0 +1,61 @@ +package net.fabricmc.fabric.api.debug.v1; + +import java.util.Objects; +import java.util.function.Predicate; + +import net.minecraft.util.debug.DebugSubscription; +import net.minecraft.world.entity.Entity; + +import net.fabricmc.fabric.impl.debug.EntityDebugSubscriptionRegistryImpl; + +/// A registry for [debug subscriptions][DebugSubscription] specific to entities +/// or properties of entities. +public final class EntityDebugSubscriptionRegistry { + /// Registers a [DebugSubscription] based on a given [Entity] and + /// [Predicate]. + /// + /// @param the inner type of the [DebugSubscription]. + /// @param the type of [Entity] to check against. + /// @param debugSubscription the [DebugSubscription]. + /// @param shouldSubscribe whether an [Entity] should subscribe to this + /// [DebugSubscription]. + /// @param valueFactory the factory for the value of type [T]. + public static void register( + DebugSubscription debugSubscription, + Predicate shouldSubscribe, + DebugValueFactory valueFactory + ) { + Objects.requireNonNull(debugSubscription); + EntityDebugSubscriptionRegistryImpl.register( + debugSubscription, + shouldSubscribe, + valueFactory + ); + } + + /// Registers a [DebugSubscription] based on a given [Entity] and + /// [Predicate] if `isEnabledFlag` is `true`. + /// + /// @param the inner type of the [DebugSubscription]. + /// @param the type of [Entity] to check against. + /// @param debugSubscription the [DebugSubscription]. + /// @param shouldSubscribe whether an [Entity] should subscribe to this + /// [DebugSubscription]. + /// @param valueFactory the factory for the value of type [T]. + /// @param isEnabledFlag the flag determining whether to register this + /// [DebugSubscription]. + public static void register( + DebugSubscription debugSubscription, + Predicate shouldSubscribe, + DebugValueFactory valueFactory, + boolean isEnabledFlag + ) { + if (isEnabledFlag) { + register( + debugSubscription, + shouldSubscribe, + valueFactory + ); + } + } +} diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EntityDebugSubscriptionRegistryImpl.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EntityDebugSubscriptionRegistryImpl.java new file mode 100644 index 00000000000..acbe691ac77 --- /dev/null +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EntityDebugSubscriptionRegistryImpl.java @@ -0,0 +1,68 @@ +package net.fabricmc.fabric.impl.debug; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; +import java.util.function.Predicate; + +import net.minecraft.util.debug.DebugSubscription; +import net.minecraft.util.debug.DebugValueSource; +import net.minecraft.world.entity.Entity; + +import net.fabricmc.fabric.api.debug.v1.DebugValueFactory; + +public final class EntityDebugSubscriptionRegistryImpl { + public static final Set ENTITY_DEBUG_SUBSCRIPTIONS = + new HashSet<>(); + + public static void register( + DebugSubscription debugSubscription, + Predicate shouldSubscribe, + DebugValueFactory valueFactory + ) { + //noinspection unchecked // Casts to super-type + ENTITY_DEBUG_SUBSCRIPTIONS.add(new Entry( + (DebugSubscription) debugSubscription, + shouldSubscribe, + (DebugValueFactory) valueFactory + )); + } + + public static void addDebugValues( + Object entity, + DebugValueSource.Registration registration + ) { + for (Entry entry : ENTITY_DEBUG_SUBSCRIPTIONS) { + if (entry.shouldSubscribe().test((Entity) entity)) { + registration.register( + entry.debugSubscription(), + () -> entry.valueFactory().create((Entity) entity) + ); + } + } + } + + public record Entry( + DebugSubscription debugSubscription, + Predicate shouldSubscribe, + DebugValueFactory valueFactory + ) { + // Ensure DebugSubscriptions with different values don't both + // get into the Set, causing undesirable behavior + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + Entry entry = (Entry) o; + return Objects.equals( + debugSubscription, + entry.debugSubscription + ); + } + + @Override + public int hashCode() { + return Objects.hash(debugSubscription); + } + } +} diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java new file mode 100644 index 00000000000..94844c8da89 --- /dev/null +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java @@ -0,0 +1,27 @@ +package net.fabricmc.fabric.mixin.debug; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.debug.DebugValueSource; +import net.minecraft.world.entity.Entity; + +import net.fabricmc.fabric.impl.debug.EntityDebugSubscriptionRegistryImpl; + +@Mixin(Entity.class) +public abstract class EntityMixin { + @Inject( + method = "registerDebugValues", + at = @At("HEAD") + ) + private void addDebugValues( + ServerLevel level, + DebugValueSource.Registration registration, + CallbackInfo ci + ) { + EntityDebugSubscriptionRegistryImpl.addDebugValues(this, registration); + } +} diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java new file mode 100644 index 00000000000..97e2f977a00 --- /dev/null +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java @@ -0,0 +1,30 @@ +package net.fabricmc.fabric.mixin.debug; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.debug.DebugValueSource; +import net.minecraft.world.entity.Mob; + +import net.fabricmc.fabric.impl.debug.EntityDebugSubscriptionRegistryImpl; + +/// The Mob class does not super-call +/// [net.minecraft.world.entity.Entity#registerDebugValues], so we have to +/// duplicate some code. +@Mixin(Mob.class) +public abstract class MobMixin { + @Inject( + method = "registerDebugValues", + at = @At("HEAD") + ) + private void addDebugValues( + ServerLevel level, + DebugValueSource.Registration registration, + CallbackInfo ci + ) { + EntityDebugSubscriptionRegistryImpl.addDebugValues(this, registration); + } +} diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/ServerDebugSubscribersMixin.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/ServerDebugSubscribersMixin.java new file mode 100644 index 00000000000..173b86d8685 --- /dev/null +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/ServerDebugSubscribersMixin.java @@ -0,0 +1,29 @@ +package net.fabricmc.fabric.mixin.debug; + +import com.llamalad7.mixinextras.expression.Definition; +import com.llamalad7.mixinextras.expression.Expression; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import net.minecraft.util.debug.ServerDebugSubscribers; + +import net.fabricmc.loader.api.FabricLoader; + +@Mixin(ServerDebugSubscribers.class) +public abstract class ServerDebugSubscribersMixin { + @Definition( + id = "IS_RUNNING_IN_IDE", + field = "Lnet/minecraft/SharedConstants;IS_RUNNING_IN_IDE:Z" + ) + @Expression("IS_RUNNING_IN_IDE") + @WrapOperation( + method = "hasRequiredPermissions", + at = @At("MIXINEXTRAS:EXPRESSION") + ) + private boolean requireInIde(Operation original) { + return original.call() || FabricLoader.getInstance() + .isDevelopmentEnvironment(); + } +} diff --git a/fabric-debug-api-v1/src/main/resources/assets/fabric-debug-api-v1/icon.png b/fabric-debug-api-v1/src/main/resources/assets/fabric-debug-api-v1/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..12c4531de92fe0544a0e15347f84381c132a7feb GIT binary patch literal 1555 zcmbVMONbmr817YeS0`Bvm<_8$sdPkC($if%&o0utJLwrS1L<{`3}loX(o5`x6Ep1Z4+am|^rTyU-RHPnPe)^ld+*!=$4&3I z>W!eGA48bhNyDT~k_>H^p*imGQs^3Zl?0$k+Loj8KVQ7W1ItwT6B%97U5#|C^1vg< z2P<_vSjCFTFD-(@Az}nJ2@DY0UB^eE$`5%FTSvzt4~CFnRpkqjLeS8wK%*W3nPgVL zFfD_el7v}Fk<*8OEWw;8R1=sseC60TqKJ9em~hy zC8^gIp`s|FB#W{vFofW*JAn}jj(>2%P$WL~EH|*I10qJFN!J3EXO@m!u-%x}@yB6e z0TV;R6=70}Tp9vR9OK+IuRBz3Vv%%-O`O1ISQum74h^W^p?^aii~pp6g;v*N9S^m| zwqq53Q0g%^#sPUK+OMy>M63~?u6dZ0dd$p&kvA^VJYodYt5e#YJXCdJGSIZ>Ve;Um z6P9DrzW?%$JEUj?MCBv70A&GY>oAKlX#{hElt+>@g6hlcrFNcIG_C5bC_#`dML=rKZ5X)F-wenaX=`<9S6l@7;C1a*r zFpYEBk-O}Ek>a%|3nur?|9Ss4&tg?*bRU@~s?8{UP}%a?!>*63=Qw$Dyy{wDm@&w} zQ6;E6j#7Y_{P@^<utq@Kv^7o)Nrxg!46%b{#X ziBI6HZ$!(uVX;lz@`%IwoW~m4((?!2X3g;ZO0iH6ziV#JEKKiv@r~aK;fD%m+`qeP zqj!gUd>JIZzIXQGa=BdwQ+vS+TaVp2d4HjC{TKZ1T^OEP^h*yupZ((7eYf^3ZRqE( zWln<`?)nV)~_M|=0.18.3", + "fabric-api-base": "*", + "fabric-registry-sync-v0": "*" + }, + "description": "A toolkit for registering and using debug subscriptions and other debug tools Mojang have created.", + "mixins": [ + "fabric-debug-api-v1.mixins.json", + { + "config": "fabric-debug-api-v1.client.mixins.json", + "environment": "client" + } + ], + "accessWidener" : "fabric-debug-api-v1.accesswidener", + "custom": { + "fabric-api:module-lifecycle": "stable" + } +} diff --git a/fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/DebugApiTest.java b/fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/DebugApiTest.java new file mode 100644 index 00000000000..f17206a8af0 --- /dev/null +++ b/fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/DebugApiTest.java @@ -0,0 +1,40 @@ +package net.fabricmc.fabric.test.debug; + +import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.Identifier; +import net.minecraft.util.debug.DebugSubscription; +import net.minecraft.world.entity.Avatar; +import net.minecraft.world.entity.decoration.Mannequin; + +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.debug.v1.EntityDebugSubscriptionRegistry; +import net.fabricmc.loader.api.FabricLoader; + +public class DebugApiTest implements ModInitializer { + public static DebugSubscription SUS_AVATAR; + public static boolean DEBUG_SUS_AVATAR = true; + + @Override + public void onInitialize() { + if (FabricLoader.getInstance().isDevelopmentEnvironment()) { + SUS_AVATAR = Registry.register( + BuiltInRegistries.DEBUG_SUBSCRIPTION, + Identifier.fromNamespaceAndPath( + "fabric-debug-api-v1-testmod", + "sus_avatar" + ), + new DebugSubscription<>(SusDebugInfo.STREAM_CODEC) + ); + EntityDebugSubscriptionRegistry.register( + SUS_AVATAR, + entity -> entity instanceof Avatar, + avatar -> new SusDebugInfo( + avatar.getPlainTextName(), + avatar instanceof Mannequin + ), + DEBUG_SUS_AVATAR + ); + } + } +} diff --git a/fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/SusDebugInfo.java b/fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/SusDebugInfo.java new file mode 100644 index 00000000000..75571d4cd30 --- /dev/null +++ b/fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/SusDebugInfo.java @@ -0,0 +1,20 @@ +package net.fabricmc.fabric.test.debug; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; + +public record SusDebugInfo( + String playerName, + boolean isSuspicious +) { + public static final StreamCodec STREAM_CODEC = StreamCodec.of( + (byteBuf, object) -> { + byteBuf.writeUtf(object.playerName); + byteBuf.writeBoolean(object.isSuspicious); + }, + byteBuf -> new SusDebugInfo( + byteBuf.readUtf(), + byteBuf.readBoolean() + ) + ); +} diff --git a/fabric-debug-api-v1/src/testmod/resources/fabric.mod.json b/fabric-debug-api-v1/src/testmod/resources/fabric.mod.json new file mode 100644 index 00000000000..ee5b29f9e73 --- /dev/null +++ b/fabric-debug-api-v1/src/testmod/resources/fabric.mod.json @@ -0,0 +1,18 @@ +{ + "schemaVersion": 1, + "id": "fabric-debug-api-v1-testmod", + "name": "Fabric Debug API (v1) Test Mod", + "version": "1.0.0", + "environment": "*", + "license": "Apache-2.0", + "entrypoints": { + "main": [ + "net.fabricmc.fabric.test.debug.DebugApiTest" + ], + "client": [ + "net.fabricmc.fabric.test.debug.client.DebugApiTestClient" + ], + "fabric-client-gametest": [ + ] + } +} diff --git a/fabric-debug-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/debug/client/DebugApiTestClient.java b/fabric-debug-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/debug/client/DebugApiTestClient.java new file mode 100644 index 00000000000..04fee801f45 --- /dev/null +++ b/fabric-debug-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/debug/client/DebugApiTestClient.java @@ -0,0 +1,112 @@ +package net.fabricmc.fabric.test.debug.client; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.culling.Frustum; +import net.minecraft.client.renderer.debug.DebugRenderer; +import net.minecraft.gizmos.GizmoStyle; +import net.minecraft.gizmos.Gizmos; +import net.minecraft.gizmos.TextGizmo; +import net.minecraft.util.ARGB; +import net.minecraft.util.debug.DebugValueAccess; +import net.minecraft.world.phys.Vec3; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.debug.v1.client.ClientDebugSubscriptionRegistry; +import net.fabricmc.fabric.api.debug.v1.client.renderer.DebugRendererRegistry; +import net.fabricmc.fabric.test.debug.DebugApiTest; +import net.fabricmc.loader.api.FabricLoader; + +public class DebugApiTestClient implements ClientModInitializer { + @Override + public void onInitializeClient() { + if (FabricLoader.getInstance().isDevelopmentEnvironment()) { + ClientDebugSubscriptionRegistry.register( + DebugApiTest.SUS_AVATAR, + DebugApiTest.DEBUG_SUS_AVATAR + ); + DebugRendererRegistry.register( + DebugApiTest.SUS_AVATAR, + SuspiciousDebugRenderer::new, + DebugApiTest.DEBUG_SUS_AVATAR + ); + } + } + + public static class SuspiciousDebugRenderer implements DebugRenderer.SimpleDebugRenderer { + public SuspiciousDebugRenderer(Minecraft ignoredMinecraft) { + } + + @Override + public void emitGizmos( + double d, + double e, + double f, + DebugValueAccess debugValueAccess, + Frustum frustum, + float g + ) { + debugValueAccess.forEachEntity( + DebugApiTest.SUS_AVATAR, + (entity, susDebugInfo) -> { + Gizmos.billboardText( + susDebugInfo.playerName(), + new Vec3(entity.getX(), entity.getY() + 3.25, entity.getZ()), + TextGizmo.Style.whiteAndCentered() + ); + + if (susDebugInfo.isSuspicious()) { + Vec3 arrowPos = new Vec3( + entity.getX() + 1.0, + entity.getY() + 2.7, + entity.getZ() + 1.0 + ); + Gizmos.arrow( + arrowPos, + arrowPos.add(new Vec3(-0.5, -1.0, -0.5)), + ARGB.color(255, 255, 0, 0) + ); + Gizmos.billboardText( + "Sussy", + arrowPos.add(0.0, 0.125, 0.0), + TextGizmo.Style.forColorAndCentered(ARGB.color( + 255, + 191, + 0, + 0 + )) + ); + Gizmos.circle( + new SwappedVec3(entity.getEyePosition()), + 0.5f, + GizmoStyle.stroke(ARGB.color( + 255, + 255, + 0, + 0 + ), 8.0f) + ); + } + } + ); + } + } + + private static class SwappedVec3 extends Vec3 { + SwappedVec3(double x, double y, double z) { + super(x, y, z); + } + + SwappedVec3(Vec3 vec3) { + this(vec3.x(), vec3.y(), vec3.z()); + } + + @Override + public Vec3 add(double d, double e, double f) { + return super.add( + f, + d, + e + ); + } + } +} diff --git a/gradle.properties b/gradle.properties index 23ce5d2d2e8..e9b1764653e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,6 +22,7 @@ fabric-content-registries-v0-version=11.0.2 fabric-crash-report-info-v1-version=1.0.0 fabric-data-attachment-api-v1-version=2.0.3 fabric-data-generation-api-v1-version=24.0.2 +fabric-debug-api-v1-version=1.0.0 fabric-dimensions-v1-version=5.0.0 fabric-entity-events-v1-version=4.1.1 fabric-events-interaction-v0-version=5.1.1 diff --git a/settings.gradle b/settings.gradle index e9fa705c1f7..5af79d947d7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -37,6 +37,7 @@ include 'fabric-crash-report-info-v1' include 'fabric-creative-tab-api-v1' include 'fabric-data-attachment-api-v1' include 'fabric-data-generation-api-v1' +include 'fabric-debug-api-v1' include 'fabric-dimensions-v1' include 'fabric-entity-events-v1' include 'fabric-events-interaction-v0' From b7ec8424162dc8c43813b7c13c99d85e9901b97a Mon Sep 17 00:00:00 2001 From: sylv256 Date: Tue, 13 Jan 2026 20:12:00 -0500 Subject: [PATCH 03/48] docs(EntityDebugSubscriptionRegistry): clarify it's server-side only --- .../fabric/api/debug/v1/EntityDebugSubscriptionRegistry.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EntityDebugSubscriptionRegistry.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EntityDebugSubscriptionRegistry.java index ae69f6d02a3..a0404efb454 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EntityDebugSubscriptionRegistry.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EntityDebugSubscriptionRegistry.java @@ -8,8 +8,8 @@ import net.fabricmc.fabric.impl.debug.EntityDebugSubscriptionRegistryImpl; -/// A registry for [debug subscriptions][DebugSubscription] specific to entities -/// or properties of entities. +/// A server-side registry for [debug subscriptions][DebugSubscription] specific +/// to entities or properties of entities. public final class EntityDebugSubscriptionRegistry { /// Registers a [DebugSubscription] based on a given [Entity] and /// [Predicate]. From 9f343f0db8479ca106fd9f43dee03a166ac3c761 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Tue, 13 Jan 2026 20:19:49 -0500 Subject: [PATCH 04/48] chore: apply licenses --- .../client/ClientDebugSubscriptionRegistry.java | 16 ++++++++++++++++ .../v1/client/renderer/DebugRendererFactory.java | 16 ++++++++++++++++ .../client/renderer/DebugRendererRegistry.java | 16 ++++++++++++++++ .../ClientDebugSubscriptionRegistryImpl.java | 16 ++++++++++++++++ .../renderer/DebugRendererRegistryImpl.java | 16 ++++++++++++++++ .../debug/client/ClientDebugSubscriberMixin.java | 16 ++++++++++++++++ .../mixin/debug/client/DebugRendererMixin.java | 16 ++++++++++++++++ .../fabric/api/debug/v1/DebugValueFactory.java | 16 ++++++++++++++++ .../v1/EntityDebugSubscriptionRegistry.java | 16 ++++++++++++++++ .../EntityDebugSubscriptionRegistryImpl.java | 16 ++++++++++++++++ .../fabricmc/fabric/mixin/debug/EntityMixin.java | 16 ++++++++++++++++ .../fabricmc/fabric/mixin/debug/MobMixin.java | 16 ++++++++++++++++ .../mixin/debug/ServerDebugSubscribersMixin.java | 16 ++++++++++++++++ .../fabricmc/fabric/test/debug/DebugApiTest.java | 16 ++++++++++++++++ .../fabricmc/fabric/test/debug/SusDebugInfo.java | 16 ++++++++++++++++ .../test/debug/client/DebugApiTestClient.java | 16 ++++++++++++++++ 16 files changed, 256 insertions(+) diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java index e7d82649bca..91e04f672f9 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.api.debug.v1.client; import java.util.Objects; diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java index f4985693217..6cecbd5a70b 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.api.debug.v1.client.renderer; import net.minecraft.client.Minecraft; diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererRegistry.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererRegistry.java index 9ef0ddecaae..c98c3fabef8 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererRegistry.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererRegistry.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.api.debug.v1.client.renderer; import java.util.Objects; diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/ClientDebugSubscriptionRegistryImpl.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/ClientDebugSubscriptionRegistryImpl.java index 87010fd75f2..3df5e245c2a 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/ClientDebugSubscriptionRegistryImpl.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/ClientDebugSubscriptionRegistryImpl.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.impl.debug.client; import java.util.HashSet; diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/renderer/DebugRendererRegistryImpl.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/renderer/DebugRendererRegistryImpl.java index d6d8d72bed2..be8e4250f09 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/renderer/DebugRendererRegistryImpl.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/renderer/DebugRendererRegistryImpl.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.impl.debug.client.renderer; import java.util.HashSet; diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/ClientDebugSubscriberMixin.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/ClientDebugSubscriberMixin.java index b85c71d3612..b7c8637ace6 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/ClientDebugSubscriberMixin.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/ClientDebugSubscriberMixin.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.mixin.debug.client; import java.util.Set; diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/DebugRendererMixin.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/DebugRendererMixin.java index b1374722e51..7ea91774790 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/DebugRendererMixin.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/DebugRendererMixin.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.mixin.debug.client; import java.util.List; diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/DebugValueFactory.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/DebugValueFactory.java index 27a495ddde6..fe144b3fe11 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/DebugValueFactory.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/DebugValueFactory.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.api.debug.v1; /// Constructs a debug value of type [T] using data of type [D] diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EntityDebugSubscriptionRegistry.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EntityDebugSubscriptionRegistry.java index a0404efb454..4783ea6266f 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EntityDebugSubscriptionRegistry.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EntityDebugSubscriptionRegistry.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.api.debug.v1; import java.util.Objects; diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EntityDebugSubscriptionRegistryImpl.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EntityDebugSubscriptionRegistryImpl.java index acbe691ac77..1c3f66a0c62 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EntityDebugSubscriptionRegistryImpl.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EntityDebugSubscriptionRegistryImpl.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.impl.debug; import java.util.HashSet; diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java index 94844c8da89..40e1704fb59 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.mixin.debug; import org.spongepowered.asm.mixin.Mixin; diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java index 97e2f977a00..4f90e2e12de 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.mixin.debug; import org.spongepowered.asm.mixin.Mixin; diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/ServerDebugSubscribersMixin.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/ServerDebugSubscribersMixin.java index 173b86d8685..5112fb639a6 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/ServerDebugSubscribersMixin.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/ServerDebugSubscribersMixin.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.mixin.debug; import com.llamalad7.mixinextras.expression.Definition; diff --git a/fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/DebugApiTest.java b/fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/DebugApiTest.java index f17206a8af0..4c589bc5758 100644 --- a/fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/DebugApiTest.java +++ b/fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/DebugApiTest.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.test.debug; import net.minecraft.core.Registry; diff --git a/fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/SusDebugInfo.java b/fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/SusDebugInfo.java index 75571d4cd30..103dc6020a5 100644 --- a/fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/SusDebugInfo.java +++ b/fabric-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/SusDebugInfo.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.test.debug; import net.minecraft.network.RegistryFriendlyByteBuf; diff --git a/fabric-debug-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/debug/client/DebugApiTestClient.java b/fabric-debug-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/debug/client/DebugApiTestClient.java index 04fee801f45..3fe76a822cb 100644 --- a/fabric-debug-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/debug/client/DebugApiTestClient.java +++ b/fabric-debug-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/debug/client/DebugApiTestClient.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.test.debug.client; import net.minecraft.client.Minecraft; From 23099802e61d1fefdbd5a0059dc48ad7efe3e519 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Tue, 20 Jan 2026 16:07:50 -0500 Subject: [PATCH 05/48] docs: `Constructor` -> `Factory` terminology on factory interfaces --- .../api/debug/v1/client/renderer/DebugRendererFactory.java | 2 +- .../net/fabricmc/fabric/api/debug/v1/DebugValueFactory.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java index 6cecbd5a70b..294cf90a5f1 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java @@ -19,7 +19,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.debug.DebugRenderer; -/// A constructor for a +/// A factory that creates a /// [debug subscription][net.minecraft.util.debug.DebugSubscription] renderer. @FunctionalInterface public interface DebugRendererFactory { diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/DebugValueFactory.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/DebugValueFactory.java index fe144b3fe11..c41cd34a0b9 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/DebugValueFactory.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/DebugValueFactory.java @@ -16,11 +16,11 @@ package net.fabricmc.fabric.api.debug.v1; -/// Constructs a debug value of type [T] using data of type [D] +/// A factory that creates a debug value of type [T] using data of type [D]. /// /// @param the data passed for construction -/// (e.g. [net.minecraft.world.entity.Entity]) -/// @param the debug value being constructed +/// (e.g. [net.minecraft.world.entity.Entity]). +/// @param the debug value being constructed. @FunctionalInterface public interface DebugValueFactory { T create(D data); From f0a43db27c64e5e852a87ad132c4e06420750d03 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Fri, 23 Jan 2026 17:13:02 -0500 Subject: [PATCH 06/48] fix: depend `fabricloader` `>=0.18.4` --- fabric-debug-api-v1/src/main/resources/fabric.mod.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric-debug-api-v1/src/main/resources/fabric.mod.json b/fabric-debug-api-v1/src/main/resources/fabric.mod.json index b2786dcf90d..4b76263097f 100644 --- a/fabric-debug-api-v1/src/main/resources/fabric.mod.json +++ b/fabric-debug-api-v1/src/main/resources/fabric.mod.json @@ -16,7 +16,7 @@ "FabricMC" ], "depends": { - "fabricloader": ">=0.18.3", + "fabricloader": ">=0.18.4", "fabric-api-base": "*", "fabric-registry-sync-v0": "*" }, From 9754e49fc402fdb3e9cdd10fafd586c7fb882d00 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Sun, 25 Jan 2026 21:30:00 -0500 Subject: [PATCH 07/48] refactor: merge `MobMixin` & `EntityMixin` --- .../fabric/mixin/debug/EntityMixin.java | 5 +- .../fabricmc/fabric/mixin/debug/MobMixin.java | 46 ------------------- .../resources/fabric-debug-api-v1.mixins.json | 1 - 3 files changed, 4 insertions(+), 48 deletions(-) delete mode 100644 fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java index 40e1704fb59..03ca9c5c150 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java @@ -24,10 +24,13 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.util.debug.DebugValueSource; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.Mob; import net.fabricmc.fabric.impl.debug.EntityDebugSubscriptionRegistryImpl; -@Mixin(Entity.class) +/// The Mob class does not super-call +/// [net.minecraft.world.entity.Entity#registerDebugValues], so we have to Mixin it as well. +@Mixin(value = {Entity.class, Mob.class}) public abstract class EntityMixin { @Inject( method = "registerDebugValues", diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java deleted file mode 100644 index 4f90e2e12de..00000000000 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.fabricmc.fabric.mixin.debug; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import net.minecraft.server.level.ServerLevel; -import net.minecraft.util.debug.DebugValueSource; -import net.minecraft.world.entity.Mob; - -import net.fabricmc.fabric.impl.debug.EntityDebugSubscriptionRegistryImpl; - -/// The Mob class does not super-call -/// [net.minecraft.world.entity.Entity#registerDebugValues], so we have to -/// duplicate some code. -@Mixin(Mob.class) -public abstract class MobMixin { - @Inject( - method = "registerDebugValues", - at = @At("HEAD") - ) - private void addDebugValues( - ServerLevel level, - DebugValueSource.Registration registration, - CallbackInfo ci - ) { - EntityDebugSubscriptionRegistryImpl.addDebugValues(this, registration); - } -} diff --git a/fabric-debug-api-v1/src/main/resources/fabric-debug-api-v1.mixins.json b/fabric-debug-api-v1/src/main/resources/fabric-debug-api-v1.mixins.json index 3d269d3c84d..90c7e828aa1 100644 --- a/fabric-debug-api-v1/src/main/resources/fabric-debug-api-v1.mixins.json +++ b/fabric-debug-api-v1/src/main/resources/fabric-debug-api-v1.mixins.json @@ -4,7 +4,6 @@ "compatibilityLevel": "JAVA_25", "mixins": [ "EntityMixin", - "MobMixin", "ServerDebugSubscribersMixin" ], "injectors": { From c3ac770a3682a8819e3c22d81642ccb3da16d3dd Mon Sep 17 00:00:00 2001 From: Sylv Date: Sun, 25 Jan 2026 21:47:31 -0500 Subject: [PATCH 08/48] use @apiNote in javadoc and use package-private Mixins Co-authored-by: Juuz <6596629+Juuxel@users.noreply.github.com> --- .../api/debug/v1/client/ClientDebugSubscriptionRegistry.java | 4 ++-- .../fabric/mixin/debug/client/ClientDebugSubscriberMixin.java | 2 +- .../fabric/mixin/debug/client/DebugRendererMixin.java | 2 +- .../java/net/fabricmc/fabric/mixin/debug/EntityMixin.java | 2 +- .../main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java | 2 +- .../fabric/mixin/debug/ServerDebugSubscribersMixin.java | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java index 91e04f672f9..163f5f93375 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java @@ -27,7 +27,7 @@ public final class ClientDebugSubscriptionRegistry { /// Registers a [DebugSubscription] on the client. /// - /// **Note:** this will register **outside development environments** if it + /// @apiNote This will register **outside development environments** if it /// is not checked. Surround calls to this method with /// [net.fabricmc.loader.api.FabricLoader#isDevelopmentEnvironment] if you /// do not intend for a debug feature to be present in production. @@ -42,7 +42,7 @@ public static void register(DebugSubscription debugSubscription) { /// Registers a [DebugSubscription] on the client if the `isEnabledFlag` /// parameter is `true`. /// - /// **Note:** this will register **outside development environments** if it + /// @apiNote This will register **outside development environments** if it /// is not checked. Surround calls to this method with /// [net.fabricmc.loader.api.FabricLoader#isDevelopmentEnvironment] if you /// do not intend for a debug feature to be present in production. diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/ClientDebugSubscriberMixin.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/ClientDebugSubscriberMixin.java index b7c8637ace6..b0e1135d4b1 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/ClientDebugSubscriberMixin.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/ClientDebugSubscriberMixin.java @@ -30,7 +30,7 @@ import net.fabricmc.fabric.impl.debug.client.ClientDebugSubscriptionRegistryImpl; @Mixin(ClientDebugSubscriber.class) -public abstract class ClientDebugSubscriberMixin { +abstract class ClientDebugSubscriberMixin { @Inject( method = "requestedSubscriptions", at = @At("RETURN") diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/DebugRendererMixin.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/DebugRendererMixin.java index 7ea91774790..aa7624b2d77 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/DebugRendererMixin.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/mixin/debug/client/DebugRendererMixin.java @@ -31,7 +31,7 @@ import net.fabricmc.fabric.impl.debug.client.renderer.DebugRendererRegistryImpl; @Mixin(DebugRenderer.class) -public abstract class DebugRendererMixin { +abstract class DebugRendererMixin { @Shadow @Final private List renderers; diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java index 40e1704fb59..c41bcacebcc 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/EntityMixin.java @@ -28,7 +28,7 @@ import net.fabricmc.fabric.impl.debug.EntityDebugSubscriptionRegistryImpl; @Mixin(Entity.class) -public abstract class EntityMixin { +abstract class EntityMixin { @Inject( method = "registerDebugValues", at = @At("HEAD") diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java index 4f90e2e12de..3addd6833f1 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/MobMixin.java @@ -31,7 +31,7 @@ /// [net.minecraft.world.entity.Entity#registerDebugValues], so we have to /// duplicate some code. @Mixin(Mob.class) -public abstract class MobMixin { +abstract class MobMixin { @Inject( method = "registerDebugValues", at = @At("HEAD") diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/ServerDebugSubscribersMixin.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/ServerDebugSubscribersMixin.java index 5112fb639a6..f68947d1710 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/ServerDebugSubscribersMixin.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/mixin/debug/ServerDebugSubscribersMixin.java @@ -28,7 +28,7 @@ import net.fabricmc.loader.api.FabricLoader; @Mixin(ServerDebugSubscribers.class) -public abstract class ServerDebugSubscribersMixin { +abstract class ServerDebugSubscribersMixin { @Definition( id = "IS_RUNNING_IN_IDE", field = "Lnet/minecraft/SharedConstants;IS_RUNNING_IN_IDE:Z" From d3271d8ab92a525bdb8bae3e50d14fec489e5626 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Sun, 25 Jan 2026 21:51:57 -0500 Subject: [PATCH 09/48] =?UTF-8?q?refactor!:=20`net.fabricmc.fabric.api.deb?= =?UTF-8?q?ug.v1.client`=20->=20`=E2=80=A6.api.client.debug.v1`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../debug/v1}/ClientDebugSubscriptionRegistry.java | 2 +- .../debug/v1}/renderer/DebugRendererFactory.java | 2 +- .../debug/v1}/renderer/DebugRendererRegistry.java | 2 +- .../impl/debug/client/renderer/DebugRendererRegistryImpl.java | 2 +- .../fabricmc/fabric/test/debug/client/DebugApiTestClient.java | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) rename fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/{debug/v1/client => client/debug/v1}/ClientDebugSubscriptionRegistry.java (98%) rename fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/{debug/v1/client => client/debug/v1}/renderer/DebugRendererFactory.java (94%) rename fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/{debug/v1/client => client/debug/v1}/renderer/DebugRendererRegistry.java (97%) diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/client/debug/v1/ClientDebugSubscriptionRegistry.java similarity index 98% rename from fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java rename to fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/client/debug/v1/ClientDebugSubscriptionRegistry.java index 163f5f93375..e9cfa9ac7f9 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/ClientDebugSubscriptionRegistry.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/client/debug/v1/ClientDebugSubscriptionRegistry.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.api.debug.v1.client; +package net.fabricmc.fabric.api.client.debug.v1; import java.util.Objects; diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/client/debug/v1/renderer/DebugRendererFactory.java similarity index 94% rename from fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java rename to fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/client/debug/v1/renderer/DebugRendererFactory.java index 294cf90a5f1..10096abd025 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererFactory.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/client/debug/v1/renderer/DebugRendererFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.api.debug.v1.client.renderer; +package net.fabricmc.fabric.api.client.debug.v1.renderer; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.debug.DebugRenderer; diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererRegistry.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/client/debug/v1/renderer/DebugRendererRegistry.java similarity index 97% rename from fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererRegistry.java rename to fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/client/debug/v1/renderer/DebugRendererRegistry.java index c98c3fabef8..c5df8a858a5 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/debug/v1/client/renderer/DebugRendererRegistry.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/api/client/debug/v1/renderer/DebugRendererRegistry.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.api.debug.v1.client.renderer; +package net.fabricmc.fabric.api.client.debug.v1.renderer; import java.util.Objects; diff --git a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/renderer/DebugRendererRegistryImpl.java b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/renderer/DebugRendererRegistryImpl.java index be8e4250f09..1e74d352f78 100644 --- a/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/renderer/DebugRendererRegistryImpl.java +++ b/fabric-debug-api-v1/src/client/java/net/fabricmc/fabric/impl/debug/client/renderer/DebugRendererRegistryImpl.java @@ -22,7 +22,7 @@ import net.minecraft.util.debug.DebugSubscription; -import net.fabricmc.fabric.api.debug.v1.client.renderer.DebugRendererFactory; +import net.fabricmc.fabric.api.client.debug.v1.renderer.DebugRendererFactory; public final class DebugRendererRegistryImpl { public static final Set RENDERERS = new HashSet<>(); diff --git a/fabric-debug-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/debug/client/DebugApiTestClient.java b/fabric-debug-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/debug/client/DebugApiTestClient.java index 3fe76a822cb..01d5f2a8afe 100644 --- a/fabric-debug-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/debug/client/DebugApiTestClient.java +++ b/fabric-debug-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/debug/client/DebugApiTestClient.java @@ -27,8 +27,8 @@ import net.minecraft.world.phys.Vec3; import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.fabric.api.debug.v1.client.ClientDebugSubscriptionRegistry; -import net.fabricmc.fabric.api.debug.v1.client.renderer.DebugRendererRegistry; +import net.fabricmc.fabric.api.client.debug.v1.ClientDebugSubscriptionRegistry; +import net.fabricmc.fabric.api.client.debug.v1.renderer.DebugRendererRegistry; import net.fabricmc.fabric.test.debug.DebugApiTest; import net.fabricmc.loader.api.FabricLoader; From dffdb53d2d1edf74de9b296902601eee82c84020 Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Sun, 29 Mar 2026 22:48:56 +0200 Subject: [PATCH 10/48] Move event scopes to debug api --- build.gradle | 3 +-- .../src/main/java/net/fabricmc/fabric/api/test/EventScope.java | 0 .../main/java/net/fabricmc/fabric/api/test/EventTesting.java | 0 .../java/net/fabricmc/fabric/impl/test/EventScopeImpl.java | 0 .../java/net/fabricmc/fabric/impl/test/EventTestingImpl.java | 0 .../fabricmc/fabric/impl/test/TestableArrayBackedEvent.java | 0 .../fabricmc/fabric/impl/test/TestableEventFactoryImpl.java | 0 .../net.fabricmc.fabric.impl.base.event.EventFactoryImpl | 0 fabric-test-api-v1/build.gradle | 3 --- settings.gradle | 1 - 10 files changed, 1 insertion(+), 6 deletions(-) rename {fabric-test-api-v1 => fabric-debug-api-v1}/src/main/java/net/fabricmc/fabric/api/test/EventScope.java (100%) rename {fabric-test-api-v1 => fabric-debug-api-v1}/src/main/java/net/fabricmc/fabric/api/test/EventTesting.java (100%) rename {fabric-test-api-v1 => fabric-debug-api-v1}/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java (100%) rename {fabric-test-api-v1 => fabric-debug-api-v1}/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java (100%) rename {fabric-test-api-v1 => fabric-debug-api-v1}/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java (100%) rename {fabric-test-api-v1 => fabric-debug-api-v1}/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java (100%) rename {fabric-test-api-v1 => fabric-debug-api-v1}/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl (100%) delete mode 100644 fabric-test-api-v1/build.gradle diff --git a/build.gradle b/build.gradle index bc47f5dbc6f..f12291ea116 100644 --- a/build.gradle +++ b/build.gradle @@ -614,8 +614,7 @@ void setupRepositories(RepositoryHandler repositories) { // These modules are not included in the fat jar, maven will resolve them via the pom. def devOnlyModules = [ "fabric-client-gametest-api-v1", - "fabric-gametest-api-v1", - "fabric-test-api-v1", + "fabric-gametest-api-v1" ] dependencies { diff --git a/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java similarity index 100% rename from fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java rename to fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java diff --git a/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventTesting.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventTesting.java similarity index 100% rename from fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventTesting.java rename to fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventTesting.java diff --git a/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java similarity index 100% rename from fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java rename to fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java diff --git a/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java similarity index 100% rename from fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java rename to fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java diff --git a/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java similarity index 100% rename from fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java rename to fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java diff --git a/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java similarity index 100% rename from fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java rename to fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java diff --git a/fabric-test-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl b/fabric-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl similarity index 100% rename from fabric-test-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl rename to fabric-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl diff --git a/fabric-test-api-v1/build.gradle b/fabric-test-api-v1/build.gradle deleted file mode 100644 index 9ced6ef8b49..00000000000 --- a/fabric-test-api-v1/build.gradle +++ /dev/null @@ -1,3 +0,0 @@ -version = getSubprojectVersion(project) - -moduleDependencies(project, ['fabric-api-base']) diff --git a/settings.gradle b/settings.gradle index 1b3bc601aaf..8e249715bc4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -65,7 +65,6 @@ include 'fabric-screen-api-v1' include 'fabric-serialization-api-v1' include 'fabric-sound-api-v1' include 'fabric-tag-api-v1' -include 'fabric-test-api-v1' include 'fabric-transfer-api-v1' include 'fabric-transitive-access-wideners-v1' include 'deprecated' From 2cc663fb67fce81b93d7f07adf04bf421f40067c Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Sun, 29 Mar 2026 23:31:12 +0200 Subject: [PATCH 11/48] refactor: ServerMobEffectsGameTest now uses EventScopes refactor: ServerMobEffectsGameTest now uses EventScopes, an api introduced through the fabric-debug-api-v1 module --- .../fabricmc/fabric/api/test/EventScope.java | 14 +++++ .../fabric/api/test/EventTesting.java | 20 ------- fabric-entity-events-v1/build.gradle | 3 +- .../gametest/ServerMobEffectsGameTest.java | 58 ++++++++++--------- 4 files changed, 47 insertions(+), 48 deletions(-) delete mode 100644 fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventTesting.java diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java index 0e96b0c679b..f4529562613 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java @@ -1,9 +1,23 @@ package net.fabricmc.fabric.api.test; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.impl.test.EventTestingImpl; + +import net.minecraft.resources.Identifier; + import org.jetbrains.annotations.ApiStatus; @ApiStatus.NonExtendable +@FunctionalInterface public interface EventScope extends AutoCloseable { @Override void close(); + + static EventScope registerScoped(Event event, T listener) { + return registerScoped(event, Event.DEFAULT_PHASE, listener); + } + + static EventScope registerScoped(Event event, Identifier phase, T listener) { + return EventTestingImpl.registerScoped(event, phase, listener); + } } diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventTesting.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventTesting.java deleted file mode 100644 index be813cb3d68..00000000000 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventTesting.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.fabricmc.fabric.api.test; - -import net.fabricmc.fabric.api.event.Event; - -import net.fabricmc.fabric.impl.test.EventTestingImpl; - -import net.minecraft.resources.Identifier; - -public final class EventTesting { - private EventTesting() { - } - - public static EventScope registerScoped(Event event, T listener) { - return registerScoped(event, Event.DEFAULT_PHASE, listener); - } - - public static EventScope registerScoped(Event event, Identifier phase, T listener) { - return EventTestingImpl.registerScoped(event, phase, listener); - } -} diff --git a/fabric-entity-events-v1/build.gradle b/fabric-entity-events-v1/build.gradle index 54d84046d6c..ee59808b9f5 100644 --- a/fabric-entity-events-v1/build.gradle +++ b/fabric-entity-events-v1/build.gradle @@ -10,5 +10,6 @@ testDependencies(project, [ ':fabric-command-api-v2', ':fabric-networking-api-v1', ':fabric-registry-sync-v0', - ':fabric-rendering-v1' + ':fabric-rendering-v1', + ':fabric-debug-api-v1' ]) diff --git a/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java b/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java index 3b5e553ba39..8c24a50f25b 100644 --- a/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java +++ b/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java @@ -16,6 +16,7 @@ package net.fabricmc.fabric.test.entity.event.gametest; +import net.fabricmc.fabric.api.test.EventScope; import net.minecraft.core.Holder; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.world.InteractionHand; @@ -110,42 +111,45 @@ public void allowEarlyRemove(GameTestHelper context) { @GameTest public void beforeAfterRemove(GameTestHelper context) { - var obj = new Object() { // Scoped events at home - GameTestHelper contextRef = context; + ServerMobEffectEvents.BeforeRemove beforeRemove = (_, entity, _) -> { + if (!isThisTheSalmon(entity) || context == null) return; + context.assertTrue(entity.hasEffect(MobEffects.SATURATION), "The Salmon must have saturation as it should not yet have been removed"); }; - ServerMobEffectEvents.BEFORE_REMOVE.register((effectInstance, entity, ctx) -> { - if (!isThisTheSalmon(entity) || obj.contextRef == null) return; - obj.contextRef.assertTrue(entity.hasEffect(MobEffects.SATURATION), "The Salmon must have saturation as it should not yet have been removed"); - }); - ServerMobEffectEvents.AFTER_REMOVE.register((effectInstance, entity, ctx) -> { - if (!isThisTheSalmon(entity) || obj.contextRef == null) return; - obj.contextRef.assertFalse(entity.hasEffect(MobEffects.SATURATION), "The Salmon mustn't have saturation as it should have been removed by now"); - }); + + ServerMobEffectEvents.AfterRemove afterRemove = (_, entity, _) -> { + if (!isThisTheSalmon(entity) || context == null) return; + context.assertFalse(entity.hasEffect(MobEffects.SATURATION), "The Salmon mustn't have saturation as it should have been removed by now"); + }; + Salmon theSalmon = summonTheSalmon(context); - theSalmon.addEffect(createEffect(MobEffects.SATURATION)); - theSalmon.removeEffect(MobEffects.SATURATION); - context.succeed(); - obj.contextRef = null; + try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.BEFORE_REMOVE, beforeRemove); + EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_REMOVE, afterRemove) + ) { + theSalmon.addEffect(createEffect(MobEffects.SATURATION)); + theSalmon.removeEffect(MobEffects.SATURATION); + context.succeed(); + } } // Regression test for https://github.com/FabricMC/fabric-api/issues/5121 @GameTest public void removeNoneExistentEffect(GameTestHelper context) { - var obj = new Object() { // Scoped events at home - GameTestHelper contextRef = context; + ServerMobEffectEvents.BeforeRemove beforeRemove = (_, entity, _) -> { + if (!isThisTheSalmon(entity)) return; + context.fail("The BEFORE_REMOVE event must not be called when removing a non-existent effect"); }; - ServerMobEffectEvents.BEFORE_REMOVE.register((effectInstance, entity, ctx) -> { - if (!isThisTheSalmon(entity) || obj.contextRef == null) return; - obj.contextRef.fail("The BEFORE_REMOVE event must not be called when removing a non-existent effect"); - }); - ServerMobEffectEvents.AFTER_REMOVE.register((effectInstance, entity, ctx) -> { - if (!isThisTheSalmon(entity) || obj.contextRef == null) return; - obj.contextRef.fail("The AFTER_REMOVE event must not be called when removing a non-existent effect"); - }); + ServerMobEffectEvents.AfterRemove afterRemove = (_, entity, _) -> { + if (!isThisTheSalmon(entity)) return; + context.fail("The AFTER_REMOVE event must not be called when removing a non-existent effect"); + }; + Salmon theSalmon = summonTheSalmon(context); - theSalmon.removeEffect(MobEffects.SATURATION); - context.succeed(); - obj.contextRef = null; + try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.BEFORE_REMOVE, beforeRemove); + EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_REMOVE, afterRemove) + ) { + theSalmon.removeEffect(MobEffects.SATURATION); + context.succeed(); + } } private static Salmon summonTheSalmon(GameTestHelper context) { From 64235c9dabc415d1f830da7559c7cc5887bd69f1 Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Mon, 30 Mar 2026 00:21:45 +0200 Subject: [PATCH 12/48] spotless apply --- .../entity/event/gametest/ServerMobEffectsGameTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java b/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java index 8c24a50f25b..2fb7f8e3dfb 100644 --- a/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java +++ b/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java @@ -16,7 +16,6 @@ package net.fabricmc.fabric.test.entity.event.gametest; -import net.fabricmc.fabric.api.test.EventScope; import net.minecraft.core.Holder; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.world.InteractionHand; @@ -34,6 +33,7 @@ import net.fabricmc.fabric.api.entity.event.v1.effect.ServerMobEffectEvents; import net.fabricmc.fabric.api.gametest.v1.GameTest; +import net.fabricmc.fabric.api.test.EventScope; public class ServerMobEffectsGameTest { @GameTest @@ -123,7 +123,7 @@ public void beforeAfterRemove(GameTestHelper context) { Salmon theSalmon = summonTheSalmon(context); try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.BEFORE_REMOVE, beforeRemove); - EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_REMOVE, afterRemove) + EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_REMOVE, afterRemove) ) { theSalmon.addEffect(createEffect(MobEffects.SATURATION)); theSalmon.removeEffect(MobEffects.SATURATION); @@ -145,7 +145,7 @@ public void removeNoneExistentEffect(GameTestHelper context) { Salmon theSalmon = summonTheSalmon(context); try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.BEFORE_REMOVE, beforeRemove); - EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_REMOVE, afterRemove) + EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_REMOVE, afterRemove) ) { theSalmon.removeEffect(MobEffects.SATURATION); context.succeed(); From 6abca3686e86717e639d71516195fedbea5a6c93 Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Mon, 30 Mar 2026 00:23:05 +0200 Subject: [PATCH 13/48] fix: checkstyle --- .../java/net/fabricmc/fabric/api/test/EventScope.java | 6 +++--- .../net/fabricmc/fabric/impl/test/EventScopeImpl.java | 4 ++-- .../net/fabricmc/fabric/impl/test/EventTestingImpl.java | 4 ++-- .../fabric/impl/test/TestableArrayBackedEvent.java | 6 +++--- .../fabric/impl/test/TestableEventFactoryImpl.java | 8 ++------ .../entity/event/gametest/ServerMobEffectsGameTest.java | 4 ++-- 6 files changed, 14 insertions(+), 18 deletions(-) diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java index f4529562613..a40412b28cc 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java @@ -1,11 +1,11 @@ package net.fabricmc.fabric.api.test; -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.impl.test.EventTestingImpl; +import org.jetbrains.annotations.ApiStatus; import net.minecraft.resources.Identifier; -import org.jetbrains.annotations.ApiStatus; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.impl.test.EventTestingImpl; @ApiStatus.NonExtendable @FunctionalInterface diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java index 5df048884f0..6ccc2907fed 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java @@ -1,9 +1,9 @@ package net.fabricmc.fabric.impl.test; -import net.fabricmc.fabric.api.test.EventScope; - import net.minecraft.resources.Identifier; +import net.fabricmc.fabric.api.test.EventScope; + public class EventScopeImpl implements EventScope { private final TestableArrayBackedEvent event; private final Identifier phase; diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java index c555789c198..504cdcea2de 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java @@ -1,10 +1,10 @@ package net.fabricmc.fabric.impl.test; +import net.minecraft.resources.Identifier; + import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.test.EventScope; -import net.minecraft.resources.Identifier; - public final class EventTestingImpl { private EventTestingImpl() { } diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java index 76f15695386..6fff9b599f6 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java @@ -1,11 +1,11 @@ package net.fabricmc.fabric.impl.test; -import net.fabricmc.fabric.impl.base.event.ArrayBackedEvent; +import java.util.Objects; +import java.util.function.Function; import net.minecraft.resources.Identifier; -import java.util.Objects; -import java.util.function.Function; +import net.fabricmc.fabric.impl.base.event.ArrayBackedEvent; class TestableArrayBackedEvent extends ArrayBackedEvent { TestableArrayBackedEvent(Class type, Function invokerFactory) { diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java index c5c3356fb27..10053aa1181 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java @@ -1,14 +1,10 @@ package net.fabricmc.fabric.impl.test; -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.test.EventScope; +import java.util.function.Function; + import net.fabricmc.fabric.impl.base.event.ArrayBackedEvent; import net.fabricmc.fabric.impl.base.event.EventFactoryImpl; -import net.minecraft.resources.Identifier; - -import java.util.function.Function; - public class TestableEventFactoryImpl extends EventFactoryImpl { @Override protected ArrayBackedEvent doCreateArrayBacked(Class type, Function invokerFactory) { diff --git a/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java b/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java index 2fb7f8e3dfb..34f60a8a0ff 100644 --- a/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java +++ b/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java @@ -123,7 +123,7 @@ public void beforeAfterRemove(GameTestHelper context) { Salmon theSalmon = summonTheSalmon(context); try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.BEFORE_REMOVE, beforeRemove); - EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_REMOVE, afterRemove) + EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_REMOVE, afterRemove) ) { theSalmon.addEffect(createEffect(MobEffects.SATURATION)); theSalmon.removeEffect(MobEffects.SATURATION); @@ -145,7 +145,7 @@ public void removeNoneExistentEffect(GameTestHelper context) { Salmon theSalmon = summonTheSalmon(context); try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.BEFORE_REMOVE, beforeRemove); - EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_REMOVE, afterRemove) + EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_REMOVE, afterRemove) ) { theSalmon.removeEffect(MobEffects.SATURATION); context.succeed(); From 21584f02d9050e1b9c3209901fea0e3c7ee61a37 Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Mon, 30 Mar 2026 01:34:57 +0200 Subject: [PATCH 14/48] chore: more descriptive exceptions --- .../main/java/net/fabricmc/fabric/api/test/EventScope.java | 1 - .../java/net/fabricmc/fabric/impl/test/EventTestingImpl.java | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java index a40412b28cc..12d92c8fddb 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java @@ -8,7 +8,6 @@ import net.fabricmc.fabric.impl.test.EventTestingImpl; @ApiStatus.NonExtendable -@FunctionalInterface public interface EventScope extends AutoCloseable { @Override void close(); diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java index 504cdcea2de..2370a2ae5d5 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java @@ -4,12 +4,17 @@ import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.test.EventScope; +import net.fabricmc.loader.api.FabricLoader; public final class EventTestingImpl { private EventTestingImpl() { } public static EventScope registerScoped(Event event, Identifier phase, T listener) { + if (!FabricLoader.getInstance().isDevelopmentEnvironment()) { + throw new IllegalArgumentException("EventScopes only work in development environments!"); + } + if (!(event instanceof TestableArrayBackedEvent testableEvent)) { throw new IllegalArgumentException("Event is not testable, something has gone very wrong!"); } From 55d1173ff59edba1570a31c1eff1cccc8be1978d Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Mon, 30 Mar 2026 01:35:14 +0200 Subject: [PATCH 15/48] chore: remove unnecessary code remove unnecessary null checking --- .../test/entity/event/gametest/ServerMobEffectsGameTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java b/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java index 34f60a8a0ff..611ae2fb97f 100644 --- a/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java +++ b/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java @@ -112,12 +112,12 @@ public void allowEarlyRemove(GameTestHelper context) { @GameTest public void beforeAfterRemove(GameTestHelper context) { ServerMobEffectEvents.BeforeRemove beforeRemove = (_, entity, _) -> { - if (!isThisTheSalmon(entity) || context == null) return; + if (!isThisTheSalmon(entity)) return; context.assertTrue(entity.hasEffect(MobEffects.SATURATION), "The Salmon must have saturation as it should not yet have been removed"); }; ServerMobEffectEvents.AfterRemove afterRemove = (_, entity, _) -> { - if (!isThisTheSalmon(entity) || context == null) return; + if (!isThisTheSalmon(entity)) return; context.assertFalse(entity.hasEffect(MobEffects.SATURATION), "The Salmon mustn't have saturation as it should have been removed by now"); }; From 6320f81a5f291caca36f72c96b05a47766ffb480 Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Mon, 30 Mar 2026 01:46:18 +0200 Subject: [PATCH 16/48] refactor: use EventScopes more --- .../gametest/ServerMobEffectsGameTest.java | 87 ++++++++++--------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java b/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java index 611ae2fb97f..7bfb7fabb5f 100644 --- a/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java +++ b/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java @@ -38,75 +38,82 @@ public class ServerMobEffectsGameTest { @GameTest public void allowAdd(GameTestHelper context) { - ServerMobEffectEvents.ALLOW_ADD.register((effectInstance, entity, ctx) -> { + ServerMobEffectEvents.AllowAdd allowAdd = (effectInstance, entity, ctx) -> { if (ctx.isFromCommand()) return true; // If the entity wants to regenerate and is holding a potato, // deny them regeneration privileges. // This is specific enough since events aren't scoped for // GameTests. return !(effectInstance.is(MobEffects.REGENERATION) && isThisTheSalmon(entity)); - }); + }; + Salmon theSalmon = summonTheSalmon(context); - theSalmon.addEffect(createEffect(MobEffects.REGENERATION)); - context.assertTrue(theSalmon.getMainHandItem().is(Items.POTATO), "The Salmon must be holding (how!?) a potato"); - context.assertFalse(theSalmon.hasEffect(MobEffects.REGENERATION), "The Salmon must not have regeneration"); - context.succeed(); + + try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.ALLOW_ADD, allowAdd)) { + theSalmon.addEffect(createEffect(MobEffects.REGENERATION)); + context.assertTrue(theSalmon.getMainHandItem().is(Items.POTATO), "The Salmon must be holding (how!?) a potato"); + context.assertFalse(theSalmon.hasEffect(MobEffects.REGENERATION), "The Salmon must not have regeneration"); + context.succeed(); + } } @GameTest public void beforeAfterAdd(GameTestHelper context) { - var obj = new Object() { // Scoped events at home - GameTestHelper contextRef = context; + ServerMobEffectEvents.BeforeAdd beforeAdd = (_, entity, _) -> { + if (!isThisTheSalmon(entity)) return; + context.assertFalse(entity.hasEffect(MobEffects.ABSORPTION), "The Salmon mustn't have absorption yet"); }; - ServerMobEffectEvents.BEFORE_ADD.register((effectInstance, entity, ctx) -> { - if (!isThisTheSalmon(entity) || obj.contextRef == null) return; - obj.contextRef.assertFalse(entity.hasEffect(MobEffects.ABSORPTION), "The Salmon mustn't have absorption yet"); - }); - ServerMobEffectEvents.AFTER_ADD.register((effectInstance, entity, ctx) -> { - if (!isThisTheSalmon(entity) || obj.contextRef == null) return; - obj.contextRef.assertTrue(entity.hasEffect(MobEffects.ABSORPTION), "The Salmon must have absorption at this point"); - }); - Salmon theSalmon = summonTheSalmon(context); - theSalmon.addEffect(createEffect(MobEffects.ABSORPTION)); - context.succeed(); - obj.contextRef = null; + + ServerMobEffectEvents.AfterAdd afterAdd = (_, entity, _) -> { + if (!isThisTheSalmon(entity)) return; + context.assertTrue(entity.hasEffect(MobEffects.ABSORPTION), "The Salmon must have absorption at this point"); + }; + + try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.BEFORE_ADD, beforeAdd); + EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_ADD, afterAdd)) { + Salmon theSalmon = summonTheSalmon(context); + theSalmon.addEffect(createEffect(MobEffects.ABSORPTION)); + context.succeed(); + } } @GameTest( maxTicks = 150 ) public void allowEarlyRemove(GameTestHelper context) { - ServerMobEffectEvents.ALLOW_EARLY_REMOVE.register((effectInstance, entity, ctx) -> { + ServerMobEffectEvents.AllowEarlyRemove allowEarlyRemove = (effectInstance, entity, ctx) -> { if (ctx.isFromCommand()) return true; // Same thing as ALLOW_ADD. boolean isThisTheEntity = isThisTheSalmon(entity) || isThisThePlayer(entity); boolean cannotRemove = effectInstance.is(MobEffects.BLINDNESS) || effectInstance.is(MobEffects.POISON); return !(cannotRemove && isThisTheEntity); - }); + }; - // Regular Salmon testing - Salmon theSalmon = summonTheSalmon(context); - theSalmon.addEffect(createEffect(MobEffects.BLINDNESS)); - context.assertTrue(theSalmon.hasEffect(MobEffects.BLINDNESS), "The Salmon must have blindness"); + try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.ALLOW_EARLY_REMOVE, allowEarlyRemove)) { + // Regular Salmon testing + Salmon theSalmon = summonTheSalmon(context); + theSalmon.addEffect(createEffect(MobEffects.BLINDNESS)); + context.assertTrue(theSalmon.hasEffect(MobEffects.BLINDNESS), "The Salmon must have blindness"); - // Player milk testing - Player thePlayer = summonThePlayer(context); - thePlayer.addEffect(createEffect(MobEffects.WEAVING)); - thePlayer.addEffect(createEffect(MobEffects.BLINDNESS)); - useItem(thePlayer); + // Player milk testing + Player thePlayer = summonThePlayer(context); + thePlayer.addEffect(createEffect(MobEffects.WEAVING)); + thePlayer.addEffect(createEffect(MobEffects.BLINDNESS)); + useItem(thePlayer); - context.assertFalse(thePlayer.isUsingItem(), "The Player mustn't be using an item at this point; this is a bug with the test"); // Sanity check so you don't go insane - context.assertFalse(thePlayer.hasEffect(MobEffects.WEAVING), "The Player mustn't have weaving as it should have been cleared after drinking milk"); - context.assertTrue(thePlayer.hasEffect(MobEffects.BLINDNESS), "The Player must still have blindness after drinking milk"); + context.assertFalse(thePlayer.isUsingItem(), "The Player mustn't be using an item at this point; this is a bug with the test"); // Sanity check so you don't go insane + context.assertFalse(thePlayer.hasEffect(MobEffects.WEAVING), "The Player mustn't have weaving as it should have been cleared after drinking milk"); + context.assertTrue(thePlayer.hasEffect(MobEffects.BLINDNESS), "The Player must still have blindness after drinking milk"); - // Player honey/poison testing - thePlayer.addEffect(createEffect(MobEffects.POISON)); - thePlayer.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(Items.HONEY_BOTTLE)); - useItem(thePlayer); + // Player honey/poison testing + thePlayer.addEffect(createEffect(MobEffects.POISON)); + thePlayer.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(Items.HONEY_BOTTLE)); + useItem(thePlayer); - context.assertTrue(thePlayer.hasEffect(MobEffects.POISON), "The Player must still have poison after drinking a honey bottle"); + context.assertTrue(thePlayer.hasEffect(MobEffects.POISON), "The Player must still have poison after drinking a honey bottle"); - context.succeed(); + context.succeed(); + } } @GameTest From 83b205ed85a0f54b7a0afed92568dfce73a79de4 Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Mon, 30 Mar 2026 02:16:09 +0200 Subject: [PATCH 17/48] safer updating because less hardcoding --- .../net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java index a07b9e2d865..5cc651aa0b9 100644 --- a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java +++ b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java @@ -33,6 +33,7 @@ import net.minecraft.resources.Identifier; import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.impl.test.TestableEventFactoryImpl; public class EventFactoryImpl { public static final EventFactoryImpl INSTANCE = ServiceLoader.load(EventFactoryImpl.class).findFirst().orElseGet(EventFactoryImpl::new); @@ -42,7 +43,7 @@ public class EventFactoryImpl { protected EventFactoryImpl() { Class thisClass = getClass(); - if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals("net.fabricmc.fabric.impl.test.TestableEventFactoryImpl")) { + if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals(TestableEventFactoryImpl.class.getName())) { throw new IllegalStateException("You are not allowed to create a custom EventFactoryImpl!"); } } From 61092fc63dbc9288cd44716cba5d5036ed57f523 Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Mon, 30 Mar 2026 02:18:58 +0200 Subject: [PATCH 18/48] prettify code --- .../net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java index 5cc651aa0b9..2a4c54fb6ab 100644 --- a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java +++ b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java @@ -43,7 +43,9 @@ public class EventFactoryImpl { protected EventFactoryImpl() { Class thisClass = getClass(); - if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals(TestableEventFactoryImpl.class.getName())) { + String validInheritor = TestableEventFactoryImpl.class.getName(); + + if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals(validInheritor)) { throw new IllegalStateException("You are not allowed to create a custom EventFactoryImpl!"); } } From 981c5149c548ea4f45e2527ee03b061af4efe9b4 Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Mon, 30 Mar 2026 02:35:43 +0200 Subject: [PATCH 19/48] chore: javadoc Initial work on javadoc for EventScopes. --- .../main/java/net/fabricmc/fabric/api/test/EventScope.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java index 12d92c8fddb..ca7d98afad9 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java @@ -7,6 +7,11 @@ import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.impl.test.EventTestingImpl; +/** + * Represents a wrapper around a short-lived {@link Event}. + * This class implements {@link AutoCloseable} and is intended to be used in a try-with-resources statement. When + * closed, the Event be unregistered. + */ @ApiStatus.NonExtendable public interface EventScope extends AutoCloseable { @Override From 2e6e6f572fbeac01eea67a74e23cb562903755f9 Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Mon, 30 Mar 2026 02:36:28 +0200 Subject: [PATCH 20/48] chore: fix grammar --- .../src/main/java/net/fabricmc/fabric/api/test/EventScope.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java index ca7d98afad9..76f7293ee79 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java +++ b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java @@ -10,7 +10,7 @@ /** * Represents a wrapper around a short-lived {@link Event}. * This class implements {@link AutoCloseable} and is intended to be used in a try-with-resources statement. When - * closed, the Event be unregistered. + * closed, the Event will be unregistered. */ @ApiStatus.NonExtendable public interface EventScope extends AutoCloseable { From a9e233275feb6bdf3a569fd0fd9b3e6fe9d9dc6d Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Mon, 30 Mar 2026 16:02:55 +0200 Subject: [PATCH 21/48] Move changes to module `fabric-dev-debug-api-v1` --- build.gradle | 3 +- .../impl/base/event/EventFactoryImpl.java | 5 +-- .../fabric/impl/test/EventScopeImpl.java | 22 ---------- .../impl/test/TestableArrayBackedEvent.java | 25 ----------- .../impl/test/TestableEventFactoryImpl.java | 13 ------ fabric-dev-debug-api-v1/build.gradle | 8 ++++ .../fabric/api/devdebug/v1}/EventScope.java | 20 ++++++++- .../impl/devdebug/v1/EventScopeImpl.java | 38 ++++++++++++++++ .../impl/devdebug/v1}/EventTestingImpl.java | 20 ++++++++- .../devdebug/v1/TestableArrayBackedEvent.java | 41 ++++++++++++++++++ .../devdebug/v1/TestableEventFactoryImpl.java | 29 +++++++++++++ ...mc.fabric.impl.base.event.EventFactoryImpl | 1 + .../assets/fabric-dev-debug-api-v1/icon.png | Bin 0 -> 1555 bytes .../src/main/resources/fabric.mod.json | 21 +++++++++ fabric-entity-events-v1/build.gradle | 2 +- .../gametest/ServerMobEffectsGameTest.java | 4 +- .../src/testmod/resources/fabric.mod.json | 3 +- gradle.properties | 1 + settings.gradle | 3 ++ 19 files changed, 186 insertions(+), 73 deletions(-) delete mode 100644 fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java delete mode 100644 fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java delete mode 100644 fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java create mode 100644 fabric-dev-debug-api-v1/build.gradle rename {fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test => fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/devdebug/v1}/EventScope.java (51%) create mode 100644 fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/EventScopeImpl.java rename {fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test => fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1}/EventTestingImpl.java (50%) create mode 100644 fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/TestableArrayBackedEvent.java create mode 100644 fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/TestableEventFactoryImpl.java create mode 100644 fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl create mode 100644 fabric-dev-debug-api-v1/src/main/resources/assets/fabric-dev-debug-api-v1/icon.png create mode 100644 fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json diff --git a/build.gradle b/build.gradle index cb2038978bd..cc1ed014b4a 100644 --- a/build.gradle +++ b/build.gradle @@ -617,7 +617,8 @@ void setupRepositories(RepositoryHandler repositories) { // These modules are not included in the fat jar, maven will resolve them via the pom. def devOnlyModules = [ "fabric-client-gametest-api-v1", - "fabric-gametest-api-v1" + "fabric-gametest-api-v1", + "fabric-dev-debug-api-v1" ] dependencies { diff --git a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java index 2a4c54fb6ab..a07b9e2d865 100644 --- a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java +++ b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java @@ -33,7 +33,6 @@ import net.minecraft.resources.Identifier; import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.impl.test.TestableEventFactoryImpl; public class EventFactoryImpl { public static final EventFactoryImpl INSTANCE = ServiceLoader.load(EventFactoryImpl.class).findFirst().orElseGet(EventFactoryImpl::new); @@ -43,9 +42,7 @@ public class EventFactoryImpl { protected EventFactoryImpl() { Class thisClass = getClass(); - String validInheritor = TestableEventFactoryImpl.class.getName(); - - if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals(validInheritor)) { + if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals("net.fabricmc.fabric.impl.test.TestableEventFactoryImpl")) { throw new IllegalStateException("You are not allowed to create a custom EventFactoryImpl!"); } } diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java deleted file mode 100644 index 6ccc2907fed..00000000000 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.fabricmc.fabric.impl.test; - -import net.minecraft.resources.Identifier; - -import net.fabricmc.fabric.api.test.EventScope; - -public class EventScopeImpl implements EventScope { - private final TestableArrayBackedEvent event; - private final Identifier phase; - private final T listener; - - public EventScopeImpl(TestableArrayBackedEvent event, Identifier phase, T listener) { - this.event = event; - this.phase = phase; - this.listener = listener; - } - - @Override - public void close() { - event.unregister(phase, listener); - } -} diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java deleted file mode 100644 index 6fff9b599f6..00000000000 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.fabricmc.fabric.impl.test; - -import java.util.Objects; -import java.util.function.Function; - -import net.minecraft.resources.Identifier; - -import net.fabricmc.fabric.impl.base.event.ArrayBackedEvent; - -class TestableArrayBackedEvent extends ArrayBackedEvent { - TestableArrayBackedEvent(Class type, Function invokerFactory) { - super(type, invokerFactory); - } - - public void unregister(Identifier phaseIdentifier, T listener) { - Objects.requireNonNull(phaseIdentifier, "Tried to unregister a listener for a null phase!"); - Objects.requireNonNull(listener, "Tried to unregister a null listener!"); - - synchronized (lock) { - if (getOrCreatePhase(phaseIdentifier, false).removeListener(listener)) { - rebuildInvoker(handlers.length - 1); - } - } - } -} diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java b/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java deleted file mode 100644 index 10053aa1181..00000000000 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.fabricmc.fabric.impl.test; - -import java.util.function.Function; - -import net.fabricmc.fabric.impl.base.event.ArrayBackedEvent; -import net.fabricmc.fabric.impl.base.event.EventFactoryImpl; - -public class TestableEventFactoryImpl extends EventFactoryImpl { - @Override - protected ArrayBackedEvent doCreateArrayBacked(Class type, Function invokerFactory) { - return new TestableArrayBackedEvent<>(type, invokerFactory); - } -} diff --git a/fabric-dev-debug-api-v1/build.gradle b/fabric-dev-debug-api-v1/build.gradle new file mode 100644 index 00000000000..d5600c62db8 --- /dev/null +++ b/fabric-dev-debug-api-v1/build.gradle @@ -0,0 +1,8 @@ +version = getSubprojectVersion(project) + +moduleDependencies(project, [ + 'fabric-api-base' +]) + +testDependencies(project, [ +]) diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/devdebug/v1/EventScope.java similarity index 51% rename from fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java rename to fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/devdebug/v1/EventScope.java index 76f7293ee79..eeb0f16e71a 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/api/test/EventScope.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/devdebug/v1/EventScope.java @@ -1,11 +1,27 @@ -package net.fabricmc.fabric.api.test; +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.api.devdebug.v1; import org.jetbrains.annotations.ApiStatus; import net.minecraft.resources.Identifier; import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.impl.test.EventTestingImpl; +import net.fabricmc.fabric.impl.devdebug.v1.EventTestingImpl; /** * Represents a wrapper around a short-lived {@link Event}. diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/EventScopeImpl.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/EventScopeImpl.java new file mode 100644 index 00000000000..5ed42c53bce --- /dev/null +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/EventScopeImpl.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.impl.devdebug.v1; + +import net.minecraft.resources.Identifier; + +import net.fabricmc.fabric.api.devdebug.v1.EventScope; + +public class EventScopeImpl implements EventScope { + private final TestableArrayBackedEvent event; + private final Identifier phase; + private final T listener; + + public EventScopeImpl(TestableArrayBackedEvent event, Identifier phase, T listener) { + this.event = event; + this.phase = phase; + this.listener = listener; + } + + @Override + public void close() { + event.unregister(phase, listener); + } +} diff --git a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/EventTestingImpl.java similarity index 50% rename from fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java rename to fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/EventTestingImpl.java index 2370a2ae5d5..19f07e250dc 100644 --- a/fabric-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventTestingImpl.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/EventTestingImpl.java @@ -1,9 +1,25 @@ -package net.fabricmc.fabric.impl.test; +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.impl.devdebug.v1; import net.minecraft.resources.Identifier; +import net.fabricmc.fabric.api.devdebug.v1.EventScope; import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.test.EventScope; import net.fabricmc.loader.api.FabricLoader; public final class EventTestingImpl { diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/TestableArrayBackedEvent.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/TestableArrayBackedEvent.java new file mode 100644 index 00000000000..d1305dc2857 --- /dev/null +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/TestableArrayBackedEvent.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.impl.devdebug.v1; + +import java.util.Objects; +import java.util.function.Function; + +import net.minecraft.resources.Identifier; + +import net.fabricmc.fabric.impl.base.event.ArrayBackedEvent; + +public class TestableArrayBackedEvent extends ArrayBackedEvent { + TestableArrayBackedEvent(Class type, Function invokerFactory) { + super(type, invokerFactory); + } + + public void unregister(Identifier phaseIdentifier, T listener) { + Objects.requireNonNull(phaseIdentifier, "Tried to unregister a listener for a null phase!"); + Objects.requireNonNull(listener, "Tried to unregister a null listener!"); + + synchronized (lock) { + if (getOrCreatePhase(phaseIdentifier, false).removeListener(listener)) { + rebuildInvoker(handlers.length - 1); + } + } + } +} diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/TestableEventFactoryImpl.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/TestableEventFactoryImpl.java new file mode 100644 index 00000000000..f5e6ccd77cd --- /dev/null +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/TestableEventFactoryImpl.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.impl.devdebug.v1; + +import java.util.function.Function; + +import net.fabricmc.fabric.impl.base.event.ArrayBackedEvent; +import net.fabricmc.fabric.impl.base.event.EventFactoryImpl; + +public class TestableEventFactoryImpl extends EventFactoryImpl { + @Override + protected ArrayBackedEvent doCreateArrayBacked(Class type, Function invokerFactory) { + return new TestableArrayBackedEvent<>(type, invokerFactory); + } +} diff --git a/fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl b/fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl new file mode 100644 index 00000000000..29f8176edfd --- /dev/null +++ b/fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl @@ -0,0 +1 @@ +net.fabricmc.fabric.impl.devdebug.v1.TestableEventFactoryImpl diff --git a/fabric-dev-debug-api-v1/src/main/resources/assets/fabric-dev-debug-api-v1/icon.png b/fabric-dev-debug-api-v1/src/main/resources/assets/fabric-dev-debug-api-v1/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..12c4531de92fe0544a0e15347f84381c132a7feb GIT binary patch literal 1555 zcmbVMONbmr817YeS0`Bvm<_8$sdPkC($if%&o0utJLwrS1L<{`3}loX(o5`x6Ep1Z4+am|^rTyU-RHPnPe)^ld+*!=$4&3I z>W!eGA48bhNyDT~k_>H^p*imGQs^3Zl?0$k+Loj8KVQ7W1ItwT6B%97U5#|C^1vg< z2P<_vSjCFTFD-(@Az}nJ2@DY0UB^eE$`5%FTSvzt4~CFnRpkqjLeS8wK%*W3nPgVL zFfD_el7v}Fk<*8OEWw;8R1=sseC60TqKJ9em~hy zC8^gIp`s|FB#W{vFofW*JAn}jj(>2%P$WL~EH|*I10qJFN!J3EXO@m!u-%x}@yB6e z0TV;R6=70}Tp9vR9OK+IuRBz3Vv%%-O`O1ISQum74h^W^p?^aii~pp6g;v*N9S^m| zwqq53Q0g%^#sPUK+OMy>M63~?u6dZ0dd$p&kvA^VJYodYt5e#YJXCdJGSIZ>Ve;Um z6P9DrzW?%$JEUj?MCBv70A&GY>oAKlX#{hElt+>@g6hlcrFNcIG_C5bC_#`dML=rKZ5X)F-wenaX=`<9S6l@7;C1a*r zFpYEBk-O}Ek>a%|3nur?|9Ss4&tg?*bRU@~s?8{UP}%a?!>*63=Qw$Dyy{wDm@&w} zQ6;E6j#7Y_{P@^<utq@Kv^7o)Nrxg!46%b{#X ziBI6HZ$!(uVX;lz@`%IwoW~m4((?!2X3g;ZO0iH6ziV#JEKKiv@r~aK;fD%m+`qeP zqj!gUd>JIZzIXQGa=BdwQ+vS+TaVp2d4HjC{TKZ1T^OEP^h*yupZ((7eYf^3ZRqE( zWln<`?)nV)~_M|=0.18.4", + "fabric-api-base": "*", + "fabric-registry-sync-v0": "*" + }, + "description": "A toolkit for using Events scoped narrowly.", + "custom": { + "fabric-api:module-lifecycle": "experimental" + } +} diff --git a/fabric-entity-events-v1/build.gradle b/fabric-entity-events-v1/build.gradle index ee59808b9f5..e9fc59560c3 100644 --- a/fabric-entity-events-v1/build.gradle +++ b/fabric-entity-events-v1/build.gradle @@ -11,5 +11,5 @@ testDependencies(project, [ ':fabric-networking-api-v1', ':fabric-registry-sync-v0', ':fabric-rendering-v1', - ':fabric-debug-api-v1' + ':fabric-dev-debug-api-v1' ]) diff --git a/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java b/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java index 7bfb7fabb5f..fd39a01b840 100644 --- a/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java +++ b/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java @@ -31,9 +31,9 @@ import net.minecraft.world.level.GameType; import net.minecraft.world.phys.Vec3; +import net.fabricmc.fabric.api.devdebug.v1.EventScope; import net.fabricmc.fabric.api.entity.event.v1.effect.ServerMobEffectEvents; import net.fabricmc.fabric.api.gametest.v1.GameTest; -import net.fabricmc.fabric.api.test.EventScope; public class ServerMobEffectsGameTest { @GameTest @@ -70,7 +70,7 @@ public void beforeAfterAdd(GameTestHelper context) { }; try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.BEFORE_ADD, beforeAdd); - EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_ADD, afterAdd)) { + EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_ADD, afterAdd)) { Salmon theSalmon = summonTheSalmon(context); theSalmon.addEffect(createEffect(MobEffects.ABSORPTION)); context.succeed(); diff --git a/fabric-entity-events-v1/src/testmod/resources/fabric.mod.json b/fabric-entity-events-v1/src/testmod/resources/fabric.mod.json index 2ee26947333..339ea046c8e 100644 --- a/fabric-entity-events-v1/src/testmod/resources/fabric.mod.json +++ b/fabric-entity-events-v1/src/testmod/resources/fabric.mod.json @@ -8,7 +8,8 @@ "depends": { "fabric-entity-events-v1": "*", "fabric-command-api-v2": "*", - "fabric-registry-sync-v0": "*" + "fabric-registry-sync-v0": "*", + "fabric-dev-debug-api-v1": "*" }, "entrypoints": { "main": [ diff --git a/gradle.properties b/gradle.properties index c435305d50d..60fc2e5cd06 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,6 +23,7 @@ fabric-crash-report-info-v1-version=1.0.3 fabric-data-attachment-api-v1-version=2.2.2 fabric-data-generation-api-v1-version=24.0.17 fabric-debug-api-v1-version=1.0.1 +fabric-dev-debug-api-v1-version=1.0.0 fabric-dimensions-v1-version=5.1.4 fabric-entity-events-v1-version=5.0.2 fabric-events-interaction-v0-version=5.1.10 diff --git a/settings.gradle b/settings.gradle index 5b58ec989c1..30aa0394a04 100644 --- a/settings.gradle +++ b/settings.gradle @@ -38,6 +38,7 @@ include 'fabric-creative-tab-api-v1' include 'fabric-data-attachment-api-v1' include 'fabric-data-generation-api-v1' include 'fabric-debug-api-v1' +include 'fabric-dev-debug-api-v1' include 'fabric-dimensions-v1' include 'fabric-entity-events-v1' include 'fabric-events-interaction-v0' @@ -69,3 +70,5 @@ include 'fabric-transfer-api-v1' include 'fabric-transitive-access-wideners-v1' include 'deprecated' include 'deprecated:fabric-resource-loader-v0' + +include 'fabric-dev-debug-api-v1' From 542113a091eb2b74786abcf047d2d5991c013a3a Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Mon, 30 Mar 2026 18:29:05 +0200 Subject: [PATCH 22/48] fix wrong classname --- .../net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java index a07b9e2d865..5b714429633 100644 --- a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java +++ b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java @@ -42,7 +42,7 @@ public class EventFactoryImpl { protected EventFactoryImpl() { Class thisClass = getClass(); - if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals("net.fabricmc.fabric.impl.test.TestableEventFactoryImpl")) { + if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals("net.fabricmc.fabric.impl.devdebug.v1.TestableEventFactoryImpl")) { throw new IllegalStateException("You are not allowed to create a custom EventFactoryImpl!"); } } From aed99937fddc39c57e5a31acaa90db8af2b6d6d8 Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Mon, 30 Mar 2026 18:37:06 +0200 Subject: [PATCH 23/48] remove redundant file --- .../net.fabricmc.fabric.impl.base.event.EventFactoryImpl | 1 - 1 file changed, 1 deletion(-) delete mode 100644 fabric-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl diff --git a/fabric-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl b/fabric-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl deleted file mode 100644 index 2211a85aaf6..00000000000 --- a/fabric-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl +++ /dev/null @@ -1 +0,0 @@ -net.fabricmc.fabric.impl.test.TestableEventFactoryImpl From 7718a8dbbf79040a24307239818c93ee2c9f6df0 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 15:06:16 -0400 Subject: [PATCH 24/48] refactor: remove EventScope usage, we can PR that later --- fabric-entity-events-v1/build.gradle | 3 +- .../gametest/ServerMobEffectsGameTest.java | 145 ++++++++---------- .../src/testmod/resources/fabric.mod.json | 3 +- 3 files changed, 69 insertions(+), 82 deletions(-) diff --git a/fabric-entity-events-v1/build.gradle b/fabric-entity-events-v1/build.gradle index e9fc59560c3..54d84046d6c 100644 --- a/fabric-entity-events-v1/build.gradle +++ b/fabric-entity-events-v1/build.gradle @@ -10,6 +10,5 @@ testDependencies(project, [ ':fabric-command-api-v2', ':fabric-networking-api-v1', ':fabric-registry-sync-v0', - ':fabric-rendering-v1', - ':fabric-dev-debug-api-v1' + ':fabric-rendering-v1' ]) diff --git a/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java b/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java index fd39a01b840..3b5e553ba39 100644 --- a/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java +++ b/fabric-entity-events-v1/src/testmod/java/net/fabricmc/fabric/test/entity/event/gametest/ServerMobEffectsGameTest.java @@ -31,132 +31,121 @@ import net.minecraft.world.level.GameType; import net.minecraft.world.phys.Vec3; -import net.fabricmc.fabric.api.devdebug.v1.EventScope; import net.fabricmc.fabric.api.entity.event.v1.effect.ServerMobEffectEvents; import net.fabricmc.fabric.api.gametest.v1.GameTest; public class ServerMobEffectsGameTest { @GameTest public void allowAdd(GameTestHelper context) { - ServerMobEffectEvents.AllowAdd allowAdd = (effectInstance, entity, ctx) -> { + ServerMobEffectEvents.ALLOW_ADD.register((effectInstance, entity, ctx) -> { if (ctx.isFromCommand()) return true; // If the entity wants to regenerate and is holding a potato, // deny them regeneration privileges. // This is specific enough since events aren't scoped for // GameTests. return !(effectInstance.is(MobEffects.REGENERATION) && isThisTheSalmon(entity)); - }; - + }); Salmon theSalmon = summonTheSalmon(context); - - try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.ALLOW_ADD, allowAdd)) { - theSalmon.addEffect(createEffect(MobEffects.REGENERATION)); - context.assertTrue(theSalmon.getMainHandItem().is(Items.POTATO), "The Salmon must be holding (how!?) a potato"); - context.assertFalse(theSalmon.hasEffect(MobEffects.REGENERATION), "The Salmon must not have regeneration"); - context.succeed(); - } + theSalmon.addEffect(createEffect(MobEffects.REGENERATION)); + context.assertTrue(theSalmon.getMainHandItem().is(Items.POTATO), "The Salmon must be holding (how!?) a potato"); + context.assertFalse(theSalmon.hasEffect(MobEffects.REGENERATION), "The Salmon must not have regeneration"); + context.succeed(); } @GameTest public void beforeAfterAdd(GameTestHelper context) { - ServerMobEffectEvents.BeforeAdd beforeAdd = (_, entity, _) -> { - if (!isThisTheSalmon(entity)) return; - context.assertFalse(entity.hasEffect(MobEffects.ABSORPTION), "The Salmon mustn't have absorption yet"); - }; - - ServerMobEffectEvents.AfterAdd afterAdd = (_, entity, _) -> { - if (!isThisTheSalmon(entity)) return; - context.assertTrue(entity.hasEffect(MobEffects.ABSORPTION), "The Salmon must have absorption at this point"); + var obj = new Object() { // Scoped events at home + GameTestHelper contextRef = context; }; - - try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.BEFORE_ADD, beforeAdd); - EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_ADD, afterAdd)) { - Salmon theSalmon = summonTheSalmon(context); - theSalmon.addEffect(createEffect(MobEffects.ABSORPTION)); - context.succeed(); - } + ServerMobEffectEvents.BEFORE_ADD.register((effectInstance, entity, ctx) -> { + if (!isThisTheSalmon(entity) || obj.contextRef == null) return; + obj.contextRef.assertFalse(entity.hasEffect(MobEffects.ABSORPTION), "The Salmon mustn't have absorption yet"); + }); + ServerMobEffectEvents.AFTER_ADD.register((effectInstance, entity, ctx) -> { + if (!isThisTheSalmon(entity) || obj.contextRef == null) return; + obj.contextRef.assertTrue(entity.hasEffect(MobEffects.ABSORPTION), "The Salmon must have absorption at this point"); + }); + Salmon theSalmon = summonTheSalmon(context); + theSalmon.addEffect(createEffect(MobEffects.ABSORPTION)); + context.succeed(); + obj.contextRef = null; } @GameTest( maxTicks = 150 ) public void allowEarlyRemove(GameTestHelper context) { - ServerMobEffectEvents.AllowEarlyRemove allowEarlyRemove = (effectInstance, entity, ctx) -> { + ServerMobEffectEvents.ALLOW_EARLY_REMOVE.register((effectInstance, entity, ctx) -> { if (ctx.isFromCommand()) return true; // Same thing as ALLOW_ADD. boolean isThisTheEntity = isThisTheSalmon(entity) || isThisThePlayer(entity); boolean cannotRemove = effectInstance.is(MobEffects.BLINDNESS) || effectInstance.is(MobEffects.POISON); return !(cannotRemove && isThisTheEntity); - }; + }); - try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.ALLOW_EARLY_REMOVE, allowEarlyRemove)) { - // Regular Salmon testing - Salmon theSalmon = summonTheSalmon(context); - theSalmon.addEffect(createEffect(MobEffects.BLINDNESS)); - context.assertTrue(theSalmon.hasEffect(MobEffects.BLINDNESS), "The Salmon must have blindness"); + // Regular Salmon testing + Salmon theSalmon = summonTheSalmon(context); + theSalmon.addEffect(createEffect(MobEffects.BLINDNESS)); + context.assertTrue(theSalmon.hasEffect(MobEffects.BLINDNESS), "The Salmon must have blindness"); - // Player milk testing - Player thePlayer = summonThePlayer(context); - thePlayer.addEffect(createEffect(MobEffects.WEAVING)); - thePlayer.addEffect(createEffect(MobEffects.BLINDNESS)); - useItem(thePlayer); + // Player milk testing + Player thePlayer = summonThePlayer(context); + thePlayer.addEffect(createEffect(MobEffects.WEAVING)); + thePlayer.addEffect(createEffect(MobEffects.BLINDNESS)); + useItem(thePlayer); - context.assertFalse(thePlayer.isUsingItem(), "The Player mustn't be using an item at this point; this is a bug with the test"); // Sanity check so you don't go insane - context.assertFalse(thePlayer.hasEffect(MobEffects.WEAVING), "The Player mustn't have weaving as it should have been cleared after drinking milk"); - context.assertTrue(thePlayer.hasEffect(MobEffects.BLINDNESS), "The Player must still have blindness after drinking milk"); + context.assertFalse(thePlayer.isUsingItem(), "The Player mustn't be using an item at this point; this is a bug with the test"); // Sanity check so you don't go insane + context.assertFalse(thePlayer.hasEffect(MobEffects.WEAVING), "The Player mustn't have weaving as it should have been cleared after drinking milk"); + context.assertTrue(thePlayer.hasEffect(MobEffects.BLINDNESS), "The Player must still have blindness after drinking milk"); - // Player honey/poison testing - thePlayer.addEffect(createEffect(MobEffects.POISON)); - thePlayer.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(Items.HONEY_BOTTLE)); - useItem(thePlayer); + // Player honey/poison testing + thePlayer.addEffect(createEffect(MobEffects.POISON)); + thePlayer.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(Items.HONEY_BOTTLE)); + useItem(thePlayer); - context.assertTrue(thePlayer.hasEffect(MobEffects.POISON), "The Player must still have poison after drinking a honey bottle"); + context.assertTrue(thePlayer.hasEffect(MobEffects.POISON), "The Player must still have poison after drinking a honey bottle"); - context.succeed(); - } + context.succeed(); } @GameTest public void beforeAfterRemove(GameTestHelper context) { - ServerMobEffectEvents.BeforeRemove beforeRemove = (_, entity, _) -> { - if (!isThisTheSalmon(entity)) return; - context.assertTrue(entity.hasEffect(MobEffects.SATURATION), "The Salmon must have saturation as it should not yet have been removed"); + var obj = new Object() { // Scoped events at home + GameTestHelper contextRef = context; }; - - ServerMobEffectEvents.AfterRemove afterRemove = (_, entity, _) -> { - if (!isThisTheSalmon(entity)) return; - context.assertFalse(entity.hasEffect(MobEffects.SATURATION), "The Salmon mustn't have saturation as it should have been removed by now"); - }; - + ServerMobEffectEvents.BEFORE_REMOVE.register((effectInstance, entity, ctx) -> { + if (!isThisTheSalmon(entity) || obj.contextRef == null) return; + obj.contextRef.assertTrue(entity.hasEffect(MobEffects.SATURATION), "The Salmon must have saturation as it should not yet have been removed"); + }); + ServerMobEffectEvents.AFTER_REMOVE.register((effectInstance, entity, ctx) -> { + if (!isThisTheSalmon(entity) || obj.contextRef == null) return; + obj.contextRef.assertFalse(entity.hasEffect(MobEffects.SATURATION), "The Salmon mustn't have saturation as it should have been removed by now"); + }); Salmon theSalmon = summonTheSalmon(context); - try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.BEFORE_REMOVE, beforeRemove); - EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_REMOVE, afterRemove) - ) { - theSalmon.addEffect(createEffect(MobEffects.SATURATION)); - theSalmon.removeEffect(MobEffects.SATURATION); - context.succeed(); - } + theSalmon.addEffect(createEffect(MobEffects.SATURATION)); + theSalmon.removeEffect(MobEffects.SATURATION); + context.succeed(); + obj.contextRef = null; } // Regression test for https://github.com/FabricMC/fabric-api/issues/5121 @GameTest public void removeNoneExistentEffect(GameTestHelper context) { - ServerMobEffectEvents.BeforeRemove beforeRemove = (_, entity, _) -> { - if (!isThisTheSalmon(entity)) return; - context.fail("The BEFORE_REMOVE event must not be called when removing a non-existent effect"); - }; - ServerMobEffectEvents.AfterRemove afterRemove = (_, entity, _) -> { - if (!isThisTheSalmon(entity)) return; - context.fail("The AFTER_REMOVE event must not be called when removing a non-existent effect"); + var obj = new Object() { // Scoped events at home + GameTestHelper contextRef = context; }; - + ServerMobEffectEvents.BEFORE_REMOVE.register((effectInstance, entity, ctx) -> { + if (!isThisTheSalmon(entity) || obj.contextRef == null) return; + obj.contextRef.fail("The BEFORE_REMOVE event must not be called when removing a non-existent effect"); + }); + ServerMobEffectEvents.AFTER_REMOVE.register((effectInstance, entity, ctx) -> { + if (!isThisTheSalmon(entity) || obj.contextRef == null) return; + obj.contextRef.fail("The AFTER_REMOVE event must not be called when removing a non-existent effect"); + }); Salmon theSalmon = summonTheSalmon(context); - try (EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.BEFORE_REMOVE, beforeRemove); - EventScope _ = EventScope.registerScoped(ServerMobEffectEvents.AFTER_REMOVE, afterRemove) - ) { - theSalmon.removeEffect(MobEffects.SATURATION); - context.succeed(); - } + theSalmon.removeEffect(MobEffects.SATURATION); + context.succeed(); + obj.contextRef = null; } private static Salmon summonTheSalmon(GameTestHelper context) { diff --git a/fabric-entity-events-v1/src/testmod/resources/fabric.mod.json b/fabric-entity-events-v1/src/testmod/resources/fabric.mod.json index 339ea046c8e..2ee26947333 100644 --- a/fabric-entity-events-v1/src/testmod/resources/fabric.mod.json +++ b/fabric-entity-events-v1/src/testmod/resources/fabric.mod.json @@ -8,8 +8,7 @@ "depends": { "fabric-entity-events-v1": "*", "fabric-command-api-v2": "*", - "fabric-registry-sync-v0": "*", - "fabric-dev-debug-api-v1": "*" + "fabric-registry-sync-v0": "*" }, "entrypoints": { "main": [ From 7b8f8536a4135f8468277212ef69d22bc55c8bb0 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 15:13:14 -0400 Subject: [PATCH 25/48] fix: dependencies --- fabric-debug-api-v1/src/main/resources/fabric.mod.json | 3 +-- fabric-dev-debug-api-v1/build.gradle | 3 ++- fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fabric-debug-api-v1/src/main/resources/fabric.mod.json b/fabric-debug-api-v1/src/main/resources/fabric.mod.json index 4b76263097f..6be29e7c74a 100644 --- a/fabric-debug-api-v1/src/main/resources/fabric.mod.json +++ b/fabric-debug-api-v1/src/main/resources/fabric.mod.json @@ -17,8 +17,7 @@ ], "depends": { "fabricloader": ">=0.18.4", - "fabric-api-base": "*", - "fabric-registry-sync-v0": "*" + "fabric-api-base": "*" }, "description": "A toolkit for registering and using debug subscriptions and other debug tools Mojang have created.", "mixins": [ diff --git a/fabric-dev-debug-api-v1/build.gradle b/fabric-dev-debug-api-v1/build.gradle index d5600c62db8..1a3e00c4b88 100644 --- a/fabric-dev-debug-api-v1/build.gradle +++ b/fabric-dev-debug-api-v1/build.gradle @@ -1,7 +1,8 @@ version = getSubprojectVersion(project) moduleDependencies(project, [ - 'fabric-api-base' + 'fabric-api-base', + 'fabric-debug-api-v1' ]) testDependencies(project, [ diff --git a/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json b/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json index a4da2fccc30..0b4d135e28c 100644 --- a/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json +++ b/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json @@ -12,7 +12,7 @@ "depends": { "fabricloader": ">=0.18.4", "fabric-api-base": "*", - "fabric-registry-sync-v0": "*" + "fabric-debug-api-v1": "*" }, "description": "A toolkit for using Events scoped narrowly.", "custom": { From 860f2f612d188d3c9ad58fb26f4d5cd7e05ee4e4 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 15:14:11 -0400 Subject: [PATCH 26/48] docs: change description to accurately reflect purpose --- fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json b/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json index 0b4d135e28c..5a4435c5eb5 100644 --- a/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json +++ b/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json @@ -14,7 +14,7 @@ "fabric-api-base": "*", "fabric-debug-api-v1": "*" }, - "description": "A toolkit for using Events scoped narrowly.", + "description": "An extension of Debug API with features only available in development environments.", "custom": { "fabric-api:module-lifecycle": "experimental" } From 16cfcf34c26d223c153ae56d37f0ab78d2421fd1 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 15:16:13 -0400 Subject: [PATCH 27/48] fix: don't include dev debug api --- settings.gradle | 2 -- 1 file changed, 2 deletions(-) diff --git a/settings.gradle b/settings.gradle index 30aa0394a04..6e35b97c3bb 100644 --- a/settings.gradle +++ b/settings.gradle @@ -70,5 +70,3 @@ include 'fabric-transfer-api-v1' include 'fabric-transitive-access-wideners-v1' include 'deprecated' include 'deprecated:fabric-resource-loader-v0' - -include 'fabric-dev-debug-api-v1' From 0a7f5dd37cbb4fee3afd0301ecaff918dc508b14 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 15:18:43 -0400 Subject: [PATCH 28/48] refactor: move dev debug api to packages matching debug api --- .../fabric/api/{devdebug => debug}/v1/EventScope.java | 4 ++-- .../fabric/impl/{devdebug/v1 => debug}/EventScopeImpl.java | 4 ++-- .../fabric/impl/{devdebug/v1 => debug}/EventTestingImpl.java | 4 ++-- .../impl/{devdebug/v1 => debug}/TestableArrayBackedEvent.java | 2 +- .../impl/{devdebug/v1 => debug}/TestableEventFactoryImpl.java | 2 +- .../net.fabricmc.fabric.impl.base.event.EventFactoryImpl | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) rename fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/{devdebug => debug}/v1/EventScope.java (92%) rename fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/{devdebug/v1 => debug}/EventScopeImpl.java (91%) rename fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/{devdebug/v1 => debug}/EventTestingImpl.java (93%) rename fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/{devdebug/v1 => debug}/TestableArrayBackedEvent.java (96%) rename fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/{devdebug/v1 => debug}/TestableEventFactoryImpl.java (95%) diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/devdebug/v1/EventScope.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java similarity index 92% rename from fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/devdebug/v1/EventScope.java rename to fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java index eeb0f16e71a..76349f587c6 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/devdebug/v1/EventScope.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package net.fabricmc.fabric.api.devdebug.v1; +package net.fabricmc.fabric.api.debug.v1; import org.jetbrains.annotations.ApiStatus; import net.minecraft.resources.Identifier; import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.impl.devdebug.v1.EventTestingImpl; +import net.fabricmc.fabric.impl.debug.EventTestingImpl; /** * Represents a wrapper around a short-lived {@link Event}. diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/EventScopeImpl.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EventScopeImpl.java similarity index 91% rename from fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/EventScopeImpl.java rename to fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EventScopeImpl.java index 5ed42c53bce..17693369456 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/EventScopeImpl.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EventScopeImpl.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.devdebug.v1; +package net.fabricmc.fabric.impl.debug; import net.minecraft.resources.Identifier; -import net.fabricmc.fabric.api.devdebug.v1.EventScope; +import net.fabricmc.fabric.api.debug.v1.EventScope; public class EventScopeImpl implements EventScope { private final TestableArrayBackedEvent event; diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/EventTestingImpl.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EventTestingImpl.java similarity index 93% rename from fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/EventTestingImpl.java rename to fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EventTestingImpl.java index 19f07e250dc..54227e84450 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/EventTestingImpl.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EventTestingImpl.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.devdebug.v1; +package net.fabricmc.fabric.impl.debug; import net.minecraft.resources.Identifier; -import net.fabricmc.fabric.api.devdebug.v1.EventScope; +import net.fabricmc.fabric.api.debug.v1.EventScope; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.loader.api.FabricLoader; diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/TestableArrayBackedEvent.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/TestableArrayBackedEvent.java similarity index 96% rename from fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/TestableArrayBackedEvent.java rename to fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/TestableArrayBackedEvent.java index d1305dc2857..8b56c748322 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/TestableArrayBackedEvent.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/TestableArrayBackedEvent.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.devdebug.v1; +package net.fabricmc.fabric.impl.debug; import java.util.Objects; import java.util.function.Function; diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/TestableEventFactoryImpl.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/TestableEventFactoryImpl.java similarity index 95% rename from fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/TestableEventFactoryImpl.java rename to fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/TestableEventFactoryImpl.java index f5e6ccd77cd..36bb84bada0 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/devdebug/v1/TestableEventFactoryImpl.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/TestableEventFactoryImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.devdebug.v1; +package net.fabricmc.fabric.impl.debug; import java.util.function.Function; diff --git a/fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl b/fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl index 29f8176edfd..b373fc262f7 100644 --- a/fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl +++ b/fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl @@ -1 +1 @@ -net.fabricmc.fabric.impl.devdebug.v1.TestableEventFactoryImpl +net.fabricmc.fabric.impl.debug.TestableEventFactoryImpl From 452e8b5236ef4356bcf8c0d32974a1368bd91226 Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Mon, 30 Mar 2026 21:33:03 +0200 Subject: [PATCH 29/48] docs: javadoc for EventScope --- .../fabricmc/fabric/api/debug/v1/EventScope.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java index 76349f587c6..a6853104bcb 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java @@ -23,6 +23,8 @@ import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.impl.debug.EventTestingImpl; +import java.util.function.Function; + /** * Represents a wrapper around a short-lived {@link Event}. * This class implements {@link AutoCloseable} and is intended to be used in a try-with-resources statement. When @@ -33,10 +35,22 @@ public interface EventScope extends AutoCloseable { @Override void close(); + /** + * @param event The {@link Event} that should get registered + * @param listener The corresponding listener + * @return a new {@link EventScope} instance holding the event, its listener and the event phase {@link Event#DEFAULT_PHASE} + * @param is the type parameter of the event and the listener it should hold + */ static EventScope registerScoped(Event event, T listener) { return registerScoped(event, Event.DEFAULT_PHASE, listener); } - + /** + * @param event The {@link Event} that should get registered + * @param phase The event phase, see {@link net.fabricmc.fabric.api.event.EventFactory#createWithPhases(Class, Function, Identifier...)} for details + * @param listener The corresponding listener + * @return a new {@link EventScope} instance holding the event, its listener and the event phase + * @param is the type parameter of the event and the listener it should hold + */ static EventScope registerScoped(Event event, Identifier phase, T listener) { return EventTestingImpl.registerScoped(event, phase, listener); } From d90e87e8679a6d42956e051a8f3866f2c6ef8e0c Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 15:41:23 -0400 Subject: [PATCH 30/48] docs: clarify listener type parameter doc --- .../java/net/fabricmc/fabric/api/debug/v1/EventScope.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java index a6853104bcb..f72ec7e7065 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java @@ -39,7 +39,7 @@ public interface EventScope extends AutoCloseable { * @param event The {@link Event} that should get registered * @param listener The corresponding listener * @return a new {@link EventScope} instance holding the event, its listener and the event phase {@link Event#DEFAULT_PHASE} - * @param is the type parameter of the event and the listener it should hold + * @param is the type parameter for the event's listener */ static EventScope registerScoped(Event event, T listener) { return registerScoped(event, Event.DEFAULT_PHASE, listener); @@ -49,7 +49,7 @@ static EventScope registerScoped(Event event, T listener) { * @param phase The event phase, see {@link net.fabricmc.fabric.api.event.EventFactory#createWithPhases(Class, Function, Identifier...)} for details * @param listener The corresponding listener * @return a new {@link EventScope} instance holding the event, its listener and the event phase - * @param is the type parameter of the event and the listener it should hold + * @param is the type parameter for the event's listener */ static EventScope registerScoped(Event event, Identifier phase, T listener) { return EventTestingImpl.registerScoped(event, phase, listener); From 60397ac8722c9de1df9fa7848209d02d22380881 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 15:45:12 -0400 Subject: [PATCH 31/48] docs: use @linkplain's and @see, fix docs --- .../fabricmc/fabric/api/debug/v1/EventScope.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java index f72ec7e7065..204b45ff637 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java @@ -16,15 +16,16 @@ package net.fabricmc.fabric.api.debug.v1; +import java.util.function.Function; + import org.jetbrains.annotations.ApiStatus; import net.minecraft.resources.Identifier; import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; import net.fabricmc.fabric.impl.debug.EventTestingImpl; -import java.util.function.Function; - /** * Represents a wrapper around a short-lived {@link Event}. * This class implements {@link AutoCloseable} and is intended to be used in a try-with-resources statement. When @@ -38,18 +39,20 @@ public interface EventScope extends AutoCloseable { /** * @param event The {@link Event} that should get registered * @param listener The corresponding listener - * @return a new {@link EventScope} instance holding the event, its listener and the event phase {@link Event#DEFAULT_PHASE} * @param is the type parameter for the event's listener + * @return a new {@link EventScope} instance holding the event, its listener and the event phase {@link Event#DEFAULT_PHASE} */ static EventScope registerScoped(Event event, T listener) { return registerScoped(event, Event.DEFAULT_PHASE, listener); } + /** * @param event The {@link Event} that should get registered - * @param phase The event phase, see {@link net.fabricmc.fabric.api.event.EventFactory#createWithPhases(Class, Function, Identifier...)} for details + * @param phase The {@linkplain EventFactory#createWithPhases(Class, Function, Identifier...) event phase} * @param listener The corresponding listener - * @return a new {@link EventScope} instance holding the event, its listener and the event phase * @param is the type parameter for the event's listener + * @return a new {@link EventScope} instance holding the event, its listener and the event phase + * @see EventFactory#createWithPhases(Class, Function, Identifier...) */ static EventScope registerScoped(Event event, Identifier phase, T listener) { return EventTestingImpl.registerScoped(event, phase, listener); From 6615de770e5e8c89892e0841890bdb71d8732538 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 18:06:31 -0400 Subject: [PATCH 32/48] fix: class name check of TestableEventFactoryImpl --- .../net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java index 5b714429633..7628b3c6382 100644 --- a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java +++ b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java @@ -42,7 +42,7 @@ public class EventFactoryImpl { protected EventFactoryImpl() { Class thisClass = getClass(); - if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals("net.fabricmc.fabric.impl.devdebug.v1.TestableEventFactoryImpl")) { + if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals("net.fabricmc.fabric.impl.debug.TestableEventFactoryImpl")) { throw new IllegalStateException("You are not allowed to create a custom EventFactoryImpl!"); } } From 28aa46416ac474d6c2332ae68fe5880701811034 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 18:14:10 -0400 Subject: [PATCH 33/48] fix: move everything to `debug.dev` packages to avoid javadoc errors --- .../net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java | 2 +- .../fabricmc/fabric/api/debug/{ => dev}/v1/EventScope.java | 4 ++-- .../fabricmc/fabric/impl/debug/{ => dev}/EventScopeImpl.java | 4 ++-- .../fabric/impl/debug/{ => dev}/EventTestingImpl.java | 4 ++-- .../fabric/impl/debug/{ => dev}/TestableArrayBackedEvent.java | 2 +- .../fabric/impl/debug/{ => dev}/TestableEventFactoryImpl.java | 2 +- .../net.fabricmc.fabric.impl.base.event.EventFactoryImpl | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) rename fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/{ => dev}/v1/EventScope.java (95%) rename fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/{ => dev}/EventScopeImpl.java (91%) rename fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/{ => dev}/EventTestingImpl.java (93%) rename fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/{ => dev}/TestableArrayBackedEvent.java (96%) rename fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/{ => dev}/TestableEventFactoryImpl.java (95%) diff --git a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java index 7628b3c6382..2069704a2fb 100644 --- a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java +++ b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java @@ -42,7 +42,7 @@ public class EventFactoryImpl { protected EventFactoryImpl() { Class thisClass = getClass(); - if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals("net.fabricmc.fabric.impl.debug.TestableEventFactoryImpl")) { + if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals("net.fabricmc.fabric.impl.debug.dev.TestableEventFactoryImpl")) { throw new IllegalStateException("You are not allowed to create a custom EventFactoryImpl!"); } } diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java similarity index 95% rename from fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java rename to fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java index 204b45ff637..fb48f0068ba 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/v1/EventScope.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.api.debug.v1; +package net.fabricmc.fabric.api.debug.dev.v1; import java.util.function.Function; @@ -24,7 +24,7 @@ import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; -import net.fabricmc.fabric.impl.debug.EventTestingImpl; +import net.fabricmc.fabric.impl.debug.dev.EventTestingImpl; /** * Represents a wrapper around a short-lived {@link Event}. diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EventScopeImpl.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventScopeImpl.java similarity index 91% rename from fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EventScopeImpl.java rename to fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventScopeImpl.java index 17693369456..c90821fa765 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EventScopeImpl.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventScopeImpl.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.debug; +package net.fabricmc.fabric.impl.debug.dev; import net.minecraft.resources.Identifier; -import net.fabricmc.fabric.api.debug.v1.EventScope; +import net.fabricmc.fabric.api.debug.dev.v1.EventScope; public class EventScopeImpl implements EventScope { private final TestableArrayBackedEvent event; diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EventTestingImpl.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventTestingImpl.java similarity index 93% rename from fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EventTestingImpl.java rename to fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventTestingImpl.java index 54227e84450..7efc8ce8c5a 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/EventTestingImpl.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventTestingImpl.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.debug; +package net.fabricmc.fabric.impl.debug.dev; import net.minecraft.resources.Identifier; -import net.fabricmc.fabric.api.debug.v1.EventScope; +import net.fabricmc.fabric.api.debug.dev.v1.EventScope; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.loader.api.FabricLoader; diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/TestableArrayBackedEvent.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/TestableArrayBackedEvent.java similarity index 96% rename from fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/TestableArrayBackedEvent.java rename to fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/TestableArrayBackedEvent.java index 8b56c748322..0c33d654ae2 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/TestableArrayBackedEvent.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/TestableArrayBackedEvent.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.debug; +package net.fabricmc.fabric.impl.debug.dev; import java.util.Objects; import java.util.function.Function; diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/TestableEventFactoryImpl.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/TestableEventFactoryImpl.java similarity index 95% rename from fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/TestableEventFactoryImpl.java rename to fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/TestableEventFactoryImpl.java index 36bb84bada0..0eb0d407095 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/TestableEventFactoryImpl.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/TestableEventFactoryImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.debug; +package net.fabricmc.fabric.impl.debug.dev; import java.util.function.Function; diff --git a/fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl b/fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl index b373fc262f7..31a51a283bb 100644 --- a/fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl +++ b/fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl @@ -1 +1 @@ -net.fabricmc.fabric.impl.debug.TestableEventFactoryImpl +net.fabricmc.fabric.impl.debug.dev.TestableEventFactoryImpl From 32effd15a027918606a9a52386f1037c17313a5a Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 18:16:57 -0400 Subject: [PATCH 34/48] docs(EventScope): nitpick changes to phrasing and word choice --- .../fabricmc/fabric/api/debug/dev/v1/EventScope.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java index fb48f0068ba..fb28b894f65 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java @@ -28,8 +28,8 @@ /** * Represents a wrapper around a short-lived {@link Event}. - * This class implements {@link AutoCloseable} and is intended to be used in a try-with-resources statement. When - * closed, the Event will be unregistered. + * This class implements {@link AutoCloseable} and is intended to be used in a try-with-resources block. + * When closed, the event will be unregistered. */ @ApiStatus.NonExtendable public interface EventScope extends AutoCloseable { @@ -37,8 +37,8 @@ public interface EventScope extends AutoCloseable { void close(); /** - * @param event The {@link Event} that should get registered - * @param listener The corresponding listener + * @param event The {@link Event} to be registered in an {@link EventScope} + * @param listener The event listener * @param is the type parameter for the event's listener * @return a new {@link EventScope} instance holding the event, its listener and the event phase {@link Event#DEFAULT_PHASE} */ @@ -47,9 +47,9 @@ static EventScope registerScoped(Event event, T listener) { } /** - * @param event The {@link Event} that should get registered + * @param event The {@link Event} to be registered in an {@link EventScope} * @param phase The {@linkplain EventFactory#createWithPhases(Class, Function, Identifier...) event phase} - * @param listener The corresponding listener + * @param listener The event listener * @param is the type parameter for the event's listener * @return a new {@link EventScope} instance holding the event, its listener and the event phase * @see EventFactory#createWithPhases(Class, Function, Identifier...) From bddd1d5ee038e18ba38f83c81cebe02dd8e77666 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 18:48:44 -0400 Subject: [PATCH 35/48] test: add tests for `EventScope` --- fabric-dev-debug-api-v1/build.gradle | 1 + .../fabric/test/debug/dev/EventScopeTest.java | 39 +++++++++++++++++++ .../src/testmod/resources/fabric.mod.json | 13 +++++++ 3 files changed, 53 insertions(+) create mode 100644 fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java create mode 100644 fabric-dev-debug-api-v1/src/testmod/resources/fabric.mod.json diff --git a/fabric-dev-debug-api-v1/build.gradle b/fabric-dev-debug-api-v1/build.gradle index 1a3e00c4b88..dd6c9db0d35 100644 --- a/fabric-dev-debug-api-v1/build.gradle +++ b/fabric-dev-debug-api-v1/build.gradle @@ -6,4 +6,5 @@ moduleDependencies(project, [ ]) testDependencies(project, [ + 'fabric-gametest-api-v1' ]) diff --git a/fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java b/fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java new file mode 100644 index 00000000000..0fc90162026 --- /dev/null +++ b/fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java @@ -0,0 +1,39 @@ +package net.fabricmc.fabric.test.debug.dev; + +import net.minecraft.gametest.framework.GameTestHelper; + +import net.fabricmc.fabric.api.debug.dev.v1.EventScope; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.fabricmc.fabric.api.gametest.v1.GameTest; + +public class EventScopeTest { + private static final Event EVENT = EventFactory.createArrayBacked( + Foo.class, + listeners -> () -> { + for (Foo listener : listeners) { + if (!listener.doSomething()) { + return false; + } + } + + return true; + } + ); + + @GameTest + public void testEventScope(GameTestHelper helper) { + Foo foo = () -> false; + + try (EventScope _ = EventScope.registerScoped(EVENT, foo)) { + helper.assertFalse(EVENT.invoker().doSomething(), "Event Foo in EventScope was not registered."); + } + + helper.assertTrue(EVENT.invoker().doSomething(), "EventScope did not unregister event Foo after closing."); + helper.succeed(); + } + + private interface Foo { + boolean doSomething(); + } +} diff --git a/fabric-dev-debug-api-v1/src/testmod/resources/fabric.mod.json b/fabric-dev-debug-api-v1/src/testmod/resources/fabric.mod.json new file mode 100644 index 00000000000..e47fc92038b --- /dev/null +++ b/fabric-dev-debug-api-v1/src/testmod/resources/fabric.mod.json @@ -0,0 +1,13 @@ +{ + "schemaVersion": 1, + "id": "fabric-dev-debug-api-v1-testmod", + "name": "Fabric Dev Debug API (v1) Test Mod", + "version": "1.0.0", + "environment": "*", + "license": "Apache-2.0", + "entrypoints": { + "fabric-gametest": [ + "net.fabricmc.fabric.test.debug.dev.EventScopeTest" + ] + } +} From 8cd5b48382610ce8e62a688ea831cd738803b110 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 18:57:01 -0400 Subject: [PATCH 36/48] docs: change description of Debug API to more accurately reflect its scope --- fabric-debug-api-v1/src/main/resources/fabric.mod.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric-debug-api-v1/src/main/resources/fabric.mod.json b/fabric-debug-api-v1/src/main/resources/fabric.mod.json index 6be29e7c74a..7c879a3ff89 100644 --- a/fabric-debug-api-v1/src/main/resources/fabric.mod.json +++ b/fabric-debug-api-v1/src/main/resources/fabric.mod.json @@ -19,7 +19,7 @@ "fabricloader": ">=0.18.4", "fabric-api-base": "*" }, - "description": "A toolkit for registering and using debug subscriptions and other debug tools Mojang have created.", + "description": "A toolkit for using debug tools Mojang have created and other utilities in tests and development.", "mixins": [ "fabric-debug-api-v1.mixins.json", { From 1fc87253514bbcc40fb61358925d275e967a1b09 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 18:59:55 -0400 Subject: [PATCH 37/48] fix: remove unnecessary dev env check --- .../net/fabricmc/fabric/impl/debug/dev/EventTestingImpl.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventTestingImpl.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventTestingImpl.java index 7efc8ce8c5a..64267106ec2 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventTestingImpl.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventTestingImpl.java @@ -20,17 +20,12 @@ import net.fabricmc.fabric.api.debug.dev.v1.EventScope; import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.loader.api.FabricLoader; public final class EventTestingImpl { private EventTestingImpl() { } public static EventScope registerScoped(Event event, Identifier phase, T listener) { - if (!FabricLoader.getInstance().isDevelopmentEnvironment()) { - throw new IllegalArgumentException("EventScopes only work in development environments!"); - } - if (!(event instanceof TestableArrayBackedEvent testableEvent)) { throw new IllegalArgumentException("Event is not testable, something has gone very wrong!"); } From 08382c515a51a67d4060b45987c1b49a9dfb728b Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 19:02:23 -0400 Subject: [PATCH 38/48] refactor: move merge EventTestingImpl with EventScopeImpl --- .../fabric/api/debug/dev/v1/EventScope.java | 4 +-- .../fabric/impl/debug/dev/EventScopeImpl.java | 10 ++++++ .../impl/debug/dev/EventTestingImpl.java | 36 ------------------- 3 files changed, 12 insertions(+), 38 deletions(-) delete mode 100644 fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventTestingImpl.java diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java index fb28b894f65..8819b318977 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java @@ -24,7 +24,7 @@ import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; -import net.fabricmc.fabric.impl.debug.dev.EventTestingImpl; +import net.fabricmc.fabric.impl.debug.dev.EventScopeImpl; /** * Represents a wrapper around a short-lived {@link Event}. @@ -55,6 +55,6 @@ static EventScope registerScoped(Event event, T listener) { * @see EventFactory#createWithPhases(Class, Function, Identifier...) */ static EventScope registerScoped(Event event, Identifier phase, T listener) { - return EventTestingImpl.registerScoped(event, phase, listener); + return EventScopeImpl.registerScoped(event, phase, listener); } } diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventScopeImpl.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventScopeImpl.java index c90821fa765..b47bcf1a899 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventScopeImpl.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventScopeImpl.java @@ -19,6 +19,7 @@ import net.minecraft.resources.Identifier; import net.fabricmc.fabric.api.debug.dev.v1.EventScope; +import net.fabricmc.fabric.api.event.Event; public class EventScopeImpl implements EventScope { private final TestableArrayBackedEvent event; @@ -31,6 +32,15 @@ public EventScopeImpl(TestableArrayBackedEvent event, Identifier phase, T lis this.listener = listener; } + public static EventScope registerScoped(Event event, Identifier phase, T listener) { + if (!(event instanceof TestableArrayBackedEvent testableEvent)) { + throw new IllegalArgumentException("Event is not testable, something has gone very wrong!"); + } + + event.register(phase, listener); + return new EventScopeImpl<>(testableEvent, phase, listener); + } + @Override public void close() { event.unregister(phase, listener); diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventTestingImpl.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventTestingImpl.java deleted file mode 100644 index 64267106ec2..00000000000 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventTestingImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.fabricmc.fabric.impl.debug.dev; - -import net.minecraft.resources.Identifier; - -import net.fabricmc.fabric.api.debug.dev.v1.EventScope; -import net.fabricmc.fabric.api.event.Event; - -public final class EventTestingImpl { - private EventTestingImpl() { - } - - public static EventScope registerScoped(Event event, Identifier phase, T listener) { - if (!(event instanceof TestableArrayBackedEvent testableEvent)) { - throw new IllegalArgumentException("Event is not testable, something has gone very wrong!"); - } - - event.register(phase, listener); - return new EventScopeImpl<>(testableEvent, phase, listener); - } -} From c5753e142ba78e7ff130d609c7f89a761b59bd70 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 19:16:07 -0400 Subject: [PATCH 39/48] chore: spotless apply --- .../fabric/test/debug/dev/EventScopeTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java b/fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java index 0fc90162026..27586df9487 100644 --- a/fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java +++ b/fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.test.debug.dev; import net.minecraft.gametest.framework.GameTestHelper; From 6e715f3aa73ad1c29aa302d89787c8805bae9f97 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Mon, 30 Mar 2026 19:54:18 -0400 Subject: [PATCH 40/48] refactor: `EventScope#registerScoped` -> `#register` --- .../net/fabricmc/fabric/api/debug/dev/v1/EventScope.java | 8 ++++---- .../fabricmc/fabric/impl/debug/dev/EventScopeImpl.java | 2 +- .../fabricmc/fabric/test/debug/dev/EventScopeTest.java | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java index 8819b318977..ae6f24b90ba 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java @@ -42,8 +42,8 @@ public interface EventScope extends AutoCloseable { * @param is the type parameter for the event's listener * @return a new {@link EventScope} instance holding the event, its listener and the event phase {@link Event#DEFAULT_PHASE} */ - static EventScope registerScoped(Event event, T listener) { - return registerScoped(event, Event.DEFAULT_PHASE, listener); + static EventScope register(Event event, T listener) { + return register(event, Event.DEFAULT_PHASE, listener); } /** @@ -54,7 +54,7 @@ static EventScope registerScoped(Event event, T listener) { * @return a new {@link EventScope} instance holding the event, its listener and the event phase * @see EventFactory#createWithPhases(Class, Function, Identifier...) */ - static EventScope registerScoped(Event event, Identifier phase, T listener) { - return EventScopeImpl.registerScoped(event, phase, listener); + static EventScope register(Event event, Identifier phase, T listener) { + return EventScopeImpl.register(event, phase, listener); } } diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventScopeImpl.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventScopeImpl.java index b47bcf1a899..65593bfd053 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventScopeImpl.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventScopeImpl.java @@ -32,7 +32,7 @@ public EventScopeImpl(TestableArrayBackedEvent event, Identifier phase, T lis this.listener = listener; } - public static EventScope registerScoped(Event event, Identifier phase, T listener) { + public static EventScope register(Event event, Identifier phase, T listener) { if (!(event instanceof TestableArrayBackedEvent testableEvent)) { throw new IllegalArgumentException("Event is not testable, something has gone very wrong!"); } diff --git a/fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java b/fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java index 27586df9487..c01cf96191f 100644 --- a/fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java +++ b/fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java @@ -41,7 +41,7 @@ public class EventScopeTest { public void testEventScope(GameTestHelper helper) { Foo foo = () -> false; - try (EventScope _ = EventScope.registerScoped(EVENT, foo)) { + try (EventScope _ = EventScope.register(EVENT, foo)) { helper.assertFalse(EVENT.invoker().doSomething(), "Event Foo in EventScope was not registered."); } From 6ea9b072b516820d72fbd049b254d96470dad62e Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Wed, 1 Apr 2026 23:15:58 +0200 Subject: [PATCH 41/48] remove hacky inheritor verification address feedback --- .../fabricmc/fabric/impl/base/event/EventFactoryImpl.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java index 2069704a2fb..37dd04ac540 100644 --- a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java +++ b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java @@ -40,11 +40,6 @@ public class EventFactoryImpl { = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap()); protected EventFactoryImpl() { - Class thisClass = getClass(); - - if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals("net.fabricmc.fabric.impl.debug.dev.TestableEventFactoryImpl")) { - throw new IllegalStateException("You are not allowed to create a custom EventFactoryImpl!"); - } } public static void invalidate() { From 85b6147b8857f3461dd22d5c8abdb1fac25a2eef Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Wed, 1 Apr 2026 23:21:16 +0200 Subject: [PATCH 42/48] mark api as stable --- fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json b/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json index 5a4435c5eb5..17652b59f3a 100644 --- a/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json +++ b/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json @@ -16,6 +16,6 @@ }, "description": "An extension of Debug API with features only available in development environments.", "custom": { - "fabric-api:module-lifecycle": "experimental" + "fabric-api:module-lifecycle": "stable" } } From a8e7e0efdb78a55bacc53957247aa07d6ae1f751 Mon Sep 17 00:00:00 2001 From: Kilip1000 <206253641+Kilip1000@users.noreply.github.com> Date: Wed, 1 Apr 2026 23:27:26 +0200 Subject: [PATCH 43/48] Revert "remove hacky inheritor verification" This reverts commit 6ea9b072b516820d72fbd049b254d96470dad62e. --- .../fabricmc/fabric/impl/base/event/EventFactoryImpl.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java index 37dd04ac540..2069704a2fb 100644 --- a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java +++ b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java @@ -40,6 +40,11 @@ public class EventFactoryImpl { = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap()); protected EventFactoryImpl() { + Class thisClass = getClass(); + + if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals("net.fabricmc.fabric.impl.debug.dev.TestableEventFactoryImpl")) { + throw new IllegalStateException("You are not allowed to create a custom EventFactoryImpl!"); + } } public static void invalidate() { From 39d745fd3f3c2db07c764b0e6b5fc4d9dbc9e5d1 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 1 Apr 2026 19:17:44 -0400 Subject: [PATCH 44/48] fix: remove inheritance check & ServiceLoader jank, use custom FMJ value --- .../impl/base/event/EventFactoryImpl.java | 32 +++++++++++++++---- .../src/main/resources/fabric.mod.json | 3 +- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java index 2069704a2fb..51cc64f04ca 100644 --- a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java +++ b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java @@ -24,7 +24,6 @@ import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.util.Collections; -import java.util.ServiceLoader; import java.util.Set; import java.util.function.Function; @@ -33,20 +32,39 @@ import net.minecraft.resources.Identifier; import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.loader.api.FabricLoader; public class EventFactoryImpl { - public static final EventFactoryImpl INSTANCE = ServiceLoader.load(EventFactoryImpl.class).findFirst().orElseGet(EventFactoryImpl::new); + public static final EventFactoryImpl INSTANCE; private static final Set> ARRAY_BACKED_EVENTS = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap()); - protected EventFactoryImpl() { - Class thisClass = getClass(); - - if (thisClass != EventFactoryImpl.class && !thisClass.getName().equals("net.fabricmc.fabric.impl.debug.dev.TestableEventFactoryImpl")) { - throw new IllegalStateException("You are not allowed to create a custom EventFactoryImpl!"); + static { + final String eventScopeModule = "fabric-dev-debug-api-v1"; + + if (FabricLoader.getInstance().isModLoaded(eventScopeModule)) { + String clazzName = FabricLoader.getInstance() + .getModContainer(eventScopeModule) + .orElseThrow() + .getMetadata() + .getCustomValue("fabric-api-base:event_factory_impl") + .getAsString(); + try { + Class clazz = Class.forName(clazzName); + INSTANCE = (EventFactoryImpl) MethodHandles.publicLookup() + .findConstructor(clazz, MethodType.methodType(void.class)) + .invoke(); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } else { + INSTANCE = new EventFactoryImpl(); } } + protected EventFactoryImpl() { + } + public static void invalidate() { ARRAY_BACKED_EVENTS.forEach(ArrayBackedEvent::update); } diff --git a/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json b/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json index 17652b59f3a..bf97502afe4 100644 --- a/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json +++ b/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json @@ -16,6 +16,7 @@ }, "description": "An extension of Debug API with features only available in development environments.", "custom": { - "fabric-api:module-lifecycle": "stable" + "fabric-api:module-lifecycle": "stable", + "fabric-api-base:event_factory_impl": "net.fabricmc.fabric.impl.debug.dev.TestableEventFactoryImpl" } } From b6c31d4552fe8a573f94d2bc3708ceacd6bdfecc Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 1 Apr 2026 19:18:44 -0400 Subject: [PATCH 45/48] chore: mark API experimental --- .../java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java | 1 + fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java index ae6f24b90ba..fa602f7246d 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java +++ b/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java @@ -32,6 +32,7 @@ * When closed, the event will be unregistered. */ @ApiStatus.NonExtendable +@ApiStatus.Experimental public interface EventScope extends AutoCloseable { @Override void close(); diff --git a/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json b/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json index bf97502afe4..930763a7da3 100644 --- a/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json +++ b/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json @@ -16,7 +16,7 @@ }, "description": "An extension of Debug API with features only available in development environments.", "custom": { - "fabric-api:module-lifecycle": "stable", + "fabric-api:module-lifecycle": "experimental", "fabric-api-base:event_factory_impl": "net.fabricmc.fabric.impl.debug.dev.TestableEventFactoryImpl" } } From 68e2541b8017a52074837fc089159e714b6f439e Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 1 Apr 2026 19:46:02 -0400 Subject: [PATCH 46/48] Revert "docs: change description of Debug API to more accurately reflect its scope" This reverts commit 8cd5b48382610ce8e62a688ea831cd738803b110. --- fabric-debug-api-v1/src/main/resources/fabric.mod.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric-debug-api-v1/src/main/resources/fabric.mod.json b/fabric-debug-api-v1/src/main/resources/fabric.mod.json index 7c879a3ff89..6be29e7c74a 100644 --- a/fabric-debug-api-v1/src/main/resources/fabric.mod.json +++ b/fabric-debug-api-v1/src/main/resources/fabric.mod.json @@ -19,7 +19,7 @@ "fabricloader": ">=0.18.4", "fabric-api-base": "*" }, - "description": "A toolkit for using debug tools Mojang have created and other utilities in tests and development.", + "description": "A toolkit for registering and using debug subscriptions and other debug tools Mojang have created.", "mixins": [ "fabric-debug-api-v1.mixins.json", { From 371d9490f5a17587c18b549808afdb6cc4fb3525 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 1 Apr 2026 20:10:35 -0400 Subject: [PATCH 47/48] refactor: remove reliance on Debug API, convert to `test-api` --- build.gradle | 2 +- .../impl/base/event/EventFactoryImpl.java | 2 +- ...mc.fabric.impl.base.event.EventFactoryImpl | 1 - .../src/main/resources/fabric.mod.json | 22 ------------------ .../build.gradle | 3 +-- .../fabric/api/test}/v1/EventScope.java | 4 ++-- .../fabric/impl/test}/EventScopeImpl.java | 4 ++-- .../impl/test}/TestableArrayBackedEvent.java | 2 +- .../impl/test}/TestableEventFactoryImpl.java | 2 +- .../assets/fabric-test-api-v1}/icon.png | Bin .../src/main/resources/fabric.mod.json | 21 +++++++++++++++++ .../fabricmc/fabric/test}/EventScopeTest.java | 4 ++-- .../src/testmod/resources/fabric.mod.json | 6 ++--- gradle.properties | 2 +- settings.gradle | 2 +- 15 files changed, 37 insertions(+), 40 deletions(-) delete mode 100644 fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl delete mode 100644 fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json rename {fabric-dev-debug-api-v1 => fabric-test-api-v1}/build.gradle (75%) rename {fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev => fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test}/v1/EventScope.java (95%) rename {fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev => fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test}/EventScopeImpl.java (93%) rename {fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev => fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test}/TestableArrayBackedEvent.java (96%) rename {fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev => fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test}/TestableEventFactoryImpl.java (95%) rename {fabric-dev-debug-api-v1/src/main/resources/assets/fabric-dev-debug-api-v1 => fabric-test-api-v1/src/main/resources/assets/fabric-test-api-v1}/icon.png (100%) create mode 100644 fabric-test-api-v1/src/main/resources/fabric.mod.json rename {fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev => fabric-test-api-v1/src/testmod/java/net/fabricmc/fabric/test}/EventScopeTest.java (93%) rename {fabric-dev-debug-api-v1 => fabric-test-api-v1}/src/testmod/resources/fabric.mod.json (50%) diff --git a/build.gradle b/build.gradle index 512954527f7..c86c41281e3 100644 --- a/build.gradle +++ b/build.gradle @@ -617,7 +617,7 @@ void setupRepositories(RepositoryHandler repositories) { def devOnlyModules = [ "fabric-client-gametest-api-v1", "fabric-gametest-api-v1", - "fabric-dev-debug-api-v1" + "fabric-test-api-v1" ] dependencies { diff --git a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java index 51cc64f04ca..a5af6c54ffd 100644 --- a/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java +++ b/fabric-api-base/src/main/java/net/fabricmc/fabric/impl/base/event/EventFactoryImpl.java @@ -40,7 +40,7 @@ public class EventFactoryImpl { = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap()); static { - final String eventScopeModule = "fabric-dev-debug-api-v1"; + final String eventScopeModule = "fabric-test-api-v1"; if (FabricLoader.getInstance().isModLoaded(eventScopeModule)) { String clazzName = FabricLoader.getInstance() diff --git a/fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl b/fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl deleted file mode 100644 index 31a51a283bb..00000000000 --- a/fabric-dev-debug-api-v1/src/main/resources/META-INF/services/net.fabricmc.fabric.impl.base.event.EventFactoryImpl +++ /dev/null @@ -1 +0,0 @@ -net.fabricmc.fabric.impl.debug.dev.TestableEventFactoryImpl diff --git a/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json b/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json deleted file mode 100644 index 930763a7da3..00000000000 --- a/fabric-dev-debug-api-v1/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "schemaVersion": 1, - "id": "fabric-dev-debug-api-v1", - "name": "Fabric Dev Debug API (v1)", - "version": "${version}", - "environment": "*", - "license": "Apache-2.0", - "icon": "assets/fabric-dev-debug-api-v1/icon.png", - "authors": [ - "FabricMC" - ], - "depends": { - "fabricloader": ">=0.18.4", - "fabric-api-base": "*", - "fabric-debug-api-v1": "*" - }, - "description": "An extension of Debug API with features only available in development environments.", - "custom": { - "fabric-api:module-lifecycle": "experimental", - "fabric-api-base:event_factory_impl": "net.fabricmc.fabric.impl.debug.dev.TestableEventFactoryImpl" - } -} diff --git a/fabric-dev-debug-api-v1/build.gradle b/fabric-test-api-v1/build.gradle similarity index 75% rename from fabric-dev-debug-api-v1/build.gradle rename to fabric-test-api-v1/build.gradle index dd6c9db0d35..b93723665d3 100644 --- a/fabric-dev-debug-api-v1/build.gradle +++ b/fabric-test-api-v1/build.gradle @@ -1,8 +1,7 @@ version = getSubprojectVersion(project) moduleDependencies(project, [ - 'fabric-api-base', - 'fabric-debug-api-v1' + 'fabric-api-base' ]) testDependencies(project, [ diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/v1/EventScope.java similarity index 95% rename from fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java rename to fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/v1/EventScope.java index fa602f7246d..11a0e2c902a 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/api/debug/dev/v1/EventScope.java +++ b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/api/test/v1/EventScope.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.api.debug.dev.v1; +package net.fabricmc.fabric.api.test.v1; import java.util.function.Function; @@ -24,7 +24,7 @@ import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; -import net.fabricmc.fabric.impl.debug.dev.EventScopeImpl; +import net.fabricmc.fabric.impl.test.EventScopeImpl; /** * Represents a wrapper around a short-lived {@link Event}. diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventScopeImpl.java b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java similarity index 93% rename from fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventScopeImpl.java rename to fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java index 65593bfd053..5cadf08ce21 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/EventScopeImpl.java +++ b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.debug.dev; +package net.fabricmc.fabric.impl.test; import net.minecraft.resources.Identifier; -import net.fabricmc.fabric.api.debug.dev.v1.EventScope; +import net.fabricmc.fabric.api.test.v1.EventScope; import net.fabricmc.fabric.api.event.Event; public class EventScopeImpl implements EventScope { diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/TestableArrayBackedEvent.java b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java similarity index 96% rename from fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/TestableArrayBackedEvent.java rename to fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java index 0c33d654ae2..454cb5cf199 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/TestableArrayBackedEvent.java +++ b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableArrayBackedEvent.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.debug.dev; +package net.fabricmc.fabric.impl.test; import java.util.Objects; import java.util.function.Function; diff --git a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/TestableEventFactoryImpl.java b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java similarity index 95% rename from fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/TestableEventFactoryImpl.java rename to fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java index 0eb0d407095..09dae87f261 100644 --- a/fabric-dev-debug-api-v1/src/main/java/net/fabricmc/fabric/impl/debug/dev/TestableEventFactoryImpl.java +++ b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/TestableEventFactoryImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.debug.dev; +package net.fabricmc.fabric.impl.test; import java.util.function.Function; diff --git a/fabric-dev-debug-api-v1/src/main/resources/assets/fabric-dev-debug-api-v1/icon.png b/fabric-test-api-v1/src/main/resources/assets/fabric-test-api-v1/icon.png similarity index 100% rename from fabric-dev-debug-api-v1/src/main/resources/assets/fabric-dev-debug-api-v1/icon.png rename to fabric-test-api-v1/src/main/resources/assets/fabric-test-api-v1/icon.png diff --git a/fabric-test-api-v1/src/main/resources/fabric.mod.json b/fabric-test-api-v1/src/main/resources/fabric.mod.json new file mode 100644 index 00000000000..b04da2f566b --- /dev/null +++ b/fabric-test-api-v1/src/main/resources/fabric.mod.json @@ -0,0 +1,21 @@ +{ + "schemaVersion": 1, + "id": "fabric-test-api-v1", + "name": "Fabric Test API (v1)", + "version": "${version}", + "environment": "*", + "license": "Apache-2.0", + "icon": "assets/fabric-test-api-v1/icon.png", + "authors": [ + "FabricMC" + ], + "depends": { + "fabricloader": ">=0.18.4", + "fabric-api-base": "*" + }, + "description": "General utilities for tests and development environments.", + "custom": { + "fabric-api:module-lifecycle": "experimental", + "fabric-api-base:event_factory_impl": "net.fabricmc.fabric.impl.test.TestableEventFactoryImpl" + } +} diff --git a/fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java b/fabric-test-api-v1/src/testmod/java/net/fabricmc/fabric/test/EventScopeTest.java similarity index 93% rename from fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java rename to fabric-test-api-v1/src/testmod/java/net/fabricmc/fabric/test/EventScopeTest.java index c01cf96191f..9e15aa8e9b5 100644 --- a/fabric-dev-debug-api-v1/src/testmod/java/net/fabricmc/fabric/test/debug/dev/EventScopeTest.java +++ b/fabric-test-api-v1/src/testmod/java/net/fabricmc/fabric/test/EventScopeTest.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package net.fabricmc.fabric.test.debug.dev; +package net.fabricmc.fabric.test; import net.minecraft.gametest.framework.GameTestHelper; -import net.fabricmc.fabric.api.debug.dev.v1.EventScope; +import net.fabricmc.fabric.api.test.v1.EventScope; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; import net.fabricmc.fabric.api.gametest.v1.GameTest; diff --git a/fabric-dev-debug-api-v1/src/testmod/resources/fabric.mod.json b/fabric-test-api-v1/src/testmod/resources/fabric.mod.json similarity index 50% rename from fabric-dev-debug-api-v1/src/testmod/resources/fabric.mod.json rename to fabric-test-api-v1/src/testmod/resources/fabric.mod.json index e47fc92038b..40d35d750e7 100644 --- a/fabric-dev-debug-api-v1/src/testmod/resources/fabric.mod.json +++ b/fabric-test-api-v1/src/testmod/resources/fabric.mod.json @@ -1,13 +1,13 @@ { "schemaVersion": 1, - "id": "fabric-dev-debug-api-v1-testmod", - "name": "Fabric Dev Debug API (v1) Test Mod", + "id": "fabric-test-api-v1-testmod", + "name": "Fabric Test API (v1) Test Mod", "version": "1.0.0", "environment": "*", "license": "Apache-2.0", "entrypoints": { "fabric-gametest": [ - "net.fabricmc.fabric.test.debug.dev.EventScopeTest" + "net.fabricmc.fabric.test.EventScopeTest" ] } } diff --git a/gradle.properties b/gradle.properties index 2d3d281d723..47779f15408 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,7 +23,6 @@ fabric-crash-report-info-v1-version=1.0.3 fabric-data-attachment-api-v1-version=2.2.3 fabric-data-generation-api-v1-version=24.0.17 fabric-debug-api-v1-version=1.0.1 -fabric-dev-debug-api-v1-version=1.0.0 fabric-dimensions-v1-version=5.1.4 fabric-entity-events-v1-version=5.0.2 fabric-events-interaction-v0-version=5.1.10 @@ -53,6 +52,7 @@ fabric-menu-api-v1-version=2.0.12 fabric-serialization-api-v1-version=2.0.3 fabric-sound-api-v1-version=2.0.4 fabric-tag-api-v1-version=2.0.9 +fabric-test-api-v1-version=1.0.0 fabric-transfer-api-v1-version=8.0.2 fabric-transitive-access-wideners-v1-version=8.0.11 fabric-convention-tags-v2-version=4.3.2 diff --git a/settings.gradle b/settings.gradle index 812b764dae0..1b3bc601aaf 100644 --- a/settings.gradle +++ b/settings.gradle @@ -38,7 +38,6 @@ include 'fabric-creative-tab-api-v1' include 'fabric-data-attachment-api-v1' include 'fabric-data-generation-api-v1' include 'fabric-debug-api-v1' -include 'fabric-dev-debug-api-v1' include 'fabric-dimensions-v1' include 'fabric-entity-events-v1' include 'fabric-events-interaction-v0' @@ -66,6 +65,7 @@ include 'fabric-screen-api-v1' include 'fabric-serialization-api-v1' include 'fabric-sound-api-v1' include 'fabric-tag-api-v1' +include 'fabric-test-api-v1' include 'fabric-transfer-api-v1' include 'fabric-transitive-access-wideners-v1' include 'deprecated' From c146b32349d09344a8dd9d915fd6ef0c23f87014 Mon Sep 17 00:00:00 2001 From: sylv256 Date: Wed, 1 Apr 2026 20:30:32 -0400 Subject: [PATCH 48/48] test: convert gametest to unit test --- .../fabric/impl/test/EventScopeImpl.java | 2 +- .../fabric/test}/test/EventScopeTest.java | 29 +++++++++++++------ .../src/testmod/resources/fabric.mod.json | 7 +---- 3 files changed, 22 insertions(+), 16 deletions(-) rename fabric-test-api-v1/src/{testmod/java/net/fabricmc/fabric => test/java/net/fabricmc/fabric/test}/test/EventScopeTest.java (64%) diff --git a/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java index 5cadf08ce21..adcc545d8ea 100644 --- a/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java +++ b/fabric-test-api-v1/src/main/java/net/fabricmc/fabric/impl/test/EventScopeImpl.java @@ -18,8 +18,8 @@ import net.minecraft.resources.Identifier; -import net.fabricmc.fabric.api.test.v1.EventScope; import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.test.v1.EventScope; public class EventScopeImpl implements EventScope { private final TestableArrayBackedEvent event; diff --git a/fabric-test-api-v1/src/testmod/java/net/fabricmc/fabric/test/EventScopeTest.java b/fabric-test-api-v1/src/test/java/net/fabricmc/fabric/test/test/EventScopeTest.java similarity index 64% rename from fabric-test-api-v1/src/testmod/java/net/fabricmc/fabric/test/EventScopeTest.java rename to fabric-test-api-v1/src/test/java/net/fabricmc/fabric/test/test/EventScopeTest.java index 9e15aa8e9b5..cd8f9ee4619 100644 --- a/fabric-test-api-v1/src/testmod/java/net/fabricmc/fabric/test/EventScopeTest.java +++ b/fabric-test-api-v1/src/test/java/net/fabricmc/fabric/test/test/EventScopeTest.java @@ -14,14 +14,20 @@ * limitations under the License. */ -package net.fabricmc.fabric.test; +package net.fabricmc.fabric.test.test; -import net.minecraft.gametest.framework.GameTestHelper; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import net.minecraft.SharedConstants; +import net.minecraft.server.Bootstrap; -import net.fabricmc.fabric.api.test.v1.EventScope; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; -import net.fabricmc.fabric.api.gametest.v1.GameTest; +import net.fabricmc.fabric.api.test.v1.EventScope; public class EventScopeTest { private static final Event EVENT = EventFactory.createArrayBacked( @@ -37,16 +43,21 @@ public class EventScopeTest { } ); - @GameTest - public void testEventScope(GameTestHelper helper) { + @BeforeAll + static void bootstrap() { + SharedConstants.tryDetectVersion(); + Bootstrap.bootStrap(); + } + + @Test + void testEventScope() { Foo foo = () -> false; try (EventScope _ = EventScope.register(EVENT, foo)) { - helper.assertFalse(EVENT.invoker().doSomething(), "Event Foo in EventScope was not registered."); + assertFalse(EVENT.invoker().doSomething(), "Event Foo in EventScope was not registered."); } - helper.assertTrue(EVENT.invoker().doSomething(), "EventScope did not unregister event Foo after closing."); - helper.succeed(); + assertTrue(EVENT.invoker().doSomething(), "EventScope did not unregister event Foo after closing."); } private interface Foo { diff --git a/fabric-test-api-v1/src/testmod/resources/fabric.mod.json b/fabric-test-api-v1/src/testmod/resources/fabric.mod.json index 40d35d750e7..ffbfee655f6 100644 --- a/fabric-test-api-v1/src/testmod/resources/fabric.mod.json +++ b/fabric-test-api-v1/src/testmod/resources/fabric.mod.json @@ -4,10 +4,5 @@ "name": "Fabric Test API (v1) Test Mod", "version": "1.0.0", "environment": "*", - "license": "Apache-2.0", - "entrypoints": { - "fabric-gametest": [ - "net.fabricmc.fabric.test.EventScopeTest" - ] - } + "license": "Apache-2.0" }