Skip to content

Commit 7e85f73

Browse files
authored
Merge pull request #218 from SkyBlade1978/master-1.18
Master 1.18
2 parents a541297 + 25498c0 commit 7e85f73

44 files changed

Lines changed: 2879 additions & 1382 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
* text=auto
1+
# Store and check out repository text as LF on every platform. Windows command
2+
# files are the sole exception below.
3+
* text=auto eol=lf
24

35
*.bat text eol=crlf
46
#*.bat text eol=lf

CHANGELOG.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
Version 4.0.6
2+
3+
* Fix provider top and filler materials being generated one block below exposed ground.
4+
* Apply underwater materials from the corrected ground and ceiling materials to roof undersides.
5+
* Preserve trees, vegetation, structures and block entities by running surface replacement before late features.
6+
* Existing chunks are not rewritten; the correction applies while generating new chunks.
7+
8+
Version 4.0.5
9+
10+
* Complete native translations for every shipped non-English locale
11+
* Add automatic fresh-and-reload validation for provider-owned custom biomes
12+
* Verify both public biome-registration helpers on Forge 40
13+
* Confirm Minecraft 1.18.2 ResourceLocation documentation and ForgeGradle workflow
14+
* Preserve public API major 1 and provider/global/world schemas 4/6/5
15+
116
Version 3.3.1
217

318
* Fix several bugs

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,20 @@ exported to `config/orespawn-guide/` without overwriting existing files.
7979
Use Java 17 from the repository root:
8080

8181
```powershell
82-
.\gradlew.bat test processResources build javadoc --no-daemon
82+
.\gradlew.bat clean build javadoc --no-daemon
8383
.\gradlew.bat genEclipseRuns eclipse --no-daemon
8484
```
8585

86+
`build` runs the standard `check` lifecycle. In addition to the JUnit suite,
87+
that lifecycle packages a test-only provider mod and verifies exposed,
88+
underwater, filler, and ceiling surfaces in open and ceiling normal-noise
89+
dimensions. It also proves later vegetation, structures, and block entities
90+
survive, then reopens and checks the exact saved world. The fixture is not
91+
included in OreSpawn's published jars.
92+
93+
Run both `genEclipseRuns` and `eclipse` after importing or refreshing this
94+
ForgeGradle 6 project in Eclipse.
95+
8696
Machine-specific `AGENTS.md` and `agent-notes/` files are intentionally ignored.
8797
Public developer and AI integration guidance lives in `docs/` and is included
8898
in the built jar.

build.gradle

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,16 @@ minecraft {
174174
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
175175
args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
176176
}
177+
178+
['Fresh', 'Reload'].each { String phase ->
179+
create("surfaceIntegration${phase}") {
180+
parent runs.server
181+
workingDirectory layout.buildDirectory.dir('surface-integration-run').get().asFile
182+
property 'forge.logging.console.level', 'info'
183+
property 'surfaceprobe.integrationPhase', phase.toLowerCase(Locale.ROOT)
184+
args '--nogui'
185+
}
186+
}
177187
}
178188
}
179189

@@ -278,6 +288,84 @@ tasks.named('test', Test).configure {
278288
useJUnitPlatform()
279289
}
280290

291+
def surfaceIntegrationClasses = layout.buildDirectory.dir('surface-integration-fixture/classes')
292+
def compileSurfaceIntegrationTestMod = tasks.register('compileSurfaceIntegrationTestMod', JavaCompile) {
293+
dependsOn tasks.named('classes')
294+
source fileTree('src/biomeIntegrationTest/java')
295+
classpath = files(sourceSets.main.output, sourceSets.main.compileClasspath)
296+
destinationDirectory.set(surfaceIntegrationClasses)
297+
javaCompiler.set(javaToolchains.compilerFor {
298+
languageVersion = JavaLanguageVersion.of(17)
299+
})
300+
options.release = 17
301+
options.encoding = 'UTF-8'
302+
}
303+
304+
def surfaceIntegrationTestModJar = tasks.register('surfaceIntegrationTestModJar', Jar) {
305+
dependsOn compileSurfaceIntegrationTestMod
306+
archiveFileName = 'surfaceprobe.jar'
307+
destinationDirectory = layout.buildDirectory.dir('surface-integration-fixture')
308+
from surfaceIntegrationClasses
309+
from 'src/biomeIntegrationTest/resources'
310+
}
311+
312+
def surfaceIntegrationRunDirectory = layout.buildDirectory.dir('surface-integration-run')
313+
def prepareSurfaceIntegrationTest = tasks.register('prepareSurfaceIntegrationTest') {
314+
dependsOn surfaceIntegrationTestModJar
315+
doLast {
316+
File runDirectory = surfaceIntegrationRunDirectory.get().asFile
317+
delete runDirectory
318+
runDirectory.mkdirs()
319+
copy {
320+
from surfaceIntegrationTestModJar.flatMap { it.archiveFile }
321+
into surfaceIntegrationRunDirectory.map { it.dir('mods') }
322+
}
323+
new File(runDirectory, 'server.properties').setText('''\
324+
level-name=surface-integration-world
325+
level-seed=0
326+
level-type=minecraft:normal
327+
online-mode=false
328+
allow-nether=true
329+
generate-structures=false
330+
spawn-protection=0
331+
max-tick-time=-1
332+
''', 'UTF-8')
333+
new File(runDirectory, 'eula.txt').setText('eula=true\n', 'UTF-8')
334+
}
335+
}
336+
337+
tasks.configureEach {
338+
if (name == 'runSurfaceIntegrationFresh') {
339+
dependsOn prepareSurfaceIntegrationTest
340+
} else if (name == 'runSurfaceIntegrationReload') {
341+
dependsOn 'runSurfaceIntegrationFresh'
342+
}
343+
}
344+
345+
def surfaceIntegrationTest = tasks.register('surfaceIntegrationTest') {
346+
group = 'verification'
347+
description = 'Verifies provider surfaces and dynamic-biome geology across fresh and reloaded normal terrain.'
348+
dependsOn 'runSurfaceIntegrationReload'
349+
doLast {
350+
File marker = surfaceIntegrationRunDirectory.get().file(
351+
'surface-integration-world/surfaceprobe-integration.properties').asFile
352+
if (!marker.isFile()) {
353+
throw new GradleException("Surface integration completion marker is missing: ${marker}")
354+
}
355+
Properties result = new Properties()
356+
marker.withInputStream { result.load(it) }
357+
if (result.getProperty('reload_verified') != 'true') {
358+
throw new GradleException("Surface integration reload was not verified: ${marker}")
359+
}
360+
logger.lifecycle('Provider surfaces and dynamic-biome geology verified: {} dimensions, {} columns each, fresh + reload',
361+
result.getProperty('dimensions'), result.getProperty('columns_per_dimension'))
362+
}
363+
}
364+
365+
tasks.named('check') {
366+
dependsOn surfaceIntegrationTest
367+
}
368+
281369
// Keep every Eclipse launch input on Buildship's physical Gradle cache. Command-line
282370
// verification may deliberately use a separate cache, which must not leak into Eclipse.
283371
def syncEclipseRunClasspaths = tasks.register('syncEclipseRunClasspaths') {
@@ -454,6 +542,7 @@ def syncEclipseRunClasspaths = tasks.register('syncEclipseRunClasspaths') {
454542
}
455543

456544
int changedLaunches = 0
545+
int changedTestExclusions = 0
457546
if (eclipseLaunchDir.isDirectory()) {
458547
File eclipseClasses = file('bin/main').canonicalFile
459548
String modClasses = "${mod_id}%%${eclipseClasses.absolutePath}"
@@ -471,6 +560,27 @@ def syncEclipseRunClasspaths = tasks.register('syncEclipseRunClasspaths') {
471560
/<mapEntry key="MOD_CLASSES" value="[^"]*"\/>/) {
472561
"<mapEntry key=\"MOD_CLASSES\" value=\"${modClasses}\"/>"
473562
}
563+
String excludeTestKey = 'org.eclipse.jdt.launching.ATTR_EXCLUDE_TEST_CODE'
564+
String excludeTestAttribute =
565+
"<booleanAttribute key=\"${excludeTestKey}\" value=\"true\"/>"
566+
String beforeTestExclusion = synced
567+
if (synced.contains("key=\"${excludeTestKey}\"")) {
568+
synced = synced.replaceFirst(
569+
/<booleanAttribute key="org\.eclipse\.jdt\.launching\.ATTR_EXCLUDE_TEST_CODE" value="[^"]*"\/>/,
570+
excludeTestAttribute)
571+
} else {
572+
int launchHeaderEnd = synced.indexOf('\n', synced.indexOf('<launchConfiguration'))
573+
if (launchHeaderEnd < 0) {
574+
throw new GradleException("Malformed Eclipse Java launch configuration: ${launchFile}")
575+
}
576+
String lineSeparator = synced.contains('\r\n') ? '\r\n' : '\n'
577+
synced = "${synced.substring(0, launchHeaderEnd + 1)}" +
578+
" ${excludeTestAttribute}${lineSeparator}" +
579+
synced.substring(launchHeaderEnd + 1)
580+
}
581+
if (beforeTestExclusion != synced) {
582+
changedTestExclusions++
583+
}
474584
if (original != synced) {
475585
launchFile.setText(synced, 'UTF-8')
476586
changedLaunches++
@@ -496,7 +606,7 @@ def syncEclipseRunClasspaths = tasks.register('syncEclipseRunClasspaths') {
496606
changedLaunchGroups++
497607
}
498608
}
499-
logger.lifecycle("Eclipse runtime paths aligned with ${eclipseCache} (${stableClasspaths.size()} Forge classpaths, ${changedProjectClasspath} project classpath, ${changedResourceExclusions} metadata exclusion, ${changedPrepareLaunches} prepare launches, ${changedLaunches} slim launches, ${changedLaunchGroups} direct project launches updated)")
609+
logger.lifecycle("Eclipse runtime paths aligned with ${eclipseCache} (${stableClasspaths.size()} Forge classpaths, ${changedProjectClasspath} project classpath, ${changedResourceExclusions} metadata exclusion, ${changedPrepareLaunches} prepare launches, ${changedLaunches} slim launches, ${changedTestExclusions} test exclusions, ${changedLaunchGroups} direct project launches updated)")
500610
}
501611
}
502612

docs/AGENTS.md

Lines changed: 12 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,15 @@
1-
# OreSpawn Integration Notes For Coding Agents
1+
# OreSpawn Documentation Map
22

3-
OreSpawn 4.0 is a required Forge mod and declarative world-generation engine.
4-
Public API major version 1 consists only of `zone.moddev.mc.orespawn.api`. Treat
5-
every other Java package as internal and unstable.
3+
This index is for navigating the documentation to learn how to integrate with
4+
and use OreSpawn with a mod or modpack. Start with
5+
[DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md).
66

7-
Integration entry points:
7+
Use the focused guides for implementation details:
88

9-
- Java declarations: `OreSpawnApi.enqueue(WorldgenProvider)` during
10-
`InterModEnqueueEvent`.
11-
- Packaged declarations: `data/<modid>/orespawn/provider.json`.
12-
- Pack overrides: `config/<modid>-orespawn.json`.
13-
- Active queries: `getActiveProfile(MinecraftServer)` and
14-
`createSampler(ServerLevel)`.
15-
- Native-ore takeover: disable only when `isOreTakeoverActive(modid)` is true.
16-
17-
Configuration contracts:
18-
19-
- Global `config/orespawn-worldgen.json`: schema 6.
20-
- World `serverconfig/orespawn-worldgen.json`: schema 5.
21-
- Provider files: schema 4; legacy schemas 1-3 remain accepted.
22-
- Ore placement accepts fixed `quantity` or paired inclusive
23-
`min_quantity`/`max_quantity` values in the range 1-64. A complete range is
24-
authoritative when both forms exist.
25-
- `dimension_selectors.orespawn:all_except_nether_end` applies to ordinary
26-
dimensions but never Nether or End. Explicit dimension entries override it
27-
per ore and must also drive vanilla-feature suppression.
28-
- JSON Schemas and examples are under `META-INF/orespawn/docs/` in the jar.
29-
- Schema 4 providers may declare `biome_palettes` and `dimension_materials`.
30-
Palettes wrap the native dimension biome source; they do not require
31-
TerraBlender. Region presets are 128, 256, 512, 1024, and 2048 blocks.
32-
33-
Lifecycle and ownership:
34-
35-
- Forge setup is parallel. Never mutate OreSpawn internals directly.
36-
- A pack override file is authoritative over packaged and API definitions for
37-
the same provider. A malformed override fails closed.
38-
- Provider rule IDs use the provider namespace. A rule's `block` or weighted
39-
output may reference any installed block.
40-
- Definitions freeze at load completion and change only after restart or an
41-
operator `/orespawn reload`.
42-
- Auto-selected templates apply only to fresh worlds with no explicit
43-
`default_template`. Highest priority wins, then lexical ID. Existing world
44-
profiles never auto-switch.
45-
46-
Performance constraints:
47-
48-
- Do not request callbacks in block-generation loops.
49-
- Registry IDs remain `ResourceLocation` values until setup-time baking.
50-
- Dimension, tag, alias, biome, geome, family, pattern, and block-state
51-
resolution occurs before generation.
52-
- Biome palettes bake holders, climate bounds, namespace filters, weights,
53-
surfaces, and dimension materials. Provider callbacks never run in selection.
54-
- Ore rules support `uniform`, `triangle`, `bottom_triangle`, and
55-
`uniform_bottom_triangle` height distributions plus a 0-1
56-
`discard_chance_on_air_exposure` value for buried deposits.
57-
- The chunk hot path must contain no config reads, registry access, strings,
58-
logging, reflection, or per-block allocation.
59-
- Cache biome filters as registry keys, never `Biome` object identities; 1.18
60-
dynamic-registry biome instances are not identity-stable.
61-
- Ore and flat-bedrock retrogen are bounded and marker-based. Terrain strata
62-
are never retrogened.
63-
64-
Compatibility defaults:
65-
66-
- Standalone OreSpawn is passive: no rocks, terrain dimensions, fluid deposits, ore
67-
suppression, retrogen, or flat bedrock are enabled by default.
68-
- The Overworld is the conventional geology target, but a provider must opt it
69-
in. Nether and End terrain remain untouched unless explicitly configured.
70-
- Mineralogy 6 is a provider, not a public-API compatibility facade. Do not use
71-
removed `zone.moddev.mc.mineralogy.api` classes.
72-
73-
Common tasks are documented in `API.md`, `PROVIDERS.md`, `FEATURES.md`,
74-
`TEMPLATES.md`, `BIOMES.md`, and `DIMENSIONS.md`. Start with
75-
`DEVELOPER_GUIDE.md` when the task is broader than one isolated schema or API
76-
question.
9+
- [API.md](API.md) for the supported Java API;
10+
- [PROVIDERS.md](PROVIDERS.md) for packaged and configurable providers;
11+
- [FEATURES.md](FEATURES.md) for rocks, ores, deposits, and geology;
12+
- [BIOMES.md](BIOMES.md) and [DIMENSIONS.md](DIMENSIONS.md) for world integration;
13+
- [TEMPLATES.md](TEMPLATES.md) for selectable world styles;
14+
- [CONFIGURATION.md](CONFIGURATION.md) for configuration behavior;
15+
- [README.md](README.md) for schemas, examples, and the complete documentation index.

docs/BIOMES.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,16 @@ Biome surfaces support:
119119
- `ceiling_block`: optional underside material;
120120
- `filler_depth`: 0-16 blocks.
121121

122+
Provider surfaces run during `LOCAL_MODIFICATIONS`: after Minecraft has built
123+
base surfaces and lakes, but before structures and vegetation. That ordering
124+
lets OreSpawn replace the actual exposed ground while preserving later trees,
125+
plants, authored structures, and block entities. In ceiling dimensions,
126+
`ceiling_block` applies to the roof underside and does not replace the roof top.
127+
128+
Surface correction is generation-only. Installing or updating OreSpawn does
129+
not rewrite already generated chunks; travel into new terrain to see a changed
130+
provider surface definition.
131+
122132
Dimension materials support the ordinary aquifer fluid, a deep aquifer fluid
123133
and threshold, and replacements for vanilla snow and ice. OreSpawn converts
124134
weather products in loaded chunks and around players; it does not replace every

docs/CONFIGURATION.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,21 @@ When a control is `custom`, its value comes from `formations.custom`:
7575
| `edge_octaves` | 1-8 | Number of boundary-detail scales |
7676
| `continuity` | 0-1 | Proportion of formations retaining global identity |
7777

78+
For Stable Layers, the Edge Detail presets use these
79+
`wavelength / amplitude / octaves` values:
80+
81+
| Preset | Edge detail |
82+
|---|---:|
83+
| Tiny | `48 / 4 / 1` |
84+
| Small | `64 / 12 / 2` |
85+
| Average | `96 / 24 / 3` |
86+
| Large | `128 / 48 / 4` |
87+
| Huge | `192 / 96 / 5` |
88+
89+
Average is calibrated to retain visible variation at later layer contacts.
90+
Custom profiles keep their explicit values; these numbers are only used by the
91+
named presets and as defaults for new Custom settings.
92+
7893
Cyano settings use `cyano.geome_size` (4-32767),
7994
`cyano.rock_layer_noise` (1-32767), and `cyano.rock_layer_thickness` (1-255).
8095
They are ignored by Sky.

docs/DEVELOPER_GUIDE.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,12 @@ bounded ore or bedrock retrogen is enabled.
197197
and without compatibility mods.
198198
6. Confirm the provider appears in `/orespawn status`.
199199
7. Test a new world; profile edits do not rewrite already generated terrain.
200+
201+
OreSpawn's own standard `check` lifecycle includes a consumer-style surface
202+
integration test. A separate test provider creates independently marked
203+
Grass/Dirt, underwater, filler, and roof columns in open and ceiling
204+
normal-noise dimensions. The gate verifies biome and chunk edges, late tree,
205+
vegetation, structure and chest sentinels, the roof underside, and exact save
206+
reload behavior. Run `gradlew check` (or `gradlew build`, which includes it)
207+
before publishing any change to biome registration, palettes, surfaces,
208+
feature ordering, height handling, or profile persistence.

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ mod_name=MMD OreSpawn
4848
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
4949
mod_license=LGPL-2.1
5050
# The mod version. See https://semver.org/
51-
mod_version=4.0.4
51+
mod_version=4.0.6
5252
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
5353
# This should match the base package used for the mod sources.
5454
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html

0 commit comments

Comments
 (0)