<# BLOCKLINE - Relay District : cross-platform build script -------------------------------------------------------- Exports standalone builds for: - Windows (x86_64) -> dist/windows/BLOCKLINE.exe (+ .pck/data) - macOS (universal) -> dist/macos/BLOCKLINE.zip (Intel + Apple Silicon) Everything runs against the Godot editor bundled in tools/godot/. Export templates for 4.5.stable are downloaded automatically on first run. Usage (from anywhere): powershell -ExecutionPolicy Bypass -File build-tools\Build-Game.ps1 powershell -ExecutionPolicy Bypass -File build-tools\Build-Game.ps1 -Target win powershell -ExecutionPolicy Bypass -File build-tools\Build-Game.ps1 -Target mac powershell -ExecutionPolicy Bypass -File build-tools\Build-Game.ps1 -DebugBuild #> [CmdletBinding()] param( [ValidateSet('all', 'win', 'mac')] [string]$Target = 'all', [switch]$DebugBuild ) $ErrorActionPreference = 'Stop' # --- Paths -------------------------------------------------------------- $ProjectRoot = Split-Path -Parent $PSScriptRoot # build-tools/ -> project root $GodotExe = Join-Path $ProjectRoot 'tools\godot\Godot_v4.5-stable_win64_console.exe' $DistDir = Join-Path $ProjectRoot 'dist' $GodotVersion = '4.5.stable' $TemplatesUrl = 'https://github.com/godotengine/godot/releases/download/4.5-stable/Godot_v4.5-stable_export_templates.tpz' function Write-Step($msg) { Write-Host "`n==> $msg" -ForegroundColor Cyan } function Write-Ok($msg) { Write-Host " $msg" -ForegroundColor Green } function Write-Warn2($msg){ Write-Host " $msg" -ForegroundColor Yellow } # --- Sanity checks ------------------------------------------------------ if (-not (Test-Path $GodotExe)) { throw "Godot editor not found at: $GodotExe" } if (-not (Test-Path (Join-Path $ProjectRoot 'project.godot'))) { throw "project.godot not found in $ProjectRoot. Is this the right folder?" } if (-not (Test-Path (Join-Path $ProjectRoot 'export_presets.cfg'))) { throw "export_presets.cfg not found in $ProjectRoot. It ships next to this script; copy it to the project root." } # --- Export templates --------------------------------------------------- # Godot looks for templates in %APPDATA%\Godot\export_templates\\ $TemplatesDir = Join-Path $env:APPDATA "Godot\export_templates\$GodotVersion" function Ensure-Templates { $required = @() if ($Target -ne 'mac') { $required += 'windows_release_x86_64.exe' } if ($Target -ne 'win') { $required += 'macos.zip' } if (@($required | Where-Object { -not (Test-Path (Join-Path $TemplatesDir $_)) }).Count -eq 0) { Write-Ok "Export templates already installed ($GodotVersion)." return } Write-Step "Export templates for $GodotVersion not found. Downloading (~700 MB, one time)." $tmpTpz = Join-Path $env:TEMP "godot_templates_$GodotVersion.tpz" $tmpExtract = Join-Path $env:TEMP "godot_templates_$GodotVersion" try { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Invoke-WebRequest -Uri $TemplatesUrl -OutFile $tmpTpz -UseBasicParsing } catch { throw ("Failed to download export templates. Download manually from " + $TemplatesUrl + " then in Godot: Editor > Manage Export Templates > Install from File. " + $_) } Write-Ok "Extracting templates..." if (Test-Path $tmpExtract) { Remove-Item $tmpExtract -Recurse -Force } # A .tpz is a plain zip; contents live inside a 'templates/' folder. $zipCopy = "$tmpTpz.zip" Copy-Item $tmpTpz $zipCopy -Force Expand-Archive -Path $zipCopy -DestinationPath $tmpExtract -Force New-Item -ItemType Directory -Force -Path $TemplatesDir | Out-Null Get-ChildItem -Path (Join-Path $tmpExtract 'templates') -File | ForEach-Object { Copy-Item $_.FullName -Destination $TemplatesDir -Force } Remove-Item $tmpTpz, $zipCopy -Force -ErrorAction SilentlyContinue Remove-Item $tmpExtract -Recurse -Force -ErrorAction SilentlyContinue Write-Ok "Templates installed to $TemplatesDir" } # --- Export helper ------------------------------------------------------ function Export-Preset($presetName, $outFile) { $outDir = Split-Path -Parent $outFile New-Item -ItemType Directory -Force -Path $outDir | Out-Null $mode = if ($DebugBuild) { '--export-debug' } else { '--export-release' } Write-Step ("Exporting '" + $presetName + "' (" + [IO.Path]::GetFileName($outFile) + ")") & $GodotExe --headless --path $ProjectRoot $mode $presetName $outFile if ($LASTEXITCODE -ne 0) { throw ("Godot export for '" + $presetName + "' failed (exit " + $LASTEXITCODE + "). Scroll up for the editor's error output.") } if (Test-Path $outFile) { $size = [math]::Round((Get-Item $outFile).Length / 1MB, 1) Write-Ok "Built $outFile ($size MB)" } else { Write-Warn2 "Godot reported success but $outFile is missing. Check the log above." } } # --- Run ---------------------------------------------------------------- $started = Get-Date Ensure-Templates if ($Target -eq 'all' -or $Target -eq 'win') { Export-Preset 'Windows Desktop' (Join-Path $DistDir 'windows\BLOCKLINE.exe') } if ($Target -eq 'all' -or $Target -eq 'mac') { $macArchive = Join-Path $DistDir 'macos\BLOCKLINE.build.zip' Export-Preset 'macOS' $macArchive & (Join-Path $PSScriptRoot 'Test-MacArchive.ps1') -ArchivePath $macArchive # Add helpers OUTSIDE the signed app. Never repack an extracted app on Windows. Add-Type -AssemblyName System.IO.Compression.FileSystem $zip = [IO.Compression.ZipFile]::Open($macArchive, [IO.Compression.ZipArchiveMode]::Update) try { foreach ($name in @('Open-BLOCKLINE.command', 'STANDALONE-README.txt')) { $entry = $zip.CreateEntry($name) $entry.ExternalAttributes = (0x81ED -shl 16) $stream = $entry.Open() try { $text = [IO.File]::ReadAllText((Join-Path $ProjectRoot ('macos/' + $name))).Replace("`r`n", "`n") $bytes = [Text.UTF8Encoding]::new($false).GetBytes($text) $stream.Write($bytes, 0, $bytes.Length) } finally { $stream.Dispose() } } } finally { $zip.Dispose() } & (Join-Path $PSScriptRoot 'Test-MacArchive.ps1') -ArchivePath $macArchive Move-Item -LiteralPath $macArchive -Destination (Join-Path $DistDir 'macos\BLOCKLINE.zip') -Force } Write-Step ("Done in {0:n0}s. Output in: {1}" -f ((Get-Date) - $started).TotalSeconds, $DistDir) Write-Host "" Write-Host "Windows: dist\windows\BLOCKLINE.exe - ship the whole windows\ folder." -ForegroundColor Gray Write-Host "macOS: dist\macos\BLOCKLINE.zip - universal (Intel + Apple Silicon)." -ForegroundColor Gray Write-Host " Ad-hoc signed. For a quarantined download, see STANDALONE-README.txt in the ZIP." -ForegroundColor Gray