-
Notifications
You must be signed in to change notification settings - Fork 521
Environment attribute API for adding custom attribute layers #5201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
FoxSamu
wants to merge
14
commits into
FabricMC:26.1
Choose a base branch
from
FoxSamu:26.1
base: 26.1
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 9 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
14c0ce9
Environment attribute API for adding custom attribute layers
FoxSamu 02d8b03
Change v0 into v1
FoxSamu d05868b
Replace events with proper sortable registry.
FoxSamu 5a2e97a
Merge branch '26.1' into 26.1
FoxSamu 14e89bc
Be more consistent with terms used in docs and code
FoxSamu fcba42c
Merge remote-tracking branch 'origin/26.1' into 26.1
FoxSamu 8721f5a
Merge branch '26.1' into 26.1
FoxSamu 250d6d6
Fix javadoc errors
FoxSamu 66ebdd3
Add a small essential comment in the docs about the nature of layers
FoxSamu ece2392
Make implementation naming match API naming
FoxSamu 9af08de
Change module name to match convention
FoxSamu f0fc207
Fix environment attribute api dependencies
FoxSamu 6fa1af7
Fix test mod dependency
FoxSamu e4809a0
Merge branch '26.1' into 26.1
FoxSamu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| version = getSubprojectVersion(project) | ||
|
|
||
| moduleDependencies(project, [ | ||
| 'fabric-api-base', | ||
| 'fabric-lifecycle-events-v1' | ||
| ]) | ||
|
|
||
| testDependencies(project, [ | ||
| ':fabric-resource-loader-v1', | ||
| ':fabric-client-gametest-api-v1' | ||
| ]) |
142 changes: 142 additions & 0 deletions
142
...rc/main/java/net/fabricmc/fabric/api/environment/attribute/v1/AttributeLayerProvider.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| /* | ||
| * 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.environment.attribute.v1; | ||
|
|
||
| import net.minecraft.resources.Identifier; | ||
| import net.minecraft.world.attribute.EnvironmentAttributeLayer; | ||
| import net.minecraft.world.attribute.EnvironmentAttributeSystem; | ||
| import net.minecraft.world.level.Level; | ||
|
|
||
| /** | ||
| * Provides {@link EnvironmentAttributeLayer}s to an {@link EnvironmentAttributeSystem}. You may register custom | ||
| * {@link AttributeLayerProvider} implementations using {@link AttributeLayerRegistry#registerLayerProvider}. Using | ||
| * {@link AttributeLayerProvider}, you can implement custom logic for modify and overriding attributes, based on | ||
| * things like weather, location or time. You can set restrictions on when your layer provider should apply in relation | ||
| * to vanilla providers or other modded providers using {@link AttributeLayerRegistry#addProviderOrdering} | ||
| * | ||
| * <h2>Background</h2> | ||
| * | ||
| * <p> | ||
| * The {@link EnvironmentAttributeSystem} assigns zero or more layers to every environment attribute. A layer here is | ||
| * represented by a {@link EnvironmentAttributeLayer}. Layers modify or | ||
| * override the value of an environment attribute by some implementation-specific logic. In vanilla Minecraft, defining an | ||
| * environment attribute in a dimension type, biome or timeline will cause a layer for that attribute to be added that | ||
| * modifies the attribute accordingly. Note that each attribute has its own stack of layers: layers apply to individual | ||
| * attributes, not to the system as a whole. | ||
| * </p> | ||
| * | ||
| * <p> | ||
| * Minecraft creates an {@link EnvironmentAttributeSystem} for each {@link Level}, both on the client and the server, | ||
| * and adds layers to this system through four different providers: | ||
| * </p> | ||
| * | ||
| * <ol> | ||
| * <li>Dimension type overrides: a layer is added for each attribute defined in the dimension type of the {@link Level}.</li> | ||
| * <li>Biome overrides: if one or more biomes define an attribute, a layer is added for that attribute that alters the | ||
| * attribute throughout different biomes.</li> | ||
| * <li>Timeline overrides: if one or more timelines define an attribute, a layer isadded for that attribute that alters | ||
| * the attribute according to how the timeline defines it.</li> | ||
| * <li>Weather overrides: if the {@link Level} {@linkplain Level#canHaveWeather() has weather}, Minecraft defines some | ||
| * hardcoded weather layers for weather for some attributes.</li> | ||
| * </ol> | ||
| * | ||
| * <p> | ||
| * Each layer is given the value outputted by the previous layer, and must modify or replace | ||
| * this value based on some context parameters. The first layer is given the default value of the attribute. | ||
| * </p> | ||
| * | ||
| * <h2>Adding modded layers</h2> | ||
| * | ||
| * <p> | ||
| * As mentioned, the {@link AttributeLayerProvider} allows you to add modded layers to environment attributes during | ||
| * the creation of the {@link EnvironmentAttributeSystem}. Every provider is associated to an {@link Identifier}, | ||
| * including vanilla's providers (despite that vanilla's providers are not implemented as separate classes). | ||
| * As order matters, attribute layers can be ordered relative to vanilla's layers or other modded layers using | ||
| * {@link AttributeLayerRegistry#addProviderOrdering}. | ||
| * </p> | ||
| * | ||
| * <p> | ||
| * Depending on the type of {@link EnvironmentAttributeLayer}, Minecraft caches values of environment attributes. Minecraft | ||
| * allows three different types of layers: | ||
| * </p> | ||
| * | ||
| * <ul> | ||
| * <li>{@linkplain EnvironmentAttributeLayer.Constant Constant layers}: these modify the value in a context-independent | ||
| * manner. Minecraft uses these for dimensions and expects them to be constant - do not depend on external variables | ||
| * when implementing constant layers. If an attribute has only constant layers, the attribute value is simply cached and | ||
| * never recomputed again. Minecraft uses constant layers to provide a dimension's attribute values.</li> | ||
| * <li>{@linkplain EnvironmentAttributeLayer.Positional Positional layers}: these modify the value based on a position | ||
| * in the world. If a positional layer is added to an attribute, Minecraft will recompute the value every time. | ||
| * Minecraft uses positional layers for biome interpolated attribute values. Note that environment attributes can be | ||
| * sampled without a position. In this case, positional layers are completely ignored.</li> | ||
| * <li>{@linkplain EnvironmentAttributeLayer.TimeBased Time based layers}: these modify the value based on time. | ||
| * Minecraft will cache the value per tick, so that if it is sampled multiple times per tick, it is only evaluated once. | ||
| * Minecraft uses time based layers for timelines and weather.</li> | ||
| * </ul> | ||
| * | ||
| * <p> | ||
| * It is important that modded implementations take into account the constraints of different layer types, otherwise | ||
| * they may not work properly. | ||
| * </p> | ||
| * | ||
| */ | ||
| public interface AttributeLayerProvider { | ||
| /** | ||
| * Identifier associated to vanilla's dimension attribute layer provider. | ||
| */ | ||
| Identifier DIMENSIONS = Identifier.withDefaultNamespace("dimensions"); | ||
|
|
||
| /** | ||
| * Identifier associated to vanilla's biome attribute layer provider. | ||
| */ | ||
| Identifier BIOMES = Identifier.withDefaultNamespace("biomes"); | ||
|
|
||
| /** | ||
| * Identifier associated to vanilla's timeline attribute layer provider. | ||
| */ | ||
| Identifier TIMELINES = Identifier.withDefaultNamespace("timelines"); | ||
|
|
||
| /** | ||
| * Identifier associated to vanilla's weather attribute layer provider. | ||
| */ | ||
| Identifier WEATHER = Identifier.withDefaultNamespace("weather"); | ||
|
|
||
| /** | ||
| * The identifier associated to the first vanilla provider. Currently, this is an alias for {@link #DIMENSIONS}. | ||
| * This constant exists purely for compatibility: if Minecraft ever adds another provider before its dimension provider, | ||
| * then this constant is updated so that mods can guarantee that their layer provider activates before all | ||
| * vanilla providers. | ||
| */ | ||
| Identifier FIRST_VANILLA_PROVIDER = DIMENSIONS; | ||
|
|
||
| /** | ||
| * The identifier associated to the last vanilla provider. Currently, this is an alias for {@link #WEATHER}. | ||
| * This constant exists purely for compatibility: if Minecraft ever adds another provider after its weather provider, | ||
| * then this constant is updated so that mods can guarantee that their layer provider activates after all | ||
| * vanilla providers. | ||
| */ | ||
| Identifier LAST_VANILLA_PROVIDER = WEATHER; | ||
|
|
||
| /** | ||
| * Called to add attribute layers to an {@link EnvironmentAttributeSystem.Builder} for the given {@link Level}. | ||
| * This is called both on the client and on the server each time a {@link Level} is initialized. | ||
| * | ||
| * @param systemBuilder The {@link EnvironmentAttributeSystem.Builder} to add layers to. | ||
| * @param level The {@link Level} that the environment attribute system is being created for. | ||
| */ | ||
| void addAttributeLayers(EnvironmentAttributeSystem.Builder systemBuilder, Level level); | ||
| } |
54 changes: 54 additions & 0 deletions
54
...rc/main/java/net/fabricmc/fabric/api/environment/attribute/v1/AttributeLayerRegistry.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| /* | ||
| * 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.environment.attribute.v1; | ||
|
|
||
| import org.jspecify.annotations.NullMarked; | ||
|
|
||
| import net.minecraft.resources.Identifier; | ||
|
|
||
| import net.fabricmc.fabric.impl.environment.attribute.AttributeLayerRegistryImpl; | ||
|
|
||
| /** | ||
| * Utility class allowing you to register and reorder {@link AttributeLayerProvider}s. | ||
| */ | ||
| @NullMarked | ||
| public class AttributeLayerRegistry { | ||
| /** | ||
| * Register a {@link AttributeLayerProvider}. If a layer provider with the given identifier already exists, an exception | ||
| * is thrown. | ||
| * | ||
| * @param id The identifier of the layer provider. This identifier can be used to set an ordering via | ||
| * {@link #addProviderOrdering}. . | ||
| * @param layer The layer provider to register. | ||
| */ | ||
| public static void registerLayerProvider(Identifier id, AttributeLayerProvider layer) { | ||
| AttributeLayerRegistryImpl.registerLayerProvider(id, layer); | ||
| } | ||
|
|
||
| /** | ||
| * Declares that the layer provider with the first identifier should activate before the layer provider with the | ||
| * second identifier. Unless this causes a cyclic dependency, the two layer providers are guaranteed to activate in | ||
| * said order. You may use this to order your layer provider against vanilla layer providers using any of the constants in | ||
| * {@link AttributeLayerProvider}. If both layer identifiers are the same, then an exception is thrown. | ||
| * | ||
| * @param firstLayer The ID of the layer provider that should activate earlier. | ||
| * @param secondLayer The ID of the layer provider that should activate later. | ||
| */ | ||
| public static void addProviderOrdering(Identifier firstLayer, Identifier secondLayer) { | ||
FoxSamu marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| AttributeLayerRegistryImpl.addProviderOrdering(firstLayer, secondLayer); | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.