Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ jobs:
if-no-files-found: error
retention-days: 30
path: |
build/libs/OreSpawn-4.1.2.112021.jar
build/libs/OreSpawn-4.1.2.112021-sources.jar
build/libs/OreSpawn-4.1.2.112021-javadoc.jar
build/libs/OreSpawn-4.1.3.112021.jar
build/libs/OreSpawn-4.1.3.112021-sources.jar
build/libs/OreSpawn-4.1.3.112021-javadoc.jar
build/release/SHA256SUMS
CHANGELOG.txt

Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
Version 4.1.3.112021

* Apply hybrid and replacement background limits to imported built-in ore
patterns, just as for ordinary native rules. Keep explicit channels and
third-party deposit patterns independent.
* Retain older Ore Sources selections under their saved pattern names without
rewriting imported settings or regenerating existing chunks.
* Show imported placement choices in the editor without duplicate old-channel
rows. Distinguish an inactive source from a missing mod, and keep custom
channels and saved choices intact.
* Keep the empty Ore Sources message inside its pane in smaller windows.
* Remove old 1.10-only ABI test tasks that could start an empty server on 1.12.

Version 4.1.2.112021

* Respect Manage Vanilla Ores for imported OS1/OS3 rules. With it off, leave
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ It gives mods and modpacks one place to configure ores, deposit shapes, optional
rock strata and geomes, provider-owned underground fluid deposits, biome
palettes and world materials, flat bedrock, and bounded ore retrogen.

This branch builds target-qualified version `4.1.2.112021`: the OreSpawn 4.1.2
This branch builds target-qualified version `4.1.3.112021`: the OreSpawn 4.1.3
feature set for Minecraft 1.12.2 and Forge. It adds stable generation identity,
non-loading geology sampling, per-resource background control, existing-world
provider merge policy, an Ore Sources arbiter for equivalent provider ores, a
Expand Down
14 changes: 14 additions & 0 deletions docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,14 @@ informational because the original rules remain independent. The compact help
and row tooltips explain fixed, selectable, missing and inactive states without
reducing the alias-list height.

Built-in patterns use the standard channel whether their names are short
(`default`, `vein`) or fully qualified (`orespawn:default`, `orespawn:vein`).
This lets a child's hybrid or replacement policy reduce imported ordinary
veins too. An explicit `placement_channel` always wins, and third-party pattern
channels remain independent. Older saved source selections still select the
same rule; changing this classification does not rewrite their ore settings
or existing terrain.

Native vanilla ore rules are active placement sources only when
`manage_vanilla_ores` is enabled. Changing that option refreshes the pending
Ore Sources snapshot before the editor opens. While it is disabled, Group
Expand Down Expand Up @@ -338,6 +346,12 @@ BaseSciences has no ordinary ore-source role. An Ore Dictionary member whose
generator is not controlled by OreSpawn is reported as external generation and
is never suppressed, so total abundance may still be increased by that mod.

Older imported profiles may still store a built-in pattern name as their
placement channel. The Ore Sources editor shows a single ordinary placement
row for that choice; opening the screen does not rewrite the saved profile.
Explicit custom channels stay separate. A source whose placement is switched
off remains listed as output-only, rather than being reported as a missing mod.

## Fluid Deposits, Retrogen, And Bedrock

Each `fluid_deposits` entry has a stable provider-namespaced rule ID, an
Expand Down
7 changes: 7 additions & 0 deletions docs/MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,13 @@ Original), preserving prior placement frequency, ordering and output behaviour.
Missing selected sources and dormant policies remain recorded. Policy changes
affect new chunks only and do not add retrogen.

Legacy imports may spell built-in patterns as `orespawn:default` or another
fully qualified built-in name. These are ordinary generation, so hybrid and
replacement background limits apply to them. Saved Ore Sources choices under
those older inferred channel names remain valid without changing the saved
ore rule. Explicit channels, custom patterns, imported quantities and heights,
and already generated chunks are left alone.

The old `place_crude_oil` and singleton `oil` fields migrate to
`place_fluid_deposits` and a provider-owned rule. A valid block becomes
`<namespace>:fluid_deposit/<path>`; `minecraft:air` creates no rule. Mineralogy
Expand Down
2 changes: 1 addition & 1 deletion docs/VERSIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Examples:
| Minecraft | Loader | Target | Example full OreSpawn version |
| --- | --- | ---: | --- |
| 1.10.2 | Forge | `110021` | `4.0.6.110021` |
| 1.12.2 | Forge | `112021` | `4.1.2.112021` |
| 1.12.2 | Forge | `112021` | `4.1.3.112021` |
| 1.13.2 | Forge | `113021` | `4.0.6.113021` |
| 1.20.6 | Forge | `120061` | `4.0.6.120061` |
| 1.21.11 | Forge | `121111` | `4.0.6.121111` |
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ mod_vendor=Minecraft Mod Development
mod_license=LGPL-2.1
mod_license_name=GNU Lesser General Public License, Version 2.1
mod_license_url=https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
mod_version=4.1.2.112021
mod_version=4.1.3.112021
mod_group=zone.moddev.mc.orespawn
mod_authors=SkyBlade1978, dshadowwolf, the MMD Team
mod_description=Configurable, provider-driven terrain, ore, and deposit generation.
Expand Down
12 changes: 8 additions & 4 deletions gradle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ to the tasks they configure:
| Script | Responsibility |
| --- | --- |
| `verification/support.gradle` | Sealed fixtures, Java 8 verification, Forge-run delegation, runtime log audits. |
| `verification/legacy-and-migration.gradle` | Surface and migration worlds, Mineralogy lineage, opt-in OS1/OS3 ABI probes. |
| `verification/legacy-and-migration.gradle` | Surface and migration worlds, including both Mineralogy lineages. |
| `verification/client-and-benchmark.gradle` | Client integration and opt-in worldgen benchmark. |
| `verification/packaged-forge.gradle` | Fresh/reload test of the reobfuscated jar under installed Forge 14. |
| `release/artifacts.gradle` | API and release jars, release configuration and artifact audits, checksums. |
Expand All @@ -28,8 +28,12 @@ The routine offline gate runs `clean check build javadoc verifyReleaseArtifacts
Run `clientIntegrationProcess` separately for rendered client and editor coverage,
and `genEclipseRuns verifyEclipseProductionClasspath` for ordinary production-only
IDE launches.
`legacyAbiIntegrationTest` and `benchmarkIntegrationProcess` remain opt-in
compatibility and performance gates. The benchmark requires `benchmarkRunDir`;
the packaged server gate requires `packagedMinecraftServerJar` and
`benchmarkIntegrationProcess` is an opt-in performance gate and requires
`benchmarkRunDir`. The packaged server gate requires `packagedMinecraftServerJar` and
`packagedForgeLibrariesRoot`, and its server command ends with literal `nogui`.
All gates support the existing `--offline --no-daemon` workflow.

The ordinary tests cover the OS3 bridge and legacy Codec linkage. Published
OS3 3.2.2 and 3.3.1 consumer binaries are also checked in separate packaged
Forge runs with the sealed 1.12 fixtures. Those checks use the original
target-native binaries, not the removed 1.10 fixture source layout.
6 changes: 3 additions & 3 deletions gradle/release/artifacts.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ tasks.register('verifyReleaseConfiguration') {
description = 'Validates the target-qualified release, API, schemas, reports, and publishing identity.'

doLast {
if (project.mod_version != '4.1.2.112021'
if (project.mod_version != '4.1.3.112021'
|| project.mod_group != expectedMavenGroup) {
throw new GradleException("Unexpected OreSpawn release version: ${project.mod_version}")
}
Expand All @@ -108,8 +108,8 @@ tasks.register('verifyReleaseConfiguration') {
'src/main/java/zone/moddev/mc/orespawn/worldgen/LegacyOs3ProfileMigration.java',
'README.md', 'CHANGELOG.txt'
].each { path ->
if (!file(path).getText('UTF-8').contains('4.1.2.112021')) {
throw new GradleException("Authoritative release location does not contain 4.1.2.112021: ${path}")
if (!file(path).getText('UTF-8').contains('4.1.3.112021')) {
throw new GradleException("Authoritative release location does not contain 4.1.3.112021: ${path}")
}
}
if (!file('docs/API.md').getText('UTF-8').contains('orespawn@[4.0.6,5.0.0)')) {
Expand Down
79 changes: 0 additions & 79 deletions gradle/verification/legacy-and-migration.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
def verification = project.ext.oreSpawnVerification
def legacyFixtureArtifacts = verification.fixtureArtifacts
def legacyFixtureWorlds = verification.fixtureWorlds
def legacyMineralogy112OracleJar = verification.mineralogy112Oracle
def verifyLegacyFixtures = tasks.named('verifyLegacyFixtures')
Expand Down Expand Up @@ -162,84 +161,6 @@ if (project.hasProperty('migrationRunDir')) {
}
}

// These probes were compiled against older OreSpawn APIs. Run them on demand to
// confirm that those public binaries still load without rebuilding the mods.
def os1AbiFixtureClasses = file("${buildDir}/legacy-abi/os1/classes")
def os3AbiFixtureClasses = file("${buildDir}/legacy-abi/os3/classes")

task compileOs1AbiFixture(type: JavaCompile, dependsOn: verifyLegacyFixtures) {
source fileTree('src/os1AbiFixture/java')
classpath = files(sourceSets.main.compileClasspath,
new File(legacyFixtureArtifacts, 'OreSpawn_1.10.2-1.1.0.jar'))
destinationDirectory = os1AbiFixtureClasses
options.encoding = 'UTF-8'
}

task os1AbiFixtureJar(type: Jar, dependsOn: compileOs1AbiFixture) {
archiveFileName = 'os1abiprobe.jar'
destinationDirectory = file("${buildDir}/legacy-abi/os1")
from os1AbiFixtureClasses
from 'src/os1AbiFixture/resources'
}

task compileOs3AbiFixture(type: JavaCompile, dependsOn: verifyLegacyFixtures) {
source fileTree('src/os3AbiFixture/java')
classpath = files(sourceSets.main.compileClasspath,
new File(legacyFixtureArtifacts, 'OreSpawn-1.10.2-3.2.2.104.jar'))
destinationDirectory = os3AbiFixtureClasses
options.encoding = 'UTF-8'
}

task os3AbiFixtureJar(type: Jar, dependsOn: compileOs3AbiFixture) {
archiveFileName = 'os3abiprobe.jar'
destinationDirectory = file("${buildDir}/legacy-abi/os3")
from os3AbiFixtureClasses
from 'src/os3AbiFixture/resources'
}

def configureLegacyAbiProcess = { String generation, Task fixtureJar, String markerName ->
File runDirectory = file("${buildDir}/legacy-abi/${generation}/run")
Task prepare = tasks.create("prepare${generation.capitalize()}AbiRun", Copy) {
dependsOn fixtureJar
into new File(runDirectory, 'mods')
from fixtureJar.archiveFile
doFirst { project.delete(runDirectory) }
doLast {
new File(runDirectory, 'eula.txt').setText('eula=true\n', 'UTF-8')
new File(runDirectory, 'server.properties').setText(
'eula=true\nonline-mode=false\nlevel-name=world\nlevel-seed=zsjpxah\n' +
'spawn-animals=false\nspawn-monsters=false\n', 'UTF-8')
}
}
tasks.create("${generation}AbiIntegrationProcess", JavaExec) {
group = 'verification'
dependsOn prepare
workingDir runDirectory
configureFromForgeRun(delegate, 'runServer')
doLast {
File marker = new File(runDirectory, "world/${markerName}")
if (!marker.isFile() || !marker.text.contains('registered=true')) {
throw new GradleException("${generation.toUpperCase()} binary ABI probe did not complete: ${marker}")
}
File latest = new File(runDirectory, 'logs/latest.log')
if (latest.isFile() && latest.text.contains('Encountered an unexpected exception')) {
throw new GradleException("${generation.toUpperCase()} binary ABI probe logged a server failure")
}
}
}
}

configureLegacyAbiProcess('os1', os1AbiFixtureJar, 'os1-abi-probe.properties')
configureLegacyAbiProcess('os3', os3AbiFixtureJar, 'os3-abi-probe.properties')

task legacyAbiIntegrationTest {
group = 'verification'
dependsOn os1AbiIntegrationProcess, os3AbiIntegrationProcess
}

// Forge 1.12's published OS3 ABI fixture remains an opt-in external gate; the
// 1.10 OS1/OS3 compiled probes are not part of this target's standard check.

// The same old save is exercised with 1.10-origin and native 1.12 Mineralogy
// settings. Both paths must keep their intended values through a reload.
def legacyMineralogyArchive = new File(legacyFixtureWorlds, 'os3-331-default-source.zip')
Expand Down
3 changes: 1 addition & 2 deletions gradle/verification/support.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def legacyFixtureHashes = [

task verifyLegacyFixtures {
group = 'verification'
description = 'Verifies the sealed ABI and migration corpus used only by isolated tests.'
description = 'Verifies the sealed Mineralogy and migration fixtures used only by isolated tests.'
inputs.files legacyFixtureHashes.keySet().collect { new File(legacyFixtureRoot, it) }
doLast {
legacyFixtureHashes.each { String relativePath, String expectedHash ->
Expand Down Expand Up @@ -309,7 +309,6 @@ tasks.named('check') {
// The other verification scripts use these helpers and fixture locations.
// Keep this list small so the scripts remain understandable on their own.
ext.oreSpawnVerification = [
fixtureArtifacts: legacyFixtureArtifacts,
fixtureWorlds: legacyFixtureWorlds,
mineralogy112Oracle: legacyMineralogy112OracleJar,
java8Launcher: java8Launcher,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,7 @@ private static void writeHumanUpgradeReport(Path destination) throws IOException
}
}
List<String> lines = new ArrayList<>();
lines.add("OreSpawn 4.1.2.112021 Upgrade Report");
lines.add("OreSpawn 4.1.3.112021 Upgrade Report");
lines.add("================================");
lines.add("");
lines.add("RESULT: Legacy OreSpawn configuration was consumed and translated for OS4.");
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/zone/moddev/mc/orespawn/OreSpawn.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public class OreSpawn {

public static final String MODID = "orespawn";
public static final String NAME = "OreSpawn";
public static final String VERSION = "4.1.2.112021";
public static final String VERSION = "4.1.3.112021";

private static final Logger LOGGER = LogManager.getLogger();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ List<OreSourceGroup> oreSourceGroups() {
List<OreSourceGroup> result = new ArrayList<>();
for (Entry<String, JsonElement> entry : section("ore_source_policies").entrySet()) {
if (!entry.getValue().isJsonObject()) continue;
JsonObject policy = entry.getValue().getAsJsonObject();
JsonObject policy = OreSourceEditorView.policy(root, entry.getValue().getAsJsonObject());
String material = string(policy, "material", "");
String domain = string(policy, "domain", "");
if (!validResource(material) || !validResource(domain)) continue;
Expand Down Expand Up @@ -983,17 +983,19 @@ private static boolean hasManagedPlacementSource(JsonObject policy) {
}

private static void refreshOreSourceStatus(JsonObject policy) {
Set<String> missing = new HashSet<>();
Set<String> inactivePlacements = new HashSet<>();
Set<String> loaded = new HashSet<>();
Set<String> loadedPlacements = new HashSet<>();
boolean external = false;
boolean review = bool(policy, "review_required", false);
if (policy.has("candidates") && policy.get("candidates").isJsonArray()) {
for (JsonElement element : policy.getAsJsonArray("candidates")) {
if (!element.isJsonObject()) continue;
JsonObject candidate = element.getAsJsonObject();
String sourceId = string(candidate, "source_id", "");
if (!bool(candidate, "loaded", false)) missing.add(sourceId);
if (!bool(candidate, "placement_active", false)) inactivePlacements.add(sourceId);
if (bool(candidate, "loaded", false)) {
loaded.add(sourceId);
loadedPlacements.add(sourceId + "|" + string(candidate, "placement_channel", "orespawn:standard"));
}
external |= bool(candidate, "external", false) && bool(candidate, "loaded", false);
}
}
Expand All @@ -1005,10 +1007,10 @@ private static void refreshOreSourceStatus(JsonObject policy) {
return;
}
for (String id : outputs.keySet()) {
if (missing.contains(id)) { policy.addProperty("status", "missing_source"); return; }
if (!loaded.contains(id)) { policy.addProperty("status", "missing_source"); return; }
}
for (String id : placements.values()) {
if (missing.contains(id) || inactivePlacements.contains(id)) {
for (Entry<String, String> placement : placements.entrySet()) {
if (!loadedPlacements.contains(placement.getValue() + "|" + placement.getKey())) {
policy.addProperty("status", "missing_source"); return;
}
}
Expand Down
Loading
Loading