Some of the web games on this site (like Chuckie Egg Returns) have their game maps embedded in the source. To make the JavaScript game file smaller and therefore quicker to download, they are run through a program like the one below. As the game maps are simple maps (only around 10 elements), the maps can be reduced in size by around 50% using Run Length Encoding (RLE).
The process I use is:
# # Bmp2Rle by ssjx (https://ssjx.co.uk) # import sys fn="" if len(sys.argv)==2: fn=sys.argv[1] else: print("Bmp2Rle Py by ssjx (https://ssjx.co.uk)") print("---------------------------------------") print("Usage: py bmp2rle.py myfile.bmp") exit(0) try: myfile=open(fn,"rb") except: print("Could not open the file...") exit() bmp_header=myfile.read(14) if (chr(bmp_header[0])!='B' and chr(bmp_header[1])!='M'): print("This file does not look like a bitmap image?") exit() bmp_info=myfile.read(40) width=int.from_bytes(bmp_info[4:8],'little') height=int.from_bytes(bmp_info[8:12],'little') depth=bmp_info[14] print(fn+": "+str(width)+" x "+str(height)+" x "+str(depth)) if (width % 4)!=0: print("The width should be divisible by 4.") exit() if depth!=8: print("Images should be 8bit colour.") exit() # Got this far so probably a valid bitmap! offset=int.from_bytes(bmp_header[10:14],'little') print("Data Offset: ",offset) myfile.seek(offset,0) data=myfile.read(width*height) myfile.close() for j in range(0,height): no=1 # byte count outstr="" # clear output text pos=width*(height-j-1) # flipped position in bitmap pb=data[pos] # previous byte (first byte of line) for i in range(1,width): cb=data[pos+i] # current byte if (cb==pb) and (no<200): no+=1 else: outstr+=str(no)+","+str(pb)+"," no=1 pb=cb if (no>0): outstr+=str(no)+","+str(pb)+"," print(outstr)
Save the above as something, bit2rle.py for example, then run it as usual specifying a bitmap file. The bit in blue is the part that would go into the JavaScript array in your game (remove the final comma).
#skip>py bmp2rle.py 1.bmp
1.bmp: 40 x 20 x 8
Data Offset: 1078
40,1,
1,1,38,0,1,1,
1,1,1,0,1,6,36,0,1,1,
1,1,9,0,1,7,1,0,1,2,1,0,1,4,2,0,1,3,3,0,1,3,1,0,1,7,3,0,1,3,2,0,1,3,6,0,1,7,1,0,1,1,
1,1,9,0,4,1,1,4,3,1,2,0,14,1,2,0,4,1,
1,1,13,0,1,4,6,0,1,7,17,0,1,1,
1,1,7,0,1,7,1,4,1,0,1,2,1,3,1,0,1,4,3,0,4,1,17,0,1,1,
1,1,7,0,1,1,1,4,4,1,1,4,24,0,1,1,
1,1,8,0,1,4,4,0,1,4,15,0,3,1,6,0,1,1,
1,1,8,0,1,4,4,0,1,4,12,0,3,1,9,0,1,1,
1,1,5,0,1,7,2,0,1,4,1,0,1,2,1,3,1,0,1,4,6,0,1,3,1,7,1,0,3,1,12,0,1,1,
1,1,4,0,9,1,1,4,3,1,2,0,4,1,11,0,1,7,3,0,1,1,
1,1,13,0,1,4,16,0,6,1,2,0,1,1,
1,1,13,0,1,4,24,0,1,1,
1,1,2,0,1,7,1,0,1,3,1,0,1,4,1,2,1,0,1,3,3,0,1,4,2,0,1,3,3,0,1,4,3,0,1,2,1,0,1,3,1,7,4,0,1,4,2,0,1,7,2,0,1,1,
1,1,2,0,4,1,1,4,6,1,1,4,6,1,1,4,11,1,1,4,3,1,2,0,1,1,
1,1,6,0,1,4,6,0,1,4,6,0,1,4,11,0,1,4,5,0,1,1,
1,1,6,0,1,4,6,0,1,4,6,0,1,4,11,0,1,4,5,0,1,1,
1,1,4,0,1,3,1,0,1,4,1,2,1,0,1,3,3,0,1,4,1,7,1,0,1,3,1,5,2,0,1,4,5,0,1,3,2,0,1,2,2,0,1,4,5,0,1,1,
40,1,
Not going to go into to much depth, but to decompress, the first number is the number of times to repeat the second number. If you stored the above data in an array called tmp, you would decompress to an array called map using something like the code below:
for(let i=0;i<tmp.length;i+=2){ for(let x=0;x<tmp[i];x++){ map[pos++]=tmp[i+1]; } }#skip
Created 19/07/2025