THIS PAGE WON'T BE UPDATED. Future updates will be in the sizecoding.org wiki: [http://www.sizecoding.org/wiki/Bytebattles]
This is an evolving list of various useful tricks for delivering the most awesome fatalities in byte battles. Possibly also interesting for TIC-80 sizecoding in general.
| Symbol | Definition |
|---|---|
x |
x-coordinate of a pixel |
y |
y-coordinate of a pixel |
i |
index of a pixel |
s |
alias for math.sin |
-
Functions, that are called 3 or more times should be aliased. For example,
e=elliwithe()e()e()is 3 bytes shorter thanelli()elli()elli(). Functions with 5 characters may already benefit from aliasing with 2 calls:r=rectbwithr()r()is 1 byte shorter thanrectb()rectb(). -
t=0witht=t+.1is 3 bytes shorter thant=time()/399. -
for i=0,32639 do x=i%240y=i/240 endis 2-3 bytes shorter thanfor y=0,135 do for x=0,239 do end end. -
(x*x+y*y)^.5is 6 bytes shorter thanmath.sqrt(x*x+y*y). -
s(w-11)ands(w+8)both approximatemath.cos(w), so onlymath.sinneeds to be aliased.s(w-11)is slightly more accurate, with the cost of 1 byte.
Most whitespace can be removed from LUA code. For example: x=0y=0 is
valid. All new lines can be removed or replaced with space, making the
whole code a single line:
function TIC()cls()for i=0,32639 do poke4(i,i)end end
⚠️ Lettersa-fandA-Fafter a number cause problems.a=0b=0is not valid code. It is advisable to only used one letter variables in the rangesg-zandG-Zfrom the start; this will make eventual one-lining easier.
Function load takes a string of code and returns a function with no
named arguments, with the code as its body. It's particularly useful for
shortening the TIC function after it's onelined:
TIC=load'cls()for i=0,32639 do poke4(i,i)end'As a rule of thumb, one-lining and using the load trick can bring a ~ 275 character code down to 256.
load can be even used to minimize a function with parameters: ...
returns the parameters. For example, the following saves 3 bytes:
SCN=load'r=...poke(16320,r)'
⚠️ The backlash causes problems when using the load trick. In particular, if you have a string with escaped characters in the original code i.e.print("foo\nbar"), then this needs to be double-escaped:load'print("foo\\nbar")'.
If you have a floating point color value, TIC-80 pix and poke functions
round it (toward zero). To add dithering, add a small value, between 0
and 1, to the color. The best technique depends whether you have x and
y available or only i and how many bytes you can spare:
A quick example demonstrating the 2x2 block dithering:
function TIC()
cls()
for i=0,2399 do
x=i%240
y=i//240
poke4(i,x/30+(x*2-y%2)%4/4)
end
endThe following palettes assume that j goes from 0 to 47. Usually
there's no need to make a new loop for this: just reuse another loop
with j=i%48.
Code for testing palettes:
function TIC()
cls()
for j=0,47 do poke(16320+j,s(j/15)*255)end
for c=0,15 do rect(c*5,0,5,5,c)end
end
s=math.sinIn TIC-80 API, the pix and poke4 functions round numbers towards
zero. This can be abused for a motion blur: poke4(i,peek4(i)-.9) maps
colors 1 to 15 into one lower value, but value 0 stays at it is. Like
so:
function TIC()
t=time()/9
circ(t%240,t%136,9,15)
for i=0,32639 do poke4(i,peek4(i)-.9)end
endThe basic structure for a raymarcher that has not been crunched to keep it readable. The map is bunch of repeated spheres here:
function TIC()
for i=0,32639 do
-- ray (u,v,w), not normalized!
u=i%240/120-1
v=i/32639-.5
w=1
-- camera origo (x,y,z)
x=3
y=0
z=time()/999 -- camera moves with time
j=0
repeat
X=x%6-3 -- domain repetition
Y=y%6-3
Z=z%6-3
-- ray not normalized=>reduce scale
m=(X*X+Y*Y+Z*Z)^.5/2-1
x=x+m*u
y=y+m*v
z=z+m*w
j=j+1
until j>15 or m<.1
poke4(i,j)
end
end







