This makes me think you have some kind of display scaling going on with a 125% scale. 1280*1.25 = 1600 and 800*1.25 = 1000. What does window.get_display_scale() return?
I’m super curious to go test after work if this also sorts out the issue I had a few months ago with a parallax background getting deleted too soon on web platform…
Do you think it would be worth it for me to go find a few places in documentation where it may make sense to warn people about this? Maybe here and in the APIDOC for get_size()?
Decided that before I go and spread more confusion by updating documentation, I should first try to make sure I completely understand what’s going on. I found more issues related to this in my Gunit testing library’s own test code - seems my confusion is two-fold:
window.get_size(): when should I divide by window.get_display_scale() and when not?
Mouse / touch input: when to use action.x and action.y versus action.screen_x and action.screen_y and depending on which, when do I use window.get_display_scale()?
To help clear it up I created a little example project (for now provided here as zip, but tell me if it is worth getting it into Git as an official example): defold-display-scaling-example.zip (631.1 KB)
Unfortunately, I still haven’t figured out a clear answer that would let me say: “always do this and it will work correctly under every circumstance”. For now I’ll share the results of this morning’s testing here and come back to it again a bit later…
Windowed, 100% scale
Everything works as expected and none of this matters:
Fullscreen (via defos), 100% scale
I realize defos is an extension, so not official, but interesting to note at least - if I toggle to fullscreen with defos.toggle_fullscreen() things get very broken - placing things with action.x is mostly correct, but everything else is way off:
TL;DR: action.x and action.y are the action positions in virtual coordinates, which are needed to detect clicks in the GUI using gui.pick_node(). Most likely, you don’t need them for any manual calculations.
Use action.screen_x and action.screen_y instead.
Full Explanation
The engine does the following steps to get these values:
Raw Input: Defold receives mouse/touch coordinates in actual screen pixels (where the user clicked).
Virtual Scaling: These pixel coordinates are scaled to match your game’s virtual resolution (set in game.project under display.width and display.height).
Pixel Centering: A 0.5 pixel offset ensures coordinates point to the center of pixels rather than their corners.
What This Means for You
action.x and action.y are always in your game’s virtual coordinate space.
If your game is set to 960x640 virtual resolution, coordinates will be 0–960 horizontally and 0–640 vertically.
This works regardless of the actual screen size — a 1920x1080 screen or a 480x320 screen will both give you the same virtual coordinates.
What Should You Use Then?
It’s better to use action.screen_x and action.screen_y for everything you want to calculate yourself.
Screen space is a universal space that can be used to convert different coordinates between different systems. For example:
From world to GUI
From GUI to world (depends on camera setup)
From a GUI node with one scale setting to a GUI node with another
We don’t have such functions for go because they highly depend on the camera/render_script setup. (We plan to add them under the camera.* or go.* namespaces.)
In the meantime, here are examples of helper functions you can use: