Log In  


domske said:
> I never used CTRL+D. You could do this after the line you want to copy:
> - Enter for new line.
> - Shift + Arrow Up to select the line above.
> - CTRL + C to copy and CTRL + V insert again and again

This is also a bug though: this does not work in the picotron code editor for me (1.0d Mac) the way it works in every other WYSIWYG editor I can think of. The picotron editor trims the trailing line break so you end up with everything on one line.

P#144833 2024-03-28 13:37

As I mentioned in this post https://www.lexaloffle.com/bbs/?pid=144801#p the blit procedure of the Picotron implementation is using scaled units rather than pixels for width and height calculations, and while it appears to be correcting for this later so the window is properly centered (I have not yet figured out where exactly) the way it does that results in image blurriness when presented on a scaled display — and more importantly when Picotron calculates the closest divisible resolution it still uses scaled units, essentially missing the actual closest match and settling for much bigger borders than necessary.

While I believe there is a way to tell macOS that a program should not be scaled, macOS just runs it at a lower resolution and scales it up making it blurry, so it would be neat if this was fixed properly <3

P#144865 2024-03-28 16:56

I've encountered a bug where picotron is crashing, and not outputting it to the log file. I've narrowed it down to this piece of code:

function get_tile(x, y) -- Patch because mget always uses 0.map??
    local bmp = current_level[1].bmp
    local idx = x + y * level_width
    if idx < 0 or idx >= #bmp then
        return 0
    return bmp[idx] & 0x3fff -- Mask off flip bits

I'm initialising current_level and level_width with:

current_level = fetch("map/bonus.map")
level_width = 10

so it shouldn't be caused by nil values. This function was working fine, but now it just crashes.

EDIT: I've narrowed it down to this line:

local idx = x + y * level_width

No crash if I replace it with

local idx = 0

But it crashes when:

local idx = x

EDIT: I've found it! You can use bmp:get(x, y), and that does not cause a crash!

P#144893 2024-03-28 19:51 ( Edited 2024-04-05 21:39)

minor bug:
If you create a folder inside picotron and name it say 'feel' renaming it (inside picotron) to something like 'list' works alright but if I rename it to any words that share the original name picotron interprets it as a delete. For example renaming the folder 'feel' to 'feel v2' or 'feeling' ends up in picotron deleting the file (This is through picotrons file explorer).

~Using windows build v0.1.0d on Windows 10

P#144989 2024-03-29 15:19 ( Edited 2024-03-29 15:28)

I'm noticing some strange behaviour with tline3d (in 0.1d) when giving negative map coordinates, for example in this cartridge with one tile set in the map at (0, 0) it's being rendered four times when i render just the area around the origin of the map

local src
function _init ()
  src = fetch("map/0.map")

function _draw ()
  local W = 480
  local H = 270
  for i = 0, H-1 do
    tline3d (src[1].bmp,
      0, i, W-1, i,
      -4, i/H * 8 - 4, 4, i/H * 8 - 4)
P#145007 2024-03-29 17:31 ( Edited 2024-03-29 17:40)

in v0.1.0d I noticed an issue where the wrangle library wasn't either saving or loading (or both?) f64 userdata values.

I've made a script to reproduce simply (skipping wrangle since it's either in store or fetch)

--saves & loads fine
ud_a = userdata("u8",3)

--these don't survive save/load
ud_b = userdata("f64",3)

ud_c = vec(0.420,69.69)

    a_u8 = ud_a,
    b_f64 = ud_b,
    c_vec = ud_c

function _init()
    print("Storing: ")
    store("testfile.xyz", testobj)

    testobj = fetch("testfile.xyz")


function recursiveprint(t,depth)
    local prestr = ""
    for i=1,depth do
    for k,v in pairs(t) do
        local vstr = tostr(v)
        if type(v)=="userdata" then

        print(prestr.." "..k.." ___ "..vstr)

        if type(v)=="table" then
function udtostr(ud)
    local s="["
    for i=1,ud:width() do
        if (i<ud:width()) s..=", "
    return s.."]"

P#145032 2024-03-29 20:09

I don't know if this showed up already. The bug thread has become a bit long to read on a single evening. I managed to do the following:

For anyone who didn't spot at first glance: At "ring.x" there is some overlapping text.
I feel like this could be a cursed images meme.

P#145034 2024-03-29 20:37

Another round of "is this a bug"?
Been playing around with userdata. There isn't really a "memset" (but there is :copy) so I came up with the following... (I was also trying to use it so I could copy the default palette into it from memory and play about with it)

udata = userdata("u8", 128)

-- Note that 0xc000 is listed as "unused" in the gfx pipeline doc
-- I'm assuming that this segment is intended for loading up to 4 userdata "banks" into memory
memmap(0xc000, udata)

memset(0xc000, 0xff, udata:width())

assert(peek(0xc000) == 0xff) -- Works
assert(udata[0] == 0xff) -- Fails

Doesn't work though. I'm assuming that the mapping failed because the memory appears to be set correctly.

Ps. Just out of interest: What was the thinking behind :height() returning nil if the data is 1d? Wouldn't it make more sense to just return 1?

Edit (5 days later): Figured out what was going wrong. All maps under 0x10000 have to fill the 4k region or they wont work
Changed the address to 0x30000 and it works. The only question is, how big is the memory space?

E2: Just figured out how to "memset" the userdata way.
udata:copy(0xff, true)

P#145038 2024-03-29 21:26 ( Edited 2024-04-05 00:33)

Picotron version: 0.1.0d
Platform: macOS Monterey 12.7

Looks like playing a note in the instrument editor changes the picture of the waveform to a flat line. When key is released, the waveform comes back. This seems to happen no matter which wave is selected via the knob. Not sure if this is a bug or not and not a big deal but just FYI.

P#145066 2024-03-30 01:38 ( Edited 2024-03-30 01:41)

Ceil() function does not work correctly:

ceil(1) returns 1
ceil(1.0) returns 2 <--Error

Same for any N.0 float. Seems to work correctly in other circumstances.

LUA math.ceil(1.0) correctly returns 1 and can therefore be used as an alternative in the meantime.

Tested with version 0.1.0e on Windows 10

P#145078 2024-03-30 05:01 ( Edited 2024-03-31 01:24)

could not load any cart with a dash in the filename. for example:
will not load

using 0.1.0c on linux

P#145106 2024-03-30 10:28

Hello, last night I created some sprites for a game and the only thing I did was ctrl+s for every change, and in one of that saves, I received an alert with the message "/system/apps/map.64/main.lua:110: attempt to index a nil value (local 'gfx_data')"

No stacktrace given, just this message and my cart don't load the sprites anymore, just my scripts

Picotron version 1.0d

If it helps, here's the game file contents:

Edit: I would be happy if someone could tell me a way to recover the sprites

picotron cartridge // www.picotron.net
version 2

:: gfx/
:: gfx/0.gfx
:: gfx/.info.pod
:: main.lua
--[[pod_format="raw",created="2024-03-29 00:05:07",modified="2024-03-30 03:03:01",revision=426]]
function _init()
    px = 10
    py = 16
   idle = {8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9}
   run = {0,1,2,3,4,5,6,7}

    animCicle = 0
   actualAnim = idle
   actualAnimFrame = 1
   mirrored = false


function _draw()
    spr(actualAnim[actualAnimFrame], px, py, mirrored)

function _update()
    animCicle += 1

    if animCicle == 4 then
        animCicle = 0
        actualAnimFrame += 1

        if actualAnimFrame > #actualAnim then
            actualAnimFrame = 1

    if btn(0) or btn(1) then
        if actualAnim == idle then
            actualAnim = run
            animCicle = 0
            actualAnimFrame = 1
            mirrored = btn(0)
        if btn(0) then
            px -= 1
        elseif btn(1) then
            px += 1
    elseif actualAnim ~= idle then
        actualAnim = idle
        animCicle = 0
        actualAnimFrame = 1
:: map/
:: map/0.map
:: map/.info.pod
:: sfx/
:: sfx/0.sfx
:: sfx/.info.pod
:: .info.pod
:: [eoc]
P#145125 2024-03-30 15:33 ( Edited 2024-03-30 17:23)

New bug, I don't think this is what the patch notes meant, right? It only stretches vertically

Display size is also still miscalculated in HiDPI mode :(

P#145173 2024-03-30 21:29

Trying to access x/y less than 0 with the map() command crashes Picotron.

version 0.1.0e
o/s: Linux Mint 21.3

P#145177 2024-03-30 21:33

0.1.0e, macOS: Terminal cursor becomes invisible if the current text at the prompt extends beyond the first line and the cursor is not on the first line. Editing still works, and the cursor appears when moved to the first line even with long text at the prompt.

P#145182 2024-03-30 21:56 ( Edited 2024-03-30 21:58)

Having an issue on NixOS Linux where sfx.64 seems to be mapping notes based on letters entered and where are in the QWERTY layout even though we're using Colemak-DH and it should be mapping to scancodes - it seems to have appeared in v0.1.0d and is still here in v0.1.0e.

P#145183 2024-03-30 21:56

Obvious feature request: Terminal: Emacs-style editing key sequences. Ctrl-e for "end of line" is implemented. For example:

  • Ctrl-A: beginning of line (similar to Home)
  • Ctrl-Left: beginning of previous word
  • Ctrl-Right: beginning of next word
  • Ctrl-D or Delete: delete character under cursor

Of course what I actually want is the full GNU readline spec, with command history (Up/Down), history search (Ctrl-S/Ctrl-R to prompt), Ctrl-K to cut to clipboard from cursor to end of line, Ctrl-Y to paste. But I don't want to be greedy at the 0.1.0 stage. :)

I also don't want to go too far in the direction of a traditional (arcane) shell. Terminal copy/paste could just as easily work similarly to the code editor: Shift + cursor movement (by char, by word, etc.) could select, and the usual copy/cut/paste keyboard keys could do their thing, just limited to the context of a line.

I'm curious how mouse select might work in the terminal. Despite sharing the display with graphics, it looks like it's potentially smart enough to mess with text without interfering with graphics: text has a position and a logical line arrangement, could be the subject of mouse events.

P#145186 2024-03-30 22:11

fwiw: Right-shift as magnifier is a choice. 😅 I routinely use both shift keys to type and the magnifier keeps popping up unexpectedly. It's cool that it's accessible and built-in, but this option is a bit distracting. (I'm currently using the proposed custom keymap to restore Alt on macOS, if that makes a difference.)

P#145187 2024-03-30 22:14

This is perhaps more a feature request than a bug report, but the traceback in the event of a runtime error doesn't show the frames of the user's program, it shows internal Picotron functions, which isn't useful to the end user when debugging.

Here is a program with a small bug as an example

function _update()

function a()
    local foo = b()

function b(input)
    return 1 << input

The bug is that b() is not given an input when called inside function a(), which will lead to an error when attempting to shift. When this code is run, Picotron gives the following error.

/ram/cart/main.lua:11: attempt to perform bitwise operation on a nil value (local 'input')
stack traceback:
    /system/apps/terminal.lua:97: in upvalue 'run_cproj_callback'
    /system/apps/terminal.lua:524: in function '_update'
    /system/lib/foot.lua:53: in local 'func'

The functions listed in the traceback aren't relevant to the developer, but more importantly don't give the user's trace leading up to the call in function b(). This is a pretty obvious example to fix, but if b() had been called in a dozen places across multiple files, it can be quite the chore to discover how nil had been passed in.

For reference, this is the error message you get when you run that code in Lua 5.4

lua: test.lua:11: attempt to perform bitwise operation on a nil value (local 'input')
stack traceback:
    test.lua:11: in function 'b'
    test.lua:6: in function 'a'
    test.lua:2: in function '_update'
    test.lua:14: in main chunk
    [C]: in ?

This is what I would expect to see, the traceback notes that we hit a bug on line 11, via line 6, via line 2, and so on. From here I can directly begin to diagnose the issue, rather than first having to figure out where b was even called from.

P#145188 2024-03-30 22:23

Picotron version: 0.1.0e
Platform: macOS Monterey 12.7

Every time I start Picotron, after the boot screen I get a 1-2 second flash of the main code editor window, then it switches to my actual desktop.

P#145212 2024-03-31 04:56

Picotron version: 0.1.0e
OS: Windows 10

All of sfx above 63 are filled with C0 00 000 and will not play even if you replace the notes or change settings.

P#145248 2024-03-31 14:39


  • Now the { (ALTgr + 7) works. But it also triggers "captured label".
  • The screen is not scaled with original ratio. It's stretched.
  • Monospace font for the code editor would be great.
  • How to define custom colors in game / editor? Btw. show color id on mouse hover like in Pico 8.
  • How secure / sandboxed is Picotron? This is an important question when it comes to running cartridges and having internet features. The host system, like the file system, must not be accessible. Just a concern.

Consider to make this project available on an issue tracker like GitHub, GitLab, Forgejo, etc. This does not mean open source. The repo can only contain a readme.md with the issue tracker, where you can better manage the bugs. E.g. avoid duplicate reports. But you could also consider to make this open source and monetize via donation etc. Unit tests etc can also help to avoid regressions. But please don't get me wrong. It's just well-intentioned advice. It's ok if the forum is sufficient as a bug report for you. :)

P#145273 2024-03-31 18:21

Picotron version: 0.1.0e
OS: Windows 10

Similar to the above, all instruments above 15 are empty with no way to modify them. Attempting to use them in an SFX results in silence. (In a saved cart from an older version, this also affected any instruments above 7.) You can fix this yourself by copying an instrument from a lower slot, and then pasting it into a higher slot. (This workaround sadly does not work for the issue @fantasticfox posted.)

P#145274 2024-03-31 18:32

Putting your cursor at the end of some text in the code editor, then shift+clicking the cursor to the start should highlight the section inbetween. Instead, it highlights all of the text to the left of the shift+click. Also, it's great that we can change the spritesheet in the map editor, but only to the indexed gfx files (0.gfx etc). Maybe clicking on it could open up filenav to choose a different one? I also can't find a way to use different map files in mget(). (and the function I made to do that just crashes picotron with no log file, see my earlier post.)

P#145275 2024-03-31 18:33 ( Edited 2024-03-31 18:37)

Windows picotron 0.1.0e

If I use the stretch option as you can see Picotron doesn't stretch how it should, I think it's a known issue, but it works perfectly on macOS 12.5

P#145295 2024-03-31 21:49 ( Edited 2024-04-01 01:15)

It seems that fetch("http://whatever") will always cache the result. Is there a way to tell it not to? You can update the cache by adding a query string to the end of the URL, but it would have to be unique every time.

P#145299 2024-03-31 22:11

Windows 11 with Picotron 0.1.0e

I've got a strange error today:

I didn't understand until I load the lua file in VSCode:

function _draw()

    for comma   nd in all(Game.pending_commands) do

A space has been created in the "command" word but I can't see it in the picotron editor !

P#145302 2024-03-31 22:29 ( Edited 2024-03-31 22:31)

For the resolution issue, this seems to work reliably for me:

int closest_size(int native, int software) {
    return max(software * (native / software), software);

void get_dest_rect(SDL_Rect *rect, int w, int h) {
    int closest_w = closest_size(w, 480);
    rect->x = (w - closest_w) / 2;
    rect->w = closest_w;
    int height = closest_w * 270 / 480;
    rect->y = (h - height) / 2;
    rect->h = height;

    if (rect->h > h) {
        int closest_h = closest_size(h, 270);
        rect->y = (h - closest_h) / 2;
        rect->h = closest_h;
        int width = closest_h * 480 / 270;
        rect->x = (w - width) / 2;
        rect->w = width;

But actually patching something like this into Picotron does not work correctly, and I double checked every cpu instruction. It's as if SDL isn't in HiDPI mode in the first place, SDL_RenderCopy is in itself using low resolution pixels. That would also explain why picotron appears blurry on macOS.

When I leave out the SDL_WINDOW_ALLOW_HIGHDPI flag in my sample code I get results consistent with Picotron — It chooses too low for the closest resolution and appears blurry.


I spent 2 DAYS staring at the assembly and replaced entire procedures, and all I had to do was patch the flags for SDL_CreateWindow:

It works correctly — sharp, centered and without oversized borders.
The bug was hiding in plain sight all along.

@zep you need to add the flag in SDL, the NSHighResolutionCapable setting in info.plist doesn't do anything as far as I can tell :)

You also need to switch SDL_GetWindowSize to SDL_GetWindowSizeInPixels since they will no longer be the same, and look into cursor position code as it seems to be hardcoded to the lower resolution somehow.

P#145298 2024-03-31 22:33 ( Edited 2024-03-31 23:01)

@Fenouil That's a tab! tabs are handled interestingly in Picotron, because the width aligns to a grid, so it would look like this:

a   b
aa  b
aaa b

The above block is what it would look like with 1 tab between the last a and the first b. The solution would be to make tabs always a fixed width, instead of aligning to a grid.

P#145303 2024-03-31 22:49

@Soupster I don't know for sure if this works, but a trick I've used in a different context before for cache busting is to add an arbitrary query string to the URL. For example, if fetch("http://whatever") is getting cached, you could try appending a random number to the end like so:

local nocache = flr(rnd() * 1000000000)
P#145308 2024-04-01 00:55

@oconnerj Yes, I went over that in my comment, but it would be nice to have an optional argument to disable caching, for simplicity.

P#145327 2024-04-01 03:36

@Soupster Whoops, apologies. Not sure how I missed that in your original comment. Agreed, having an optional argument to disable the caching would be great.

P#145328 2024-04-01 03:50

a behavior i found in file navigation, should probably be fixed:

you can left click and then right click directly after, and it will count as a double-click AND open up the right-click menu. this happens on both desktop and file explorer.

similarly, you can click once on one file, and click once on another directly after, and it will count as a double-click on the last file. this only happens on file explorer, desktop works as intended.

P#145355 2024-04-01 10:31

0.1.0e - the added "gfx bank selection" input in the map editor doesn't appear to do anything for me.

I have a project with multiple gfx files and it still only wants to use tiles from 0.gfx.

EDIT: wait this DOES work, but only when my gfx files are named numerically (1.gfx works, but world_tiles.gfx does not work)

P#145361 2024-04-01 13:28 ( Edited 2024-04-01 14:08)

Not exactly a bug since it is written in the spec, but if the vertical resolution was 272 we could divide it by 16/8 (also, real 480x272 screens exists)

vid(0) 480x270 -> 480x272 (+2 pixel, can be divided by 16)
vid(3) 240x135 -> 240x136 (+1 pixel, can be divided by 8)
vid(4) 160x90

P#145365 2024-04-01 13:48 ( Edited 2024-04-01 15:32)

Mac OS 12.5 intel - Picotron 0.1.0e

Happend for the second time tonight...

As you can see, code editor froze and I cant use it no more, it happend right after I pasted some code I found on the web into Picotron. If I load a new cart it works

P#145409 2024-04-01 22:53 ( Edited 2024-04-02 12:21)

Unfortunately I cannot use picotron with Windows defender activated.

The exe is flagged as a virus (Behavior:Win32/DefenseEvasion.A!ml), and it does not even allow me to download the zip file :(

I presume and hope this is a false positive since I have run it on my machine.

P#145451 2024-04-02 09:52

super minor bug but holding down ctrl+S causes a bunch of slowdown, presumably from saving every time the keyboard ticks.

(windows, 0.1.0e)

P#145456 2024-04-02 11:00

Mac OS 12.5 intel - Picotron 0.1.0e

Update on Picotron freezing when pasting code from outside the workstation

Runtime Error:

If I press ESC then it freezes and gives me this strange bug.

I can still navigate to other parts of Picotron (I can even save from the terminal or with CMD+S) but the code editor keeps staying like that. It doesn't happen everytime I paste "outside" code so I don't know what could be the issue

P#145463 2024-04-02 12:20 ( Edited 2024-04-02 12:22)

Windows 10

When I get some "Runntime Error" this happens! Crash, mouse pointer trail, not responding ESC!
btw: WHen I stop program ESC it not show the terminal prompt on first ESC press.

P#145487 2024-04-02 15:43 ( Edited 2024-04-02 15:46)

Different behavior when you ctrl-r a loaded cart vs double clicking a .p64. The issue we noticed was for instance in a button testing program it would work fine when launched with ctrl-r but if you double click the .p64 version there was no input detected.

The issue ended up being that there was no _update function. Just by adding an empty function _update() end the .p64 double click version worked. I know a lot of us just use _draw and skip _update for testing things. I would think ctrl-r and double clicking should ideally function the same. I'm not sure if this is intended functionality but wanted to report it to zep.

P#145523 2024-04-02 21:19

@Souspter Oh yes I didn't see it! I think the tab can be aligned to the grid but with a minimum width. If the tab is less than this minimum, then it exceeds the grid.

P#145524 2024-04-02 21:46

picotron.exe is infected with Trojan.Generic.35536287

P#145553 2024-04-03 07:43

Thank you for all the bugfixes so far. As a reward, please have some more bug reports.

Linux version, v0.1.0e:

  • In the terminal, pressing the Delete key while the block cursor is over a character does not delete the character, as one would expect. Backspace works normally.
  • Sound is still choppy and crackly.

Web player / website, on Firefox, Ubuntu 23.10:

  • Pressing up and down on the keyboard scrolls the window up and down. This doesn't happen in the Pico-8 player.
  • Sound is still a little flaky.
  • BBS link on main page and top bar has no trailing slash, but this redirects to a URL with the trailing slash, and which begins with http: instead of https: which can lead to a redirect loop in Firefox if automatic HTTPS upgrading is enabled. The solution is presumably to fix the redirect to start with https: instead of http: and/or add a slash to the link since that appears to be the canonical URL anyway.
P#145585 2024-04-03 17:46

Windows 11
Picotron 0.1.0e

For a moment I though I lost again my data, but now the bug is that when I load the cartridge, only the code tab opens, the gfx/map/sfx tabs shows "[ empty workspace ]"

Clicking in the new tab and selecting the /ram/cart/0.gfx opens the sprites correctly.

When I click ctrl+r, the game runs and don't stop anymore, if I click ESC, I can cycle the workspaces, but when I go to the terminal, the game is still running

Dont know when it started, but the behaviour is consistent with my p64 file

P#145699 2024-04-04 18:39 ( Edited 2024-04-04 18:42)

@marioolofo same for me..
Normaly it supposed to stop with a promp on first ESC press. Normaly it happens when we first use _draw or when we first start new card and code from scratch.

P#145734 2024-04-04 22:57 ( Edited 2024-04-05 06:09)

@BGelais what do you mean by "strat our code from scratch"?
EDIT: yesterday I was tired, now I read correctly, you mean a fresh cartridge, I got it!

I found out that my code have some poke() that I imported from PICO-8 to address 0..8k, and when this code runs, it messes up the stop with ESC

When I comment the poke(), the code run and stops correctly, but still my gfx/map/sfx don't load automatically

P#145738 2024-04-04 23:29 ( Edited 2024-04-05 14:13)

Windows 10
Picotron 0.1.0e

Just an interesting thought about userdata.
Picotron currently doesn't seem to like to convert between userdata types.

In a recent experiment to determine whether a value would overflow before being converted or whether it would be converted first, I found out that the original userdata wasn't taken into account at all.

u1 = userdata("u8", 1)
u2 = userdata("i16", 1)

u1[0] = 0xff

u1:add(8, u2)

--Final value of i16 userdata is "8"
assert(u2[0] == 8)

It works fine if you :copy it over though.

P#145997 2024-04-07 21:02

vid(3) (and i guess vid(4)) dont work in wallpapers.

P#146006 2024-04-07 23:35 ( Edited 2024-04-07 23:36)

Just because I mistakenly put a slash at the beginning of a line when I ran my cart it just showed the terminal without any error message! And I thought i had corrupted my project...

(macos 12.5 intel)

P#146016 2024-04-08 02:04

[Please log in to post a comment]