#!/usr/bin/env pwsh <# .SYNOPSIS Production Build Script for Spacetris SDL3 Game .DESCRIPTION This script builds the Spacetris game for production distribution, including: - Clean Release build with optimizations - Dependency collection and packaging - Asset organization and validation - Distributable package creation .PARAMETER Clean Perform a clean build (removes existing build directories) .PARAMETER PackageOnly Skip building and only create the distribution package .PARAMETER OutputDir Directory where the final package will be created (default: ./dist) .EXAMPLE .\build-production.ps1 -Clean .\build-production.ps1 -PackageOnly -OutputDir "C:\Releases" #> param( [switch]$Clean, [switch]$PackageOnly, [string]$OutputDir = "dist" ) # Configuration $ProjectName = "spacetris" $BuildDir = "build-release" $PackageDir = Join-Path $OutputDir "SpacetrisGame" $Version = Get-Date -Format "yyyy.MM.dd" # Colors for output function Write-ColorOutput($ForegroundColor) { $fc = $host.UI.RawUI.ForegroundColor $host.UI.RawUI.ForegroundColor = $ForegroundColor if ($args) { Write-Output $args } $host.UI.RawUI.ForegroundColor = $fc } function Write-Success { Write-ColorOutput Green $args } function Write-Info { Write-ColorOutput Cyan $args } function Write-Warning { Write-ColorOutput Yellow $args } function Write-Error { Write-ColorOutput Red $args } Write-Info "======================================" Write-Info " Spacetris SDL3 Production Builder" Write-Info "======================================" Write-Info "Version: $Version" Write-Info "Output: $PackageDir" Write-Info "" # Check if we're in the right directory if (!(Test-Path "CMakeLists.txt")) { Write-Error "Error: CMakeLists.txt not found. Please run this script from the project root directory." exit 1 } # Step 1: Clean if requested if ($Clean) { Write-Info "๐Ÿงน Cleaning previous builds..." if (Test-Path $BuildDir) { Remove-Item $BuildDir -Recurse -Force Write-Success "Removed $BuildDir" } if (Test-Path $OutputDir) { Remove-Item $OutputDir -Recurse -Force Write-Success "Removed $OutputDir" } } # Step 2: Build (unless PackageOnly) if (!$PackageOnly) { Write-Info "๐Ÿ”จ Building Release version..." # Create build directory if (!(Test-Path $BuildDir)) { New-Item -ItemType Directory -Path $BuildDir | Out-Null } # Configure with CMake for Release Write-Info "Configuring CMake for Release build..." $configResult = & cmake -S . -B $BuildDir -DCMAKE_BUILD_TYPE=Release 2>&1 if ($LASTEXITCODE -ne 0) { Write-Error "CMake configuration failed:" Write-Error $configResult exit 1 } Write-Success "CMake configuration completed" # Build the project Write-Info "Compiling Release build..." $buildResult = & cmake --build $BuildDir --config Release 2>&1 if ($LASTEXITCODE -ne 0) { Write-Error "Build failed:" Write-Error $buildResult exit 1 } Write-Success "Build completed successfully" } # Step 3: Verify executable exists $ExecutablePath = Join-Path $BuildDir "Release\$ProjectName.exe" if (!(Test-Path $ExecutablePath)) { # Try alternative path structure $ExecutablePath = Join-Path $BuildDir "$ProjectName.exe" if (!(Test-Path $ExecutablePath)) { Write-Error "Error: Executable not found at expected locations" Write-Error "Expected: $ExecutablePath" exit 1 } } Write-Success "Found executable: $ExecutablePath" # Step 4: Create package directory structure Write-Info "๐Ÿ“ฆ Creating distribution package..." if (Test-Path $PackageDir) { Remove-Item $PackageDir -Recurse -Force } New-Item -ItemType Directory -Path $PackageDir -Force | Out-Null # Step 5: Copy executable Write-Info "Copying executable..." Copy-Item $ExecutablePath $PackageDir Write-Success "Copied $ProjectName.exe" # Step 6: Copy assets Write-Info "Copying game assets..." # Copy all required assets $AssetFolders = @("assets", "fonts") foreach ($folder in $AssetFolders) { if (Test-Path $folder) { $destPath = Join-Path $PackageDir $folder Copy-Item $folder -Destination $destPath -Recurse -Force Write-Success "Copied $folder" } } # Copy font files from root (if any) $FontFiles = @("FreeSans.ttf") foreach ($font in $FontFiles) { if (Test-Path $font) { Copy-Item $font $PackageDir Write-Success "Copied $font" } } # Step 7: Copy dependencies (DLLs) Write-Info "Copying runtime dependencies..." $buildVcpkgBin = Join-Path (Join-Path $BuildDir "vcpkg_installed") "x64-windows/bin" $repoVcpkgBin = "vcpkg_installed/x64-windows/bin" $DependencyDirs = @($buildVcpkgBin, $repoVcpkgBin) | Where-Object { $_ } | Select-Object -Unique $copiedNames = @{} foreach ($dir in $DependencyDirs) { if (!(Test-Path $dir)) { continue } Write-Info "Scanning $dir for DLLs..." $dlls = Get-ChildItem -Path $dir -Filter "*.dll" -ErrorAction SilentlyContinue foreach ($dll in $dlls) { $dest = Join-Path $PackageDir $dll.Name Copy-Item $dll.FullName $dest -Force if (-not $copiedNames.ContainsKey($dll.Name)) { Write-Success "Copied $($dll.Name)" $copiedNames[$dll.Name] = $true } } } if ($copiedNames.Count -eq 0) { Write-Warning "No dependency DLLs were copied. Please ensure vcpkg has been built for Release." } # Step 8: Create README and batch file for easy launching Write-Info "Creating distribution files..." # Create README $ReadmeContent = @" Spacetris SDL3 Game - Release $Version ===================================== ## System Requirements - Windows 10/11 (64-bit) - DirectX compatible graphics - Audio device for music and sound effects ## Installation 1. Extract all files to a folder 2. Run spacetris.exe ## Controls - Arrow Keys: Move pieces - Z/X: Rotate pieces - C: Hold piece - Space: Hard drop - P: Pause - F11: Toggle fullscreen - Esc: Return to menu ## Troubleshooting - If the game doesn't start, ensure all DLL files are in the same folder as spacetris.exe - For audio issues, check that your audio drivers are up to date - The game requires the assets folder to be in the same directory as the executable ## Files Included - spacetris.exe - Main game executable - SDL3.dll, SDL3_ttf.dll, SDL3_image.dll - Required libraries - assets/ - Game assets (images, music, fonts) - FreeSans.ttf - Main font file Enjoy playing Spacetris! "@ $ReadmeContent | Out-File -FilePath (Join-Path $PackageDir "README.txt") -Encoding UTF8 Write-Success "Created README.txt" # Create launch batch file $BatchContent = @" @echo off cd /d "%~dp0" tetris.exe pause "@ $BatchContent | Out-File -FilePath (Join-Path $PackageDir "Launch-Spacetris.bat") -Encoding ASCII Write-Success "Created Launch-Spacetris.bat" # Step 9: Validate package Write-Info "๐Ÿ” Validating package..." $RequiredFiles = @("$ProjectName.exe", "assets", "FreeSans.ttf") $MissingFiles = @() foreach ($file in $RequiredFiles) { $filePath = Join-Path $PackageDir $file if (!(Test-Path $filePath)) { $MissingFiles += $file } } if ($MissingFiles.Count -gt 0) { Write-Warning "Warning: Missing files detected:" foreach ($missing in $MissingFiles) { Write-Warning " - $missing" } } else { Write-Success "All required files present" } # Step 10: Calculate package size $PackageSize = (Get-ChildItem $PackageDir -Recurse | Measure-Object -Property Length -Sum).Sum $PackageSizeMB = [math]::Round($PackageSize / 1MB, 2) # Step 11: Create ZIP archive (optional) $ZipPath = Join-Path $OutputDir "SpacetrisGame-$Version.zip" Write-Info "๐Ÿ“ Creating ZIP archive..." try { Compress-Archive -Path $PackageDir -DestinationPath $ZipPath -Force Write-Success "Created ZIP: $ZipPath" } catch { Write-Warning "Failed to create ZIP archive: $($_.Exception.Message)" } # Final summary Write-Info "" Write-Success "======================================" Write-Success " Build Completed Successfully!" Write-Success "======================================" Write-Info "Package location: $PackageDir" Write-Info "Package size: $PackageSizeMB MB" if (Test-Path $ZipPath) { Write-Info "ZIP archive: $ZipPath" } Write-Info "" Write-Info "The game is ready for distribution!" Write-Info "Users can run spacetris.exe or Launch-Spacetris.bat" Write-Info ""