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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Disable autocrlf on generated files, they always generate with LF
# Add any extra files or paths here to make git stop saying they
# are changed when only line endings change.
* text=auto eol=lf
.gitattributes text eol=lf
src/generated/**/.cache/cache text eol=lf
src/generated/**/*.json text eol=lf
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,19 @@ jobs:
--no-daemon --stacktrace
first="$RUNNER_TEMP/basemetals-first"
mkdir -p "$first"
cp build/libs/BaseMetals-3.0.1.118021.jar "$first/"
cp build/libs/BaseMetals-3.0.1.118021-sources.jar "$first/"
cp build/libs/BaseMetals-3.0.1.118021-javadoc.jar "$first/"
cp build/libs/BaseMetals-3.1.0.118021.jar "$first/"
cp build/libs/BaseMetals-3.1.0.118021-sources.jar "$first/"
cp build/libs/BaseMetals-3.1.0.118021-javadoc.jar "$first/"
cp build/release/SHA256SUMS "$first/"

- name: Rebuild and prove byte-identical archives
run: |
./gradlew clean assemble verifyReleaseArtifacts writeReleaseChecksums \
-PorespawnVerificationRepository="${{ steps.orespawn.outputs.repository }}" \
--no-daemon --stacktrace
cmp "$RUNNER_TEMP/basemetals-first/BaseMetals-3.0.1.118021.jar" build/libs/BaseMetals-3.0.1.118021.jar
cmp "$RUNNER_TEMP/basemetals-first/BaseMetals-3.0.1.118021-sources.jar" build/libs/BaseMetals-3.0.1.118021-sources.jar
cmp "$RUNNER_TEMP/basemetals-first/BaseMetals-3.0.1.118021-javadoc.jar" build/libs/BaseMetals-3.0.1.118021-javadoc.jar
cmp "$RUNNER_TEMP/basemetals-first/BaseMetals-3.1.0.118021.jar" build/libs/BaseMetals-3.1.0.118021.jar
cmp "$RUNNER_TEMP/basemetals-first/BaseMetals-3.1.0.118021-sources.jar" build/libs/BaseMetals-3.1.0.118021-sources.jar
cmp "$RUNNER_TEMP/basemetals-first/BaseMetals-3.1.0.118021-javadoc.jar" build/libs/BaseMetals-3.1.0.118021-javadoc.jar
cmp "$RUNNER_TEMP/basemetals-first/SHA256SUMS" build/release/SHA256SUMS

- name: Run all required GameTests
Expand Down Expand Up @@ -128,9 +128,9 @@ jobs:
if-no-files-found: error
retention-days: 30
path: |
build/libs/BaseMetals-3.0.1.118021.jar
build/libs/BaseMetals-3.0.1.118021-sources.jar
build/libs/BaseMetals-3.0.1.118021-javadoc.jar
build/libs/BaseMetals-3.1.0.118021.jar
build/libs/BaseMetals-3.1.0.118021-sources.jar
build/libs/BaseMetals-3.1.0.118021-javadoc.jar
build/release/SHA256SUMS
CHANGELOG.txt

Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
Base Metals 3.1.0.118021

- Bring raw metals, ore overlays and High/Low Fantasy modes to Minecraft 1.18.2, along with the fixes from the earlier ports.
- Use KiriCattus' ore overlays over vanilla block textures, including resource-pack replacements.
- Add twelve raw metals, Fortune and Silk Touch drops, raw crushing, smelting and blasting. Copper uses vanilla raw copper.
- Add High and Low Fantasy modes and a configuration screen in both the Mods list and OreSpawn. Old configs default to High Fantasy.
- Stop metal powders and nuggets burning in furnaces (#473).
- Give doors distinct six-ingredient recipes, separate from trapdoors (#474).
- Restore sixteen steel rails, material-based ranged damage, and ingot-based recipe discovery (#467).
- Fix Obsidian and equipment recipe loops. Keep plate repair recipes out of the recipe book and preserve names and custom item data.
- Fix thin transparent blocks hiding neighbouring faces, improve bucket names and tooltips, and make horse armour unstackable.
- Improve old-world aliases and wall conversion, remove phantom bed entities, and protect saved terrain while allowing 1.18's new underground.
- Require the published OreSpawn 4.1.0.118021 release. Keep the existing ore rules, height ranges and disabled-by-default Base Metals copper generation.
- Move native model and data generation out of the production source set. The generateResources task updates the checked-in data.
- Keep optional mods out of normal development launches. Add a separate client profile for Tinkers, Mantle and compatibility testing.
- Fix flickering bar textures by using the correct centre-post and end pieces, without changing their collision shapes.

Base Metals 3.0.1.118021

- Modernize the Minecraft 1.18.2 build to ForgeGradle 7.0.34 and Gradle 9.6.1.
Expand Down
81 changes: 59 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@ shields, bows, crossbows, arrows, and bolts. The mod also includes Crack
Hammers, scythes, metal anvils, the human detector, villager trades,
advancements, and structure loot.

The Minecraft 1.18.2 line is a native Forge/Java 17 port. Its current version is
`3.0.1.118021`: functional version `3.0.1`, built for the `118021` target
(Minecraft 1.18.2, Forge). It preserves the historical `basemetals` registry
IDs while replacing MMDLib, Additional Loot Tables, and the old Base Metals
world generator with modern Forge and data-pack systems.
This is the Minecraft 1.18.2 Forge version, `3.1.0.118021`. It brings over the
fixes and features from the earlier ports, including raw metals, ore texture
overlays and High/Low Fantasy modes. Existing Base Metals items and blocks keep
their registry IDs. OreSpawn handles ore generation; MMDLib and Additional Loot
Tables are no longer needed.

## Requirements

- Minecraft `1.18.2`
- Forge `40.3.0` or newer in the Minecraft 1.18.2 Forge 40 line
- Java 17
- OreSpawn `[4.0.1,5.0.0)` on both client and server
- OreSpawn `[4.1.0.118021,5.0.0)` on both client and server

This version is built and qualified against OreSpawn `4.0.16.118021`. Put
`BaseMetals-3.0.1.118021.jar` and a compatible OreSpawn JAR in the `mods`
This version uses OreSpawn `4.1.0.118021`. Put
`BaseMetals-3.1.0.118021.jar` and a compatible OreSpawn JAR in the `mods`
directory. MMDLib and Additional Loot Tables must not be carried forward from
an older installation. Mineralogy is optional.

Expand All @@ -39,25 +39,31 @@ Base Metals provides 22 materials:
- Alloys: Brass, Bronze, Cupronickel, Electrum, Invar, Pewter, and Steel.
- Fantasy materials: Adamantine, Aquarium, Cold Iron, Mithril, and Starsteel.

The available forms intentionally vary by material to preserve the established
Base Metals content. Forge tags are used throughout recipes, so compatible
ores, ingots, powders, plates, rods, gears, and other components from different
mods can interoperate without a Java API dependency.
All existing items and blocks stay registered, including when Low Fantasy
limits which items you can make. Recipes use Forge tags, so compatible ores,
ingots, powders, plates, rods, gears and other components from different mods
can be used together.

Notable mechanics include:

- Crack Hammers crush supported mined blocks through the data-driven
`basemetals:crushing` recipe type. They can also crush dropped items by using
the hammer on the block beneath them; sneaking processes as much of a stack
as the hammer's remaining durability allows.
- Supported ore powders can be smelted into ingots, and alloy blends provide the
historical furnace-based alloying route.
- Mining ores normally gives raw metal. Fortune increases the drops, and Silk
Touch keeps the ore block. Copper uses vanilla raw copper. A dropped raw piece
makes one powder when crushed; hammering an ore block directly gives two.
- Raw metals can be smelted or blasted into ingots. Powders, not raw metals, are
used to make alloy blends.
- Scythes harvest a horizontal 3x3 area while respecting normal Forge block
break and protection events, drops, enchantments, and durability.
- Material shields can be upgraded at an anvil with one strictly harder tagged
plate while retaining their enchantments.
- Base Metals bows fire its material arrows. Its legacy-style crossbows are
draw-and-release weapons which fire material bolts.
- Bows fire arrows, while Base Metals' draw-and-release crossbows fire bolts.
Both the weapon and ammunition material contribute to the damage, before
enchantment bonuses. Picked-up projectiles keep their material and item data.
- One matching plate fully repairs damaged armour or a shield in a crafting
grid, keeping its enchantments, name and other item data.
- Configurable armour and melee effects give Adamantine, Aquarium, Cold Iron,
Lead, Mithril, and Starsteel their distinctive behaviour. Held Starsteel
equipment repairs by one durability every 200 server ticks; Starsteel armour
Expand All @@ -66,11 +72,31 @@ Notable mechanics include:
fluids are world blocks and compatibility resources rather than a second
Base Metals processing system.

The common configuration deliberately contains only four default-enabled
switches: special equipment effects, Starsteel regeneration, mercury immersion
effects, and villager trades. Registries, materials, recipes, and world
generation are stable data contracts and cannot be disabled individually by
the common configuration.
Ore blocks use KiriCattus' overlays on vanilla stone, netherrack and end stone,
so they follow your resource pack's surrounding textures. Bars, doors and
trapdoors keep their transparent gaps without hiding nearby blocks. Bar models
also avoid overlapping faces that caused their vertical edges to flicker.

## Configuration

Open **Mods → Base Metals → Config** from the main menu, or use the Base Metals
cog in OreSpawn's world-creation screen. You can also edit
`config/basemetals-common.toml`.

High Fantasy is the default and keeps all of the usual crafting options.
Low Fantasy limits equipment to suitable materials and removes Base Metals
bow, crossbow and fishing-rod recipes. Existing equipment still works, and
everything remains available in Creative mode. Neither mode changes vanilla
Minecraft recipes or ore placement.

Restart Minecraft after changing the mode. A client must use the same mode
as its server; older configuration files without this setting default to
High Fantasy. This is a server or modpack setting, not a per-world setting.
Ore generation is still configured in OreSpawn.

The other four switches control equipment effects, held Starsteel regeneration,
mercury immersion effects and villager trades. They are enabled by default.
Done saves your changes; Cancel or Escape leaves the settings unchanged.

## Ore generation

Expand Down Expand Up @@ -135,14 +161,25 @@ Generate and verify Eclipse launches with:
./gradlew genEclipseRuns eclipse isolateEclipseProductionRuns verifyEclipseProductionClasspath
```

Use **runClient** for normal testing with Base Metals and OreSpawn only.
**runClientOptionalMods** adds Tinkers' Construct and Mantle for compatibility
testing. It uses `run-optional-mods`, keeping its settings and saves separate
from the normal client's `run` folder. Both profiles are available in Eclipse
and through Gradle tasks.

Use the Gradle **generateResources** task when changing recipes, models or
translations. It updates the checked-in data; ordinary builds only check for
drift. Ore models use KiriCattus' transparent overlays over vanilla textures,
so resource packs can replace the surrounding stone, netherrack or end stone.

The CI workflow also runs all required GameTests, generated-data drift checks,
packaged client and dedicated-server smokes, release-JAR audits, dependency
identity checks, and a second clean build to prove byte-identical release
artifacts. GameTests, smoke probes, migration fixtures, and reference sources
are isolated from the published JAR.

Release artifacts use Maven coordinate
`zone.moddev.mc.basemetals:BaseMetals:3.0.1.118021`.
`zone.moddev.mc.basemetals:BaseMetals:3.1.0.118021`.

Report defects and compatibility problems through the
[Base Metals issue tracker](https://github.com/MinecraftModDevelopmentMods/BaseMetals/issues).
Expand Down
43 changes: 38 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,25 @@ tasks.withType(AbstractArchiveTask).configureEach {
reproducibleFileOrder = true
}

tasks.withType(Jar).configureEach {
includeEmptyDirs = false
}

// Validation-only client code is kept out of the published mod. ForgeGradle
// adds this source set to the client run only when the integrated-world smoke
// is explicitly requested.
sourceSets {
optionalMods {
java.setSrcDirs([])
resources.setSrcDirs([])
runtimeClasspath += sourceSets.main.output
}
dataGenerator {
java.srcDir 'src/dataGenerator/java'
resources.setSrcDirs([])
compileClasspath += sourceSets.main.output
runtimeClasspath += sourceSets.main.output
}
gameTestValidation {
java.srcDir 'src/gametest/java'
resources.srcDir 'src/gametest/resources'
Expand Down Expand Up @@ -126,6 +141,10 @@ sourceSets {
}

configurations {
optionalModsImplementation.extendsFrom implementation
dataGeneratorImplementation.extendsFrom implementation
dataGeneratorCompileOnly.extendsFrom compileOnly
dataGeneratorRuntimeOnly.extendsFrom runtimeOnly
orespawnRelease
gameTestValidationImplementation.extendsFrom implementation
gameTestValidationCompileOnly.extendsFrom compileOnly
Expand All @@ -152,6 +171,9 @@ minecraft {
runs {
configureEach {
workingDir.convention layout.projectDirectory.dir('run')
with(sourceSets.optionalMods) {
workingDir.set(layout.projectDirectory.dir('run-optional-mods'))
}
jvmArgs '--add-opens', 'java.base/java.lang.invoke=ALL-UNNAMED'

// Keep registry diagnostics available in development logs.
Expand Down Expand Up @@ -247,9 +269,10 @@ minecraft {

data {
workingDir.convention layout.projectDirectory.dir('run-data')

// Regenerate the checked-in resources from the material catalogue.
args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
systemProperty 'basemetals.projectDir', projectDir.absolutePath
mods { "${mod_id}" { source sourceSets.dataGenerator } }
// Generate into build output. Only generateResources updates the checked-in files.
args '--mod', mod_id, '--all', '--output', file('build/generated-verification'), '--existing', file('src/main/resources/')
}
}
}
Expand All @@ -273,15 +296,19 @@ def registerRunModOutput = { String taskName, SourceSet validationSourceSet ->
}

def productionRunMod = registerRunModOutput('prepareDevelopmentMod', null)
def dataRunMod = registerRunModOutput('prepareDataDevelopmentMod', sourceSets.dataGenerator)
def gameTestRunMod = registerRunModOutput('prepareGameTestDevelopmentMod', sourceSets.gameTestValidation)
def integratedRunMod = registerRunModOutput('prepareIntegratedSmokeDevelopmentMod', sourceSets.integratedSmoke)
def upgradeRunMod = registerRunModOutput('prepareUpgradeSmokeDevelopmentMod', sourceSets.upgradeSmoke)

tasks.withType(JavaExec).configureEach { JavaExec runTask ->
def selected = productionRunMod
if (runTask.name == 'runGameTestServer') {
if (runTask.name == 'runData') {
selected = dataRunMod
} else if (runTask.name == 'runGameTestServer') {
selected = gameTestRunMod
} else if (runTask.name == 'runClient' && providers.gradleProperty('integratedWorldSmoke').isPresent()) {
} else if (runTask.name in ['runClient', 'runOptionalModsClient']
&& providers.gradleProperty('integratedWorldSmoke').isPresent()) {
selected = integratedRunMod
} else if (runTask.name == 'runServer' && (providers.gradleProperty('upgradeWorldSmoke').isPresent()
|| providers.gradleProperty('legacyWorldSmoke').isPresent())) {
Expand All @@ -297,6 +324,12 @@ tasks.withType(JavaExec).configureEach { JavaExec runTask ->
}
}

tasks.register('runClientOptionalMods') {
group = 'forgegradle runs'
description = 'Runs the client with Tinkers, Mantle and any selected compatibility mods.'
dependsOn 'runOptionalModsClient'
}

// Generated resources are checked in; the local cache is never packaged.
sourceSets.main.resources {
srcDir 'src/generated/resources'
Expand Down
12 changes: 12 additions & 0 deletions docs/COMPATIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,15 @@ through Forge tags.

Mineralogy is entirely optional. Base Metals never links to its Java classes;
OreSpawn's rock-family host matching is the only integration point.

## Low Fantasy

Base Metals filters its own crafting, processing, trades and chest additions.
Its conditional integration recipes follow the same material restrictions.
Tinkers' bundled material stats do not provide bows or parts that would enable
a restricted tool family. Explicit third-party recipes and data-pack overrides
remain under the pack author's control.

Raw metals have their own `forge:raw_materials/<metal>` tags. They are not dusts
and cannot replace powders in alloy blends. Vanilla raw iron, gold and copper
are supported by the crushing recipes.
Loading
Loading