This information applies to the PICO-8 0.1.6 release.
This document is here to help folks with a proficiency in Lua understand the limitations and discrepencies between Lua and PICO-8's Lua.
You can always view the manual or yellowafterlife's extended 0.1.1 manual.
- anything written in uppercase the PICO-8 editor or .p8 is made lowercase by the editor. → editing the .p8 file directly can work
- print(function() end)outputs the string- functioninstead of the string- function: 0x0000000.
- printtakes three arguments (string,x,y) → use- printh()instead
- PICO-8's Lua supports a few Compound assignment operators: +=,-=,*=,/=,%=
- PICO-8's Lua has single line shorthand for if then else operators. → Compare to ternary?: PICO-8 Lua: IF (NOT B) THEN I=1 J=2 ENDvs Lua:i,j = not b and 1,j or i,2.
- PICO-8's Lua has a different precision (16:16 fixed point) vs Lua's double-precision floating-point.
- PICO-8's Lua has additional Comparison operators/relational operators for "Not Equal To" (~=):!=
- There is no ioobject. → There is technically "Cartridge Data" that you can use for persistant information - seecartdata()
- load()has been overwritten with a PICO-8 function.
- PICO-8 introduces many other global functions (see manual).
- There are general rounding errors: print("-1"*1 == -1") -- false
- Global functions and variables have been removed: collectgarbage,dofile,error,ipairs,loadfile,loadstring,math,module,package,pcall,rawequal,rawlen,rawget,require,select,string,table,tonumber,tostring,unpack,xpcall,_VERSION, andgetmetatable.
- _Gglobal table has been removed.
- assert()and- type()were removed in- 0.1.3but added back in- 0.1.4.
- coroutine.[create|resume|status|yield]()was removed in- 0.1.3but added in- 0.1.6as- coroutine(),- cocreate(),- coresume(),- costatus()and- yield()respectively.
- setmetatablewas removed in- 0.1.3but added back in- 0.1.6
function munpack(t, from, to)
  from = from or 1
  to = to or #t
  if from > to then return end
  return t[from], munpack(t, from+1, to)
end
print(munpack{1, 2, 3, 4})Thanks to bartbes for this much better version
function pow(x,a)
	if (a==0) return 1
	if (a<0) x,a=1/x,-a
	local ret,a0,xn=1,flr(a),x
	a-=a0
	while a0>=1 do
	if (a0%2>=1) ret*=xn
	xn,a0=xn*xn,shr(a0,1)
	end
	while a>0 do
	while a<1 do x,a=sqrt(x),a+a end
	ret,a=ret*x,a-1
	end
	return ret
endThanks to samhocevar for this implementation (link)
0.1.3
The string table is no longer available.
0.1.2
- strings that use upper case pattern matching will not be able to be entered into the editor directly.
- string.bytereturns a fraction [incorrect value]
- string.charoperates differently:
- string.dumpreturns the characters- vabut offset I think? [incorrect value?]
- string.findreturns small fractions [invalid indexes]
- string.gmatchdoes not return a working iterator [broken iterator index]
- string.gsubdoes not return the correct index [incorrect second value]
- string.lenreturns a rather small fraction [incorrect value] → use the- #operator instead
- string.[upper|lower]while both of these functions technically work correctly, because the char table has had the upper case characters removed, it will not work as intended.
0.1.3
The table table is no longer available.
0.1.2
- table.insert(t,o)does not insert the proper key. → use- add(t,o)instead
- table.insert(t,p,o)does not insert the proper key. Attempting to insert beyond table initialization causes an position out of bounds error.
- table.remove(t,p)removes the correct value, but then assocates every following value with the key before it. → use- del(t,o)instead
0.1.3
The math table is no longer available.
0.1.2
- math.a[cos|sin|tan][2]does not work correctly. [Rounding errors?] → use- atan2()instead of- math.atan2(). Untested versions here
- math.[floor|ceil]returns input [incorrect value] → use- flr()instead. For- math.ceil(), use- function ceil(x) return -flr(-x) end
- math.[cos|sin]return zero [incorrect value] → use- cos()and- sin(). Functions take 0..1 instead of 0..PI*2, and- sin()is inverted.
- math.tandoes not work correctly. [Rounding errors?] → use math instead:
- math.[cos|sin|tan]hdoes not work correctly. [Rounding errors?]
- math.[deg|rad]return zero [incorrect value] → use math instead:
- math.[exp|log]does not work correctly [Rounding errors?]
- math.log10is nil [does not exist]
- math.powdoes not work correctly [returns -maxint] → use the- ^operator instead
- math.modfreturns two zeros [incorrect value] → use the- %operator instead
- math.sqrtdoes not work correctly [Rounding errors?] → use- sqrt()instead
- math.randomdoes not work correctly [returns zero] → use- rnd()instead
- math.randomseedcannot be verified until math.random is fixed [dependency issue] → use- srand()instead
- math.frexpdoes not return a value [incorrect return type] → but- math.ldexp()works for some reason!
- math.hugeis 0.5 [incorrect value and type]
- math.piis 5.341e-05 [incorrect value] → use a fixed value instead, e.g.: 3.14159
0.1.3
The os table is no longer available.
0.1.2
- os.dateworks correctly, but due to a lack of upper case characters, it does not render correctly.
- os.timereturns the incorrect value [rounding issues]
- os.getenvworks correctly, but the editor cannot write upper case characters.
- os.difftimedoes not work correctly, but I think that this could be used to get- os.time()to work correctly.
- os.re[name|move]this probably works, but operates where the binary for- pico8is located.
- os.clockdoesn't work correctly, but could probably be scaled to the correct value. → pico8 is forced at 30fps; calculate time by incrementing a variable in- _update()by 1/30.
0.1.3
The debug table is no longer available.
0.1.2
This function has not been compared, but seems intact.
- shutdownquits the- pico8binary.
- _update_buttonsfunction. Has no arguments.
- _p8_programfunction. Causes out of memory error when called.
- decompressfunction. Not sure what it does.
- cvariable may sometime be globally set. Seems to be a scope error for some other function.
- tracefunction. I'm guessing it's for the runtime errors.
- allfunction. Not sure what it does.
- _set_mainloop_existsfunction. Most likely toggles a variable in a local scope.
- stopfunction. Stops game at current point so you can debug things.
0.1.2
0.1.3
The bit32 table is no longer available.
0.1.2
- bit32table contains:- extract,- bnot,- rrotate,- arshift,- btest,- bxor,- replace,- band,- lshift,- rshift,- lrotate,- bor



