mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-26 14:00:26 +00:00
- The route-and-reject hydrology system and its probes are removed - Hydrology is configured under dimension hydrology and per biome, region and dimension hydrologyPolicy - riverPolicy and the old hydrology config types are gone - Grid kernels cover priority flood, D8 routing, flow accumulation, basin extraction, breaching and stream burning - A basin spills at its pour point and an interior bump can never be the spill - Region plans cover 4096-block regions on a 64-block grid for major rivers and lakes - Window plans cover 512-block windows on an 8-block grid for reaches and ponds - Plans are cached in memory, persisted per world under iris/hydrology and keyed by pack, seed, world height and settings - Only the main runtime of an engine persists plans and stores swap on hotload and default runtime change - Demand rasters outrank prefetch and stopping pregen withdraws its queued prefetch - Ponds come from natural basins, seeded cups and chained cups with strictly falling levels - A pond level never exceeds its rim plus maxFill or the end grade of any inflow - Pond outlet loops are opened at their lowest pond - Reaches split at junctions, pond outlets and 256-block grid lines - Reaches meander, fit the valley, grade to a running minimum and smooth with Chaikin passes - Drops of two blocks or more get a lip and one-block corner steps become dry rim ledges - Cascades and waterfalls write falling fluid from the mantle at level eight - Inflows into region lakes end at the lake level - River mouths and water beside the sea sit at the sea surface - The per-chunk raster gives terrain height, water head, role, tier, fluid, cave ceiling and shore distance - WaterRole codes are stable and exposed to packs through the WATER_ROLE engine stream - WATER_HEAD replaces the old river engine streams and an unknown stream name fails the pack load - Banks take SMOOTH, LINEAR, CONCAVE, TERRACED or CLIFF profiles - Containment berms grow as tall as the water needs - Columns within two blocks of water stay solid and keep no Terrain3D overhang - Seam dams hold water where new chunks meet chunks generated earlier - The transition blend skips hydrology-owned columns - Caves stay at least two blocks below river and pond beds - The painter is the only writer of still water - Objects cannot open water, falls or bank ground and solid objects may stand in water - On-water objects need fluid at their anchor column - Floating child islands stay out of channels - Sea inlets run inland from cliff coasts at sea level and end in a chamber pool - Inlet passages are sealed against carvers, subterrain features and the post pass - Cave pools settle into carved lows, keep one fluid and stay out of inlet space - Pool and inlet cells use their own cave actions in mantle data - Water vegetation lists sit on tiers, ponds and hydrologyPolicy with SEA_FLOOR, SEA_SURFACE and SHORE_LINE parts - Pack validation compiles hydrology settings and rejects empty or water-holding palettes - Chunk generation fails closed when its 3x3 water rasters are not planned - /iris find covers stream, river, major river, cascade, waterfall, mouth, pond, lake, dam, sea inlet and cave pool - Generation history records the new feature types and drops old hydrology entries - The studio map draws water from rasters up close and from plans when zoomed out - Pregen prepares the current region and one region ahead - hydrologyProbe, riverTransectProbe, hydrologyBlockProbe, seaInletProbe and cavePoolProbe report containment, rises, seams, tick conversion and missing surface - Test forks run with a 2 GB heap, a 60-minute timeout and the Mockito agent loaded explicitly - Generation with hydrology off is unchanged
454 lines
22 KiB
Groovy
454 lines
22 KiB
Groovy
plugins {
|
|
id 'application'
|
|
}
|
|
|
|
group = 'art.arcane'
|
|
version = rootProject.version
|
|
|
|
application {
|
|
mainClass = 'art.arcane.iris.probe.ClassloadProbe'
|
|
}
|
|
|
|
configurations {
|
|
studioProbeApi
|
|
}
|
|
|
|
dependencies {
|
|
implementation(project(':core'))
|
|
compileOnly(libs.spigot)
|
|
testImplementation('junit:junit:4.13.2')
|
|
testImplementation(libs.mockito.core)
|
|
testImplementation(libs.gson)
|
|
testImplementation(testFixtures(project(':core')))
|
|
testImplementation('com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
|
|
transitive = false
|
|
}
|
|
compileOnly('com.github.VolmitSoftware.VolmLib:volmlib-shared:master-SNAPSHOT') {
|
|
transitive = false
|
|
}
|
|
runtimeOnly(libs.paralithic)
|
|
runtimeOnly(libs.gson)
|
|
runtimeOnly(libs.lru)
|
|
runtimeOnly(libs.commons.io)
|
|
runtimeOnly(libs.commons.lang3)
|
|
runtimeOnly(libs.fastutil)
|
|
runtimeOnly(libs.caffeine)
|
|
runtimeOnly(libs.lz4)
|
|
runtimeOnly('com.fulcrumgenomics:jlibdeflate:0.2.0')
|
|
runtimeOnly(libs.zip)
|
|
runtimeOnly(libs.guava)
|
|
runtimeOnly(libs.oshi)
|
|
runtimeOnly(libs.byteBuddy.core)
|
|
runtimeOnly(libs.byteBuddy.agent)
|
|
studioProbeApi(libs.spigot) {
|
|
transitive = false
|
|
}
|
|
}
|
|
|
|
tasks.named('run', JavaExec).configure {
|
|
args(project(':core').layout.buildDirectory.dir('classes/java/main').get().asFile.absolutePath)
|
|
jvmArgs('--add-modules', 'jdk.incubator.vector')
|
|
dependsOn(':core:compileJava')
|
|
}
|
|
|
|
tasks.named('test').configure {
|
|
dependsOn(':core:compileJava')
|
|
}
|
|
|
|
Provider<String> probePack = providers.gradleProperty('probePack')
|
|
Provider<String> probeDimension = providers.gradleProperty('probeDimension')
|
|
Provider<String> probeWarmupChunks = providers.gradleProperty('probeWarmupChunks').orElse('256')
|
|
Provider<String> probeMeasuredChunks = providers.gradleProperty('probeMeasuredChunks').orElse('1024')
|
|
Provider<String> probeCenterChunkX = providers.gradleProperty('probeCenterChunkX').orElse('2048')
|
|
Provider<String> probeCenterChunkZ = providers.gradleProperty('probeCenterChunkZ').orElse('2048')
|
|
Provider<String> probeMulticore = providers.gradleProperty('probeMulticore').orElse('false')
|
|
Provider<String> probeStudio = providers.gradleProperty('probeStudio').orElse('false')
|
|
Provider<String> explicitProbeMulticore = providers.gradleProperty('probeMulticore')
|
|
Provider<String> explicitProbeStudio = providers.gradleProperty('probeStudio')
|
|
Provider<String> probeRequiredCoverage = providers.gradleProperty('probeRequiredCoverage')
|
|
Provider<String> probeSeed = providers.gradleProperty('probeSeed')
|
|
Provider<String> probeMinimumChunkX = providers.gradleProperty('probeMinimumChunkX')
|
|
Provider<String> probeMaximumChunkX = providers.gradleProperty('probeMaximumChunkX')
|
|
Provider<String> probeMinimumChunkZ = providers.gradleProperty('probeMinimumChunkZ')
|
|
Provider<String> probeMaximumChunkZ = providers.gradleProperty('probeMaximumChunkZ')
|
|
Provider<String> probeParallelism = providers.gradleProperty('probeParallelism')
|
|
Provider<String> probeShuffleSeed = providers.gradleProperty('probeShuffleSeed')
|
|
Provider<String> probeJfr = providers.gradleProperty('probeJfr')
|
|
Provider<String> probeOutput = providers.gradleProperty('probeOutput')
|
|
Provider<String> probeStrictGeometry = providers.gradleProperty('probeStrictGeometry').orElse('false')
|
|
Provider<String> probeWindows = providers.gradleProperty('probeWindows')
|
|
|
|
tasks.register('hydrologyProbe', JavaExec) {
|
|
group = 'verification'
|
|
description = 'Plans hydrology over a window range of a real pack and reports cold first-chunk latency, plan cost, yield, containment, rising water, seams and fluid-tick checks per window.'
|
|
mainClass = 'art.arcane.iris.probe.HydrologyProbe'
|
|
classpath = sourceSets.main.runtimeClasspath
|
|
jvmArgs('--add-modules', 'jdk.incubator.vector')
|
|
minHeapSize = '2g'
|
|
maxHeapSize = '6g'
|
|
dependsOn(':core:compileJava')
|
|
doFirst {
|
|
Map<String, Provider<String>> required = [
|
|
probePack: probePack,
|
|
probeSeed: probeSeed,
|
|
probeWindows: probeWindows
|
|
]
|
|
required.each { String name, Provider<String> value ->
|
|
if (!value.isPresent() || value.get().isBlank()) {
|
|
throw new GradleException("hydrologyProbe requires -P${name}=<value>")
|
|
}
|
|
}
|
|
args(probePack.get(), probeDimension.getOrElse('-'), probeSeed.get(), probeWindows.get(),
|
|
providers.gradleProperty('probeThreads').getOrElse('8'), probeStudio.get())
|
|
}
|
|
}
|
|
|
|
tasks.register('riverTransectProbe', JavaExec) {
|
|
group = 'verification'
|
|
description = 'Plans hydrology over a window range of a real pack and renders each window as a plan, river cross-sections and pond outlines.'
|
|
mainClass = 'art.arcane.iris.probe.RiverTransectProbe'
|
|
classpath = sourceSets.main.runtimeClasspath
|
|
jvmArgs('--add-modules', 'jdk.incubator.vector', '-Djava.awt.headless=true')
|
|
minHeapSize = '2g'
|
|
maxHeapSize = '6g'
|
|
dependsOn(':core:compileJava')
|
|
doFirst {
|
|
Map<String, Provider<String>> required = [
|
|
probePack: probePack,
|
|
probeSeed: probeSeed,
|
|
probeWindows: probeWindows,
|
|
probeOutput: probeOutput
|
|
]
|
|
required.each { String name, Provider<String> value ->
|
|
if (!value.isPresent() || value.get().isBlank()) {
|
|
throw new GradleException("riverTransectProbe requires -P${name}=<value>")
|
|
}
|
|
}
|
|
java.nio.file.Path output = new File(probeOutput.get()).canonicalFile.toPath()
|
|
if (output.startsWith(rootProject.projectDir.canonicalFile.toPath())) {
|
|
throw new GradleException('probeOutput must point outside the repository')
|
|
}
|
|
args(probePack.get(), probeDimension.getOrElse('-'), probeSeed.get(), probeWindows.get(), output.toString(), probeStudio.get())
|
|
}
|
|
}
|
|
|
|
tasks.register('hydrologyBlockProbe', JavaExec) {
|
|
group = 'verification'
|
|
description = 'Generates up to 64 real pack chunks and checks the planned water surface, containment, fluid-tick stability and cane support, with block images.'
|
|
mainClass = 'art.arcane.iris.probe.HydrologyBlockProbe'
|
|
classpath = sourceSets.main.runtimeClasspath
|
|
jvmArgs('--add-modules', 'jdk.incubator.vector', '-Djava.awt.headless=true')
|
|
maxHeapSize = '4g'
|
|
dependsOn(':core:compileJava')
|
|
doFirst {
|
|
Map<String, Provider<String>> required = [
|
|
probePack: probePack,
|
|
probeDimension: probeDimension,
|
|
probeSeed: probeSeed,
|
|
probeMinimumChunkX: probeMinimumChunkX,
|
|
probeMaximumChunkX: probeMaximumChunkX,
|
|
probeMinimumChunkZ: probeMinimumChunkZ,
|
|
probeMaximumChunkZ: probeMaximumChunkZ,
|
|
probeOutput: probeOutput
|
|
]
|
|
required.each { String name, Provider<String> value ->
|
|
if (!value.isPresent() || value.get().isBlank()) {
|
|
throw new GradleException("hydrologyBlockProbe requires -P${name}=<value>")
|
|
}
|
|
}
|
|
java.nio.file.Path output = new File(probeOutput.get()).canonicalFile.toPath()
|
|
if (output.startsWith(rootProject.projectDir.canonicalFile.toPath())) {
|
|
throw new GradleException('probeOutput must point outside the repository')
|
|
}
|
|
args(probePack.get(), probeDimension.get(), probeSeed.get(), probeMinimumChunkX.get(), probeMaximumChunkX.get(),
|
|
probeMinimumChunkZ.get(), probeMaximumChunkZ.get(), probeRequiredCoverage.getOrElse('-'), output.toString(), probeStudio.get())
|
|
}
|
|
}
|
|
|
|
tasks.register('terrain3DProbe', JavaExec) {
|
|
group = 'verification'
|
|
description = 'Generates real pack chunks, verifies volumetric terrain spans and required biome overhang coverage, and exports actual block cross-sections.'
|
|
mainClass = 'art.arcane.iris.probe.Terrain3DProbe'
|
|
classpath = sourceSets.main.runtimeClasspath
|
|
jvmArgs('--add-modules', 'jdk.incubator.vector', '-Djava.awt.headless=true')
|
|
dependsOn(':core:compileJava')
|
|
doFirst {
|
|
Map<String, Provider<String>> required = [
|
|
probePack: probePack,
|
|
probeDimension: probeDimension,
|
|
probeSeed: probeSeed,
|
|
probeMinimumChunkX: probeMinimumChunkX,
|
|
probeMaximumChunkX: probeMaximumChunkX,
|
|
probeMinimumChunkZ: probeMinimumChunkZ,
|
|
probeMaximumChunkZ: probeMaximumChunkZ,
|
|
probeRequiredCoverage: probeRequiredCoverage,
|
|
probeOutput: probeOutput
|
|
]
|
|
required.each { String name, Provider<String> value ->
|
|
if (!value.isPresent() || value.get().isBlank()) {
|
|
throw new GradleException("terrain3DProbe requires -P${name}=<value>")
|
|
}
|
|
}
|
|
args(probePack.get(), probeDimension.get(), probeSeed.get(), probeMinimumChunkX.get(),
|
|
probeMaximumChunkX.get(), probeMinimumChunkZ.get(), probeMaximumChunkZ.get(),
|
|
probeRequiredCoverage.get(), probeOutput.get(), probeStrictGeometry.get(), probeStudio.get())
|
|
}
|
|
}
|
|
|
|
tasks.register('genProbe', JavaExec) {
|
|
group = 'verification'
|
|
description = 'Constructs a real Iris engine over a real pack and verifies generation hashes and optional native backend usage.'
|
|
mainClass = 'art.arcane.iris.probe.GenerationProbe'
|
|
classpath = sourceSets.main.runtimeClasspath
|
|
jvmArgs('--add-modules', 'jdk.incubator.vector')
|
|
minHeapSize = '2g'
|
|
maxHeapSize = '6g'
|
|
if (providers.gradleProperty('probeNativeAccess').orElse('false').get().toBoolean()) {
|
|
jvmArgs('--enable-native-access=ALL-UNNAMED')
|
|
}
|
|
if (providers.gradleProperty('probeNativeBillow').isPresent()) {
|
|
systemProperty('volmlib.noise.nativeBillow', providers.gradleProperty('probeNativeBillow').get())
|
|
}
|
|
systemProperty('volmlib.noise.nativeBillowDiagnostics', providers.gradleProperty('probeNativeDiagnostics').orElse('false').get())
|
|
systemProperty('iris.probe.expectedBackend', providers.gradleProperty('probeExpectedBackend').orElse('').get())
|
|
systemProperty('iris.probe.requireNativeSamples', providers.gradleProperty('probeRequireNativeSamples').orElse('false').get())
|
|
if (providers.gradleProperty('probeNativeLibrary').isPresent()) {
|
|
systemProperty('volmlib.native.library', providers.gradleProperty('probeNativeLibrary').get())
|
|
}
|
|
if (providers.gradleProperty('probeNativePolicy').isPresent()) {
|
|
systemProperty('volmlib.native', providers.gradleProperty('probeNativePolicy').get())
|
|
}
|
|
systemProperty('iris.probe.threads', providers.gradleProperty('probeThreads').orElse('1').get())
|
|
systemProperty('iris.probe.pregenProfile', providers.gradleProperty('probePregenProfile').orElse('false').get())
|
|
systemProperty('iris.probe.hydrologyPreplan', providers.gradleProperty('probeHydrologyPreplan').orElse('false').get())
|
|
systemProperty('iris.probe.historyRouter', providers.gradleProperty('probeHistoryRouter').orElse('false').get())
|
|
systemProperty('iris.probe.historyDigest', providers.gradleProperty('probeHistoryDigest').orElse('false').get())
|
|
systemProperty('iris.probe.productionBuffers', providers.gradleProperty('probeProductionBuffers').orElse('false').get())
|
|
String probeCounters = providers.gradleProperty('probeCounters').orElse('false').get()
|
|
systemProperty('iris.generation.counters', probeCounters)
|
|
systemProperty('volmlib.cache.countContention', probeCounters)
|
|
dependsOn(':core:compileJava')
|
|
doFirst {
|
|
if (!probePack.isPresent() || probePack.get().isBlank()) {
|
|
throw new GradleException('genProbe requires -PprobePack=/absolute/path/to/pack')
|
|
}
|
|
Provider<String> probeDumpFile = providers.gradleProperty('probeDumpFile')
|
|
if (probeDumpFile.isPresent()) {
|
|
File dump = new File(probeDumpFile.get())
|
|
if (!dump.isAbsolute() || dump.isDirectory()) {
|
|
throw new GradleException('probeDumpFile must be an absolute file path')
|
|
}
|
|
java.nio.file.Path normalizedDump = dump.canonicalFile.toPath()
|
|
if (normalizedDump.startsWith(rootProject.projectDir.canonicalFile.toPath())) {
|
|
throw new GradleException('probeDumpFile must point outside the repository')
|
|
}
|
|
if (normalizedDump.parent == null || !normalizedDump.parent.toFile().isDirectory()) {
|
|
throw new GradleException('probeDumpFile parent directory must already exist')
|
|
}
|
|
systemProperty('iris.probe.dumpFile', normalizedDump.toString())
|
|
}
|
|
if (!probeDimension.isPresent() || probeDimension.get().isBlank()) {
|
|
throw new GradleException('genProbe requires -PprobeDimension=<dimension-key>')
|
|
}
|
|
args(
|
|
probePack.get(),
|
|
probeDimension.get(),
|
|
probeWarmupChunks.get(),
|
|
probeMeasuredChunks.get(),
|
|
probeCenterChunkX.get(),
|
|
probeCenterChunkZ.get(),
|
|
probeMulticore.get(),
|
|
probeStudio.get(),
|
|
probeSeed.orElse('1337').get())
|
|
}
|
|
}
|
|
|
|
tasks.register('genDiff', JavaExec) {
|
|
group = 'verification'
|
|
description = 'Compares two genProbe chunk dumps and reports block, surface, biome and per-category parity.'
|
|
mainClass = 'art.arcane.iris.probe.GenerationDiff'
|
|
classpath = sourceSets.main.runtimeClasspath
|
|
maxHeapSize = '4g'
|
|
doFirst {
|
|
Provider<String> baseline = providers.gradleProperty('diffBaseline')
|
|
Provider<String> candidate = providers.gradleProperty('diffCandidate')
|
|
if (!baseline.isPresent() || !candidate.isPresent()) {
|
|
throw new GradleException('genDiff requires -PdiffBaseline=<dump> and -PdiffCandidate=<dump>')
|
|
}
|
|
args(baseline.get(), candidate.get(), providers.gradleProperty('diffWorstChunks').orElse('10').get())
|
|
}
|
|
}
|
|
|
|
tasks.register('generationOrderProbe', JavaExec) {
|
|
group = 'verification'
|
|
description = 'Compares complete real-pack chunk block and biome hashes across forward, reverse, shuffled and bounded-parallel generation orders.'
|
|
mainClass = 'art.arcane.iris.probe.GenerationOrderProbe'
|
|
classpath = sourceSets.main.runtimeClasspath
|
|
jvmArgs('--add-modules', 'jdk.incubator.vector')
|
|
dependsOn(':core:compileJava')
|
|
doFirst {
|
|
Map<String, Provider<String>> required = [
|
|
probePack: probePack,
|
|
probeDimension: probeDimension,
|
|
probeSeed: probeSeed,
|
|
probeMinimumChunkX: probeMinimumChunkX,
|
|
probeMaximumChunkX: probeMaximumChunkX,
|
|
probeMinimumChunkZ: probeMinimumChunkZ,
|
|
probeMaximumChunkZ: probeMaximumChunkZ,
|
|
probeParallelism: probeParallelism,
|
|
probeShuffleSeed: probeShuffleSeed,
|
|
probeMulticore: explicitProbeMulticore,
|
|
probeStudio: explicitProbeStudio
|
|
]
|
|
required.each { String name, Provider<String> value ->
|
|
if (!value.isPresent() || value.get().isBlank()) {
|
|
throw new GradleException("generationOrderProbe requires -P${name}=<value>")
|
|
}
|
|
}
|
|
args(
|
|
probePack.get(),
|
|
probeDimension.get(),
|
|
probeSeed.get(),
|
|
probeMinimumChunkX.get(),
|
|
probeMaximumChunkX.get(),
|
|
probeMinimumChunkZ.get(),
|
|
probeMaximumChunkZ.get(),
|
|
probeParallelism.get(),
|
|
probeShuffleSeed.get(),
|
|
explicitProbeMulticore.get(),
|
|
explicitProbeStudio.get())
|
|
}
|
|
}
|
|
|
|
tasks.register('cavePoolProbe', JavaExec) {
|
|
group = 'verification'
|
|
description = 'Generates real pack chunks with cave pools and reports containment, pool sizes and generation-order hashes.'
|
|
mainClass = 'art.arcane.iris.probe.CavePoolProbe'
|
|
classpath = sourceSets.main.runtimeClasspath
|
|
jvmArgs('--add-modules', 'jdk.incubator.vector')
|
|
minHeapSize = '2g'
|
|
maxHeapSize = '8g'
|
|
dependsOn(':core:compileJava')
|
|
doFirst {
|
|
Provider<String> threads = providers.gradleProperty('probeThreads').orElse('8')
|
|
Provider<String> work = providers.gradleProperty('probeWork').orElse(System.getProperty('java.io.tmpdir'))
|
|
Map<String, Provider<String>> required = [
|
|
probePack: probePack,
|
|
probeDimension: probeDimension,
|
|
probeSeed: probeSeed,
|
|
probeMinimumChunkX: probeMinimumChunkX,
|
|
probeMaximumChunkX: probeMaximumChunkX,
|
|
probeMinimumChunkZ: probeMinimumChunkZ,
|
|
probeMaximumChunkZ: probeMaximumChunkZ
|
|
]
|
|
required.each { String name, Provider<String> value ->
|
|
if (!value.isPresent() || value.get().isBlank()) {
|
|
throw new GradleException("cavePoolProbe requires -P${name}=<value>")
|
|
}
|
|
}
|
|
args(probePack.get(), probeDimension.get(), probeSeed.get(), probeMinimumChunkX.get(), probeMaximumChunkX.get(),
|
|
probeMinimumChunkZ.get(), probeMaximumChunkZ.get(), threads.get(), work.get())
|
|
}
|
|
}
|
|
|
|
tasks.register('seaInletProbe', JavaExec) {
|
|
group = 'verification'
|
|
description = 'Plans and generates real pack chunks with and without sea inlets and reports containment, seal, roof, sea level, ocean connection and order determinism.'
|
|
mainClass = 'art.arcane.iris.probe.SeaInletProbe'
|
|
classpath = sourceSets.main.runtimeClasspath
|
|
jvmArgs('--add-modules', 'jdk.incubator.vector', '-Djava.awt.headless=true')
|
|
minHeapSize = '2g'
|
|
maxHeapSize = '8g'
|
|
dependsOn(':core:compileJava')
|
|
doFirst {
|
|
Provider<String> packOff = providers.gradleProperty('probePackOff')
|
|
Provider<String> windows = providers.gradleProperty('probeWindows')
|
|
Provider<String> mode = providers.gradleProperty('probeMode').orElse('gate')
|
|
if (!probePack.isPresent() || !packOff.isPresent() || !probeDimension.isPresent() || !windows.isPresent() || !probeOutput.isPresent()) {
|
|
throw new GradleException('seaInletProbe requires probePack, probePackOff, probeDimension, probeWindows=x0..x1,z0..z1 and probeOutput')
|
|
}
|
|
String[] axes = windows.get().split(',')
|
|
String[] xs = axes[0].split('\\.\\.')
|
|
String[] zs = axes[1].split('\\.\\.')
|
|
args(probePack.get(), packOff.get(), probeDimension.get(), probeSeed.orElse('1337').get(), xs[0], xs[1], zs[0], zs[1], mode.get(),
|
|
probeOutput.get(), providers.gradleProperty('probeThreads').orElse('6').get())
|
|
}
|
|
}
|
|
|
|
tasks.register('transitionProbe', JavaExec) {
|
|
group = 'verification'
|
|
description = 'Exercises a bounded two-pack Studio cutover, transition routing, receipts and semantics with a vanilla-biome pack.'
|
|
mainClass = 'art.arcane.iris.probe.TransitionProbe'
|
|
workingDir = rootProject.projectDir
|
|
classpath = sourceSets.main.runtimeClasspath
|
|
jvmArgs('--add-modules', 'jdk.incubator.vector')
|
|
timeout = java.time.Duration.ofMinutes(12)
|
|
doFirst {
|
|
Provider<String> replacement = providers.gradleProperty('probeReplacementPack')
|
|
if (!probePack.isPresent() || !replacement.isPresent() || !probeDimension.isPresent() || !probeOutput.isPresent()) {
|
|
throw new GradleException('transitionProbe requires probePack, probeReplacementPack, probeDimension and probeOutput')
|
|
}
|
|
java.nio.file.Path output = new File(probeOutput.get()).canonicalFile.toPath()
|
|
if (output.startsWith(rootProject.projectDir.canonicalFile.toPath())) {
|
|
throw new GradleException('probeOutput must point outside the repository')
|
|
}
|
|
args(probePack.get(), replacement.get(), probeDimension.get(), probeSeed.getOrElse('1337'),
|
|
providers.gradleProperty('probeTransitionWidth').getOrElse('32'),
|
|
providers.gradleProperty('probeTransitionChunks').getOrElse('2'), output.toString(),
|
|
providers.gradleProperty('probeTransitionReverse').getOrElse('false'))
|
|
}
|
|
}
|
|
|
|
['transitionProbe', 'hydrologyProbe', 'genProbe', 'generationOrderProbe', 'riverTransectProbe', 'terrain3DProbe',
|
|
'hydrologyBlockProbe', 'cavePoolProbe', 'seaInletProbe'].each { String taskName ->
|
|
tasks.named(taskName, JavaExec).configure { JavaExec task ->
|
|
classpath += configurations.studioProbeApi
|
|
doFirst {
|
|
if (probeJfr.isPresent()) {
|
|
String requestedPath = probeJfr.get()
|
|
if (requestedPath.isBlank()) {
|
|
throw new GradleException('probeJfr must be a nonblank absolute path')
|
|
}
|
|
File recording = new File(requestedPath)
|
|
if (!recording.isAbsolute()) {
|
|
throw new GradleException('probeJfr must be an absolute path')
|
|
}
|
|
if (recording.isDirectory()) {
|
|
throw new GradleException('probeJfr must name a recording file, not a directory')
|
|
}
|
|
java.nio.file.Path normalized = recording.canonicalFile.toPath()
|
|
java.nio.file.Path repository = rootProject.projectDir.canonicalFile.toPath()
|
|
if (normalized.startsWith(repository)) {
|
|
throw new GradleException('probeJfr must point outside the repository')
|
|
}
|
|
File parent = normalized.toFile().parentFile
|
|
if (parent == null || !parent.isDirectory()) {
|
|
throw new GradleException('probeJfr parent directory must already exist')
|
|
}
|
|
String settings = providers.gradleProperty('probeJfrSettings').orElse('profile').get()
|
|
if (settings.isBlank() || settings.contains(',')) {
|
|
throw new GradleException('probeJfrSettings must name a JFR configuration or an absolute .jfc path')
|
|
}
|
|
task.jvmArgs(
|
|
'-XX:FlightRecorderOptions=stackdepth=256',
|
|
"-XX:StartFlightRecording=filename=${normalized},settings=${settings},dumponexit=true"
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
String deserializationPack = providers.gradleProperty('deserializationPack')
|
|
.orElse(project.file('src/main/resources/deserialization-pack').absolutePath)
|
|
.get()
|
|
|
|
tasks.register('deserializationProbe', JavaExec) {
|
|
group = 'verification'
|
|
description = 'Deserializes entity, spawner and loot pack content through the real Iris Gson loaders on a Bukkit-free JVM to keep Bukkit-typed pack-model fields dead.'
|
|
mainClass = 'art.arcane.iris.probe.DeserializationProbe'
|
|
classpath = sourceSets.main.runtimeClasspath
|
|
jvmArgs('--add-modules', 'jdk.incubator.vector')
|
|
args(deserializationPack)
|
|
dependsOn(':core:compileJava')
|
|
}
|