TIC-80 Manual & Cheat Sheet

TIC-80 is a free and open source fantasy computer for making, playing and sharing tiny games.

Website at https://tic80.com

There are built-in tools for development: code, sprites, maps, sound editors and the command line, which is enough to create a mini retro game. At the exit you will get a cartridge file, which can be stored and played on the website.

Also, the game can be packed into a player that works on all popular platforms and distribute as you wish. To make a retro styled game the whole process of creation takes place under some technical limitations: 240x136 pixels display, 16 color palette, 256 8x8 color sprites, 4 channel sound and etc.

Specifications

Table 1. Specs

Resolution

240x136 pixel display

Color

16 color palette (chosen from 24-bit colorspace)

Input

4 gamepads with 8 buttons / mouse / keyboard

Sprites

256 foreground sprites and 256 background tiles (8x8 pixel)

Map

240x136 tiles (ie, 1920x1088 pixels)

Sound

4 channels (with editable waveform envelopes)

Code

512KB of source or 256KB compiled BINARY size

Memory

Up to 272kb of RAM (including 32KB of VRAM)

Bankswitching

Up to 8 banks in cart (PRO version only)

Memory Map

Table 2. Memory Map
ADDR INFO BYTES COMMENTS

0x00000

VRAM bank 0 or 1

16,384

32kB Video RAM (see below)

0x04000

Tiles

8,192

256 8x8 4-bit bg tiles - #0 to #255

0x06000

Sprites

8,192

256 8x8 4-bit fg sprites - #256 to #511

0x08000

Map

32,640

240x136 map - indexed by tile/sprite

0x0FF80

Gamepads

4

button state for 4 gamepads

0x0FF84

Mouse

4

mouse state X / Y / buttons / scroll

0x0FF88

Keyboard

4

keyboard state, up to 4 pressed buttons

0x0FF8C

SFX State

16

…​

0x0FF9C

Sound Registers

72

…​

0x0FFE4

Waveforms

256

16 waveforms, each 32 x 4-bit values

0x100E4

SFX

4,224

…​

0x11164

Music Patterns

11,520

…​

0x13E64

Music Tracks

408

…​

0x13FFC

Sound State

4

…​

0x14000

Stereo Volume

4

…​

0x14004

Persistent Memory

1,024

persistent RAM, per cartridge

0x14404

Sprite Flags

512

…​

0x14604

System Font

2,048

256 8x8 1-bit font (used by print)

0x14E04

RESERVED

12,796

…​

Language Help

Below are links for each of the languages to assist in learning.

Logo

Lua is a powerful, efficient, lightweight, embeddable scripting language. It supports procedural programming, object-oriented programming, functional programming, data-driven programming, and data description.

Lua combines simple procedural syntax with powerful data description constructs based on associative arrays and extensible semantics. Lua is dynamically typed, runs by interpreting bytecode with a register-based virtual machine, and has automatic memory management with incremental garbage collection, making it ideal for configuration, scripting, and rapid prototyping.

Logo

MoonScript is a dynamic scripting language that compiles into Lua. It gives you the power of one of the fastest scripting languages combined with a rich set of features.

MoonScript provides a clean syntax using significant whitespace that avoids all the keyword noise typically seen in a Lua script. Below is a sample of some constructs found in the language.

It also adds table comprehensions, implicit return on functions, classes, inheritance, scope management statements import & export, and a convenient object creation statement called with.

Logo

Duktape is an embeddable Javascript engine, with a focus on portability and compact footprint.

JavaScript is a high-level, often just-in-time compiled language that conforms to the ECMAScript standard. It has dynamic typing, prototype-based object-orientation, and first-class functions. It is multi-paradigm, supporting event-driven, functional, and imperative programming styles.

Logo

Website at https://wren.io

Wren is a small, fast, class-based concurrent scripting language. Think Smalltalk in a Lua-sized package with a dash of Erlang and wrapped up in a familiar, modern syntax.

  • Wren is small. The VM implementation is under 4,000 semicolons. You can skim the whole thing in an afternoon. It’s small, but not dense. It is readable and lovingly-commented.

  • Wren is fast. A fast single-pass compiler to tight bytecode, and a compact object representation help Wren compete with other dynamic languages.

  • Wren is class-based. There are lots of scripting languages out there, but many have unusual or non-existent object models. Wren places classes front and center.

  • Wren is concurrent. Lightweight fibers are core to the execution model and let you organize your program into a flock of communicating coroutines.

  • Wren is a scripting language. Wren is intended for embedding in applications. It has no dependencies, a small standard library, and an easy-to-use C API. It compiles cleanly as C99, C++98 or anything later.

Logo

Fennel is a programming language that brings together the speed, simplicity, and reach of Lua with the flexibility of a lisp syntax and macro system.

  • Full Lua compatibility: Easily call any Lua function or library from Fennel and vice-versa.

  • Zero overhead: Compiled code should be just as efficient as hand-written Lua.

  • Compile-time macros: Ship compiled code with no runtime dependency on Fennel.

  • Embeddable: Fennel is a one-file library as well as an executable. Embed it in other programs to support runtime extensibility and interactive development.

Anywhere you can run Lua code, you can run Fennel code.

  • The Tutorial teaches you the basics of the language.

  • The Rationale explains the reasoning why Fennel was created.

  • The Lua primer will catch you up if you don’t already know Lua.

  • The Reference lists out all built-in special forms and what they’re for.

  • The Style Guide advises on how to write clear and consise code.

  • The Macro Guide explains how to write macros.

  • Curious about how a piece of code compiles? See for yourself with a side-by-side view how Fennel turns into Lua and vice-versa with Antifennel

  • #fennel channel on Libera.Chat and on Matrix. This is where the developers for Fennel hang out.

  • Community events

Logo

Squirrel is a high level imperative, object-oriented programming language, designed to be a light-weight scripting language that fits in the size, memory bandwidth, and real-time requirements of applications like video games. Although Squirrel offers a wide range of features like:

  • dynamic typing

  • delegation

  • classes & inheritance

  • higher order functions

  • lexical scoping

  • generators

  • cooperative threads(coroutines)

  • tail recursion

  • exception handling

Squirrel’s syntax is similar to C/C++/Java etc…​ but the language has a very dynamic nature like Python/Lua etc…​

Logo

Website at https://mruby.org/

mruby is the lightweight implementation of the Ruby language complying with part of the ISO standard.

Ruby is a dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.

In Ruby, everything is an object. Every bit of information and code can be given their own properties and actions. Object-oriented programming calls properties by the name instance variables and actions are known as methods.

Default Carts

The carts listed below can be generated by typing the following at the tic80 cli:
The new cartridge is automatically loaded in the specified langauge.

  • new lua

  • new moon

  • new js

  • new wren

  • new fennel

  • new squirrel

  • new ruby


-- title:   game title
-- author:  game developer, email, etc.
-- desc:    short description
-- site:    website link
-- license: MIT License (change this to your license of choice)
-- version: 0.1
-- script:  lua

t=0
x=96
y=24

function TIC()

	if btn(0) then y=y-1 end
	if btn(1) then y=y+1 end
	if btn(2) then x=x-1 end
	if btn(3) then x=x+1 end

	cls(13)
	spr(1+t%60//30*2,x,y,14,3,0,0,2,2)
	print("HELLO WORLD!",84,84)
	t=t+1
end

-- title:   game title
-- author:  game developer, email, etc.
-- desc:    short description
-- site:    website link
-- license: MIT License (change this to your license of choice)
-- version: 0.1
-- script:  lua
  
t=0
x=96
y=24
  
function TIC()
  
 if btn(0) then y=y-1 end
 if btn(1) then y=y+1 end
 if btn(2) then x=x-1 end
 if btn(3) then x=x+1 end
  
 cls(13)
 spr(1+t%60//30*2,x,y,14,3,0,0,2,2)
 print("HELLO WORLD!",84,84)
 t=t+1
end

// title:   game title
// author:  game developer, email, etc.
// desc:    short description
// site:    website link
// license: MIT License (change this to your license of choice)
// version: 0.1
// script:  js
  
var t=0
var x=96
var y=24
  
function TIC()
{
 if(btn(0))y--
 if(btn(1))y++
 if(btn(2))x--
 if(btn(3))x++
  
 cls(13)
 spr(1+((t%60)/30|0)*2,x,y,14,3,0,0,2,2)
 print("HELLO WORLD!",84,84)
 t++
}

// title:   game title
// author:  game developer, email, etc.
// desc:    short description
// site:    website link
// license: MIT License (change this to your license of choice)
// version: 0.1
// script:  wren
  
class Game is TIC{
  
 construct new(){
  _t=0
  _x=96
  _y=24
 }
   
 TIC(){
  if(TIC.btn(0)){
   _y=_y-1
  }
  if(TIC.btn(1)){
   _y=_y+1
  }
  if(TIC.btn(2)){
   _x=_x-1
  }
  if(TIC.btn(3)){
   _x=_x+1
  }
    
  TIC.cls(13)
  TIC.spr(1+((_t%60)/30|0)*2,_x,_y,14,3,0,0,2,2)
  TIC.print("HELLO WORLD!",84,84)
    
  _t=_t+1
 }
} 

;; title:   game title
;; author:  game developer, email, etc.
;; desc:    short description
;; site:    website link
;; license: MIT License (change this to your license of choice)
;; version: 0.1
;; script:  fennel
;; strict:  true
  
(var t 0)
(var x 96)
(var y 24)
  
(fn _G.TIC []
  (when (btn 0) (set y (- y 1)))
  (when (btn 1) (set y (+ y 1)))
  (when (btn 2) (set x (- x 1)))
  (when (btn 3) (set x (+ x 1)))
  (cls 0)
  (spr (+ 1 (* (// (% t 60) 30) 2))
       x y 14 3 0 0 2 2)
  (print "HELLO WORLD!" 84 84)
  (set t (+ t 1)))  

// title:   game title
// author:  game developer, email, etc.
// desc:    short description
// site:    website link
// license: MIT License (change this to your license of choice)
// version: 0.1
// script:  squirrel
  
t<-0
x<-96
y<-24
  
function TIC()
{
 if (btn(0)) y=y-1;
 if (btn(1)) y=y+1;
 if (btn(2)) x=x-1;
 if (btn(3)) x=x+1;
  
 cls(13)
 spr(1+((t%60)/30)*2,x,y,14,3,0,0,2,2)
 print("HELLO WORLD!",84,84)
 t=t+1
} 

# title:   game title
# author:  game developer, email, etc.
# desc:    short description
# site:    website link
# license: MIT License (change this to your license of choice)
# version: 0.1
# script:  ruby

$t=0
$x=96
$y=24

def TIC
 $y-=1 if btn 0
 $y+=1 if btn 1
 $x-=1 if btn 2
 $x+=1 if btn 3

 cls 13
 spr 1+(($t%60)/30|0)*2,$x,$y,14,3,0,0,2,2
 print "HELLO WORLD!",84,84
 $t+=1
end

Command Line

Options below available with tic80 --help

Usage: tic80 [cart] [options]

TIC-80 startup options:

    -h, --help        show this help message and exit
    --skip            skip startup animation
    --volume=<int>    global volume value [0-15]
    --cli             console only output
    --fullscreen      enable fullscreen mode
    --vsync           enable VSYNC
    --soft            use software rendering
    --fs=<str>        path to the file system folder
    --scale=<int>     main window scale
    --cmd=<str>       run commands in the console
    --keepcmd         re-execute commands on every run
    --version         print program version
    --crt             enable CRT monitor effect
tic80 --skip --fs .                                           skip startup animation and use current directory as storage
tic80 --skip --cmd "load cart.tic"                            skip startup animation and load `cart.tic` cart
tic80 --cmd surf                                              start TIC-80 in SURF mode
tic80 --cmd "load cart.tic & export html game.zip & exit"     load `cart.tic` cart, export html `game.zip` and exit
tic80 --cmd "load cart.tic & save cart.lua & exit"            load `cart.tic`, save as a text cart and exit
tic80 --cmd "load cart.tic & export sprites spr.gif & exit"   load `cart.tic`, export sprites to `spr.gif` and exit
tic80 --cmd "load cart.tic & export track5 music.wav & exit"  load `cart.tic`, export 5th track to `music.wav` and exit
tic80 ../path/to/cart.tic --fs ../path/to                     use `../path/to/` as storage and load `cart.tic`
tic80 > log.txt                                               all trace output is redirected to the named file
tic80 | Out-File log.txt                                      same as above for PowerShell users

Shortcuts

Table 3. General TIC-80 Shortcuts

switch console/editor

ESC

show console

ALT+~

show code editor

ALT+1/F1

show sprite editor

ALT+2/F2

show map editor

ALT+3/F3

show sfx editor

ALT+4/F4

show music editor

ALT+5/F5

switch to previous/next editor mode

CTRL+PGUP/PGDOWN

fullscreen/window mode

F11/ALT+ENTER

run current project

CTRL+R/ENTER

cut/copy/paste in the editors

CTRL+X/C/V

save cart

CTRL+S

undo/redo changes

CTRL+Z/Y

navigate

ARROWS

toggle CRT filter

F6

assign cover image

F7

take a screenshot

F8

start/stop GIF video recording

F9

Button Codes

Table 3.1. Buttons

0

P1 UP

1

P1 DOWN

2

P1 LEFT

3

P1 RIGHT

4

P1 A

5

P1 B

6

P1 X

7

P1 Y

8

P2 UP

9

P2 DOWN

10

P2 LEFT

11

P2 RIGHT

12

P2 A

13

P2 B

14

P2 X

15

P2 Y

16

P3 UP

17

P3 DOWN

18

P3 LEFT

19

P3 RIGHT

20

P3 A

21

P3 B

22

P3 X

23

P3 Y

24

P4 UP

25

P4 DOWN

26

P4 LEFT

27

P4 RIGHT

28

P4 A

29

P4 B

30

P4 X

31

P4 Y

Key Codes

Table 3.2 Key Codes

CODE

KEY

1

A

2

B

3

C

4

D

5

E

6

F

7

G

8

H

9

I

10

J

11

K

12

L

13

M

14

N

15

O

16

P

17

Q

18

R

19

S

20

T

21

U

22

V

23

W

24

X

25

Y

26

Z

27

0

28

1

29

2

30

3

31

4

32

5

33

6

34

7

35

8

36

9

37

- (MINUS)

38

= (EQUALS)

39

( (LEFT BRACKET)

40

) (RIGHT BRACKET)

41

\ (BACK SLASH)

42

; (SEMICOLON)

43

' (APOSTROPHE)

44

` (GRAVE)

45

, (COMMA)

46

. (PERIOD)

47

/ (SLASH)

48

(SPACE)

49

(TAB)

50

(ENTER/RETURN)

51

(BACKSPACE)

52

(DELETE)

53

(INSERT)

54

(PAGE UP)

55

(PAGE DOWN)

56

(HOME)

57

(END)

58

(UP ARROW)

59

(DOWN ARROW)

60

(LEFT ARROW)

61

(RIGHT ARROW)

62

(CAPSLOCK)

63

(CTRL)

64

(SHIFT)

65

(ALT)

Table 4. Code Editor Shortcuts

find

CTRL+F

go to line

CTRL+G

indent line

CTRL+TAB

unindent line

CTRL+SHIFT+TAB

show code outline

CTRL+O

Table 5. Sprite Editor Shortcuts

choose previous/next palette color

[]

change brush size

-/=

Table 6. Map Editor Shortcuts

show spritesheet

SHIFT

Table 7. Music Editor Shortcuts

play pattern from cursor position

SHIFT+ENTER

Table 8. SFX Editor Shortcuts

play sfx

SPACE

Supported Platforms

TIC is developed in pure C, with SDL and Lua libraries. It works on all popular platforms, including:

  • HTML5

  • Windows

  • Windows 10 UWP

  • Linux 32/64bit

  • Android

  • Mac OS

  • Raspberry Pi / Baremetal

  • Nintendo 3DS

  • Pocket CHIP

  • iOS (courtesy of CliffsDover and Bruno Philipe)

  • libretro

Downloads

You can download compiled versions for the major operating systems directly from the releases page.

Website

https://tic80.com

Twitter

@tic_computer

Hashtag

#TIC80

Chat

Telegram / Discord

Community

Itch.io / VKontakte

Games made with Tic80

Itch.io #tic-80

Bugs

Github Issues

Wiki

Github Wiki

Changelog

Github Changelog

Author

Nesbox (Vadim Grigoruk) // grigoruk@gmail.com

MANUAL

Manual Documentation for TIC-80
Source of documentation from:
https://tic80.com/learn
https://hub.xpub.nl/sandbot/PrototypingTimes/tic80-manual.html

Main Functions / Callbacks

TIC

TIC()
TIC is the ‘main’ function and must be present in every program.
It takes no parameters and is called sixty times per second (60fps).
Syntax:
– script: lua function TIC() – Put your stuff here end

SCN

SCN()
SCN allows you to execute code between the drawing of each scan line, for example, to manipulate the palette.
Syntax:
function SCN(line) – your code here end

OVR

OVR()
OVR is called on every frame.
It draws on a separate layer and can be used together with SCN() to create separate background or foreground layers and other visual effects.
Syntax:
function OVR() –Draw foreground end

BDR

BDR(row)
Allows you to execute code between the drawing of each fullscreen scanline, for example, to manipulate the palette.

MENU

MENU(index)
Game Menu handler.

BOOT

BOOT
Startup Function.

Input

btn

Button Key Codes
btn(id: 0..31) -> pressed
Parameters:
id : the id of the key we want to interrogate, see the key map for reference

Description: This function allows you to read the status of one of the buttons attached to TIC. The function returns true if the key with the supplied id is currently in the pressed state.
It remains true for as long as the key is held down.
If you want to test if a key was just pressed, use btnp instead.

btnp

Button Key Codes
btnp([id: 0..31], [hold], [period]) -> pressed
(but wasn’t pressed in previous frame)
This function allows you to read the status of one of TIC’s buttons. It returns true only if the key has been pressed since the last frame.

You can also use the optional hold and period parameters which allow you to check if a button is being held down. After the time specified by hold has elapsed, btnp will return true each time period is passed if the key is still down. For example, to re-examine the state of button ‘0’ after 2 seconds and continue to check its state every 1/10th of a second, you would use btnp(0, 120, 6). Since time is expressed in ticks and TIC runs at 60 frames per second, we use the value of 120 to wait 2 seconds and 6 ticks (ie 60/10) as the interval for re-checking.

Parameters:
- id : The id of the key we wish to interrogate - see the key map for reference
- hold : The time (in ticks) the key must be pressed before re-checking
- period : The the amount of time (in ticks) after hold before this function will return true again.

key

Key Codes
key(code: 1 - 65) -> pressed

keyp

Key Codes
keyp(code=-1 hold=-1 period=-1) -> pressed
Parameters
code : the key code we want to check (see codes here)
hold : time in ticks before autorepeat
period : time in ticks for autorepeat interval
This function returns true if the given key is pressed but wasn’t pressed in the previous frame. Refer to btnp for an explanation of the optional hold and period parameters

mouse

mouse() -> x y left middle right scrollx scrolly
This function returns the mouse coordinates and a boolean value for the state of each mouse button, with true indicating that a button is pressed.

Drawing

clip

clip(x y width height)
clip()

This function limits drawing to a clipping region or `viewport` defined by x,y,w,h.
Things drawn outside of this area will not be visible.
Calling clip() with no parameters will reset the drawing area to the entire screen.

cls

cls(color=0)
Clear the screen.
When called this function clear all the screen using the color passed as argument.
If no parameter is passed first color (0) is used.

circ

circ(x y radius color)
This function draws a filled circle of the desired radius and color with its center at x, y.
It uses the Bresenham algorithm.

circb

circb(x y radius color)
Draws the circumference of a circle with its center at x, y using the radius and color requested.
It uses the Bresenham algorithm

line

line(x0 y0 x1 y1 color)
Draws a straight line from point (x0,y0) to point (x1,y1) in the specified color.

pix

pix(x y color)
pix(x y) -> color

This function can read or write pixel color values.
When called with a color parameter, the pixel at the specified coordinates is set to that color.
Calling the function without a color parameter returns the color of the pixel at the specified position.

rect

rect(x y w h color)
This function draws a filled rectangle of the desired size and color at the specified position.
If you only need to draw the the border or outline of a rectangle (ie not filled) see `rectb()`.

rectb

rectb(x y w h color)
This function draws a one pixel thick rectangle border at the position requested.
If you need to fill the rectangle with a color, see `rect()` instead.

tri

tri(x1 y1 x2 y2 x3 y3 color)
This function draws a triangle filled with color, using the supplied vertices.

ttri

ttri(x1 y1 x2 y2 x3 y3 u1 v1 u2 v2 u3 v3 texsrc=0 chromakey=-1 z1=0 z2=0 z3=0)
It renders a triangle filled with texture from image ram, map ram or vbank.
Use in 3D graphics.
In particular, if the vertices in the triangle have different 3D depth, you may see some distortion.
These can be thought of as the window inside image ram (sprite sheet), map ram or another vbank.
Note that the sprite sheet or map in this case is treated as a single large image, with U and V addressing its pixels directly, rather than by sprite ID.
So for example the top left corner of sprite #2 would be located at u=16, v=0.

elli

elli(x y a b color)
This function draws a filled ellipse of the desired a, b radiuses and color with its center at x, y.
It uses the Bresenham algorithm.

ellib

ellib(x y a b color)
This function draws an ellipse border with the desired radiuses a b and color with its center at x, y.
It uses the Bresenham algorithm.

Program / Interrupts

exit

exit()
exit the application.

reset

reset()
Resets the cartridge. To return to the console, see the `exit()`.

time

time() -> ticks
This function returns the number of milliseconds elapsed since the cartridge began execution.
Useful for keeping track of time, animating items and triggering events.

tstamp

tstamp() -> timestamp
This function returns the number of seconds elapsed since January 1st, 1970.
Useful for creating persistent games which evolve over time between plays.

trace

trace(message color=15)
This is a service function, useful for debugging your code.
It prints the message parameter to the console in the (optional) color specified.
Tips:
- The Lua concatenator for strings is .. (two points).
- Use console cls command to clear the output from trace.

Sprite / Map

fget

fget(sprite_id flag) -> bool
Returns true if the specified flag of the sprite is set.
See also fset()

fset

fset(sprite_id flag bool)
Each sprite has eight flags which can be used to store information or signal different conditions.
For example, flag 0 might be used to indicate that the sprite is invisible, flag 6 might indicate that the flag should be draw scaled etc.
See also fget()

map

map(x=0 y=0 w=30 h=17 sx=0 sy=0 colorkey=-1 scale=1 remap=nil)
The map consists of cells of 8x8 pixels, each of which can be filled with a sprite using the map editor.
The map can be up to 240 cells wide by 136 deep.
This function will draw the desired area of the map to a specified screen position.
For example, map(5,5,12,10,0,0) will draw a 12x10 section of the map, starting from map co-ordinates (5,5) to screen position (0,0).
The map function's last parameter is a powerful callback function for changing how map cells (sprites) are drawn when map is called.
It can be used to rotate, flip and replace sprites while the game is running.
Unlike mset, which saves changes to the map, this special function can be used to create animated tiles or replace them completely.
Some examples include changing sprites to open doorways, hiding sprites used to spawn objects in your game and even to emit the objects themselves.
The tilemap is laid out sequentially in RAM - writing 1 to 0x08000 will cause tile(sprite) #1 to appear at top left when map() is called.
To set the tile immediately below this we need to write to 0x08000 + 240, ie 0x080F0.

mget

mget(x y) -> tile_id
Gets the sprite id at the given x and y map coordinate.

mset

memset(dest value size)
This function allows you to set a continuous block of any part of TIC's RAM to the same value.
The address is specified in hexadecimal format, the value in decimal.

spr

spr(id x y colorkey=-1 scale=1 flip=0 rotate=0 w=1 h=1)
Draws the sprite number index at the x and y coordinate.
You can specify a colorkey in the palette which will be used as the transparent color or use a value of -1 for an opaque sprite.
The sprite can be scaled up by a desired factor. For example, a scale factor of 2 means an 8x8 pixel sprite is drawn to a 16x16 area of the screen.
You can flip the sprite where:
- 0 = No Flip
- 1 = Flip horizontally
- 2 = Flip vertically
- 3 = Flip both vertically and horizontally
When you rotate the sprite, it's rotated clockwise in 90 steps:
- 0 = No rotation
- 1 = 90 rotation
- 2 = 180 rotation
- 3 = 270 rotation
You can draw a composite sprite (consisting of a rectangular region of sprites from the sprite sheet) by specifying the `w` and `h` parameters (which default to 1).

Text

font

font(text x y chromakey char_width char_height fixed=false scale=1) -> width
Print string with font defined in foreground sprites.
To simply print to the screen, check out print()
To print to the console, check out trace()

print

print(text x=0 y=0 color=15 fixed=false scale=1 smallfont=false) -> width
This will simply print text to the screen using the font defined in config.
When set to true, the fixed width option ensures that each character will be printed in a `box` of the same size, so the character `i` will occupy the same width as the character `w` for example.
When fixed width is false, there will be a single space between each character.
Tips:
- To use a custom rastered font, check out font()
- To print to the console, check out trace()

Memory

memcpy

memcpy(dest source size)
This function allows you to copy a continuous block of TIC's 96K RAM from one address to another.
Addresses are specified are in hexadecimal format, values are decimal.

memset

memset(dest value size)
This function allows you to set a continuous block of any part of TIC's RAM to the same value.
The address is specified in hexadecimal format, the value in decimal.

peek

peek(addr bits=8) -> value
This function allows to read the memory from TIC.
It's useful to access resources created with the integrated tools like sprite, maps, sounds, cartridges data?
Never dream to sound a sprite?
Address are in hexadecimal format but values are decimal.
To write to a memory address, use poke()
`bits` allowed to be 1,2,4,8.

peek1

peek1(addr) -> value
This function enables you to read single bit values from TIC's RAM.
The address is often specified in hexadecimal format.

peek2

peek2(addr) -> value
This function enables you to read two bits values from TIC's RAM.
The address is often specified in hexadecimal format.

peek4

peek4(addr) -> value
This function enables you to read values from TIC's RAM.
The address is often specified in hexadecimal format.
See poke4() for detailed information on how nibble addressing compares with byte addressing.

pmem

pmem(index value)
pmem(index)
-> value
This function allows you to save and retrieve data in one of the 256 individual 32-bit slots available in the cartridge's persistent memory.
This is useful for saving high-scores, level advancement or achievements.
The data is stored as unsigned 32-bit integers (from 0 to 4294967295).
Tips:
- pmem depends on the cartridge hash (md5), so don't change your lua script if you want to keep the data.
- Use `saveid:` with a personalized string in the header metadata to override the default MD5 calculation.
This allows the user to update a cart without losing their saved data.

poke

poke(addr value bits=8)
This function allows you to write a single byte to any address in TIC's RAM.
The address should be specified in hexadecimal format, the value in decimal.
`bits` allowed to be 1,2,4,8.

poke1

poke1(addr value)
This function allows you to write single bit values directly to RAM.
The address is often specified in hexadecimal format.

poke2

poke2(addr value)
This function allows you to write two bits values directly to RAM.
The address is often specified in hexadecimal format.

poke4

poke4(addr value)
This function allows you to write directly to RAM.
The address is often specified in hexadecimal format.
For both peek4 and poke4 RAM is addressed in 4 bit segments (nibbles).
Therefore, to access the the RAM at byte address 0x4000 you would need to access both the 0x8000 and 0x8001 nibble addresses.

sync

sync(mask=0 bank=0 tocart=false)
The pro version of TIC-80 contains 8 memory banks.
To switch between these banks, sync can be used to either load contents from a memory bank to runtime, or save contents from the active runtime to a bank.
The function can only be called once per frame.
If you have manipulated the runtime memory
(e.g. by using mset), you can reset the active state by calling sync(0,0,false).
This resets the whole runtime memory to the contents of bank 0.
Note that sync is not used to load code from banks; this is done automatically.

vbank

vbank(bank) -> prev
vbank() -> prev
VRAM contains 2x16K memory chips, use vbank(0) or vbank(1) to switch between them.

Sound

music

music(track=-1 frame=-1 row=-1 loop=true sustain=false tempo=-1 speed=-1)
This function starts playing a track created in the Music Editor.
Call without arguments to stop the music.

sfx

sfx(id note=-1 duration=-1 channel=0 volume=15 speed=0)
This function will play the sound with `id` created in the sfx editor.
Calling the function with id set to -1 will stop playing the channel.
The note can be supplied as an integer between 0 and 95 (representing 8 octaves of 12 notes each) or as a string giving the note name and octave.
For example, a note value of `14` will play the note `D` in the second octave.
The same note could be specified by the string `D-2`.
Note names consist of two characters, the note itself (in upper case) followed by `-` to represent the natural note or `#` to represent a sharp.
There is no option to indicate flat values.
The available note names are therefore: C-, C#, D-, D#, E-, F-, F#, G-, G#, A-, A#, B-.
The `octave` is specified using a single digit in the range 0 to 8.
The `duration` specifies how many ticks to play the sound for since TIC-80 runs at 60 frames per second, a value of 30 represents half a second.
A value of -1 will play the sound continuously.
The `channel` parameter indicates which of the four channels to use.
Allowed values are 0 to 3.
The `volume` can be between 0 and 15.
The `speed` in the range -4 to 3 can be specified and means how many `ticks+1` to play each step, so speed==0 means 1 tick per step.