Difference between revisions of "Fantasy consoles"

From SizeCoding
Jump to: navigation, search
(Compression And Release)
(Online version: Metadata and Thumbnail image)
(27 intermediate revisions by 2 users not shown)
Line 19: Line 19:
  
 
=== Getting started ===
 
=== Getting started ===
Most TIC-80 programs are coded using the LUA Scripting language. However it is possible to select different scripting language like javascript at the cost of a couple of bytes/characters like so: <syntaxhighlight lang="lua">//script: js</syntaxhighlight>
+
Most TIC-80 programs are coded using the Lua Scripting language. However it is possible to select different scripting language like javascript at the cost of a couple of bytes/characters like so (respectively for JavaScript, MoonScript, Wren, Fennel, Squirrel):
 +
 
 +
<syntaxhighlight lang="js">//script: js</syntaxhighlight>
 +
<syntaxhighlight lang="lua">-- script: moon</syntaxhighlight>
 +
<syntaxhighlight lang="js">// script: wren</syntaxhighlight>
 +
<syntaxhighlight lang="fennel">;; script: fennel</syntaxhighlight>
 +
<syntaxhighlight lang="js">// script: squirrel</syntaxhighlight>
  
 
The main function used for updating the screen (and called 60 times a second) is the TIC() function, so this function is also a requirement for doing anything with graphics. Additionally you can also setup a sub=function SCN() that is called once per scanline at the costs of more bytes/characters.  
 
The main function used for updating the screen (and called 60 times a second) is the TIC() function, so this function is also a requirement for doing anything with graphics. Additionally you can also setup a sub=function SCN() that is called once per scanline at the costs of more bytes/characters.  
Line 30: Line 36:
 
end
 
end
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
[https://github.com/nesbox/TIC-80/wiki/tic See here] to know how tic() is called in the different language supported by TIC-80.
  
 
A full overview of the TIC80 memory map and most common used function is available in this handy TIC80 cheatsheet, as well as the TIC80 wiki page.
 
A full overview of the TIC80 memory map and most common used function is available in this handy TIC80 cheatsheet, as well as the TIC80 wiki page.
Line 36: Line 44:
  
 
=== Video display ===
 
=== Video display ===
The TIC-80 has a 240x136 pixel display with 16colors which can be accessed via a wide range of graphics functions or by writing directly to VRAM at memory address 0x0000 using the poke4 instruction.
+
The TIC-80 has a 240x136 pixel display with 16colors which can be accessed via a wide range of graphics functions or by writing directly to VRAM at memory address 0x0000 using the <code>poke4</code> instruction, that just change 4 bits. The address have to be multiplied by 2 when using poke4. access to 0x1000 for example is 0x02000 (high nibble) and 0x02001 (low nibble).
  
 
==== Draw functions ====
 
==== Draw functions ====
Line 67: Line 75:
  
 
==== Color Palette ====
 
==== Color Palette ====
Unfortunately for us sizecoders, the pre v0.8 TIC-80 came with a different palette than the now standard (and much more friendly) sweety16 palette (https://lospec.com/palette-list/sweetie-16).
+
The best way to start is to use the default sweetie16 palette (https://lospec.com/palette-list/sweetie-16) as this palette
 
+
offers a nice selection of 16 colors arranged in such a way that they are easily accessable. From the verion 0.9b version and beyond you can initialise the new default sweetie16 palette at startup by adding a 0x11 Chunk to your TIC-80 cartridge.  
But because of backwards compatibility, this old palette is also the default palette that is being used when now palette chunk is defined in the TIC cart.
 
  
[[File:TIC80 Defaultpal.png|thumb|left|]]
+
Normally a chunk would contain 4 bytes of header + data, but as this chunk has no data, it is possible to omit the extra 3 bytes of chunk-header if you place it at the end of your TIC cartridge. The new TIC-Packer linked below has the option to do this for you.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
So you can get around this limitation by either setting a palette yourself with code, or shuffling around with your color-index.
 
 
 
==== Select the Sweetie16 by using the 0x11 chunk  ====
 
From the verion 0.9b version and beyond you can initialise the new default sweetie16 palette at startup by adding a 0x11 Chunk to your TIC-80 cartridge. Normally a chunk would contain 4 bytes of header + data, but as this chunk has no data, it is possible to omit the extra 3 bytes of chunk-header if you place it at the end of your TIC cartridge. The new TIC-Packer linked below has the option to do this for you.
 
  
 
==== Setting your own color palette ====
 
==== Setting your own color palette ====
Probably the easiest way to get some color over your colors is to setup your own palette by writing to the palette area located at 0x3fc0 like so:
+
Alternatively you can setup your own palette by writing to the palette area located at 0x3fc0 like so:
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
 
for i=0,47 do poke (0x3fc0+i,i*5)end
 
for i=0,47 do poke (0x3fc0+i,i*5)end
Line 93: Line 88:
  
 
==== Color index shuffling ====
 
==== Color index shuffling ====
Alternatively, you can shuffle your color indices a bit to get 'somewhat workable' colors.
+
If you don't want to use the sweetie16 palette you can revert back to the pre 0.8 db16 palette by simply not including a 0x11 chunk in you cartridge. Although the arrangement of color-indices is not as ideal as sweetie16, you can shuffle your color indices a bit to get 'somewhat workable' colors.
 +
 
 
A couple of examples for this are
 
A couple of examples for this are
 
* (color)&10 - Some grey/blue shade
 
* (color)&10 - Some grey/blue shade
Line 128: Line 124:
 
But as you can see this costs considerably more bytes to setup.
 
But as you can see this costs considerably more bytes to setup.
  
=== Compression And Release ===
+
=== Final Optimisations ===
 
When you are happy with your intro and want to get it ready for release, it becomes time to look at squeezing those last bytes.
 
When you are happy with your intro and want to get it ready for release, it becomes time to look at squeezing those last bytes.
 
As a goal-post, you should always aim to have your uncompressed effect around the target size, and work from there.
 
As a goal-post, you should always aim to have your uncompressed effect around the target size, and work from there.
Line 135: Line 131:
 
A rule of thumb for this is that of the first or last character of a variable or function isn't a valid hex number (i.e. A-F) you can omit whitespace (so that: x=0 y=0 z=0 can become x=0y=0z=0)
 
A rule of thumb for this is that of the first or last character of a variable or function isn't a valid hex number (i.e. A-F) you can omit whitespace (so that: x=0 y=0 z=0 can become x=0y=0z=0)
  
Now as a final step you can use a python script to convert your (LUA) Script to a empty TIC Cartridge with a single ZLIB compressed code block (https://bitbucket.org/WaterEnVuur/tic80-packer/src/master/)
+
=== Release ===
 +
For releasing an intro at a demoscene event, a raw TIC cartridge file without any additional graphics/sound/metadata is needed.
 +
 
 +
Creating a http://www.sizecoding.org/index.php?title=Fantasy_Consoles&action=edit&section=13 TIC cartridge file adds a 4 byte header + 1 extra byte for a 0x11 sweetie16 chunk.
  
However, creating a TIC cartridge file adds a 4 byte header and if your code is already pretty tight, you can expect to have only a 3-5% compression rate, so it sort of evens out.
+
Luckily there are various packers that help you convert your (LUA) Script to a empty TIC Cartridge with a single ZLIB compressed code block and optional 0x11 (sweetie16) palette chunk. See the additional links for links to these packers.
 
   
 
   
 
==== Exporting Video as Animated GIF ====
 
==== Exporting Video as Animated GIF ====
Line 145: Line 144:
  
 
==== Online version: Metadata and Thumbnail image ====
 
==== Online version: Metadata and Thumbnail image ====
When uploading the intro to the TIC80 website for an playable online version, you will need to build a new TIC file with some added some meta-data and Thumbnail image (You can take this snapshot using the F7 key) and use this as you online version.
+
When uploading the intro to the TIC80 website for a playable online version, you will need to build a new TIC file with some added some meta-data and Thumbnail image (You can take this screenshot using the F7 key during the demo playback) and use this as you online version. The screenshot can also be imported from a 240×136 PNG (other size will throw an error) using inside TIC-80 console <code>import screen file[.png]</code>.
  
 
The Meta data is added at the top of your intro as follows
 
The Meta data is added at the top of your intro as follows
Line 154: Line 153:
 
-- script: lua (or moon/wren/js/fennel)
 
-- script: lua (or moon/wren/js/fennel)
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
Update: As of version 0.9b the TIC80.COM website now also allows you to upload a seperate TIC file with the metadata and keep the uploaded binary TIC file as code only.
  
 
=== Additional Resources ===
 
=== Additional Resources ===
Line 163: Line 164:
 
* TIC-80 TIC Cartridge File Format (from TIC-80 Wiki) https://github.com/nesbox/TIC-80/wiki/tic-File-Format
 
* TIC-80 TIC Cartridge File Format (from TIC-80 Wiki) https://github.com/nesbox/TIC-80/wiki/tic-File-Format
 
* TIC-80 Packer https://bitbucket.org/WaterEnVuur/tic80-packer/src/master/
 
* TIC-80 Packer https://bitbucket.org/WaterEnVuur/tic80-packer/src/master/
 +
:* Pactic, fork de TIC-80 Packer https://github.com/phlubby/pactic
 +
* TIC-Tool https://github.com/exoticorn/tic-tool
  
 
== PICO-8 ==
 
== PICO-8 ==
Line 192: Line 195:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
A full overview of the TIC80 memory map and most common used functions is available in this handy PICO-8 cheatsheet, as well as the PICO-8 wiki page.
+
Here is a single-image PICO-8 Cheat sheet to get you started.
 
<gallery>
 
<gallery>
 
+
PICO-8_Cheat_Sheet.png
 
</gallery>
 
</gallery>
  
 
=== Video display ===
 
=== Video display ===
The PICO-8 has a 128x128 pixel display with 16colors which can be accessed via a wide range of graphics functions or by writing directly to VRAM at memory address 0x6000 using the poke instruction.
+
The PICO-8 has a 128x128 pixel display with 16 colors which can be accessed via a wide range of graphics functions.
  
==== Draw functions ====
+
==== Built-in Draw functions ====
There are a couple of built-in drawing functions you can use:
+
Here are a couple of built-in drawing functions you can use:
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
cls(color=0)
+
CLS(color=0)
pix(x,y[color]) [-> color]
+
PSET(x,y,color)  
circ(x,y,r,color) -- filled circle
+
color=PGET(x,y)
circb(x,y,r,color) -- border circle
+
CIRC(x,y,r,color)
rect(x,y,w,h,color) -- filled rect
+
CIRCFILL(x,y,r,color)
rectb(x,y,w,h,color) -- border rect
+
RECT(x,y,w,h,color)
line(x0,y0,x1,y1,color)
+
RECTFILL(x,y,w,h,color)
tri(x1,y1,x2,y2,x3,y3,color)
+
LINE(x0,y0,x1,y1,color)
textri(x1,y1,x2,y2,x3,y3,u1,v1,u2,v2,u3,v3,use_map=false,colorkey=-1)
+
PRINT(text,[x,y,color])
print(text,x=0,y=0,color=15,fixed=false,scale=1,smallfont=false) -> width
+
 
 +
COLOR(color) - Set default color
 +
PAL(destindex,sourceindex) - Replace dest colorindex with color from sourceindex
 +
FILLP(mask) -- Set fill pattern for circ, circfill, rect, rectfill, pset, and line
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 232: Line 238:
 
Unfortunately for us sizecoders, the PICO-8 comes with a fixed palette to 16 colors with size-unfriendely color indexing (https://lospec.com/palette-list/pico-8).
 
Unfortunately for us sizecoders, the PICO-8 comes with a fixed palette to 16 colors with size-unfriendely color indexing (https://lospec.com/palette-list/pico-8).
  
Fortunately there are a few PICO-8 functions available that let you swap the color index of each color, but ofcourse these take up a bit of space to use.
+
Luckily, the PICO-8 provides a PAL(source,dest) function that lets you swap the color index of each color, but these are quite costly at 8-10 bytes per colorswap call.
 +
 
 +
==== Colorindex table ====
 +
One of the easier way to get a nice color-ramp without using the PAL function is to use a color indextable like so:
 +
 
 +
<syntaxhighlight lang=lua>
 +
c={0,5,6,7}
 +
pset(x,y,c[i])
 +
</syntaxhighlight>
 +
 
 +
This method gives you the most freedom in terms of building your custom ramp of colors.
  
 
==== Color index shuffling ====
 
==== Color index shuffling ====
 
Alternatively, you can shuffle your color indices a bit to get 'somewhat workable' colors.
 
Alternatively, you can shuffle your color indices a bit to get 'somewhat workable' colors.
A couple of examples for this are
+
 
 +
A couple of examples for this are:
 +
* color+4 / pal(4,0) - Replaces color index 4 with 0(black) for a 4-shade Grayscale
 
* color&7*2 - Black, Purple, brown, white
 
* color&7*2 - Black, Purple, brown, white
* (color&7)^2 -Black, blue, brown yellow
+
* (color&7)^2 - Black, blue, brown yellow
  
 
But feel free to experiment yourself as well and let us know on discord if you find something cool.
 
But feel free to experiment yourself as well and let us know on discord if you find something cool.
  
 
=== Sound ===
 
=== Sound ===
The PICO-8 has soundregisters you can either POKE directly of play with tone/sfx play command
+
The PICO-8 does not allow you to poke the soundregisters directly, but instead works with the SFX(effectindex) command to generate sounds. However we are allowed to poke the piece of memory that holds the soundeffect data, like so:
  
<syntaxhighlight>
+
<syntaxhighlight lang="lua">
TBA
+
POKE(12869+offset,value)SFX(1)
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==== Make some noise ====
+
=== PICO-8 vs TIC-80 Sizecoding ===
The easiest way to get 'some' sound going is to bitbang the sound-registers and hope for the best, for example:
+
If you are familiar with TIC-80 sizecoding, but less with PICO-8. This chapter will help you point out the main differences between the 2 platforms:
<syntaxhighlight lang="lua">
+
 
TBA
+
* Performance on PICO-8 is more limited. The use of instructions/tokens (inside and outside loops) will have a performance/token penalty.
</syntaxhighlight>
+
* Less code to work with (for a typical 256byte intro 229 characters vs 300-400 characters of LZ compressed code on the TIC-80)
 +
* Code-editor = Escape (prepare to have your desktop filled with screenshots by accidentally pressing F1 ;-)
 +
* All alphabetic letters can be tugged against numeric chars (0..9) on PICO-8
 +
* Math functions don't need the MATH. prefix (SIN, COS, ATAN2, SQRT, SGN, RND, etc.)
 +
* No integer divisions are needed anymore for logical operations
 +
* The PICO-8 has custom characters available in the font (character numbers 128+).
 +
* The PICO-8 LUA variant supports x+=value / x-=value
 +
* The XOR operator is ^^ instead of ~
 +
* FUNCTION _DRAW() = FUNCTION TIC()
 +
* Warning: The POKE4 function pokes 4 bytes intro memory instead of a nibble. Nibble poke is not available.
  
=== Compression And Release ===
+
=== Final optimisations and P8 Cartridge Release ===
 
When you are happy with your intro and want to get it ready for release, it becomes time to look at squeezing those last bytes.
 
When you are happy with your intro and want to get it ready for release, it becomes time to look at squeezing those last bytes.
As a goal-post, you should always aim to have your uncompressed effect around the target size, and work from there.
 
  
Final optimisation can be done by stringing as much code together on single lines and removing any extra spaces and whitelines.
+
Final optimisations can be done by stringing as much code together on single lines and removing any extra spaces and whitelines.
A rule of thumb you can always directly stick a letter A..Z after a number 0..9
+
 
 +
Here are a couple of other tips and tricks that help you squeeze those final bytes:
 +
 
 +
* You can always directly stick a letter A..Z after a number 0..9 or a bracket.
 +
* Make sure to reorder variable assigments and code around to make use of optimal letter/number squeezing.
 +
* Unlike the TIC-80 , no integer divides (like //1) are usually necessary for doing logical operations.
 +
* Using a GOTO loop construction like ::L:: <yourcode> FLIP()GOTO L will save you 1 character over FUNCTION _DRAW() <yourcode> END
 +
* You can alias functions that you are going to use more frequently, e.g. S=SIN or R=RND
 +
* Using decimal values instead of hexadecimal will save 1 character (32768 vs 0x8000)
 +
* Did you know that the T() shorthand version of the TIME() function is also available?
 +
* Remember that ?"text",x,y is a shorthand for PRINT("text",x,y), however it does require its own newline (2x enter) to work
  
Much like the TIC-80, most demoparties will accept a loadable .P8 cartridge file as an intro, which adds a 27 byte header like so:
+
When you are done, make sure that your raw LUA character count is around the target size minus 27 characters, as most demoparties will accept a loadable .P8 cartridge file as an intro, which adds a 27 byte header like so:
  
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
 
pico-8 cartridge
 
pico-8 cartridge
version
+
 
 
__lua__
 
__lua__
 
</syntaxhighlight>
 
</syntaxhighlight>
Followed by your raw LUA code. So please take this 27 byte hit into account when optimising your intro.
+
 
 +
Followed by your raw LUA code, so this leaves:
 +
* 101 characters for a 128 byte intro.
 +
* 229 characters for a 256 byte intro.
 +
* 485 characters for a 512 byte intro.
 +
* 997 characters for a 1024 byte intro.
 +
 
 +
The number of used characters can be made visible in the bottom right of the PICO-8 code editor, so that you can keep track.
 +
 
 +
You can edit the cartridge with with above header in an external editor or find and strip them down from your internal PICO-9 cartridge folder (type FOLDER to jump directly to your cartridge folder and/or edit the PICO-8 config.txt to save your P8 cartridge files elsewhere).
  
 
=== Additional Resources ===
 
=== Additional Resources ===
Line 277: Line 322:
 
* PICO-8 One page cheat sheet (PNG) https://imgur.com/iGrP5bK
 
* PICO-8 One page cheat sheet (PNG) https://imgur.com/iGrP5bK
 
* PICO-8 API Reference https://neko250.github.io/pico8-api/
 
* PICO-8 API Reference https://neko250.github.io/pico8-api/
* PICO-8 Intros and demos on Pouet (Press Escap for code): https://www.pouet.net/prodlist.php?platform%5B%5D=TIC-80
 
 
* PICO-8 guide https://nerdyteachers.com/PICO-8/Guide/
 
* PICO-8 guide https://nerdyteachers.com/PICO-8/Guide/
 +
* PICO-8 List of sizecoded Fantasy Console intros (PICO-8/TIC-80) https://www.pouet.net/lists.php?which=199
  
 
== Javascript ==
 
== Javascript ==

Revision as of 04:30, 2 October 2021

Introduction

Welcome to the virtual machine section of the website, where we will cover virtual machine (VM) languages and platforms like the TIC-80 and Javascript.

TIC-80

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

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.

Setting up

As the TIC-80 fantasy computer is an all-in-one creation and execution platform, setting up TIC-80 is very easy:

Just go to the https://github.com/nesbox/TIC-80/releases page

and download the package for your platform of choice (Windows, OSX, Linux and even Raspberry Pi).

Or if you are just curious you can just start doodling online at http://tic80.com/

Getting started

Most TIC-80 programs are coded using the Lua Scripting language. However it is possible to select different scripting language like javascript at the cost of a couple of bytes/characters like so (respectively for JavaScript, MoonScript, Wren, Fennel, Squirrel):

//script: js
-- script: moon
// script: wren
;; script: fennel
// script: squirrel

The main function used for updating the screen (and called 60 times a second) is the TIC() function, so this function is also a requirement for doing anything with graphics. Additionally you can also setup a sub=function SCN() that is called once per scanline at the costs of more bytes/characters.

Most animated effects will also need to use some kind of a timer, so you are likely to also use the built-in time() function or keep track of your time (t) yourself as well.. So a minimal setup would look something like this:

function TIC()t=time()
-- your effect code
end

See here to know how tic() is called in the different language supported by TIC-80.

A full overview of the TIC80 memory map and most common used function is available in this handy TIC80 cheatsheet, as well as the TIC80 wiki page.

https://zenithsal.com/assets/documents/tic-80_cheatsheet.pdf

Video display

The TIC-80 has a 240x136 pixel display with 16colors which can be accessed via a wide range of graphics functions or by writing directly to VRAM at memory address 0x0000 using the poke4 instruction, that just change 4 bits. The address have to be multiplied by 2 when using poke4. access to 0x1000 for example is 0x02000 (high nibble) and 0x02001 (low nibble).

Draw functions

There are a couple of built-in drawing functions you can use:

cls(color=0)
pix(x,y[color]) [-> color]
circ(x,y,r,color) -- filled circle
circb(x,y,r,color) -- border circle
rect(x,y,w,h,color) -- filled rect
rectb(x,y,w,h,color) -- border rect
line(x0,y0,x1,y1,color)
tri(x1,y1,x2,y2,x3,y3,color)
textri(x1,y1,x2,y2,x3,y3,u1,v1,u2,v2,u3,v3,use_map=false,colorkey=-1)
print(text,x=0,y=0,color=15,fixed=false,scale=1,smallfont=false) -> width

Getting something on screen

Here is a bit of code to get you started:

function TIC() 
t=time()/99
for y=0,136 do for x=0,240 do
pix(x,y,(x>>3~y>>3)+t)
end;end;end

Which will display an animated XOR pattern.

Color Palette

The best way to start is to use the default sweetie16 palette (https://lospec.com/palette-list/sweetie-16) as this palette offers a nice selection of 16 colors arranged in such a way that they are easily accessable. From the verion 0.9b version and beyond you can initialise the new default sweetie16 palette at startup by adding a 0x11 Chunk to your TIC-80 cartridge.

Normally a chunk would contain 4 bytes of header + data, but as this chunk has no data, it is possible to omit the extra 3 bytes of chunk-header if you place it at the end of your TIC cartridge. The new TIC-Packer linked below has the option to do this for you.

Setting your own color palette

Alternatively you can setup your own palette by writing to the palette area located at 0x3fc0 like so:

for i=0,47 do poke (0x3fc0+i,i*5)end

This produces a nice grayscale palette of 16 shades to work with.

Color index shuffling

If you don't want to use the sweetie16 palette you can revert back to the pre 0.8 db16 palette by simply not including a 0x11 chunk in you cartridge. Although the arrangement of color-indices is not as ideal as sweetie16, you can shuffle your color indices a bit to get 'somewhat workable' colors.

A couple of examples for this are

  • (color)&10 - Some grey/blue shade
  • ((color)&6)-3 - A Nice shade of Dark-cyan-white color
  • (color)^2 - A shade of brown/yellowish colors

But feel free to experiment yourself as well and let us know on discord if you find something cool.

Sound

The TIC-80 has soundregisters and 32 byte waveforms to access which are located at address 0FF9C in memory.

0FF9C SOUND REGS 72 18 byte x 4 ch
0FFE4 WAVEFORMS 256 16 wave/ 32x4b each
100E4 SFX 4224 64 sounds

Make some noise

The easiest way to get 'some' sound going is to bitbang the sound-registers and hope for the best, for example:

TIC=function()for i=0,71 do poke(65436+i,(time()/7.2)%64)end end

A more the "proper" way involves something like : define the waveform yourself (f.e. sawtooth), repeatedly (because for some reason one time is not enough), then write low part of the frequency to one byte, and the high nibble combined with the volume to another)

TIC=function()
for i=0,31 do poke4(2*65438+i,i/2) end -- setup waveforem
t=time()/10 
-- write frequencies
poke(65436+0,t%256) 
poke(65437+0,(t/65536)%16+240)
end

But as you can see this costs considerably more bytes to setup.

Final Optimisations

When you are happy with your intro and want to get it ready for release, it becomes time to look at squeezing those last bytes. As a goal-post, you should always aim to have your uncompressed effect around the target size, and work from there.

Final optimisation can be done by stringing as much code together on single lines and removing any extra spaces and whitelines. A rule of thumb for this is that of the first or last character of a variable or function isn't a valid hex number (i.e. A-F) you can omit whitespace (so that: x=0 y=0 z=0 can become x=0y=0z=0)

Release

For releasing an intro at a demoscene event, a raw TIC cartridge file without any additional graphics/sound/metadata is needed.

Creating a http://www.sizecoding.org/index.php?title=Fantasy_Consoles&action=edit&section=13 TIC cartridge file adds a 4 byte header + 1 extra byte for a 0x11 sweetie16 chunk.

Luckily there are various packers that help you convert your (LUA) Script to a empty TIC Cartridge with a single ZLIB compressed code block and optional 0x11 (sweetie16) palette chunk. See the additional links for links to these packers.

Exporting Video as Animated GIF

The TIC80 environment has a neat feature that lets you export your intro directly as an animated GIF file to converted to video later, by Pressing the F9 key to start and stop recording. However, there is a default recording limit capped to a fixed number of frames or seconds. You can change this in the tic80 config to a bigger number to match your recording-size.

If your intro is taking up too many resources and starts chugging a bit on your machine, it can be wise to make a version that steps through time lineary by adding a number to your t variable yourself instead of using the time() function.

Online version: Metadata and Thumbnail image

When uploading the intro to the TIC80 website for a playable online version, you will need to build a new TIC file with some added some meta-data and Thumbnail image (You can take this screenshot using the F7 key during the demo playback) and use this as you online version. The screenshot can also be imported from a 240×136 PNG (other size will throw an error) using inside TIC-80 console import screen file[.png].

The Meta data is added at the top of your intro as follows

-- title: My intro
-- author: scener
-- desc: my first sizecoded TIC-80 intro
-- script: lua (or moon/wren/js/fennel)

Update: As of version 0.9b the TIC80.COM website now also allows you to upload a seperate TIC file with the metadata and keep the uploaded binary TIC file as code only.

Additional Resources

Sizecoding on the TIC-80 is still in its infancy, but luckily there is already plenty of information to get you started!

PICO-8

The PICO-8 is a fantasy computer for making, playing and sharing tiny games and demos.

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: 128x128 pixels display, 16 color palette, 256 8x8 color sprites and 4 channel sound

Setting up

As the PICO-8 fantasy computer is an all-in-one creation and execution platform.

Unfortunately, the PICO-8 is a commercial package and should be purchased before you can get started.

You can go to https://lexaloffle.itch.io/pico-8 to purchase and then download the package for your platform of choice (Windows, OSX and even Raspberry Pi).

Getting started

PICO-8 programs are coded using the LUA Scripting language.

The main function used for updating the screen (and called either 30 or 60 times a second) is the _DRAW() function, so this function is also a requirement for doing anything with graphics.

Most animated effects will also need to use some kind of a timer, so you are likely to also use the built-in time() function or keep track of your time (t) yourself as well.. So a minimal setup would look something like this:

T=0 FUNCTION _DRAW()
-- your effect code
T=T+1
END

Here is a single-image PICO-8 Cheat sheet to get you started.

Video display

The PICO-8 has a 128x128 pixel display with 16 colors which can be accessed via a wide range of graphics functions.

Built-in Draw functions

Here are a couple of built-in drawing functions you can use:

CLS(color=0)
PSET(x,y,color) 
color=PGET(x,y)
CIRC(x,y,r,color)
CIRCFILL(x,y,r,color)
RECT(x,y,w,h,color)
RECTFILL(x,y,w,h,color)
LINE(x0,y0,x1,y1,color)
PRINT(text,[x,y,color])

COLOR(color) - Set default color
PAL(destindex,sourceindex) - Replace dest colorindex with color from sourceindex
FILLP(mask) -- Set fill pattern for circ, circfill, rect, rectfill, pset, and line

Getting something on screen

Here is a bit of code to get you started:

T=0FUNCTION _DRAW() 
FOR Y=0,128 DO FOR X=0,128 DO
PSET(X,Y,X~Y+T)
END END
T=T+1
END

Which will display an animated XOR pattern.

Color Palette

Unfortunately for us sizecoders, the PICO-8 comes with a fixed palette to 16 colors with size-unfriendely color indexing (https://lospec.com/palette-list/pico-8).

Luckily, the PICO-8 provides a PAL(source,dest) function that lets you swap the color index of each color, but these are quite costly at 8-10 bytes per colorswap call.

Colorindex table

One of the easier way to get a nice color-ramp without using the PAL function is to use a color indextable like so:

c={0,5,6,7}
pset(x,y,c[i])

This method gives you the most freedom in terms of building your custom ramp of colors.

Color index shuffling

Alternatively, you can shuffle your color indices a bit to get 'somewhat workable' colors.

A couple of examples for this are:

  • color+4 / pal(4,0) - Replaces color index 4 with 0(black) for a 4-shade Grayscale
  • color&7*2 - Black, Purple, brown, white
  • (color&7)^2 - Black, blue, brown yellow

But feel free to experiment yourself as well and let us know on discord if you find something cool.

Sound

The PICO-8 does not allow you to poke the soundregisters directly, but instead works with the SFX(effectindex) command to generate sounds. However we are allowed to poke the piece of memory that holds the soundeffect data, like so:

POKE(12869+offset,value)SFX(1)

PICO-8 vs TIC-80 Sizecoding

If you are familiar with TIC-80 sizecoding, but less with PICO-8. This chapter will help you point out the main differences between the 2 platforms:

  • Performance on PICO-8 is more limited. The use of instructions/tokens (inside and outside loops) will have a performance/token penalty.
  • Less code to work with (for a typical 256byte intro 229 characters vs 300-400 characters of LZ compressed code on the TIC-80)
  • Code-editor = Escape (prepare to have your desktop filled with screenshots by accidentally pressing F1 ;-)
  • All alphabetic letters can be tugged against numeric chars (0..9) on PICO-8
  • Math functions don't need the MATH. prefix (SIN, COS, ATAN2, SQRT, SGN, RND, etc.)
  • No integer divisions are needed anymore for logical operations
  • The PICO-8 has custom characters available in the font (character numbers 128+).
  • The PICO-8 LUA variant supports x+=value / x-=value
  • The XOR operator is ^^ instead of ~
  • FUNCTION _DRAW() = FUNCTION TIC()
  • Warning: The POKE4 function pokes 4 bytes intro memory instead of a nibble. Nibble poke is not available.

Final optimisations and P8 Cartridge Release

When you are happy with your intro and want to get it ready for release, it becomes time to look at squeezing those last bytes.

Final optimisations can be done by stringing as much code together on single lines and removing any extra spaces and whitelines.

Here are a couple of other tips and tricks that help you squeeze those final bytes:

  • You can always directly stick a letter A..Z after a number 0..9 or a bracket.
  • Make sure to reorder variable assigments and code around to make use of optimal letter/number squeezing.
  • Unlike the TIC-80 , no integer divides (like //1) are usually necessary for doing logical operations.
  • Using a GOTO loop construction like ::L:: <yourcode> FLIP()GOTO L will save you 1 character over FUNCTION _DRAW() <yourcode> END
  • You can alias functions that you are going to use more frequently, e.g. S=SIN or R=RND
  • Using decimal values instead of hexadecimal will save 1 character (32768 vs 0x8000)
  • Did you know that the T() shorthand version of the TIME() function is also available?
  • Remember that ?"text",x,y is a shorthand for PRINT("text",x,y), however it does require its own newline (2x enter) to work

When you are done, make sure that your raw LUA character count is around the target size minus 27 characters, as most demoparties will accept a loadable .P8 cartridge file as an intro, which adds a 27 byte header like so:

pico-8 cartridge

__lua__

Followed by your raw LUA code, so this leaves:

  • 101 characters for a 128 byte intro.
  • 229 characters for a 256 byte intro.
  • 485 characters for a 512 byte intro.
  • 997 characters for a 1024 byte intro.

The number of used characters can be made visible in the bottom right of the PICO-8 code editor, so that you can keep track.

You can edit the cartridge with with above header in an external editor or find and strip them down from your internal PICO-9 cartridge folder (type FOLDER to jump directly to your cartridge folder and/or edit the PICO-8 config.txt to save your P8 cartridge files elsewhere).

Additional Resources

Sizecoding on the PICO-8 is still in its infancy, but luckily there is already plenty of information to get you started!

Javascript

The Javascript sizecoding community has been quite active for years now.

Setting up

Video display

No information yet

Sound

Something to get your journey started:

More information to follow

Additional Resources

Tutorials / Postmortems

More to follow