What is a Pico 8 Console?

My only interest would be a PICO 8 console running on ESP32, there will be no color Arduboy as such.

3 Likes

Is pico8 available for the ESP32 already? This also sounds like a nice device.

AH! Being thinking about that. The hardest part about this is the Lua VM. I first looked at eLua, but I think this might not entirely be the right direction (ref: Link). Since PICO-8 uses a subset of Lua and has their own extension, I have come to believe that a very PICO-8 specific minimalist Lua interpreter and single stack frame might be the way to go.

Honestly, a clean and new game engine (hypothetically say, Arduboy3) with C++ and PICO-8-esque api + constraints (128x128 8-bit color) is probably optimal for an embedded system. But, fresh games would need to written or ported. It takes a while for a community to build up, if it does at all. That’s probably the most discouraging :frowning: factor for fresh engines. However, some PICO-8 devs have ported their games for platforms like the gamebuino. But, it would be best to piggyback on the PICO-8 community that already exists.

I feel like if you wrote an interpreter for pico8 to step through C++ to compile machine code for the device would be nice, otherwise I don’t think the performance is there to actually run LUA on the esp for more advanced carts.

And yes the advantage of a system like that is that it’s fully compatible with pico 8 and it’s existing catalog, and then if you wanted to develop bare metal for it that would be available and totally open too.

You mean a JIT compiler?

Technically it’s a superset of the language, but a subset of the standard library.

(Or at least, older versions of Lua before they added bitwise operators.
If you factor in the added bitwise operators, PICO-8 using ^ to mean exponentiation instead of xor is an outright incompatibility.)

I don’t think you’d need to be quite that strict.

I agree with this sentiment.
A statically typed language will always outperform a dynamically typed language when it comes to memory and performance constraints.

(But then I’ve never really understood the attraction to PICO-8 anyway. It’s like LÖVE, but not as good.)

If the licence allows it, porting should be possible, if not necessarily easy.
The real difficulties will come from the dynamic typing.


Personally I think the real flaw with trying to make something PICO-8 compatible isn’t the technical side of things, it’s the legal side - the fact PICO-8 isn’t open source, so you can’t actually do anything without permission from PICO-8’s owner.
Also the only way to find out how the undocumented bytecode format works is by reverse engineering the executable, which is an automatic copyright violation.

From a technical standpoint, making a custom Lua implementation with the library stripped out and the numbers implemented with Q16.16 fixed point arithmetic is almost certainly doable.

(Note that using the standard Lua implementation as a base would probably be a bad idea.
It was written for portability, not performance, and it relies on the standard C API, which limits its capabilities.)

1 Like

Nah I really mean a Pico8 translated to C++ with a custom library built for the esp32 with the oled to have well written routines to process what Pico8. Then just compile that into a hex.

You could just as easily run circuit python or whatever else. But the project isn’t interesting to me unless it has supported Pico8 compatibility. Otherwise it’s just another diy console.

2 Likes

Again, the legal issues (and proprietary bytecode) are the number one obstacle to that.
Whatever happens you’re at the mercy of PICO-8’s creator.
Start a discussion, bring a lawyer - such is the nature of closed source.

I’ve sent one or two mesages to him online about it and he seemed open to it but skeptical whether the system would actually run the carts full speed. I’ve always felt like as long as I could demo a unit to him that is capable he would be open to the project.

He worked with the Pocket Chip guys and I know them there is nothing that they could do that I can’t.

2 Likes

I’ve heard (anecdotal) that PICO-8 authors are open to emulators. Now, porting the games… as you said, that is tricky, unless the devs open sourced it.

As for the implementation, I think I am warming up to @bateske’s “transpile pico-8 lua to native C/C++” idea. lua2c is a thing – which can be a reference point (for example, dealing with dynamic structures like tables). But, I don’t know if they handle coroutines (which pico-8 apparently uses).

Even if they were, you’re still looking at having to discuss the situation with a lawyer present to make sure all the rights are discussed and understood.

If you can figure out how PICO-8’s proprietary bytecode works then you can understand and run any game, but that only solves the technical issues, not the licensing issues.

Translating Lua directly to calls to the Lua C API is probably too inefficient for an embdedded system.

To make a Lua implementation suitable for running on embedded systems, you’d probably have to write an entirely new Lua implementation that uses a more efficient execution model.

lua2c does handle coroutines using Coco, but whether it will work on an embedded system is another matter.

Most C implementations of coroutines rely on setjmp and longjmp.

(C++20, due to be ratified this year, will make coroutines a standard requirement for any C++ implementation.)

Sorry for the double post, but…

I was under the impression that there actually was some proprietary bytecode shenanigans going on, but it seems that all of those ‘catridge images’ in which games are distributed in actually only include the games in plaintext, not in precompiled form.

If this is true for all cartridges (I don’t know much about how PICO-8 distributes programs),
then there’s less reverse engineering involved than expected.
Writing a parser is a doddle, so the real difficulty would just be the implementation details,
and writing a Lua implementation that can run on an embedded system.

I’ve already thrown together a program that can read the source code out of the P8 PNG cartridge format as long as it’s compressed using the ‘old’ scheme.
I might work on making it read out all the other data too and then release it open source.

1 Like

This is the pickle, I don’t think you can run LUA on the microcontroller and also get the speed you need. I think you’d need to translate to C++ and compile straight to machine code.

That is one of the coolest feature about pico8, as experienced on a PC, is that you can step into the code at any moment and as it’s a scripted language you can edit your code live and swap back between the code and the runtime. Obvs youd lose this feature on pre-compiled carts but I’m not sure how many people were writing their games on the pocket chip.

1 Like

A quick google search shows other people have got LUA on the ESP already in a variety of flavors:

https://nodemcu.readthedocs.io/en/dev-esp32/

1 Like

In absence of evidence to the contrary I think it’s at least plausible.

Probably not with the default Lua implementation,
and probably not with a system that has to support interpreting,
but one with a custom bytecode format written specifically with common Lua idioms in mind I think you could get a good speed output without having to go as far as generating C++ code.

You can do that with compiled code to an extent,
though it’s a lot more difficult to implement.

If you did the bytecode approach then you wouldn’t completely loose it.
Bytcode can be partially decompiled back into source without any debug info,
but if you keep debug info in the chunk output then it can be 1-to-1 mapped back to the source code.

The last two seem to have used the official Lua implementation and just modified it slightly.

The whitecatboard one seems to have also not done much.
Seems that all they’ve added is a just-in-time bytecode optimiser which performs constant folding of unary and binary operators, replaces references to read-only tables with constant operands, and a few other bits.

In fact the latter one doesn’t look like much was modified at all.
If that runs at a decent speed then Lua’s more efficient than I was giving it credit for.
(Either that or ESP chips are faster than I recall.)

For the record, it’s “Lua”, not “LUA”. It’s not an acronym, it’s Portuguese for “moon”.


For anyone interested in Lua or bytecode-based scripting languages in general, this is an excellent read:
A No-Frills Introduction to Lua 5.1 VM Instructions.
(I first read it back in 2013 when I was dabbling with ComputerCraft (Wiki),
which was similar to PICO-8 before PICO-8 even existed.)

I have one pico8 console, it is the pocketchip :smiley:

1 Like

Righto. The Pico-8 Lua is plaintext and the first time I realized that was when looking at this JS attempt at an emulator.

Translating Lua directly to calls to the Lua C API is probably too inefficient for an embdedded system. To make a Lua implementation suitable for running on embedded systems, you’d probably have to write an entirely new Lua implementation that uses a more efficient execution model.

I disagree (until proven otherwise). Transpiling Lua to native C/C++ would indeed be performant for embedded systems. Of course, it does not have to be the Lua C API, and should not. Let’s take this specific Pico-8 Lua as an example. We parse out the AST and retarget. Tables can be class, maybe? The transpiler needn’t be solidly generic – it needs to Pico-8 Lua specific.

-- pico-8 lua
if score >= 1000 then
  print("you win!")
  score = 0
end
// transpiled C/C++
if (score >= 1000) {
  print("you win!");
  score = 0;
}

Remember CHIP-8? I bet that you have also written a CHIP-8 emulator at some point in your life.

PS: I am a software noob. My opinions are based on my limited experiences… :frowning: sorry

1 Like

There is a Lua at ESP32/ESP8266.
But I think that for ESP32 the Lua interpreter is slow, it should be compiled into bytecode.

One Swedish guy Marcus forked Little Game Engine to ESPiCo, making it closer to PICO8 API with not Lua but C syntax.
Theoretically, it’s easy to convert PICO8 Lua games to ESPiCo C now.
There are a couple of examples and they are working fine in the Web and on the ESPboy.
Don’t have enough time for thorough testing.

1 Like

I’m not saying translating to C++ would be inefficient,
it’s the standard C API I have doubts about.

But as I say, I might be underestimating the power of ESP chips.
I’m more used to AVR and ARM Cortex (M0+).

This is what I mean. If you’re going to translate it to C++,
there are probably faster alternatives.

The catch here is that you have to remember that score >= 1000 doesn’t mean “compare integer to integer”.
score would have to be an instance of a class implemented by a tagged union, because the programmer might do something like this:

local score = "10"
if score >= 1000 then
  print("you win!")
  score = 0
end

Which would translate to:

LuaValue score { "10" };
if (score >= 1000)
{
  print("you win!");
  score = 0;
}

It would of course be possible to detect the type statically in some cases, e.g.

std::string score { "10" };
// Realise there's an error
//if (score >= 1000)
//{
  //print("you win!");
  //score = 0;
//}
throw Lua::TypeError("cannot compare string to integer");

But that would naturally be extra work, and only be possible in certain circumstances.
Essentially you’s have to prove the type of the variable at any given point.
The type can only be proven when a value of unambiguous type is assigned to the variable.
Using single static assignment form might be a good way to do it.

Once or twice. :P

(When the FX chip is finally stabilised, a CHIP-8 emulator is going to be on my list of things to make.)

That doesn’t necessarily make them any less valid.

(Lua, compilers and bytecode are topics I just happen to know a lot about because I’ve done a lot of reading into them, so don’t take me as an example of what your average programmer knows about these topics.)


For the record, it’s “Lua”, not “LUA”.

Yes, SSA for sure - makes for a nice DFG and symbol table which can help with the transpilation (and formal analysis, if ever). The L/Rvalue type correctness would be checked at every assignment and dealt with.

You are right, I did not think of that. Lua, isn’t a strongly typed language. However, I still do think this is a surmountable problem, with enough care like you indicate. At a quick glance The Pico-8 Lua didn’t look too ridiculous. Honestly, I need to see more of the Pico-8 game code to realize the extent of how much of an effort this.

Nonetheless, I feel this approach (transpiling) is better than bytecode/interpretor (as far as performance is concerned on lower end uC). Right? Translating from Pico-8 Lua to ESPiCo, you’d have already taken the effort for translating (and enough code to interpret such bytecodes). Mighty as well emit clean C++, since “technically” all the code is right there.

The bytecode/interpretor has the merit of editing code on the fly (like what batske said) – but with a dpad and 2 buttons, I don’t know how enjoyable this would be on device. Of course, on the development platform (browser emulator version) – this would be fun. Which can be still done with compiled code, but with more effort.

How would you approach this, @Pharap? Pico-8 emulator for embedded systems.

Several people on twitter pointed out that gameshell is a thing, so, well, there you go.

2 Likes