Skip to content

Instantly share code, notes, and snippets.

@rostok
Created September 8, 2022 17:43
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rostok/85f3673b696e44e10da7d954d27564b4 to your computer and use it in GitHub Desktop.
Save rostok/85f3673b696e44e10da7d954d27564b4 to your computer and use it in GitHub Desktop.
source code for dehydrated - a pico8 game under 1kb
pico-8 cartridge // http://www.pico-8.com
version 37
__lua__
-- Dehydrated - a Pico1k 2022 jam entry by https://rostok.itch.io/ @von_rostock
-- as the original code was heavily compressed here is the unpacked source with a brief description of what's going on
D={}E={} -- D E tables hold x and y global position values for wind dust particles, there are 129 dust particles in total
K={} -- K L M tables store map data, they are linear with total length of 128x310 it's hard to explain how they are organized
-- since tiles are of isometric shape. however basic address is expression is v+310*u with u/v being cell coordinates
-- K table hold compacted tile information
-- bits 1-4 represent height (value range 0..15), with 0 being water, and 1+ being sand
-- 5th bit means tile will be picked random (value 32) or not (for shadow effect darkest/leftmost tile is used)
-- 6th bit means water under sand (value 64)
-- 7th bit if set indicates tree on a tile
L={} -- L table holds tile/sprite number for each cell as row number (0, 64, 128) and sprite number, these are
-- calculated only once
N={} -- hold general random 0..31 used for trees
c=0 -- temp var for cell elevation
p=0q=0 -- p q represent player position in global space (or rather screen left right corner)
w=~0 -- w is a bit mask used for both marking place with hidden water and revealing it
z=0 -- z holds random altitude for cells/tiles used for seismic quake
T="T" -- T is used for drawing tool player can find and once obtained being empty
m="\^!5f1149♥" -- sets palette on first frame (black, brown, orange, light yellow), notice skipping first byte
-- later m is used for final info text
for u=0,128do -- initialize all the tiles, apparently hardcoding constants allows for better code compression
for v=0,310do -- note that the vertical loop is inner, this is to calculate dunes shadow
d=c&15 -- d stores last cell elevation, or the one that has lower v coordinate
E[u]=0D[u]=0 -- initialize dust particle x and y to 0
e=0 -- e will store elevation using the quasi Gardner texture result, spanning from approx. -1 to 1
c=(u\16+u\8+rnd())%3+u/128+1 -- pick color for iso cube lower sides, it is color number 1 for left, 2 for right with slight variation
-- there will be total of 32 iso cubes with dimensions of 16x32
-- the ones further to right seem a little lighter
-- last 8 sprites are water and their side color is irrelevant
-- sprites are 16 pixels wide, with top being 4 pixel tall, each tile is approx 24 pixels tall in total
if(v%24+abs(u%16-8)<8)c=2+rnd(1+u/310/2) -- change the color for cube top side
sset(u,v%24+abs(u%16-8)/2+v\24*32,c+v\72*10.3) -- set pixel in sprite memory, v\72*10.3 will change the colors to blue shades (pico's default 12 and 13)
for i=1,4do -- very simple Gardner cloud texture generator with 4 iterations
g=4^i*.001e+=.4^i*(sin(g*u*2+sin(g*v)/2)+sin(g*v*2+sin(g*u)/5))
end -- for Gardner texture see Computers Graphics: Principle & Practice 2e, ch 20.8.2
c=1+12*abs(e)*min(1,10*sin(u/128/2)*sin(v/310/2))
-- now c holds value from 1 to 10, this is a elevation of the tile on map
-- elevation is damped on the edges with vertival and horizontal sin functions
-- note that sin in pico is negative for the first half but multiplying both negative results yields val > 0
if(d<=c)c|=32 -- comparing current elevation with previous one can create semi shadow effect
-- shadow is realy simple - it's the first column of tile sprites which are darkest
if(rnd()^-1.5>(u-75)^2+(v-160)^2)c|=128
-- this creates trees on the map by setting 7th bit
-- cell at 75/160 is the center where most of the trees are located
I=v+u*310 -- I holds cell index from u/v coords
K[I]=c -- store elecation, random bit, water being hidden and tree information
L[I]=rnd(3)\1*64+rnd(c&32) -- store sprite tile number
N[I]=rnd(32) -- and general random value for that tile
end
end -- ok, initialization is complete, to view sprite sheet use memcpy(0x6000,0,8192)
::_:: -- main game loop stars here
z*=.8 -- z is being damped with every frame
z&=3.75 -- and this ensures there is a cut off (without it rnd(z) may yield large values on very low z)
g=t()/2%5 -- g will hold growing radius with 10 sec period
I=(g*cos(t())+75)\1*310+(g*sin(t())+160)\1 -- calculate cell index I based on radius and angle aroiund 75/160 cell
K[I]=K[I]&w|64 -- store it but with w mask
-- remember that w is ~0 so it is all ones
-- when player finds the water this will become 192 which will flatten the height but leave the trees and water
e=(@24396&2)-@24396%2*2 -- read buttons
f=@24396\8%2-@24396\4%2 -- e is horizontal direction -2, 0 or 2, -- f is vertical direction -1, 0 or 1
?"\^1" -- flip()
p+=e -- adjust player position
q+=f
for y=0,168,4do -- draw the screen by paring 430 sprites with iso cubes, first line is ommited for performance reasons
X=y\8+q\8-p\16+y\4%2 -- this transforms screen location to U,V map coordinates
Y=y\8+q\8+p\16 -- X Y wont be changed in horizontal loop
for x=0,9do -- we draw sprite from top to bottom overwriting previous ones with higher tiles
a=2+rnd(z) -- a is height multiplier for elevation stored in K table, it is 2px minimally and in case z is set it may be more
U=Y+x -- U V cell coordinates are calculated
V=X-x
I=V%310+U%128*310 -- I is cell index trimmed with modulo
b=K[I] -- b is value with height and extra bits info
if(U!=U%128or V%310!=V)b=1a=1 -- if this cell is outside both the elevation and heigth multiplier are set to 1 - meaning flat earth and no trees
g=b&15 -- g is just elevation (leftmost 4 bits)
k=L[I]&~31 -- k is sprite index (or row multipied by 64)
n=L[I] -- n chooses one of 8 sprites in this row (it will be trimmed later)
if(g<1)n+=t()k=192 -- in case elevation is 0 this is water tile, then sprites will change with time and only the last row will be used
h=y-a*g-q%8 -- screen y position
g=x*16-p%16 -- g temp x position shifted for every second line (y is increased by 4 so y&4 is either 0 or 4)
spr(k+(n&14),g-(y&4)*2,h,2,2) -- draws sprite, the horizontal index is trimmed with &14, last bit is forced to 0 so only odd sprites are used
if(b>127)g-=N[I]\4for i=0,N[I]\8do line(g,h,g,h-3,0)line(g-3+i%2*6,h-5)h-=4g+=sin(t()/4+N[I])end
-- if 7th bit is set draw random swaying tree with branczes
end
end -- so far so good
?T,382-p,879-q,0 -- draws the seismic tool for player to pick up
if(p\8==40and q\4==207)T="" -- if player stumbles on it hide it by setting T to ""
b=K[(q+36-p/2)\8%310+(q+92+p/2)\8%128*310] -- b is cell elevation value for current player position
o=a*(b&15) -- o is a slight upward shift depending on elevation
if(o<1)o=-1m="well done" -- and if player is in water (o==0) then shift him down a little and set success notification
?"▮\+cd-\b|\#7\^jc7"..m,63,57-o -- draw player head, torso and success message
if(o>0)for i=-1,1,2do line(64+i,62-o,64+i+e*i*sin(t()*3),65-o+2*f*i*sin(t()*3))end
-- this draws player legs using e,f direction variables and time
if(btn(4)and#T<1)z=1 -- check if z is pressed and if player has tool use it by setting z to 1 (quake tiles)
if(btn(4)and#T>0)?"\#7\^jc7find my tool" -- if player has no tool show info to make him find one
if(b&64<z)?"\#7\^jc7just sand\as000" -- if there is just sand (6th bit not set) play sound and display info
if(b&64>64-z)w=192 -- if there is actually water underneath set w to 192 so water will be shown
-- this looks strange but if the button is not pressed z is zero and condition will be false
?"\f3" -- set color for dust particles
J=4+sin(t()/8) -- just a temp var with oscilating value
for i=0,128do -- draw dust particles dancing through the wind
x=D[i]-p -- D E holds global position so adjust for screen
y=E[i]-q
r=K[(E[i]%310+D[i]%128*310)\1]&15 -- is is radius for bifurcation based on cell for this particle
if(x>127or y%128!=y)E[i]=64+sin(t()/4)*32+q+q%64D[i]=p-r
-- once particle is off the screen set its new position on the left edge
D[i]+=r/2*cos(y/J/32)+rnd(4) -- twirl and swirl these little pixels to mesmerize the player
E[i]+=r/4*sin(x/J/32) -- note that D is pushed right slighltly harder
pset(x,y)
end
goto _ -- game loop ends making player to endlessly seek water on this deserted hell
pico-8 cartridge // http://www.pico-8.com
version 37
__lua__
D={}E={}K={}L={}N={}c=0p=0q=0w=~0z=0T="T"m="\^!5f1149♥"for u=0,128do
for v=0,310do
d=c&15E[u]=0D[u]=0e=0c=(u\16+u\8+rnd())%3+u/128+1if(v%24+abs(u%16-8)<8)c=2+rnd(1+u/310/2)
sset(u,v%24+abs(u%16-8)/2+v\24*32,c+v\72*10.3)for i=1,4do g=4^i*.001e+=.4^i*(sin(g*u*2+sin(g*v)/2)+sin(g*v*2+sin(g*u)/5))end
c=1+12*abs(e)*min(1,10*sin(u/128/2)*sin(v/310/2))if(d<=c)c|=32
if(rnd()^-1.5>(u-75)^2+(v-160)^2)c|=128
I=v+u*310K[I]=c
L[I]=rnd(3)\1*64+rnd(c&32)N[I]=rnd(32)end
end::_::z*=.8z&=3.75g=t()/2%5I=(g*cos(t())+75)\1*310+(g*sin(t())+160)\1K[I]=K[I]&w|64e=(@24396&2)-@24396%2*2f=@24396\8%2-@24396\4%2?"\^1"
p+=e
q+=f
for y=0,168,4do
X=y\8+q\8-p\16+y\4%2Y=y\8+q\8+p\16for x=0,9do
a=2+rnd(z)U=Y+x
V=X-x
I=V%310+U%128*310b=K[I]if(U!=U%128or V%310!=V)b=1a=1
g=b&15k=L[I]&~31n=L[I]if(g<1)n+=t()k=192
h=y-a*g-q%8g=x*16-p%16spr(k+(n&14),g-(y&4)*2,h,2,2)if(b>127)g-=N[I]\4for i=0,N[I]\8do line(g,h,g,h-3,0)line(g-3+i%2*6,h-5)h-=4g+=sin(t()/4+N[I])end
end
end?T,382-p,879-q,0
if(p\8==40and q\4==207)T=""
b=K[(q+36-p/2)\8%310+(q+92+p/2)\8%128*310]o=a*(b&15)if(o<1)o=-1m="well done"
?"▮\+cd-\b|\#7\^jc7"..m,63,57-o
if(o>0)for i=-1,1,2do line(64+i,62-o,64+i+e*i*sin(t()*3),65-o+2*f*i*sin(t()*3))end
if(btn(4)and#T<1)z=1
if(btn(4)and#T>0)?"\#7\^jc7find my tool"
if(b&64<z)?"\#7\^jc7just sand\as000"
if(b&64>64-z)w=192
?"\f3"
J=4+sin(t()/8)for i=0,128do
x=D[i]-p
y=E[i]-q
r=K[(E[i]%310+D[i]%128*310)\1]&15if(x>127or y%128!=y)E[i]=64+sin(t()/4)*32+q+q%64D[i]=p-r
D[i]+=r/2*cos(y/J/32)+rnd(4)E[i]+=r/4*sin(x/J/32)pset(x,y)end
goto _
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment