Troubleshooting
Find what you see below, then its likely causes, each with its fix and the page that explains it.
Nothing shows up
- The canvas is not mounted.
datumhue.draw.new,datumhue.image.newanddatumhue.scene.newmake something to draw on, and show nothing by themselves. Show it withDrawCanvas:mount,Image:mountorScene:mount. - The drawing is off the canvas. A canvas puts
(0, 0)in its middle, with y pointing up, so a shape at(320, 240)on a 320 by 240 canvas is outside it. See Coordinates and units. - The app is a service app.
datumhue run --service, orservice #truein a manifest, runs an app with no window at all. See How your app runs.
Shapes draw in the wrong order
Shapes made without a depth stack in the order you made them, the newest
on top. To choose the order yourself, give a shape's pos a z with a
vec3: a larger z draws in front, whenever the shape was made. See
Draw shapes and text.
App exits right away
- A service app has nothing left to do. A service app ends as soon as nothing is registered, so a script that only prints ends when its last line runs. Register what keeps it going, such as a timer or a subscription, or run it as a UI app. See How your app runs.
- Its script raised an error. The log shows the error and its
traceback, and
datumhue runexits with a failure code. See When a callback errors.
App stops responding or waits forever
- A callback is waiting for a result that never comes. A suspending
call waits with no time limit: for an image that never loads, or for
an answer to
datumhue.app.request_permissionnobody gives. While it waits, your app's other callbacks wait behind it, so clicks seem to do nothing. Do not pause for slow work: keep its handle, and react inOp:on_done, or checkOp.statefrom a timer. See Waiting. - A loop in a callback never ends. Your app runs one callback at a time, so the loop holds back every other callback of your app. Do a long job a piece per frame, in the per-frame handler.
A callback stopped and the app closed
An error escaped one of your callbacks, which ends the whole app. The
log names the app and shows the error with its traceback. Call the part
that can fail with pcall inside the callback, and handle the error
there. See When a callback errors.
A subscription keeps firing, or a service app never ends
Dropping the handle a subscribe call or a timer returns does not stop
it: the callback keeps firing, and keeps a service app alive. Keep the
handle and call Subscription:unsubscribe or Timer:unsubscribe when
you are done.
App:on_end keeps a service app alive too, until it runs or you clear it
with nil. To end the app outright, call datumhue.app.terminate. See
How your app runs.
A moved body is flung
Moving a dynamic body yourself puts it in its new place with the speed it had. A dynamic body you move with a tween keeps falling under gravity between moves, gathers speed, and flies off when the tween ends. Move a kinematic body instead, to carry what rests on it; a static body you move pushes what touches it, without carrying it. See Bodies, joints and collisions.
A body nested in another passes through it
A static or kinematic body made as a child of a dynamic one, in its
group or under its scene node, rides along with the nearest dynamic body
above it, a physics step behind. It never collides with that body or
senses it, but still collides with everything else. To have the two
collide, make the inner body a sibling of the dynamic one, not its
child; to hold two bodies together, join them with
datumhue.physics.add_joint. See
Bodies, joints and collisions.
Keys don't reach my game
- Focus navigation has them. While your app shows a widget that
takes focus, the arrow keys, the D-pad, the left stick and gamepad A
and B move focus and press widgets. Set
datumhue.ui.focus_navigationtofalseto read them yourself. - A text field has focus. A focused text field takes the keys it types with.
- Your app is not focused. An app in the background reads every key
as up. Click into your app, or check
datumhue.app.is_focused. - A window manager reserved the shortcut. A key chord a window
manager grabbed with
datumhue.wm.grab_inputnever reaches your app. - You listen for keys, but press a gamepad.
datumhue.input.on_keyhears the keyboard only; hear the gamepad withdatumhue.input.on_button.
See Input, focus and Back and Read keys, mouse, touch and gamepads.
Escape or B doesn't go back
- Focus navigation is off. With
datumhue.ui.focus_navigationset tofalse, Escape and gamepad B are your app's own keys and make no Back. Read them yourself, or turn focus navigation back on. - Nothing in your app takes the request. Give the screen that should
close a cancel handler with
UiElement:on_cancel, or make your router withpop_on_cancel = true. A request your app leaves goes to the window manager.
See Handle Back.
Sizes look wrong at another zoom
A position or size in the window's own pixels was mixed with one in UI
px. datumhue.input.mouse_position,
datumhue.input.touches and the window_resized event are in the
window's own pixels, which the zoom does not scale; UiElement.bounds
and every size you give a widget are in UI px. Use
datumhue. or UiElement:mouse_position for
the pointer, and UiElement:on_resize on datumhue.ui.root for your
own size. See Coordinates and units and
Fit any window size.
Reading a result raises
- The work is not done yet. A handle's result cannot be read until
its work is done. Wait with
Op:readyfirst, withdatumhue.readyfor several handles, or read it insideOp:on_done. - The work failed.
Op:readyraises the operation's error. Call it insidepcallto handle the failure.
See Waiting.
Require can't find a module
The error names the file it looked for: looked for lib/x.lua.
- You ran the script file, not the package.
datumhue runof a package'sinit.luaalone has nolib/to load from. Run the package's folder instead. - The name is not its path under lib/.
require("ui.toolbar")loadslib/ui/toolbar.lua. A name never includeslib,.luaor a relative./. - A dependency keeps the module private. A dependency with an
exportslist answers only for the modules it lists, and the error names them.
A call raises a permission error
- Your app lacks the permission. A package asks for permissions in
its manifest's
capabilities, and an app started by another app holds only what that app passed on. A script run withdatumhue runholds them all. - A folder was not granted.
datumhue.args.dirsholds only the folders the launch granted; reading one that is not there raises "attempt to index a nil value". Grant it with--dir NAME:PATH. - The folder is read-only. Writing through a
--dirgrant raises; grant it with--dir-rwto write. - The folder was picked in a browser that keeps it read-only. Some
browsers do not let a web page change the person's files. A folder
picked in one of them is read-only, and
Dir:modereturns"r"for it. Let the person save the file with a save button instead; see Picked files and folders in some browsers.
See Permissions and capabilities.
In a browser, nothing happens after a gamepad press
A browser lets a page open a link, a file dialog or a sign-in window, copy to the clipboard, or go full screen only right after a tap, a click or a key press. A gamepad press does not count.
When your app asks for one of these after a gamepad press, DatumHue shows a Continue chip in the middle of your app. The operation runs when someone taps, clicks or presses Enter on the chip; Escape, B or Back dismisses it, and the operation does not happen. Your app needs no code for this. See Fit any window size.
See also
Reference used on this page: datumhue.draw.new datumhue.image.new datumhue.scene.new DrawCanvas:mount Image:mount Scene:mount datumhue.app.request_permission Op:on_done Op.state Subscription:unsubscribe Timer:unsubscribe App:on_end datumhue.app.terminate datumhue.physics.add_joint datumhue.ui.focus_navigation datumhue.app.is_focused datumhue.wm.grab_input datumhue.input.on_key datumhue.input.on_button UiElement:on_cancel datumhue.input.mouse_position datumhue.input.touches UiElement.bounds datumhue.input.app_mouse_position UiElement:mouse_position UiElement:on_resize datumhue.ui.root Op:ready datumhue.ready datumhue.args Dir:mode