Bundling for HTML5 - specifically PWA on smartphone

I’m new to defold, so I’m fumbling with my igorance. I’m trying to deploy to HTML with an app desiged for 1280x720 to fit smartphone screens. I have 2 issues.

  1. When i preview on my desktop monitor and expand to full screen, or pull the browser to be wider/taller the click detection is completely thrown off.
  2. When i preview on my ihphone the graphics are scaled up x2.

I’ve been reading and researching and to be honest my head is spinning, whether to have DPI on or off, whether to scale/stretch/fit etc. I’ve tried virtually every permutation and these two problem persist. I just want my 1280x720 to filla mobile screen, and clicks to work, and on the desktop, if it goes fullscreen or the edges of the browser are shifted, for the clicks to work. I’m desperate for help. I’m also probably missing something blindingly obvious.

I’m also an idiot.

What does the code look like?

PROJECT SETTINGS/Bootatrap: default.render,

DISPLAY: 1280x720/DPI off/on(tried both!), fullscreen off/on (tried both)

HTML5: tried stretch, fit.

GAME SCRIPT:

local ih=require(“main.input_helper)

Gane script> init FN:

msg.post(“.”, “acquire_input_focus”)

msg.post(“@render:”, “use_fixed_fit_projection”, { near = -1000, far = 1000 })

Gamescript>On_input FN:

– NORMALIZE MOUSE/TOUCH INPUT TO DESIGN SPACE (1280x720)

if action_id \~= hash(“touch”) then return end
if not (action.pressed or action.released or action.repeated) then return end

local nx, ny = ih.to_design_xy(action)
if not nx then return end  -- ignore clicks in letterbox bars
action.x, action.y = nx, ny

if action.pressed then
	print("on input triggered")
	print("turn number is", globals.turnNumber)
-- Convert to world space using your existing RenderCam helper
	local screen_pos = vmath.vector3(action.x, action.y, 0)
	local world_pos = ray_helper.get_world_click_position("main:/camera_container#camera", screen_pos, 50)INPUT HELPER (code)

input_helper.lua

local M = {}

local DESIGN_W, DESIGN_H = 1280, 720

– Try “stretch” first. If not perfect, try “center”, then “bottom_left”.
local MODE = “stretch”      – “stretch” | “center” | “bottom_left”

local X_BIAS, Y_BIAS = 150,0 --x=50 wasnt bad

– Optional tiny bias (design pixels). Keep 0 unless you need 2–8px of nudge.
local Y_BIAS = 0

local function map_stretch(sx, sy, W, H)
local x = sx \* (DESIGN_W / W)
local y = sy \* (DESIGN_H / H)
return x, y
end

local function map_center(sx, sy, W, H)
local scale = math.min(W / DESIGN_W, H / DESIGN_H)
local vw = DESIGN_W \* scale
local vh = DESIGN_H \* scale
local vx = (W - vw) \* 0.5
local vy = (H - vh) \* 0.5
if sx < vx or sx > vx + vw or sy < vy or sy > vy + vh then return nil, nil end
local nx = (sx - vx) / vw
local ny = (sy - vy) / vh
return nx \* DESIGN_W, ny \* DESIGN_H
end

local function map_bottom_left(sx, sy, W, H)
local scale = math.min(W / DESIGN_W, H / DESIGN_H)
local vw = DESIGN_W \* scale
local vh = DESIGN_H \* scale
– viewport anchored at bottom-left (0,0)
if sx < 0 or sx > vw or sy < 0 or sy > vh then return nil, nil end
local nx = sx / vw
local ny = sy / vh
return nx \* DESIGN_W, ny \* DESIGN_H
end

function M.to_design_xy(action)
local sx = action.screen_x or action.x
local sy = action.screen_y or action.y
if not sx or not sy then return nil, nil end

-- Actual window/canvas size (game script safe)
local W, H = window.get_size()
if not W or not H or W == 0 or H == 0 then return nil, nil end

local x, y
if MODE == "stretch" then
    x, y = map_stretch(sx, sy, W, H)
elseif MODE == "center" then
    x, y = map_center(sx, sy, W, H)
else -- "bottom_left"
    x, y = map_bottom_left(sx, sy, W, H)
end

if not x then return nil, nil end
return x, y + Y_BIAS

end

return M

Oops… not sure why some of the code snippets have been treated as normal text and other parts as code inserts… not intentional!

You can enclose the code with three backticks on a single line:

    ```
    put your code here
    ```