Repository navigation
Java Integration
Compile against the ordinary Sky’s Ley Lines JAR for NeoForge 1.21.1. Install that mod separately in the runtime. If your integration is optional, declare it as optional in META-INF/neoforge.mods.toml and use a dedicated integration class. Check ModList.get().isLoaded("skysleylines") before loading that class so your mod can start when the dependency is absent.
For a local Gradle build, a direct compile dependency can look like this.
dependencies {
compileOnly files('libs/SkysLeyLines-0.5.4.121012.jar')
}Stage the ordinary dependency JAR as a mod in your development run’s mods directory. For release, declare a version range that covers the API you use and the versions you tested. This example declares an optional dependency on the exact build documented here. Replace yourmod with your mod ID and use type="required" if your mod relies on Ley Lines to function.
[[dependencies.yourmod]]
modId="skysleylines"
type="optional"
versionRange="[0.5.4.121012]"
ordering="AFTER"
side="BOTH"Choose an entry point based on the job.
| Job | Entry point | When to call it |
|---|---|---|
| Read natural strength for ores, structures, or rituals |
LeyLinesApi.forLevel(level).field() and LeyFieldSampler.sampleColumn(x, z)
|
Acquire the sampler on the server thread during level load. Its retained sampler supports worker reads. |
| Register a paradigm and currencies | LeyLinesApi.paradigms().register(...) |
Common setup via enqueueWork, before registration freezes at load complete. |
| Inspect balances or pay for a machine action |
NexusPowerService.quoteAt, convertAt, spendAt, or returnToRawAt
|
On the owning server thread. Use the position where the action happens. |
| Read saved rates and active flags | LeyLinesApi.currencyInfo(level) |
On the server thread. |
| Show Ley Vision to a player |
LeyVision.grant or revoke
|
On the connected player’s server thread. Register custom styles during mod setup. |
| Enforce protection rules or observe a completed transaction |
NexusTransactionEvent.Pre or .Post
|
Listen on NeoForge.EVENT_BUS. Include the player UUID in the request when one is responsible. |
Put this class in your mod, change the package and examplemagic IDs to your own, then call SurveyPower.register(modBus) in your mod constructor. This class is for a required dependency. For an optional integration, put the class behind the loader check described above.
package com.example.magic;
import java.util.List;
import java.util.Optional;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import zone.moddev.mc.skysleylines.api.LeyLinesApi;
import zone.moddev.mc.skysleylines.api.LeyVision;
import zone.moddev.mc.skysleylines.api.MagicAmount;
import zone.moddev.mc.skysleylines.api.Paradigm;
import zone.moddev.mc.skysleylines.api.PowerRequest;
import zone.moddev.mc.skysleylines.api.PowerResult;
public final class SurveyPower {
private static final ResourceLocation AETHER = ResourceLocation.parse("examplemagic:aether");
private static final ResourceLocation CONVERTER = ResourceLocation.parse("examplemagic:converter");
private static final ResourceLocation SURVEY = ResourceLocation.parse("examplemagic:survey");
public static void register(IEventBus modBus) {
modBus.addListener(SurveyPower::commonSetup);
}
private static void commonSetup(FMLCommonSetupEvent event) {
event.enqueueWork(() -> LeyLinesApi.paradigms().register(new Paradigm<>(
ResourceLocation.parse("examplemagic:survey_magic"), null,
List.of(new Paradigm.Currency(AETHER, () -> MagicAmount.of(1000))))));
}
public static PowerResult convert(ServerLevel level, BlockPos machine, ServerPlayer player) {
var consumer = new PowerRequest.Consumer(CONVERTER, Optional.of(player.getUUID()));
return LeyLinesApi.forLevel(level).power().convertAt(
machine.getX(), machine.getY(), machine.getZ(), AETHER, MagicAmount.of(5), consumer);
}
public static PowerResult castSurvey(ServerPlayer player) {
var pos = player.blockPosition();
var consumer = new PowerRequest.Consumer(SURVEY, Optional.of(player.getUUID()));
var result = LeyLinesApi.forLevel(player.serverLevel()).power().spendAt(
pos.getX(), pos.getY(), pos.getZ(), AETHER, 1000, consumer);
if (result.succeeded()) {
LeyVision.grant(player, SURVEY, 20 * 60);
}
return result;
}
private SurveyPower() {}
}Call the methods from server-side game events after checking the player's access and cooldown. Call convert with the actual machine location and its interacting player in that level. At the default saved rate it adds 5,000 aether. castSurvey spends 1,000 at the player’s feet and grants one minute of vision at 20 ticks per second. For the two actions to share the balance, both positions must resolve to the same nexus. An automated machine can use the one-argument PowerRequest.Consumer constructor when there is no player actor.
Use result.status() to tell the player what happened. For a converter, read the units credited from receipt.after().currency(AETHER) - receipt.before().currency(AETHER). This follows the saved rate in existing worlds. Use quoteAt to display current funds, then check the transaction result again when the player actually acts.
The full Technomancy Demo has block and item registration, recipes, a Creative tab, two currency definitions, and timed lamps. Its converters and lamps illustrate the same calls inside real block interactions.
For an optional ore feature, acquire the sampler in a server-side LevelEvent.Load handler before spawn preparation. Publish it in a concurrent map keyed by ServerLevel and remove the entry on LevelEvent.Unload. A worker can retrieve that sampler and reuse one column for several candidate heights. Keep the account and transaction service on the server thread. Decide how your feature behaves if Ley Lines is absent, the field is inactive, or strength is below your threshold. The optional worldgen probe shows how the loader check and sampler lifecycle fit together.
See the public API reference for complete signatures, result codes, thread rules, and examples. Pack scripts use the KubeJS guide.