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+Zundoes 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
.gmapfiles stay. Compiling doesn't delete what was inBuild/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
Delwith 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+Zbrings 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.aruand 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.stampbefore Play. See Your first game with rooms and Image editor. - An object's eye takes it out of the game, and
Ctrl+Zdoesn'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+Aand 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.
Ctrlhalfway through a drag makes the copy jump. PressCtrlbefore you start dragging; if it has already happened,Ctrl+Zputs 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
0without 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 asBoss \"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 calledenemy22, notenemy3. 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
trueorfalseones,false. Always choose from the list. See Behaviours.
Rules and states
- Change a variable with a
boolorstringvariable: use onlyset. Withadd, addingfalsedoesn't turn abooloff, and with astring,subtractandmultiplystop 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.onCollisionin 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
enemyandEnemyapart, 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.jsonthat 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 saysRead only, fix the file or get it back. See The room and the game. - A room has two names: that of its
.scnfile 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.aruwith the old name. See The room and the game. - A variable name that starts with
_loses it in the code:_livesclashes withlives, 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,
SceneUpdateandroom.nextScenemay 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, callSceneInputRead()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
SceneLoadin any.aruof 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:
SceneLoadonly leaves its path inroom.music. Play it yourself after loading the room, withSound.loadMusic(room.music)andSound.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
N255or 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
000while 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,0and3,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, andtimeis a JARU function. Rename it. See I2C drivers. - The example's
importin 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
.aruby 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.cfgis 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.cfgcomes 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()givestrueagain, 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.”, andmap.keys()[0]closes the compiler. Store the result in a variable first. See Basic syntax. andandorhave the same precedence, and they are calculated from left to right:a or b and cis(a or b) and c. When you mix them, use parentheses. See Basic syntax.~with a float or a boolean gives-1without 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
trydoesn'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,hasAttributeandsetPropertycall 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 = 5creates 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, usecopy()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.
exitwith 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 intime("%Q"). Use the codes in the table. See Standard library. vmerror()always returns0, even when there have been errors. For exceptions, usetryandcatch; for error values, look at what each function returns. See Standard library.ink()andpaper()change no color on the Windows console, and give no error either. See Standard library.
Display
- On Windows,
loadTFTdoesn't usexory: 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,polygonandgetPixeldon'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.bytesdoesn't usexory: it stretches the image over the whole window. On a board it is drawn in its place and at its size. See Draw. draw.fontandpolygondon'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; apolygonof fewer than six numbers returnstruewithout 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.newdoes nothing in this version. To make an image from the program, write it withwriteHeaderandwriteLineand load it withload. See Bitmap.
Sprite
- Without a scene with physics,
onGround()doesn't go back tofalse: oncegrid.hitssets it totrue, it stays like that. Use it with aDYNAMICbody in a scene with physics. See Sprite. spinturns 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, setspin = 0and 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,dMapandnearestconnect 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.tilemapdoesn't see whatclearchanges and keeps drawing the old map. After aclear, do asetof any cell, such asmap.set(0, 0, map.get(0, 0)). See GridMap. count,hasandfinddon't check the value: one outside 0 to 255 wraps around in a byte, andcount(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
stepRateof more than 4 times the frames per second goes in slow motion: eachupdate()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.scenedoesn't draw the sprites that aren't near the (0, 0) corner. Callupdate()before drawing the scene. See Scene.
Sound
setMusicVolume()beforeplayMusic()is lost:playMusic()sets the song's volume again. CallsetMusicVolume()afterplayMusic(). See Sound.
Input
justPressed()andreleased()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. ReadInput.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.OUTPUTis output only:GPIO.read()always returns0, andGPIO.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)andfrequency(hz)without a pin giveERR_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
initon the same port changes nothing: it keeps the earlier pins and frequency, and returnstrue. To change them, callclosefirst. See I2C.
LED
- Colors and brightness, as integers. A decimal color counts as 0, with no error; in HSV,
sandvaren't clipped outside 0 to 255; and on Windows,setBrightnesswith anything that isn't an integer sets the brightness to 255. Pass them as integers, withint()ordiv. 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 usePower.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,
seekwithout thebin the mode only goes to position 0: with any other, it throwsERR_INVALID_OPERATION. Open the file with"rb"to go to any position. See File.
Bytes
Bytes.newwithout memory for that many bytes closes the VM, andtrydoesn't stop it. Check the size before creating the block. See Bytes.
JSON
JSON.stringifyrounds decimals to 6 significant digits:1 / 3comes out as0.333333. If you need more, write the number as a string. See JSON.JSON.parsereads some decimals with an error in the last digit:JSON.parse("1.68") == 1.68isfalse. To compare decimals, check whether the difference is very small. See JSON.JSON.parse("null")throwsERR_INVALID_VALUE: a lonenullcan't be read, although inside an object or a list it arrives asnil. If the text can be justnull, catch the error withtry. 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,expandlogare missing: of the trigonometric functions there are onlysin,cosandtan, and there are no logarithms or exponential. See Math.