From 1d1464eb86f8198b96f0618f86920aaf52a1236a Mon Sep 17 00:00:00 2001 From: Luke Date: Wed, 11 Feb 2026 14:53:44 +0000 Subject: [PATCH] Fix for javascript gamemaker extension files not being correctly copied when built GameMaker javascript extensions were not being correctly copied to the assets directory when the project was built in GameMaker. An assets manifest is now created during build, and processed by main.ts before the runner.js script is loaded A seperate change is needed in the GameMaker runtime to allow javascript extensions to function correctly, but can be patched locally in the meantime by replacing: `Da[a]=eval(a)` with `Da[a]=globalThis[a]` in the client/src/public/runner.js file once built --- setup-gamemaker-devvit.bat | 45 +++++++++++++++++++++++++++++++++++- setup-gamemaker-devvit.sh | 41 ++++++++++++++++++++++++++++++++- src/client/main.ts | 47 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 2 deletions(-) diff --git a/setup-gamemaker-devvit.bat b/setup-gamemaker-devvit.bat index 539d2dc..eec1395 100644 --- a/setup-gamemaker-devvit.bat +++ b/setup-gamemaker-devvit.bat @@ -24,6 +24,7 @@ set PROJECT_NAME=%~2 set "SUBREDDIT_NAME=%PROJECT_NAME:-=_%" set RUNNER_DIR=%GAMEMAKER_DIR%\runner set CLIENT_PUBLIC=%cd%\src\client\public +set CLIENT_ASSETS=%CLIENT_PUBLIC%\assets :: Check if GameMaker directory exists if not exist "%GAMEMAKER_DIR%" ( @@ -49,10 +50,48 @@ echo GameMaker directory: %GAMEMAKER_DIR% echo Project name: %PROJECT_NAME% echo Devvit project: %cd% -:: Copy all files from runner directory to public directory +:: Create assets directory if it doesn't exist +if not exist "%CLIENT_ASSETS%" mkdir "%CLIENT_ASSETS%" + +:: Copy all files from GameMaker export directory (excluding subdirectories) to assets echo Copying GameMaker files to game directory... +echo Copying files from main export directory to assets... +for %%f in ("%GAMEMAKER_DIR%\*") do ( + if not exist "%%f\" ( + copy "%%f" "%CLIENT_ASSETS%\" /Y >nul + ) +) + +:: Copy all files from runner directory to public directory +echo Copying files from runner directory to public... xcopy "%RUNNER_DIR%\*" "%CLIENT_PUBLIC%\" /Y /Q +:: Generate manifest of .js files in assets directory +echo Generating assets manifest... +set ASSETS_MANIFEST=%CLIENT_PUBLIC%\assets-manifest.json + +:: Count files first +set count=0 +for %%f in ("%CLIENT_ASSETS%\*.js") do ( + if exist "%%f" set /a count+=1 +) + +:: Write JSON array +echo [ > "%ASSETS_MANIFEST%" +set current=0 +for %%f in ("%CLIENT_ASSETS%\*.js") do ( + if exist "%%f" ( + set /a current+=1 + if !current! equ !count! ( + echo "assets/%%~nxf" >> "%ASSETS_MANIFEST%" + ) else ( + echo "assets/%%~nxf", >> "%ASSETS_MANIFEST%" + ) + ) +) +echo ] >> "%ASSETS_MANIFEST%" +echo Assets manifest created with !count! JavaScript file^(s^) + echo. echo GameMaker game setup complete! echo. @@ -65,5 +104,9 @@ echo 1. Run "npm run dev" to start the development server echo 2. Your GameMaker game should now load in the Devvit app echo. echo Files copied: +echo - Export directory files → src\client\public\assets\ echo - Core runtime files → src\client\public\ (root level) +echo - Assets manifest → src\client\public\assets-manifest.json +echo. +echo Note: Asset JavaScript files will be loaded automatically before runner.js echo. diff --git a/setup-gamemaker-devvit.sh b/setup-gamemaker-devvit.sh index 30f915f..b919656 100644 --- a/setup-gamemaker-devvit.sh +++ b/setup-gamemaker-devvit.sh @@ -18,6 +18,7 @@ PROJECT_NAME="$2" SUBREDDIT_NAME="${PROJECT_NAME//-/_}" RUNNER_DIR="$GAMEMAKER_DIR/runner" CLIENT_PUBLIC="$(pwd)/src/client/public" +CLIENT_ASSETS="$CLIENT_PUBLIC/assets" # Check if GameMaker directory exists if [ ! -d "$GAMEMAKER_DIR" ]; then @@ -43,10 +44,44 @@ echo "GameMaker directory: $GAMEMAKER_DIR" echo "Project name: $PROJECT_NAME" echo "Devvit project: $(pwd)" -# Copy all files from runner directory to game directory +# Create assets directory if it doesn't exist +mkdir -p "$CLIENT_ASSETS" + +# Copy all files from GameMaker export directory (excluding runner directory) to assets echo "Copying GameMaker files to game directory..." +echo "Copying files from main export directory to assets..." +find "$GAMEMAKER_DIR" -maxdepth 1 -type f -exec cp {} "$CLIENT_ASSETS/" \; + +# Copy all files from runner directory to game directory +echo "Copying files from runner directory to public..." cp -r "$RUNNER_DIR"/* "$CLIENT_PUBLIC/" +# Generate manifest of .js files in assets directory +echo "Generating assets manifest..." +ASSETS_MANIFEST="$CLIENT_PUBLIC/assets-manifest.json" + +# Collect all .js files first +js_files=() +for jsfile in "$CLIENT_ASSETS"/*.js; do + if [ -f "$jsfile" ]; then + js_files+=("$(basename "$jsfile")") + fi +done + +# Write JSON array +echo "[" > "$ASSETS_MANIFEST" +for i in "${!js_files[@]}"; do + if [ $i -eq $((${#js_files[@]} - 1)) ]; then + # Last item, no comma + echo " \"assets/${js_files[$i]}\"" >> "$ASSETS_MANIFEST" + else + # Not last item, add comma + echo " \"assets/${js_files[$i]}\"," >> "$ASSETS_MANIFEST" + fi +done +echo "]" >> "$ASSETS_MANIFEST" +echo "Assets manifest created with ${#js_files[@]} JavaScript file(s)" + echo "" echo "GameMaker game setup complete!" echo "" @@ -59,5 +94,9 @@ echo "1. Run \"npm run dev\" to start the development server" echo "2. Your GameMaker game should now load in the Devvit app" echo "" echo "Files copied:" +echo "- Export directory files → src/client/public/assets/" echo "- Core runtime files → src/client/public/ (root level)" +echo "- Assets manifest → src/client/public/assets-manifest.json" +echo "" +echo "Note: Asset JavaScript files will be loaded automatically before runner.js" echo "" \ No newline at end of file diff --git a/src/client/main.ts b/src/client/main.ts index 48b46a5..7017b85 100644 --- a/src/client/main.ts +++ b/src/client/main.ts @@ -354,6 +354,50 @@ class GameLoader { } } + private async loadAssetsScripts(): Promise { + try { + const response = await fetch('/assets-manifest.json', { cache: 'no-cache' }); + if (!response.ok) { + console.log('No assets manifest found, skipping asset scripts'); + return; + } + + const assetScripts: string[] = await response.json(); + if (!Array.isArray(assetScripts) || assetScripts.length === 0) { + console.log('No asset scripts to load'); + return; + } + + console.log(`Loading ${assetScripts.length} asset script(s) before runner.js...`); + + // Load scripts sequentially + for (const scriptPath of assetScripts) { + await new Promise((resolve, reject) => { + const script = document.createElement('script'); + script.src = `/${scriptPath}`; + script.type = 'text/javascript'; + + script.onload = () => { + console.log(`Loaded asset script: ${scriptPath}`); + resolve(); + }; + + script.onerror = () => { + console.error(`Failed to load asset script: ${scriptPath}`); + // Continue loading even if one fails + resolve(); + }; + + document.head.appendChild(script); + }); + } + + console.log('All asset scripts loaded'); + } catch (error) { + console.warn('Error loading assets manifest:', error); + } + } + private async loadGame() { try { // First try to get initial data from the server @@ -365,6 +409,9 @@ class GameLoader { // Setup required global functions before loading GameMaker script this.setupGameMakerGlobals(); + // Load asset scripts before runner.js + await this.loadAssetsScripts(); + // Load the GameMaker runner script const script = document.createElement('script'); script.src = '/runner.js';