mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-11 19:14:11 +00:00
[VERY VERY VERY BAD IDEA]
This commit is contained in:
@@ -12,6 +12,9 @@ java {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api("com.github.VolmitSoftware.VolmLib:native-api:${providers.gradleProperty('volmLibCoordinate').get().tokenize(':').last()}") {
|
||||
transitive = false
|
||||
}
|
||||
testImplementation('junit:junit:4.13.2')
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeWorld;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
@@ -27,7 +29,7 @@ import java.io.File;
|
||||
* ({@link #registries()}, {@link #scheduler()}, {@link #structureHooks()}, {@link #biomeWriter()}, the
|
||||
* version and path methods) are called from generation threads and must not block on the server thread.
|
||||
* The mutating methods ({@link #callEvent(Object)}, {@link #dispatchConsoleCommand(String)},
|
||||
* {@link #spawnEntity(PlatformWorld, String, double, double, double)}) touch live server state and are
|
||||
* {@link #spawnEntity(NativeWorld, String, double, double, double)}) touch live server state and are
|
||||
* expected to be invoked on the thread that owns it - the global/server thread, or the region thread
|
||||
* owning the target chunk on regionized platforms. Use {@link #scheduler()} to get there.
|
||||
* <p>
|
||||
@@ -179,14 +181,14 @@ public interface IrisPlatform {
|
||||
/**
|
||||
* Spawns a vanilla entity by namespaced key at the given block-space position.
|
||||
* <p>
|
||||
* Adapters unwrap {@link PlatformWorld#nativeHandle()} to reach the host world, so {@code world} must
|
||||
* be a {@link PlatformWorld} produced by the active adapter. Returns false - never throws - when
|
||||
* Adapters unwrap {@link NativeWorld#nativeHandle()} to reach the host world, so {@code world} must
|
||||
* be a {@link NativeWorld} produced by the active adapter. Returns false - never throws - when
|
||||
* {@code world} or {@code entityKey} is null, the world belongs to a different adapter, the key does
|
||||
* not parse, the entity type is unknown, or the platform refuses the spawn.
|
||||
* <p>
|
||||
* Invoke on the thread owning the target chunk.
|
||||
*/
|
||||
boolean spawnEntity(PlatformWorld world, String entityKey, double x, double y, double z);
|
||||
boolean spawnEntity(NativeWorld world, String entityKey, double x, double y, double z);
|
||||
|
||||
/**
|
||||
* Routes a log line to the host logger at {@code level}. Safe from any thread. Prefer
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2026 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
/**
|
||||
* Neutral handle for a resolved biome backed by an adapter-owned native handle.
|
||||
* <p>
|
||||
* Immutable and safe to share across threads. Internal to Iris; not a published integration surface.
|
||||
*
|
||||
* @see PlatformRegistries#biome(String)
|
||||
*/
|
||||
public interface PlatformBiome {
|
||||
/**
|
||||
* Canonical {@code namespace:path} biome key. Never null.
|
||||
*/
|
||||
String key();
|
||||
|
||||
/**
|
||||
* Namespace half of {@link #key()}. Never null.
|
||||
*/
|
||||
String namespace();
|
||||
|
||||
/**
|
||||
* The adapter's backing biome object - {@code org.bukkit.block.Biome} on Bukkit, a {@code Biome} registry
|
||||
* value on a mod loader. Never null. Only code inside the owning adapter may cast it.
|
||||
*/
|
||||
Object nativeHandle();
|
||||
}
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeBiome;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -42,5 +44,5 @@ public interface PlatformBiomeWriter {
|
||||
/**
|
||||
* Every biome in the host registry, including datapack and mod biomes. Never null.
|
||||
*/
|
||||
List<PlatformBiome> allBiomes();
|
||||
List<NativeBiome> allBiomes();
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Servers
|
||||
* Copyright (c) 2026 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* One block state property as JSON schema vocabulary, so pack schema generation can describe block keys without
|
||||
* knowing platform property types.
|
||||
* <p>
|
||||
* Immutable. Produced by {@link PlatformRegistries#blockStateProperties()} and consumed only by schema
|
||||
* generation, never on the generation path. Internal to Iris; not a published integration surface.
|
||||
*
|
||||
* @param name the property name as it appears in a block key, for example {@code waterlogged}
|
||||
* @param jsonType JSON schema type: {@code boolean}, {@code integer} or {@code string}. Never null or empty
|
||||
* @param defaultValue the value the host's default state carries, boxed as its JSON representation
|
||||
* @param allowedValues every legal value, empty when the adapter cannot enumerate them. Never null
|
||||
* @param numericRange bounds for a numeric property, null for {@code boolean} and {@code string}
|
||||
*/
|
||||
public record PlatformBlockProperty(String name, String jsonType, Object defaultValue, List<Object> allowedValues, PlatformNumericRange numericRange) {
|
||||
/**
|
||||
* Whether {@link #numericRange()} is present, and therefore whether schema output should emit bounds.
|
||||
*/
|
||||
public boolean hasNumericRange() {
|
||||
return numericRange != null;
|
||||
}
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2026 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
/**
|
||||
* Neutral handle for a resolved block state; the canonical key is the config currency and the native handle is adapter-owned.
|
||||
* <p>
|
||||
* Instances are immutable value handles, interned by the adapter, and read from generation threads in bulk -
|
||||
* every predicate here must be a cached field read or cheap computation, never a registry or world lookup.
|
||||
* Compare with {@link #matches(PlatformBlockState)} rather than {@code equals}; only interned singletons such as
|
||||
* {@link PlatformRegistries#air()} are safe to compare by identity.
|
||||
* <p>
|
||||
* Internal to Iris; not a published integration surface.
|
||||
*
|
||||
* @see PlatformRegistries#block(String)
|
||||
*/
|
||||
public interface PlatformBlockState {
|
||||
/**
|
||||
* Canonical {@code namespace:path[prop=value,...]} key, the form packs and objects store. Never null.
|
||||
*/
|
||||
String key();
|
||||
|
||||
/**
|
||||
* Namespace half of {@link #key()}, for example {@code minecraft}. Never null.
|
||||
*/
|
||||
String namespace();
|
||||
|
||||
/**
|
||||
* The key with any property block stripped, memoized by implementors that intern their states.
|
||||
* Returning null means "not memoized"; callers must then derive it from {@link #key()}.
|
||||
*/
|
||||
default String materialKey() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this is air, including cave and void air.
|
||||
*/
|
||||
boolean isAir();
|
||||
|
||||
/**
|
||||
* Whether the host treats this as a solid collision block.
|
||||
*/
|
||||
boolean isSolid();
|
||||
|
||||
/**
|
||||
* Whether this blocks light fully. Drives Iris's own light and surface reasoning.
|
||||
*/
|
||||
boolean isOccluding();
|
||||
|
||||
/**
|
||||
* Whether this state came from a custom-content provider rather than a vanilla registry entry. Custom
|
||||
* states carry a {@link #deferredPlacementKey()} and a {@link #placementBaseState()}.
|
||||
*/
|
||||
boolean isCustom();
|
||||
|
||||
/**
|
||||
* For a custom state, the provider key to hand back after the block is written, so the provider can finish
|
||||
* placement once the chunk exists. Null for ordinary states.
|
||||
*/
|
||||
default String deferredPlacementKey() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The vanilla state to actually write for a custom state - the placeholder the provider later replaces.
|
||||
* Returns {@code this} for ordinary states. Never null.
|
||||
*/
|
||||
default PlatformBlockState placementBaseState() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this is a fluid block, water or lava.
|
||||
*/
|
||||
boolean isFluid();
|
||||
|
||||
/**
|
||||
* Whether this is water specifically.
|
||||
*/
|
||||
boolean isWater();
|
||||
|
||||
/**
|
||||
* Whether this state carries a {@code waterlogged=true} property.
|
||||
*/
|
||||
boolean isWaterLogged();
|
||||
|
||||
/**
|
||||
* Whether this state carries a {@code lit=true} property.
|
||||
*/
|
||||
boolean isLit();
|
||||
|
||||
/**
|
||||
* Whether the host needs a block update after this is placed - stairs, fences, redstone and other states
|
||||
* that resolve their shape from neighbours.
|
||||
*/
|
||||
boolean isUpdatable();
|
||||
|
||||
/**
|
||||
* Whether this is plant foliage: grass, ferns, flowers and similar decoration.
|
||||
*/
|
||||
boolean isFoliage();
|
||||
|
||||
/**
|
||||
* Whether this is part of a tree - tagged as a log or as leaves.
|
||||
*/
|
||||
boolean isTreeBlock();
|
||||
|
||||
/**
|
||||
* Whether foliage can be planted on top of this block.
|
||||
*/
|
||||
boolean isFoliagePlantable();
|
||||
|
||||
/**
|
||||
* Whether this is a decorant: a thin block that sits on a surface and cannot support anything.
|
||||
*/
|
||||
boolean isDecorant();
|
||||
|
||||
/**
|
||||
* Whether this block has an inventory Iris can fill from a loot table.
|
||||
*/
|
||||
boolean isStorage();
|
||||
|
||||
/**
|
||||
* Whether this is specifically a chest, which needs the pairing and orientation handling chests require.
|
||||
*/
|
||||
boolean isStorageChest();
|
||||
|
||||
/**
|
||||
* Whether this is an ore block, and therefore a candidate for
|
||||
* {@link PlatformRegistries#deepSlateOre(PlatformBlockState, PlatformBlockState)}.
|
||||
*/
|
||||
boolean isOre();
|
||||
|
||||
/**
|
||||
* Whether this is deepslate or a deepslate variant.
|
||||
*/
|
||||
boolean isDeepSlate();
|
||||
|
||||
/**
|
||||
* Whether this is a vine-like block that attaches to a face and hangs.
|
||||
*/
|
||||
boolean isVineBlock();
|
||||
|
||||
/**
|
||||
* Whether this block can be placed onto {@code onto} - the support check Iris runs before writing
|
||||
* decoration. Passing a state from a different adapter fails at runtime.
|
||||
*/
|
||||
boolean canPlaceOnto(PlatformBlockState onto);
|
||||
|
||||
/**
|
||||
* Whether the two states are the same block with the same properties. Prefer this to {@code equals}, which
|
||||
* is identity-based on some adapters.
|
||||
*/
|
||||
boolean matches(PlatformBlockState state);
|
||||
|
||||
/**
|
||||
* Convenience for the common "nothing solid here" test.
|
||||
*/
|
||||
default boolean isAirOrFluid() {
|
||||
return isAir() || isFluid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the host attaches a block entity to this block - signs, chests, spawners and similar. Such blocks
|
||||
* need their tile data applied after the block write.
|
||||
*/
|
||||
boolean hasTileEntity();
|
||||
|
||||
/**
|
||||
* This state with one property overridden, merged into {@link #key()} and re-resolved. Never mutates the
|
||||
* receiver.
|
||||
* <p>
|
||||
* Strict: a property name or value the block does not accept throws rather than being dropped. Validate
|
||||
* against {@link PlatformRegistries#blockStateProperties()} first, or resolve the full key through
|
||||
* {@link PlatformRegistries#blockOrNull(String)} instead.
|
||||
*/
|
||||
PlatformBlockState withProperty(String name, String value);
|
||||
|
||||
/**
|
||||
* The adapter's backing state object - {@code org.bukkit.block.data.BlockData} on Bukkit,
|
||||
* {@code BlockState} on a mod loader. Never null. Only code inside the owning adapter may cast it.
|
||||
*/
|
||||
Object nativeHandle();
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2026 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
/**
|
||||
* Neutral handle for a resolved entity type backed by an adapter-owned native handle.
|
||||
* <p>
|
||||
* Immutable and safe to share across threads. Internal to Iris; not a published integration surface.
|
||||
*
|
||||
* @see PlatformRegistries#entity(String)
|
||||
*/
|
||||
public interface PlatformEntityType {
|
||||
/**
|
||||
* Canonical {@code namespace:path} entity type key. Never null.
|
||||
*/
|
||||
String key();
|
||||
|
||||
/**
|
||||
* Namespace half of {@link #key()}. Never null.
|
||||
*/
|
||||
String namespace();
|
||||
|
||||
/**
|
||||
* The host's spawn category, lowercased - {@code monster}, {@code creature}, {@code ambient} and so on.
|
||||
* Iris matches it against pack spawn rules, so the string form is the contract rather than any enum. Never
|
||||
* null.
|
||||
*/
|
||||
String spawnCategory();
|
||||
|
||||
/**
|
||||
* The adapter's backing entity type object - {@code org.bukkit.entity.EntityType} on Bukkit,
|
||||
* {@code EntityType} on a mod loader. Never null. Only code inside the owning adapter may cast it.
|
||||
*/
|
||||
Object nativeHandle();
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeGenerationRegistry;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public interface PlatformGenerationRegistry {
|
||||
public interface PlatformGenerationRegistry extends NativeGenerationRegistry {
|
||||
Pattern SHA_256_PATTERN = Pattern.compile("[0-9a-f]{64}");
|
||||
|
||||
String runtimeIdentity();
|
||||
@@ -25,16 +27,6 @@ public interface PlatformGenerationRegistry {
|
||||
|
||||
String dimensionTypeResourceKey(String packName, String dimensionKey, String dimensionTypeKey);
|
||||
|
||||
Definition definition(String registryKey, String resourceKey);
|
||||
|
||||
default Definition generatedDefinition(String registryKey, String resourceKey) {
|
||||
return definition(registryKey, resourceKey);
|
||||
}
|
||||
|
||||
default Definition canonicalDefinition(String registryKey, String resourceKey, String sourceJson) {
|
||||
return Definition.exactJson(sourceJson);
|
||||
}
|
||||
|
||||
static String contentAddressedCustomBiomeResourceKey(String identitySha256) {
|
||||
String requiredFingerprint = Objects.requireNonNull(identitySha256, "identitySha256");
|
||||
if (!SHA_256_PATTERN.matcher(requiredFingerprint).matches()) {
|
||||
@@ -43,42 +35,4 @@ public interface PlatformGenerationRegistry {
|
||||
return "iris:biomes/" + requiredFingerprint;
|
||||
}
|
||||
|
||||
enum Encoding {
|
||||
JSON,
|
||||
CONSERVATIVE_IDENTITY
|
||||
}
|
||||
|
||||
record Definition(Encoding encoding, String value) {
|
||||
public Definition {
|
||||
encoding = Objects.requireNonNull(encoding, "encoding");
|
||||
value = Objects.requireNonNull(value, "value");
|
||||
if (value.isBlank()) {
|
||||
throw new IllegalArgumentException("Platform registry definition must not be blank.");
|
||||
}
|
||||
}
|
||||
|
||||
public static Definition exactJson(String json) {
|
||||
return new Definition(Encoding.JSON, json);
|
||||
}
|
||||
|
||||
public static Definition conservativeIdentity(String identity) {
|
||||
return new Definition(Encoding.CONSERVATIVE_IDENTITY, identity);
|
||||
}
|
||||
|
||||
public static Definition resourceIdentity(String registryKey, String resourceKey) {
|
||||
String requiredRegistryKey = requireText(registryKey, "registryKey");
|
||||
String requiredResourceKey = requireText(resourceKey, "resourceKey");
|
||||
return conservativeIdentity(
|
||||
"registry-resource-key-v1|" + requiredRegistryKey + "|" + requiredResourceKey
|
||||
);
|
||||
}
|
||||
|
||||
private static String requireText(String value, String label) {
|
||||
String required = Objects.requireNonNull(value, label).trim();
|
||||
if (required.isEmpty()) {
|
||||
throw new IllegalArgumentException(label + " must not be blank.");
|
||||
}
|
||||
return required;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2026 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
/**
|
||||
* Neutral handle for a resolved item type backed by an adapter-owned native handle.
|
||||
* <p>
|
||||
* Describes an item type, not a stack - no count, no components. Immutable and safe to share across threads.
|
||||
* Internal to Iris; not a published integration surface.
|
||||
*
|
||||
* @see PlatformRegistries#item(String)
|
||||
*/
|
||||
public interface PlatformItem {
|
||||
/**
|
||||
* Canonical {@code namespace:path} item key. Never null.
|
||||
*/
|
||||
String key();
|
||||
|
||||
/**
|
||||
* Namespace half of {@link #key()}. Never null.
|
||||
*/
|
||||
String namespace();
|
||||
|
||||
/**
|
||||
* The adapter's backing item object - {@code org.bukkit.Material} on Bukkit, an {@code Item} registry value
|
||||
* on a mod loader. Never null. Only code inside the owning adapter may cast it.
|
||||
*/
|
||||
Object nativeHandle();
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Servers
|
||||
* Copyright (c) 2026 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
/**
|
||||
* Inclusive-or-exclusive numeric bounds for a {@link PlatformBlockProperty}, mirroring JSON schema's
|
||||
* {@code minimum}/{@code maximum} pair.
|
||||
* <p>
|
||||
* Immutable. Bounds are carried as {@code double} regardless of the property's JSON type; an
|
||||
* {@code integer} property's bounds are whole numbers and are narrowed by the schema writer. Internal to Iris;
|
||||
* not a published integration surface.
|
||||
*
|
||||
* @param minimum lower bound
|
||||
* @param maximum upper bound
|
||||
* @param exclusiveMinimum whether {@code minimum} itself is disallowed
|
||||
* @param exclusiveMaximum whether {@code maximum} itself is disallowed
|
||||
*/
|
||||
public record PlatformNumericRange(double minimum, double maximum, boolean exclusiveMinimum, boolean exclusiveMaximum) {
|
||||
}
|
||||
@@ -18,6 +18,16 @@
|
||||
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeBlockProperty;
|
||||
|
||||
import art.arcane.volmlib.nativelib.entity.NativeEntityType;
|
||||
|
||||
import art.arcane.volmlib.nativelib.item.NativeItem;
|
||||
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeBiome;
|
||||
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeBlockState;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -43,7 +53,7 @@ public interface PlatformRegistries {
|
||||
* falls back to air; a key that cannot be parsed at all may come back null. Callers that need to tell
|
||||
* absence from air use {@link #blockOrNull(String)}.
|
||||
*/
|
||||
PlatformBlockState block(String key);
|
||||
NativeBlockState block(String key);
|
||||
|
||||
/**
|
||||
* Resolves a block key, returning null instead of an air fallback when it does not resolve. Silent.
|
||||
@@ -52,40 +62,40 @@ public interface PlatformRegistries {
|
||||
* sees keys the underlying lookup could not answer at all, so an unregistered key resolves to air through
|
||||
* {@link #block(String)} on every platform - the Bukkit-only legacy rewrite table cannot fork generation output.
|
||||
*/
|
||||
PlatformBlockState blockOrNull(String key);
|
||||
NativeBlockState blockOrNull(String key);
|
||||
|
||||
/**
|
||||
* {@link #blockOrNull(String)} with control over whether an unresolved key is logged. Pass
|
||||
* {@code warn = false} for speculative lookups.
|
||||
*/
|
||||
PlatformBlockState blockOrNull(String key, boolean warn);
|
||||
NativeBlockState blockOrNull(String key, boolean warn);
|
||||
|
||||
/**
|
||||
* The interned air state. Never null; identity-comparable across calls.
|
||||
*/
|
||||
PlatformBlockState air();
|
||||
NativeBlockState air();
|
||||
|
||||
/**
|
||||
* The deepslate variant of {@code ore} when {@code block} is deepslate, otherwise {@code ore} unchanged.
|
||||
* Lets ore placement follow the host stone without the pack enumerating variants.
|
||||
*/
|
||||
PlatformBlockState deepSlateOre(PlatformBlockState block, PlatformBlockState ore);
|
||||
NativeBlockState deepSlateOre(NativeBlockState block, NativeBlockState ore);
|
||||
|
||||
/**
|
||||
* Resolves a biome key against the live biome registry, including datapack and mod biomes. Null when the
|
||||
* key does not parse or is not registered.
|
||||
*/
|
||||
PlatformBiome biome(String key);
|
||||
NativeBiome biome(String key);
|
||||
|
||||
/**
|
||||
* Resolves an item key. Null when unknown.
|
||||
*/
|
||||
PlatformItem item(String key);
|
||||
NativeItem item(String key);
|
||||
|
||||
/**
|
||||
* Resolves an entity type key. Null when unknown.
|
||||
*/
|
||||
PlatformEntityType entity(String key);
|
||||
NativeEntityType entity(String key);
|
||||
|
||||
/**
|
||||
* Every registered block state key, properties included. Drives schema completion and command
|
||||
@@ -147,5 +157,5 @@ public interface PlatformRegistries {
|
||||
* Block key to its declared state properties, used to generate pack schema enums and numeric ranges.
|
||||
* Keyed by material-level block key. Never null.
|
||||
*/
|
||||
Map<String, List<PlatformBlockProperty>> blockStateProperties();
|
||||
Map<String, List<NativeBlockProperty>> blockStateProperties();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeWorld;
|
||||
|
||||
/**
|
||||
* Platform task dispatch; region scheduling targets the owning region thread on regionized platforms and the global thread elsewhere.
|
||||
* <p>
|
||||
@@ -42,7 +44,7 @@ public interface PlatformScheduler {
|
||||
* touches blocks or entities in a known chunk. Adapters that cannot resolve a region owner fall back to
|
||||
* {@link #global(Runnable)}.
|
||||
*/
|
||||
void region(PlatformWorld world, int chunkX, int chunkZ, Runnable task);
|
||||
void region(NativeWorld world, int chunkX, int chunkZ, Runnable task);
|
||||
|
||||
/**
|
||||
* Runs {@code task} on a pooled thread off the server thread. Must not touch world state.
|
||||
@@ -56,9 +58,9 @@ public interface PlatformScheduler {
|
||||
void laterGlobal(Runnable task, int ticks);
|
||||
|
||||
/**
|
||||
* {@link #region(PlatformWorld, int, int, Runnable)} delayed by {@code ticks}, with the same non-positive-delay
|
||||
* {@link #region(NativeWorld, int, int, Runnable)} delayed by {@code ticks}, with the same non-positive-delay
|
||||
* degradation as {@link #laterGlobal(Runnable, int)}. Adapters without regions fall back to the delayed global
|
||||
* queue.
|
||||
*/
|
||||
void laterRegion(PlatformWorld world, int chunkX, int chunkZ, Runnable task, int ticks);
|
||||
void laterRegion(NativeWorld world, int chunkX, int chunkZ, Runnable task, int ticks);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,10 @@
|
||||
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeWorld;
|
||||
|
||||
import java.util.List;
|
||||
import art.arcane.volmlib.nativelib.terrain.JigsawSourceMetadata;
|
||||
|
||||
/**
|
||||
* Neutral access to the host platform's structure, structure-set and configured-feature registries plus placement entry points.
|
||||
@@ -84,18 +87,18 @@ public interface PlatformStructureHooks {
|
||||
* Structure keys actually reachable in {@code world}, after its dimension's structure sets and biome filter
|
||||
* are applied. Narrower than {@link #structureKeys()}. Never null.
|
||||
*/
|
||||
List<String> reachableStructureKeys(PlatformWorld world);
|
||||
List<String> reachableStructureKeys(NativeWorld world);
|
||||
|
||||
/**
|
||||
* Biome keys the world's biome source can emit. Never null.
|
||||
*/
|
||||
List<String> possibleBiomeKeys(PlatformWorld world);
|
||||
List<String> possibleBiomeKeys(NativeWorld world);
|
||||
|
||||
/**
|
||||
* Places a configured feature at world coordinates with the given seed. Returns false when the key is
|
||||
* unknown or the feature declines to place. Mutates the world; see the threading note on this interface.
|
||||
*/
|
||||
boolean placeFeature(PlatformWorld world, int x, int y, int z, String featureKey, long seed);
|
||||
boolean placeFeature(NativeWorld world, int x, int y, int z, String featureKey, long seed);
|
||||
|
||||
/**
|
||||
* Generates and places a structure anchored at the given chunk.
|
||||
@@ -104,30 +107,13 @@ public interface PlatformStructureHooks {
|
||||
* @return the placed bounding box as {@code {minX, minY, minZ, maxX, maxY, maxZ}}, or null when the key is
|
||||
* unknown, the structure produced no valid start, or the box exceeded {@code maxSpan}
|
||||
*/
|
||||
int[] placeStructure(PlatformWorld world, int chunkX, int chunkZ, String structureKey, long seed, int maxSpan);
|
||||
int[] placeStructure(NativeWorld world, int chunkX, int chunkZ, String structureKey, long seed, int maxSpan);
|
||||
|
||||
/**
|
||||
* Whether this adapter implements {@link #placeStructure(PlatformWorld, int, int, String, long, int)}.
|
||||
* Whether this adapter implements {@link #placeStructure(NativeWorld, int, int, String, long, int)}.
|
||||
* Check before offering structure capture; adapters without the required host access return false.
|
||||
*/
|
||||
boolean supportsStructurePlacement();
|
||||
|
||||
record JigsawSourceMetadata(int maxDistanceHorizontal, int referenceExpansion,
|
||||
int maxStartElementHorizontalSpan) {
|
||||
public JigsawSourceMetadata(int maxDistanceHorizontal, int referenceExpansion) {
|
||||
this(maxDistanceHorizontal, referenceExpansion, 0);
|
||||
}
|
||||
|
||||
public JigsawSourceMetadata {
|
||||
if (maxDistanceHorizontal < 1 || maxDistanceHorizontal > 128) {
|
||||
throw new IllegalArgumentException("Jigsaw horizontal distance must be between 1 and 128");
|
||||
}
|
||||
if (referenceExpansion < 0) {
|
||||
throw new IllegalArgumentException("Jigsaw reference expansion must not be negative");
|
||||
}
|
||||
if (maxStartElementHorizontalSpan < 0) {
|
||||
throw new IllegalArgumentException("Jigsaw start element horizontal span must not be negative");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2026 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
/**
|
||||
* Neutral view of a loaded world for edit and lifecycle paths; never used on the generation hot path.
|
||||
* <p>
|
||||
* Metadata reads ({@link #name()}, {@link #seed()}, the height bounds) are cheap and safe from any thread. The
|
||||
* block, biome and weather accessors read or mutate live world state and must be called on the thread that
|
||||
* owns the target chunk - the region thread on regionized platforms, the server thread elsewhere. Reach that
|
||||
* thread with {@link PlatformScheduler#region(PlatformWorld, int, int, Runnable)}.
|
||||
* <p>
|
||||
* Internal to Iris; not a published integration surface.
|
||||
*/
|
||||
public interface PlatformWorld {
|
||||
/**
|
||||
* The host's world name. Never null.
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* The world seed, as the host reports it.
|
||||
*/
|
||||
long seed();
|
||||
|
||||
/**
|
||||
* Lowest buildable Y, inclusive. Usually negative.
|
||||
*/
|
||||
int minHeight();
|
||||
|
||||
/**
|
||||
* Highest buildable Y, exclusive.
|
||||
*/
|
||||
int maxHeight();
|
||||
|
||||
/**
|
||||
* The block state at world coordinates. Loads the chunk if it is not resident, so treat it as blocking.
|
||||
* Adapters delegate straight to the host, so a coordinate outside {@link #minHeight()}/{@link #maxHeight()}
|
||||
* gets whatever the host does with it - clamp, air, or throw. Bounds-check first.
|
||||
*/
|
||||
PlatformBlockState getBlock(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Writes a block state at world coordinates. Same out-of-bounds caveat as {@link #getBlock(int, int, int)}.
|
||||
*
|
||||
* @param flags platform update flags; bit 0 requests neighbour/physics updates, higher bits are
|
||||
* adapter-specific. Pass 0 for a silent write
|
||||
*/
|
||||
void setBlock(int x, int y, int z, PlatformBlockState block, int flags);
|
||||
|
||||
/**
|
||||
* The biome at world coordinates. Loads the chunk if it is not resident.
|
||||
*/
|
||||
PlatformBiome getBiome(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Whether the chunk is currently resident. Cheap; the only accessor here that never triggers a load.
|
||||
*/
|
||||
boolean isChunkLoaded(int chunkX, int chunkZ);
|
||||
|
||||
/**
|
||||
* The world's time of day in ticks.
|
||||
*/
|
||||
long getTime();
|
||||
|
||||
/**
|
||||
* Whether it is raining or snowing.
|
||||
*/
|
||||
boolean isStorming();
|
||||
|
||||
/**
|
||||
* Whether a thunderstorm is active.
|
||||
*/
|
||||
boolean isThundering();
|
||||
|
||||
/**
|
||||
* The adapter's backing world object - {@code org.bukkit.World} on Bukkit, {@code ServerLevel} on a mod
|
||||
* loader. Never null. Only code inside the owning adapter may cast it; core must not.
|
||||
*/
|
||||
Object nativeHandle();
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeWorld;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -153,7 +155,7 @@ public class IrisPlatformsBindContractTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean spawnEntity(PlatformWorld world, String entityKey, double x, double y, double z) {
|
||||
public boolean spawnEntity(NativeWorld world, String entityKey, double x, double y, double z) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
package art.arcane.iris.spi;
|
||||
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeWorld;
|
||||
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeNumericRange;
|
||||
|
||||
import art.arcane.volmlib.nativelib.terrain.NativeBlockProperty;
|
||||
|
||||
import art.arcane.volmlib.nativelib.terrain.JigsawSourceMetadata;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
@@ -14,10 +22,10 @@ public class PlatformValueContractTest {
|
||||
|
||||
@Test
|
||||
public void jigsawMetadataAcceptsTheWholeDocumentedRange() {
|
||||
PlatformStructureHooks.JigsawSourceMetadata smallest =
|
||||
new PlatformStructureHooks.JigsawSourceMetadata(1, 0, 0);
|
||||
PlatformStructureHooks.JigsawSourceMetadata largest =
|
||||
new PlatformStructureHooks.JigsawSourceMetadata(128, 7, 96);
|
||||
JigsawSourceMetadata smallest =
|
||||
new JigsawSourceMetadata(1, 0, 0);
|
||||
JigsawSourceMetadata largest =
|
||||
new JigsawSourceMetadata(128, 7, 96);
|
||||
|
||||
assertEquals(1, smallest.maxDistanceHorizontal());
|
||||
assertEquals(128, largest.maxDistanceHorizontal());
|
||||
@@ -27,8 +35,8 @@ public class PlatformValueContractTest {
|
||||
|
||||
@Test
|
||||
public void jigsawMetadataDefaultsTheStartElementSpanToZero() {
|
||||
PlatformStructureHooks.JigsawSourceMetadata metadata =
|
||||
new PlatformStructureHooks.JigsawSourceMetadata(64, 3);
|
||||
JigsawSourceMetadata metadata =
|
||||
new JigsawSourceMetadata(64, 3);
|
||||
|
||||
assertEquals(0, metadata.maxStartElementHorizontalSpan());
|
||||
}
|
||||
@@ -36,13 +44,13 @@ public class PlatformValueContractTest {
|
||||
@Test
|
||||
public void jigsawMetadataRejectsOutOfRangeGeometry() {
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> new PlatformStructureHooks.JigsawSourceMetadata(0, 0, 0));
|
||||
() -> new JigsawSourceMetadata(0, 0, 0));
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> new PlatformStructureHooks.JigsawSourceMetadata(129, 0, 0));
|
||||
() -> new JigsawSourceMetadata(129, 0, 0));
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> new PlatformStructureHooks.JigsawSourceMetadata(64, -1, 0));
|
||||
() -> new JigsawSourceMetadata(64, -1, 0));
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> new PlatformStructureHooks.JigsawSourceMetadata(64, 0, -1));
|
||||
() -> new JigsawSourceMetadata(64, 0, -1));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -112,11 +120,11 @@ public class PlatformValueContractTest {
|
||||
|
||||
@Test
|
||||
public void blockPropertiesReportWhetherTheyCarryANumericRange() {
|
||||
PlatformNumericRange range = new PlatformNumericRange(0D, 15D, false, true);
|
||||
PlatformBlockProperty numeric =
|
||||
new PlatformBlockProperty("level", "integer", 0, List.of(0, 15), range);
|
||||
PlatformBlockProperty enumerated =
|
||||
new PlatformBlockProperty("axis", "string", "y", List.of("x", "y", "z"), null);
|
||||
NativeNumericRange range = new NativeNumericRange(0D, 15D, false, true);
|
||||
NativeBlockProperty numeric =
|
||||
new NativeBlockProperty("level", "integer", 0, List.of(0, 15), range);
|
||||
NativeBlockProperty enumerated =
|
||||
new NativeBlockProperty("axis", "string", "y", List.of("x", "y", "z"), null);
|
||||
|
||||
assertTrue(numeric.hasNumericRange());
|
||||
assertEquals(range, numeric.numericRange());
|
||||
@@ -150,22 +158,22 @@ public class PlatformValueContractTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> reachableStructureKeys(PlatformWorld world) {
|
||||
public List<String> reachableStructureKeys(NativeWorld world) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> possibleBiomeKeys(PlatformWorld world) {
|
||||
public List<String> possibleBiomeKeys(NativeWorld world) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean placeFeature(PlatformWorld world, int x, int y, int z, String featureKey, long seed) {
|
||||
public boolean placeFeature(NativeWorld world, int x, int y, int z, String featureKey, long seed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] placeStructure(PlatformWorld world, int chunkX, int chunkZ, String structureKey, long seed, int maxSpan) {
|
||||
public int[] placeStructure(NativeWorld world, int chunkX, int chunkZ, String structureKey, long seed, int maxSpan) {
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user