#requires -Version 5 <# .SYNOPSIS Builds every tweak source folder under ..\pack\tweaks\ into a data-only mod jar and drops it into ..\pack\overrides\mods\. .DESCRIPTION Each subfolder of ..\pack\tweaks\ is treated as one self-contained "data-only" NeoForge mod. Its modId, version, and display name come from the folder's META-INF\neoforge.mods.toml. The script: 1. Reads modId + version from neoforge.mods.toml. 2. Zips the folder contents (data\, META-INF\, pack.mcmeta) into a jar named "-.jar". 3. Removes any older jars for the same modId from the output folder so stale versions don't get bundled into the manifest. Run this before Build-Pack.ps1, or let Build-Pack.ps1 invoke it for you. .PARAMETER TweaksRoot Folder containing tweak source subfolders. Defaults to ..\pack\tweaks\. .PARAMETER OutputRoot Where built jars go. Defaults to ..\pack\overrides\mods\. This path becomes Build-Pack.ps1's -LocalPackSource (one level up). #> [CmdletBinding()] param( [string]$TweaksRoot = "", [string]$OutputRoot = "" ) $ErrorActionPreference = 'Stop' $ProgressPreference = 'SilentlyContinue' $here = Split-Path -Parent $MyInvocation.MyCommand.Path if (-not $TweaksRoot) { $TweaksRoot = Join-Path $here '..\pack\tweaks' } if (-not $OutputRoot) { $OutputRoot = Join-Path $here '..\pack\overrides\mods' } if (-not (Test-Path $TweaksRoot)) { Write-Host "No tweaks folder at $TweaksRoot -- nothing to build." return } if (-not (Test-Path $OutputRoot)) { New-Item -ItemType Directory -Path $OutputRoot -Force | Out-Null } # Read modId + version out of a neoforge.mods.toml. We do this with a tiny regex # parser instead of a full TOML library because we only need two scalars and we # control the file format. Lines like: modId = "foo" version = "1.2.3" function Get-ModMeta { param([string]$TomlPath) if (-not (Test-Path $TomlPath)) { throw "Missing $TomlPath -- every tweak folder needs META-INF\neoforge.mods.toml." } $content = Get-Content $TomlPath -Raw $modIdMatch = [regex]::Match($content, '(?m)^\s*modId\s*=\s*"([^"]+)"') $versionMatch = [regex]::Match($content, '(?m)^\s*version\s*=\s*"([^"]+)"') if (-not $modIdMatch.Success) { throw "Could not parse modId from $TomlPath" } if (-not $versionMatch.Success) { throw "Could not parse version from $TomlPath" } return [pscustomobject]@{ ModId = $modIdMatch.Groups[1].Value Version = $versionMatch.Groups[1].Value } } Add-Type -AssemblyName System.IO.Compression.FileSystem $tweakDirs = Get-ChildItem -Path $TweaksRoot -Directory if ($tweakDirs.Count -eq 0) { Write-Host "No tweak folders found under $TweaksRoot." return } Write-Host "" Write-Host "Building tweak jars from $TweaksRoot" Write-Host "" foreach ($dir in $tweakDirs) { $tomlPath = Join-Path $dir.FullName 'META-INF\neoforge.mods.toml' $meta = Get-ModMeta -TomlPath $tomlPath $jarName = "$($meta.ModId)-$($meta.Version).jar" $jarPath = Join-Path $OutputRoot $jarName # Wipe stale jars for this modId so old versions don't get bundled into # the manifest alongside the new one. Get-ChildItem -Path $OutputRoot -Filter "$($meta.ModId)-*.jar" -ErrorAction SilentlyContinue | Where-Object { $_.Name -ne $jarName } | ForEach-Object { Write-Host (" removing stale: {0}" -f $_.Name) Remove-Item $_.FullName -Force } if (Test-Path $jarPath) { Remove-Item $jarPath -Force } [System.IO.Compression.ZipFile]::CreateFromDirectory( $dir.FullName, $jarPath, [System.IO.Compression.CompressionLevel]::Optimal, $false ) $size = (Get-Item $jarPath).Length Write-Host (" built {0,-40} {1,8:N0} bytes" -f $jarName, $size) } Write-Host "" Write-Host "Tweak jars are in: $OutputRoot"