I figured out that the dmloader script can find its dependencies if you dump the contents of the Defold build folder into “/public”.
I didn’t manage to get a screenshot of the error message beforehand, but I understand that loadArchiveDescription
was unable to parse the subdirectories in order to load the archive files. The json “description” was coming out as null. Unsure if this is specific to Nuxt3 and Vite/Nitro or dmloader.js.
Either way I will include a basic snippet for future reference:
<template>
<div id="app-container" class="canvas-app-container">
<div id="canvas-container" class="canvas-app-canvas-container">
<canvas id="canvas" class="canvas-app-canvas" tabindex="1" width="1280" height="800"></canvas>
</div>
<div class="buttons-background">
<div class="button" onclick="Module.toggleFullscreen();">Fullscreen</div>
</div>
</div>
</template>
<script setup="setup" lang="ts">
onMounted(() => {
const script = document.createElement("script");
script.onload = () => {
var extra_params = {
archive_location_filter: function( path ) {
return ("archive" + path + "");
},
engine_arguments: [],
custom_heap_size: 268435456,
full_screen_container: "#canvas-container",
disable_context_menu: true
}
Module['INITIAL_MEMORY'] = extra_params.custom_heap_size;
Module['onRuntimeInitialized'] = function() {
Module.runApp("canvas", extra_params);
};
Module["locateFile"] = function(path, scriptDirectory)
{
// dmengine*.wasm is hardcoded in the built JS loader for WASM,
// we need to replace it here with the correct project name.
if (path == "dmengine.wasm" || path == "dmengine_release.wasm" || path == "dmengine_headless.wasm") {
path = "HashSlashFrontend.wasm";
}
return scriptDirectory + path;
};
var is_iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
var buttonHeight = 0;
var prevInnerWidth = -1;
var prevInnerHeight = -1;
buttonHeight = 42;
buttonHeight = 42;
function resize_game_canvas() {
// Hack for iOS when exit from Fullscreen mode
if (is_iOS) {
window.scrollTo(0, 0);
}
var app_container = document.getElementById('app-container');
var game_canvas = document.getElementById('canvas');
var innerWidth = window.innerWidth;
var innerHeight = window.innerHeight - buttonHeight;
if (prevInnerWidth == innerWidth && prevInnerHeight == innerHeight)
{
return;
}
prevInnerWidth = innerWidth;
prevInnerHeight = innerHeight;
var width = 1280;
var height = 800;
var targetRatio = width / height;
var actualRatio = innerWidth / innerHeight;
//Downscale fit
if (innerWidth < width || innerHeight < height) {
if (actualRatio > targetRatio) {
width = innerHeight * targetRatio;
height = innerHeight;
app_container.style.marginLeft = ((innerWidth - width) / 2) + "px";
app_container.style.marginTop = "0px";
}
else {
width = innerWidth;
height = innerWidth / targetRatio;
app_container.style.marginLeft = "0px";
app_container.style.marginTop = ((innerHeight - height) / 2) + "px";
}
}
else {
app_container.style.marginLeft = ((innerWidth - width) / 2) + "px";
app_container.style.marginTop = ((innerHeight - height) / 2) + "px";
}
app_container.style.width = width + "px";
app_container.style.height = height + buttonHeight + "px";
game_canvas.width = width;
game_canvas.height = height;
}
resize_game_canvas();
window.addEventListener('resize', resize_game_canvas, false);
window.addEventListener('orientationchange', resize_game_canvas, false);
window.addEventListener('focus', resize_game_canvas, false);
EngineLoader.stream_wasm = "false" === "true";
EngineLoader.load("canvas", "HashSlashFrontend");
};
script.src = "/dmloader.js";
document.head.appendChild(script);
})
</script>
Now the next step is getting JsToDef to pass messages to the running game.