Skip to main content

Known issues

This page gathers the known issues of JARU 0.9.7, in the order of the website and, in each section, the most serious first. Each item says what happens and what to do, and takes you to the page that explains it in full. When an issue is fixed, it leaves this page and its own.

Getting started and installation​

  • Run doesn't notice that the board carries the 0.9.6 VM. A program compiled with 0.9.7 stops at the first new instruction with the error “Unknown Opcode encountered”. After updating JARU IDE, click Flash Firmware on each board before sending it programs. See Flash the firmware and run.

JARU IDE​

The interface​

  • The Error List filters don't last. Every time the code editor analyzes the file again, the list shows everything again, even though the buttons still say “0 of …”. To apply them again, type in (Filter). See The interface.

Projects​

  • Cancel in the wizard closes the IDE. After Home › Project › New, Cancel closes the whole of JARU IDE, without asking. Nothing else is lost, because the project was already closed: open the IDE again. See Projects.

Code editor​

  • Find and Font do nothing, neither in the right-click menu nor in Edit. To search, use Ctrl+F; for the font size, Ctrl + wheel. See Code editor.
  • The search and replace boxes don't clear. “Search...” and “Replace...” aren't deleted when you click on them: delete them before typing. If you leave the replace box empty and click somewhere else, R and All replace with “Replace...”, and Ctrl+Z undoes it. See Code editor.
  • Back doesn't always take you right back to where you were. After a jump of less than 20 lines it goes past it, and the forward arrow takes you back; after a jump to another file, you sometimes have to click Back twice. See Code editor.

Image editor​

  • Deleting an open image with changes deletes it even if you answer Cancel. The editor asks whether to save its changes, and with Cancel it leaves the tab open, but the file is deleted anyway. Close it before deleting it. See Image editor.
  • The editor doesn't see changes made by another program, and Save overwrites them. Close the image in the editor before changing it elsewhere, and open it again afterwards. See Image editor.
  • Rectangle doesn't use Brush Size: its outline is always 1 pixel. For a thicker one, draw the sides with Line. See Image editor.

Sprite editor​

  • The editor's New Sprite doesn't check the name. With the name of a sprite that already exists, it opens it as if it were new, and if you save, you overwrite it. Create sprites with the explorer's New Sprite, which does warn. See Sprite editor.
  • With Offset X or Offset Y, clicks are off. A single click, Auto and the eyedropper take another spot: with an offset, cut with the marquee or with Cut All. And typing in those boxes doesn't move the grid until you click them. See Sprite editor.
  • Auto and Cut All don't use the color of the BACKGROUND swatch, but the one the eyedropper took or the one the editor detected when it opened the sheet. Take the background with the eyedropper right before. See Sprite editor.
  • Without Remove background, black is transparent in the game, even though the preview shows it. If the sprite has pure black that must show, tick Remove background with a background of another color. See Sprite editor.

Tilemap editor​

  • Old .gmap files stay. Compiling doesn't delete what was in Build/flash/Maps: if you turn off Include map in build, change a map's type, rename it or delete it, the old one is still there, and on the board it takes up space. Delete it by hand. See Tilemap editor.
  • A map with no file doesn't change size. On the map that Home › View › TileMap opens, Resize Map and Size do nothing. Save it first, or create the map with New TileMap. See Tilemap editor.
  • Tiles above 254. The editor lets you paint them without a warning, and then the compilation stops. Use tiles 0 to 254. See Tilemap editor.

Scene editor​

Rooms, canvas and Play​

  • Del with a layer selected in the tree deletes the selected objects, not the layer, without asking. To delete a layer, use the bin on its row or Delete in the tree menu; if it has already happened, Ctrl+Z brings the objects back. See Scene editor.
  • Generate writes the code of a read-only room. A room saved by a newer IDE opens read only (READ ONLY), and is neither saved nor played, but Generate still rewrites its .gen.aru and the shared runtime. Don't click Generate in those rooms. See Scene editor.
  • Play doesn't see every change to the assets. It only prepares them again if some image, sprite, map or music file has changed: it doesn't notice if you rename, move or delete one, nor Include in Build or Palette in the image editor. Compile with Build › Compile, which always prepares them, or delete Build/assets.stamp before Play. See Your first game with rooms and Image editor.
  • An object's eye takes it out of the game, and Ctrl+Z doesn't undo it. If you hide one by mistake, click the eye again. See Scene editor.
  • A layer's padlock and eye don't fully protect it. The marquee, Ctrl+A and the tree select its objects, and Place, Shape, Zone, Path and Paste put objects on the active layer even if it is locked. Before placing anything, check which layer is active. See Layers.
  • The canvas doesn't see the changes to a sprite or an image you retouch with the scene editor open: it shows them as they were. Close the editor window and open it again. See Scene editor.
  • Ctrl halfway through a drag makes the copy jump. Press Ctrl before you start dragging; if it has already happened, Ctrl+Z puts everything back. See Scene editor.

Layers​

  • The LAYER section keeps the previous layer. If you choose an object of another layer in the tree, touching a field of LAYER writes the old layer's values into the new one. Before touching it, click the layer's name in the tree; if it has already happened, Ctrl+Z. See Layers.
  • The canvas doesn't draw the sprites the way the game does. The game draws all the sprites together with the scene map, and the canvas draws each object layer in its place in the stack. For the canvas to show what you will see, put the object layers right above the scene map. See Layers.
  • The order of the sprites changes when one is destroyed: the last one of the list takes its slot, and from then on it is drawn before others it used to cover. Whatever must always be in front, put it on a tile or decor layer above the scene map. See Layers.
  • Deleting the scene map layer leaves the room without one until you open it again, and Generate and Play draw the sprites in front of every layer. Mark another tile layer with Scene map, or close the room and open it again. See Layers.
  • Offset, Scroll and Position take no negative values. A layer or an object to the left of or above the room shows 0, and if you change the other axis in its box, it jumps to 0. Move them with the mouse, with Move or with the arrow keys. See Layers and Objects.
  • Move can grab another layer in the margin: a click outside the room can drag a layer with Wrap instead of the active one. If the wrong one moves, Ctrl+Z. See Layers.

Objects​

  • PROPERTIES doesn't go into undo properly. Changing a value leaves no step, and Add with the name of a property that already exists sets it to 0 without warning. To change a value, edit it in the Value column. See Objects.
  • Body doesn't change on an image: it goes back to Visual, so an image cannot be a platform. Make a sprite with the image and place the sprite. See Objects.
  • Double quotes reach the game with a backslash: Boss "bad" arrives as Boss \"bad\". Don't use double quotes in names, properties or texts. See Objects.
  • Templates can only be handled with an object chosen: with nothing chosen, TEMPLATES is greyed out. Choose any object first. See Objects.
  • The names of the copies: when you duplicate or paste enemy2, the copy is called enemy22, not enemy3. If you number your objects, rename the copy. See Objects.

Behaviours​

  • An object's fifth behaviour isn't shown: it works in the game, but you cannot edit it or remove it. Give each object four at most; if it already has five, remove one of the first four and the fifth moves into its card. See Behaviours.
  • A Spawner with Every (s) at 0 creates copies every frame, up to Max at once: the cards don't check the minimums and maximums of the settings. Give it an interval greater than 0. See Behaviours.
  • Show a variable and Spawner keep working when you hide their object with the eye: the text is still written and the spawner keeps creating copies. To take them out of the game, remove the behaviour. See Behaviours.
  • A Spawner without a zone drops its copies where it was when the room loaded, even if it has moved, and on a zone they appear at its top left corner. Give it a zone in Inside zone, or use the Create from a template action with at the subject. See Behaviours.
  • With physics, Follow / flee doesn't stop the object when its target disappears: it keeps sliding. Turn it off when that happens, with the Turn a behaviour on or off action. See Behaviours.
  • The problems panel suggests Dynamic “to also fall”, and it doesn't fall: it floats down, very slowly. Use Kinematic, or Dynamic with Gravity scale at 0. See Behaviours.
  • Show a variable on a template does nothing, and the problems panel doesn't warn about it. Put it on an object placed in the room. See Behaviours.
  • List settings take whatever you type. A value that isn't on the list gives no error: the game uses the default one, and in the true or false ones, false. Always choose from the list. See Behaviours.

Rules and states​

  • Change a variable with a bool or string variable: use only set. With add, adding false doesn't turn a bool off, and with a string, subtract and multiply stop the game. See Rules and states.
  • In States, + Action... or + Transition... right after typing in a cell can write an empty value into another row. Click the list of states first and, after adding, check the values. See Rules and states.
  • With physics, rules can miss hits between two bodies that the physics pushes apart, such as two Dynamic ones: When two things touch and Touches a tag don't see them all. For hits between bodies, use sprite.onCollision in the object's code. See Rules and states.
  • Turn a behaviour on or off, on entering a state, doesn't turn the behaviour off if nothing else in the room turns it on or off. Do it with a rule: have the entry action change a variable, and a When a variable... rule turn the behaviour off. See Rules and states.
  • Tags, always written the same way, and never on a marker. The game tells enemy and Enemy apart, and a When two things touch rule with a marker never fires, even though the problems panel accepts them. For a marker, use When it enters a zone. See Rules and states.
  • A state machine on a shape or a marker doesn't reach the game, and the panel doesn't warn about it. Put machines on sprites or images. See Rules and states.
  • The problems panel misses some warnings, and gives some it shouldn't. It doesn't warn about Take health away on an object without Health, about Ask for another room to a room that doesn't exist, or about Create from a template with a template whose sprite you deleted; and it also checks the rules and behaviours that are off, which aren't generated. Check those cases yourself. See Scene editor and Rules and states.
  • Delete always deletes an action while the rule has any. To delete a rule, click Delete once for each action and once more for the rule. See Rules and states.
  • In VALUES IN THIS STATE, decimals take a point: with a comma, the cell goes back to what it had. See Rules and states.
  • The problems panel names rules by their place (“Rule 3”), and the WHEN list doesn't number them. Count them from the top. See Rules and states.
  • If you make Room logic taller, one SETTINGS grid covers the other. Make it shorter until you can see both. See Rules and states.

The room and the game​

  • A Game.json that cannot be read (edited by hand, or with a git conflict) leaves the Game tab read only, and the Build generates the game without its controls or its variables, without warning. If the tab says Read only, fix the file or get it back. See The room and the game.
  • A room has two names: that of its .scn file and the Name field of Room, and changing one doesn't change the other. If you rename the room, change both to the same name, and delete the .gen.aru with the old name. See The room and the game.
  • A variable name that starts with _ loses it in the code: _lives clashes with lives, and the generated code doesn't compile. Don't start variable names with _. See The room and the game.
  • Defaults doesn't ask: it replaces the controls with the five standard ones and clears their pins and gamepad buttons. If you click it by mistake, Ctrl+Z. See The room and the game.
  • Each click on the Rate (fps) arrows is one undo step. Type the number in the field. See The room and the game.

The code it generates​

  • Generate .aru off in a room your game imports: the game compiles and stops when it runs. Only turn it off in rooms the game doesn't import. See The code it generates.
  • In data mode, SceneUpdate and room.nextScene may not exist, and the game stops when it reaches those lines (Undefined variable). Take them out of your loop while your rooms have no rules, and if you use the I2C gamepad, call SceneInputRead() every frame. See The code it generates.
  • In data mode, import the rooms with double quotes and with their extension, as in import "Level1.gen.aru": otherwise the Build deletes that file and the game doesn't compile. See The code it generates.
  • Naming SceneLoad in any .aru of the project, even in a comment, turns data mode on. If you don't want it, don't write that name. See The code it generates.
  • In data mode, the music of Room › Music doesn't play: SceneLoad only leaves its path in room.music. Play it yourself after loading the room, with Sound.loadMusic(room.music) and Sound.playMusic(true). See The code it generates.
  • In data mode, the first Play of a room that is only data, after changing an asset, can fail because it doesn't find its .gen.aru. Click Play again. See The code it generates.
  • If the Build of the resources fails, the editor's Compile button leaves the status bar at “Compiling the game...”. The error is in Output. See The code it generates.

Music Tracker​

  • The grid doesn't check everything. The values of commands, a noise period above N255 or an Inst that doesn't exist aren't marked, and they stop the whole compilation. Click Validate (F9) before compiling. See Music Tracker.
  • Sus % is not in percent: it goes from 0 to 255, like Sus 0-255, and 128 is half. See Music Tracker.
  • With REC, the grid jumps to row 000 while each note you record is sounding. The note is written correctly, on the cursor's row. See Music Tracker.
  • Undoing a note entered with the keyboard takes two Ctrl+Z: the first one only takes the cursor back to the note. See Music Tracker.

GPIO simulator​

  • A CSV with decimals depends on Windows: the lines it doesn't understand are skipped without a warning. Write the decimals the way your Windows does: with a comma if Min and Max show as 0,0 and 3,3. See GPIO simulator.
  • The Phototransistor shows as digital in the table. The value the program reads is the one on the card. See GPIO simulator.
  • The generator's button stays at ■ Stop when a CSV ends without Loop. One click starts it again. See GPIO simulator.

Git​

  • A file changed after Stage only shows in Staged, and the commit takes the version you staged. Click Stage All before Commit. See Git.
  • A mistyped remote address stays, and Remote Config no longer shows. Change it from a console with git remote set-url origin <address>. See Git.
  • The panel doesn't update after a merge or after deleting a server branch. Click the refresh button. See Git.
  • The message box isn't empty: “Briefly describe the changes made.” is text, not a hint. Delete it before typing, or it goes into the commit. See Git.

I2C drivers​

  • The PCF8563 example, if you already had JARU installed: your copy of the driver still keeps the time in a variable called time, and time is a JARU function. Rename it. See I2C drivers.
  • The example's import in the Code tab isn't the project's. With the drivers in a type folder, like the factory PMU, RTC and Audio ones, the program doesn't compile: “Imported file not found”. Delete that line and keep the one from Inser Driver. See I2C drivers.
  • The factory BMP280 is just the template: it reads and writes registers, but it can't read the pressure or the temperature. You have to write those readings yourself. See I2C drivers.
  • Import and Export do nothing: they only show a message. Copy the driver's .aru by hand into the library folder, or out of it, and click Refresh. See I2C drivers.
  • Chip Name keeps the first letter of the name when you type Driver Name. Fix it before clicking Create or Generate with AI. See I2C drivers.
  • The pins the AI writes are lost when you reopen the manager, if the project's board has no I2C bus: the Code tab uses pins 10 and 11. Click Refresh. See I2C drivers.

Settings​

  • Debug and the scene editor's Play don't use the Windows configuration: they start the VM with whatever boot.cfg is already there, the one from the last Run on Windows or the one ESP32 Tools made for a board. Do a Run on Windows first. See Settings and update notices.
  • The Windows VM doesn't use QoS, Retain or the Will fields of MQTT: it publishes and subscribes with QoS 0 and without retaining. See Settings and update notices.

Boards​

ESP32 Tools: flashing and running​

  • Run almost always asks about unsaved changes (“The ESP32 configuration has unsaved changes”): with Flash Size on Auto detect, the IDE writes into it the size it reads from the board and doesn't save it. Answer Yes: with No, the boot.cfg comes from what you last saved, and with Cancel, Run stops without writing anything in the Output. See Flash the firmware and run.
  • Upload Program doesn't move the serial monitor aside: if it is open on that port, it can't write to the board. The same happens with Check Storage, Get Info, Generate and Get MAC. Close it first with Close Serial, or use Run, which does move it aside. See Flash the firmware and run.
  • Application File goes back to the main file: Run, Upload Program and Check Storage change it before they start, and the board always starts the main program. To make it start another one, make that one the main file in the project. See Board profiles.

Buttons, pins and gamepad​

  • On the ESP32-S31, if the gamepad doesn't answer, the game is left with no input. With the gamepad on and no control with a GPIO, the game doesn't use the USB keyboard. If you play with the keyboard, turn the gamepad off with Gamepad on, which becomes Gamepad off. See Buttons, pins and gamepad.

Display, sound, SD and network​

  • On the boards, MQTT doesn't repeat your subscriptions when it reconnects: when MQTT.isConnect() gives true again, subscribe again. And Time Send, in ESP32 Tools, does nothing. See Display, sound, SD and network.
  • On the ESP32-P4 and the ESP32-S31, IP Static doesn't use DNS 1 or DNS 2. If your program calls a server by its name, leave IP Static off. See Display, sound, SD and network.
  • Primary, under SD Card, changes nothing on the board: the default unit is always flash:. See Display, sound, SD and network.

Memory and limits​

  • readLine() gets nothing on the board: the IDE's serial monitor doesn't send what you type, and the program waits forever. It happens to the examples that ask for a value, such as CheckPrime, Factorial_ForLoop, FibonacciGenerator and Palindromes; try them on Windows, where they work. See Memory and limits.

The language and the compiler​

Syntax and operators​

  • Indexing what a call returns doesn't work: f(x)[0] stops the program with “This object type is not indexable.”, and map.keys()[0] closes the compiler. Store the result in a variable first. See Basic syntax.
  • and and or have the same precedence, and they are calculated from left to right: a or b and c is (a or b) and c. When you mix them, use parentheses. See Basic syntax.
  • ~ with a float or a boolean gives -1 without a warning. Use the bitwise operators only with integers. See Operators.

Functions, classes and structs​

  • A recursion of about 80 calls closes the VM without any message, and try doesn't catch it; the more variables the function has, the sooner it happens. Write functions that call themselves many times with a loop. See Functions.
  • From outside the class, remove, copy, clone, methods, properties, hasAttribute and setProperty call the VM's ones, not your methods with those names. Use other names. See Classes and objects.
  • Assigning a private property from outside gives no error: a.balance = 5 creates another property, public, with the same name, and the class's methods keep using the private one. Change it with a method of the class. See Classes and objects.

Lists, maps and arrays​

  • A list or a map written in one go that doesn't fit on the stack closes the VM, without any message, on the boards too. In the main program a list takes 252 items, or a map 127 pairs, and fewer inside a function: if your list goes over about 200 items, build it in pieces with append(), or use an array. See Lists, maps and arrays.
  • clone() of something with a cycle closes the VM without any message: a list that holds itself, two maps that point to each other, a child that keeps its parent. With cycles, use copy() or copy by hand what you need. See Lists, maps and arrays.

Errors, files and the compiler​

  • In the Output, the file of a syntax error doesn't go where it says “Parser”, but after “In file”. If you don't see the mistake on the line of the error, look at the one before. See Your first program.
  • exit with something that isn't an integer writes a meaningless code. Pass it an integer. See Errors and exceptions.

API reference​

Standard library​

  • On Windows, time() with a % code that doesn't exist closes the VM without any message, as in time("%Q"). Use the codes in the table. See Standard library.
  • vmerror() always returns 0, even when there have been errors. For exceptions, use try and catch; for error values, look at what each function returns. See Standard library.
  • ink() and paper() change no color on the Windows console, and give no error either. See Standard library.

Display​

  • On Windows, loadTFT doesn't use x or y: it stretches the image over the whole window. To make it look the same as on the board, make the frame the size of the screen. See Display.
  • On Windows, the view doesn't clip until the first update(): what you draw outside it before then shows. See Display.

Draw​

  • On Windows, line, circle, polygon and getPixel don't count from the view: with a view smaller than the screen, they come out shifted. Without a view, or with a view the size of the screen, it doesn't happen. See Draw.
  • On Windows, draw.bytes doesn't use x or y: it stretches the image over the whole window. On a board it is drawn in its place and at its size. See Draw.
  • draw.font and polygon don't respond to an error the same way on Windows and on the board. A font that doesn't exist throws an exception on Windows, and on the board it only writes the error on the serial monitor; a polygon of fewer than six numbers returns true without drawing on Windows, and an error value on the board. Use fonts 0 to 8 and polygons with three vertices or more. See Draw.

Bitmap​

  • Bitmap.new does nothing in this version. To make an image from the program, write it with writeHeader and writeLine and load it with load. See Bitmap.

Sprite​

  • Without a scene with physics, onGround() doesn't go back to false: once grid.hits sets it to true, it stays like that. Use it with a DYNAMIC body in a scene with physics. See Sprite.
  • spin turns all at once after a pause, and twice as much if you draw the sprite twice: the rotation is applied when the sprite is drawn, for the time that has elapsed. Draw each sprite only once per frame; before a long pause, set spin = 0 and set it again afterwards. See Sprite.
  • A collider with width, height or radius 0 is ignored without an error: the sprite keeps the previous one. Check the sizes before assigning them. See Sprite.

GridMap​

  • path, dMap and nearest connect both axes as soon as one has wrap. If you only want one axis, close the other one with a row or a column of walls. See GridMap.
  • On Windows, draw.tilemap doesn't see what clear changes and keeps drawing the old map. After a clear, do a set of any cell, such as map.set(0, 0, map.get(0, 0)). See GridMap.
  • count, has and find don't check the value: one outside 0 to 255 wraps around in a byte, and count(256) counts the 0s. Pass them values from 0 to 255. See GridMap.

Scene​

  • Removing a sprite changes the drawing order: the last one in the list takes its slot. If a sprite must always be seen in front, don't remove the others: turn them off with sprite.active = false. See Scene.
  • A stepRate of more than 4 times the frames per second goes in slow motion: each update() takes at most 4 steps. The scene editor lets you enter up to 240 in Step rate (Hz) and doesn't warn. See Scene.
  • Before the first update(), draw.scene doesn't draw the sprites that aren't near the (0, 0) corner. Call update() before drawing the scene. See Scene.

Sound​

  • setMusicVolume() before playMusic() is lost: playMusic() sets the song's volume again. Call setMusicVolume() after playMusic(). See Sound.

Input​

  • justPressed() and released() can miss presses if you check the inputs several times in the same frame: each new reading wipes out the edge of the previous one. Read Input.pressed() once per frame and work out the edges by hand. See Input.

GPIO​

  • On the ESP32-P4 and the ESP32-S31, a pin in GPIO.OUTPUT is output only: GPIO.read() always returns 0, and GPIO.onInterrupt() doesn't fire with what you write. If you need to know how you left the pin, keep it in a variable. See GPIO.
  • On Windows, resolution(bits) and frequency(hz) without a pin give ERR_INVALID_ARG_NUMBER. Always pass the pin. See GPIO.

I2C​

  • On the ESP32 and the ESP32-S3, a write of more than 128 bytes is cut: anything beyond 128 isn't sent, without warning. Split it into chunks. See I2C.
  • On the ESP32 and the ESP32-S3, a second init on the same port changes nothing: it keeps the earlier pins and frequency, and returns true. To change them, call close first. See I2C.

LED​

  • Colors and brightness, as integers. A decimal color counts as 0, with no error; in HSV, s and v aren't clipped outside 0 to 255; and on Windows, setBrightness with anything that isn't an integer sets the brightness to 255. Pass them as integers, with int() or div. See LED.

Power​

  • The Waveshare ESP32-S3-Touch-LCD-2.8 and the JaruCade lose their USB after the first Power.sleep(): the PC no longer sees them, and the IDE can't write to them. Don't use Power.sleep() on them; to recover them, restart them with the BOOT button held down and send them another program with Run. See Power.

File​

  • On Windows, seek without the b in the mode only goes to position 0: with any other, it throws ERR_INVALID_OPERATION. Open the file with "rb" to go to any position. See File.

Bytes​

  • Bytes.new without memory for that many bytes closes the VM, and try doesn't stop it. Check the size before creating the block. See Bytes.

JSON​

  • JSON.stringify rounds decimals to 6 significant digits: 1 / 3 comes out as 0.333333. If you need more, write the number as a string. See JSON.
  • JSON.parse reads some decimals with an error in the last digit: JSON.parse("1.68") == 1.68 is false. To compare decimals, check whether the difference is very small. See JSON.
  • JSON.parse("null") throws ERR_INVALID_VALUE: a lone null can't be read, although inside an object or a list it arrives as nil. If the text can be just null, catch the error with try. See JSON.

Timer​

  • On Windows, Timer.every(0) fires only once. Use an interval of 1 ms or more. See Timer.

Math​

  • asin, acos, atan, atan2, exp and log are missing: of the trigonometric functions there are only sin, cos and tan, and there are no logarithms or exponential. See Math.