-- gen_tileset.lua: generate a 16x16 tileset sprite sheet for Honey Village. -- Produces assets/tilesets/tileset.png : 8 cols x 8 rows = 64 tiles (128x128) -- Run: aseprite -b --script tools/gen_tileset.lua local TILE = 16 local COLS = 8 local ROWS = 8 local W = COLS*TILE local H = ROWS*TILE app.command.NewFile{ width=W, height=H, colorMode=ColorMode.RGB } local spr = app.activeSprite local img = app.activeImage local C = { transparent = app.pixelColor.rgba(0,0,0,0), grassL = app.pixelColor.rgba(126,200,80,255), grassD = app.pixelColor.rgba(96,168,56,255), grassS = app.pixelColor.rgba(150,214,96,255), pathL = app.pixelColor.rgba(214,190,150,255), pathD = app.pixelColor.rgba(180,156,120,255), waterL = app.pixelColor.rgba(108,180,226,255), waterD = app.pixelColor.rgba(74,140,198,255), waterF = app.pixelColor.rgba(170,214,246,255), flowerY = app.pixelColor.rgba(255,214,80,255), flowerP = app.pixelColor.rgba(255,150,190,255), flowerG = app.pixelColor.rgba(120,200,120,255), stem = app.pixelColor.rgba(70,130,50,255), berryR = app.pixelColor.rgba(214,60,80,255), berryD = app.pixelColor.rgba(160,36,56,255), leaf = app.pixelColor.rgba(80,160,60,255), trunk = app.pixelColor.rgba(120,80,40,255), leafD = app.pixelColor.rgba(60,140,50,255), leafL = app.pixelColor.rgba(110,190,70,255), wall = app.pixelColor.rgba(236,216,184,255), wallD = app.pixelColor.rgba(200,176,140,255), roof = app.pixelColor.rgba(240,120,70,255), roofD = app.pixelColor.rgba(200,84,48,255), door = app.pixelColor.rgba(150,96,56,255), doorD = app.pixelColor.rgba(110,70,40,255), floor = app.pixelColor.rgba(230,210,180,255), floorD = app.pixelColor.rgba(204,182,150,255), bedF = app.pixelColor.rgba(120,170,230,255), bedD = app.pixelColor.rgba(86,130,190,255), pillow = app.pixelColor.rgba(240,230,210,255), counter = app.pixelColor.rgba(170,120,70,255), counterD= app.pixelColor.rgba(130,86,48,255), oven = app.pixelColor.rgba(90,90,100,255), ovenD = app.pixelColor.rgba(60,60,70,255), fire = app.pixelColor.rgba(255,150,60,255), shelf = app.pixelColor.rgba(150,100,60,255), shelfD = app.pixelColor.rgba(110,72,40,255), item = app.pixelColor.rgba(255,210,90,255), table = app.pixelColor.rgba(160,110,64,255), chair = app.pixelColor.rgba(120,84,48,255), well = app.pixelColor.rgba(120,110,110,255), wellD = app.pixelColor.rgba(84,78,78,255), wellR = app.pixelColor.rgba(150,100,60,255), wellW = app.pixelColor.rgba(60,130,180,255), fog = app.pixelColor.rgba(220,226,236,255), fogD = app.pixelColor.rgba(180,190,206,255), white = app.pixelColor.rgba(236,236,236,255), grayL = app.pixelColor.rgba(214,214,214,255), grayM = app.pixelColor.rgba(170,170,170,255), grayD = app.pixelColor.rgba(120,120,120,255), black = app.pixelColor.rgba(40,40,40,255), ribbon = app.pixelColor.rgba(255,100,140,255), ribbonD = app.pixelColor.rgba(200,70,110,255), picB = app.pixelColor.rgba(240,200,140,255), picR = app.pixelColor.rgba(200,120,80,255), bench = app.pixelColor.rgba(140,96,56,255), sign = app.pixelColor.rgba(200,170,110,255), signD = app.pixelColor.rgba(150,120,70,255), fence = app.pixelColor.rgba(160,120,70,255), fenceD = app.pixelColor.rgba(120,86,48,255), window = app.pixelColor.rgba(150,200,230,255), lamp = app.pixelColor.rgba(255,230,130,255), lampD = app.pixelColor.rgba(180,150,70,255), pot = app.pixelColor.rgba(180,90,70,255), potP = app.pixelColor.rgba(120,200,120,255), barrel = app.pixelColor.rgba(140,90,50,255), crate = app.pixelColor.rgba(170,120,70,255), ink = app.pixelColor.rgba(60,50,50,255), paper = app.pixelColor.rgba(245,240,225,255), } for y=0,H-1 do for x=0,W-1 do img:drawPixel(x,y,C.transparent) end end local function cellOrigin(idx) return (idx % COLS) * TILE, math.floor(idx / COLS) * TILE end local function rect(ox,oy,w,h,col) for y=oy,oy+h-1 do for x=ox,ox+w-1 do img:drawPixel(x,y,col) end end end local function px(x,y,col) img:drawPixel(x,y,col) end -- Tile drawing functions take ox,oy origin local function grass(ox,oy) rect(ox,oy,16,16,C.grassL) for _,d in ipairs({{2,3},{5,2},{9,4},{12,6},{3,9},{7,11},{11,9},{14,12},{6,13},{1,7},{13,2},{4,14}}) do px(ox+d[1],oy+d[2],C.grassD) end for _,d in ipairs({{6,5},{10,8},{3,12},{12,3},{8,13}}) do px(ox+d[1],oy+d[2],C.grassS) end end local function pathPlain(ox,oy) rect(ox,oy,16,16,C.pathL) for _,d in ipairs({{2,4},{7,3},{11,6},{4,9},{9,11},{13,8},{6,13},{1,11}}) do px(ox+d[1],oy+d[2],C.pathD) end end local function water(ox,oy) rect(ox,oy,16,16,C.waterL) for x=0,15 do if (x%4)<2 then px(ox+x,oy+4,C.waterD) end if (x%4)>=2 then px(ox+x,oy+10,C.waterD) end end px(ox+3,oy+7,C.waterF); px(ox+10,oy+7,C.waterF) end local function flowers(ox,oy,accent) grass(ox,oy) for _,s in ipairs({{4,6},{11,9}}) do px(ox+s[1],oy+s[2]+2,C.stem); px(ox+s[1],oy+s[2]+3,C.stem) end for _,b in ipairs({{4,6},{11,9}}) do px(ox+b[1],oy+b[2],accent); px(ox+b[1]-1,oy+b[2],accent); px(ox+b[1]+1,oy+b[2],accent) px(ox+b[1],oy+b[2]-1,accent); px(ox+b[1],oy+b[2]+1,accent) end end local function berry(ox,oy) grass(ox,oy) rect(ox+3,oy+5,10,8,C.leaf) rect(ox+4,oy+4,8,1,C.leafL) rect(ox+3,oy+5,10,1,C.leafD) for _,b in ipairs({{5,8},{8,7},{10,9},{6,11},{9,11}}) do px(ox+b[1],oy+b[2],C.berryR); px(ox+b[1]+1,oy+b[2],C.berryR); px(ox+b[1],oy+b[2]+1,C.berryD) end end local function tree(ox,oy) grass(ox,oy) rect(ox+7,oy+10,2,5,C.trunk) rect(ox+4,oy+3,8,8,C.leafD) rect(ox+5,oy+2,6,1,C.leafL) rect(ox+3,oy+5,1,4,C.leaf); rect(ox+12,oy+5,1,4,C.leaf) rect(ox+6,oy+6,4,3,C.leafL) end local function birdTree(ox,oy) tree(ox,oy) px(ox+6,oy+5,C.flowerY); px(ox+9,oy+6,C.flowerY) end local function bush(ox,oy) grass(ox,oy) rect(ox+3,oy+6,10,6,C.leaf); rect(ox+4,oy+5,8,1,C.leafL) end local function wall(ox,oy) rect(ox,oy,16,16,C.wall) for _,d in ipairs({{1,1},{5,1},{9,1},{13,1},{3,5},{7,5},{11,5},{1,9},{5,9},{9,9},{13,9},{3,13},{7,13},{11,13}}) do px(ox+d[1],oy+d[2],C.wallD) end end local function wallTop(ox,oy) rect(ox,oy,16,16,C.wall); rect(ox,oy,16,2,C.wallD) for x=0,15,4 do px(ox+x,oy+4,C.wallD) end end local function roof(ox,oy) rect(ox,oy,16,16,C.roof) for y=0,15,2 do rect(ox,oy+y,16,1,C.roofD) end end local function roofEdge(ox,oy) rect(ox,oy,16,16,C.roof); rect(ox,oy+14,16,2,C.roofD) for y=0,12,2 do rect(ox,oy+y,16,1,C.roofD) end end local function door(ox,oy) wall(ox,oy) rect(ox+3,oy+2,10,14,C.door) rect(ox+3,oy+2,10,1,C.doorD); rect(ox+3,oy+2,1,14,C.doorD) px(ox+11,oy+9,C.signD) end local function window(ox,oy) wall(ox,oy) rect(ox+3,oy+3,10,8,C.window) rect(ox+3,oy+3,10,1,C.wallD); rect(ox+3,oy+10,10,1,C.wallD) rect(ox+3,oy+3,1,8,C.wallD); rect(ox+12,oy+3,1,8,C.wallD) px(ox+7,oy+3,C.wallD); px(ox+7,oy+11,C.wallD) end local function floor(ox,oy) rect(ox,oy,16,16,C.floor) for _,d in ipairs({{2,3},{9,5},{5,11},{12,12}}) do px(ox+d[1],oy+d[2],C.floorD) end rect(ox,oy,16,1,C.floorD); rect(ox,oy+8,16,1,C.floorD) end local function floorRug(ox,oy) floor(ox,oy) rect(ox+3,oy+4,10,8,C.flowerP); rect(ox+3,oy+4,10,1,C.ribbonD); rect(ox+3,oy+11,10,1,C.ribbonD) end local function bed(ox,oy) rect(ox+1,oy+3,14,11,C.bedD); rect(ox+2,oy+4,12,9,C.bedF); rect(ox+3,oy+5,4,3,C.pillow) end local function counter(ox,oy) rect(ox,oy+5,16,7,C.counter); rect(ox,oy+5,16,1,C.counterD); rect(ox,oy+11,16,1,C.counterD) end local function oven(ox,oy) rect(ox+2,oy+2,12,13,C.oven); rect(ox+2,oy+2,12,1,C.ovenD) rect(ox+4,oy+5,8,6,C.ovenD); rect(ox+5,oy+6,6,4,C.fire) end local function shelf(ox,oy) rect(ox+1,oy+4,14,1,C.shelf); rect(ox+1,oy+9,14,1,C.shelf) rect(ox+1,oy+4,1,10,C.shelf); rect(ox+14,oy+4,1,10,C.shelf) rect(ox+1,oy+13,14,1,C.shelfD) end local function shelfFull(ox,oy) shelf(ox,oy) for i=0,4 do rect(ox+2+i*3,oy+5,2,3,C.item) end for i=0,4 do rect(ox+2+i*3,oy+10,2,3,C.item) end end local function table(ox,oy) rect(ox+1,oy+5,14,4,C.table) px(ox+2,oy+9,C.table); px(ox+13,oy+9,C.table); px(ox+2,oy+12,C.table); px(ox+13,oy+12,C.table) end local function chair(ox,oy) rect(ox+4,oy+6,8,1,C.chair); rect(ox+4,oy+6,1,6,C.chair); rect(ox+4,oy+11,9,1,C.chair) px(ox+11,oy+11,C.chair); px(ox+11,oy+13,C.chair) end local function stool(ox,oy) rect(ox+5,oy+7,6,2,C.table); px(ox+5,oy+9,C.table); px(ox+10,oy+9,C.table); px(ox+5,oy+12,C.table); px(ox+10,oy+12,C.table) end local function well(ox,oy) rect(ox,oy+6,16,7,C.well); rect(ox,oy+6,16,1,C.wellD) rect(ox+5,oy+9,6,4,C.wellW) px(ox+2,oy+1,C.wellR); px(ox+13,oy+1,C.wellR); rect(ox+2,oy+1,12,1,C.wellR); rect(ox+5,oy+0,6,2,C.wellR) end local function fog(ox,oy) rect(ox,oy,16,16,C.fog) for _,d in ipairs({{2,3},{8,5},{12,9},{4,11},{10,12},{6,7}}) do px(ox+d[1],oy+d[2],C.fogD) end end local function fogThick(ox,oy) rect(ox,oy,16,16,C.fog) for y=0,15 do for x=0,15 do if (x+y)%2==0 then px(ox+x,oy+y,C.fogD) end end end rect(ox,oy,16,16,C.fog) end local function whiteWall(ox,oy) rect(ox,oy,16,16,C.white); rect(ox,oy+15,16,1,C.grayM); px(ox,oy,C.grayL); px(ox+15,oy,C.grayL) end local function whiteFloor(ox,oy) rect(ox,oy,16,16,C.grayL); rect(ox,oy+8,16,1,C.grayM); px(ox,oy,C.grayM) end local function whiteDoor(ox,oy) rect(ox,oy,16,16,C.white); rect(ox+3,oy+1,10,14,C.grayM); rect(ox+3,oy+1,10,1,C.grayD); rect(ox+3,oy+1,1,14,C.grayD) px(ox+11,oy+9,C.grayD) end local function whiteBed(ox,oy) rect(ox+1,oy+3,14,11,C.grayM); rect(ox+2,oy+4,12,9,C.grayL); rect(ox+3,oy+5,4,3,C.white) end local function whiteMonitor(ox,oy) rect(ox+1,oy+2,14,1,C.grayD); rect(ox+3,oy+1,10,3,C.grayM); px(ox+7,oy+4,C.grayD); px(ox+8,oy+4,C.grayD) rect(ox+4,oy+4,8,3,C.wellW) end local function whiteTable(ox,oy) rect(ox+1,oy+6,14,2,C.grayM); px(ox+2,oy+8,C.grayM); px(ox+13,oy+8,C.grayM) end local function ribbon(ox,oy) rect(ox+1,oy+6,14,3,C.ribbon); rect(ox+1,oy+6,14,1,C.ribbonD) rect(ox+7,oy+3,2,10,C.ribbonD) end local function ribbon2(ox,oy) rect(ox+1,oy+5,14,4,C.ribbon); rect(ox+1,oy+8,14,1,C.ribbonD) rect(ox+4,oy+2,2,12,C.flowerP); rect(ox+10,oy+2,2,12,C.flowerY) end local function picnic(ox,oy) rect(ox,oy+4,16,9,C.picB) for i=0,7 do rect(ox+i*2,oy+4,1,9,C.picR) end end local function bench(ox,oy) rect(ox+1,oy+5,14,3,C.bench); px(ox+2,oy+8,C.bench); px(ox+13,oy+8,C.bench); px(ox+2,oy+12,C.bench); px(ox+13,oy+12,C.bench) end local function sign(ox,oy) rect(ox+1,oy+6,14,6,C.sign); rect(ox+1,oy+6,14,1,C.signD); rect(ox+1,oy+11,14,1,C.signD) rect(ox+1,oy+6,1,6,C.signD); rect(ox+14,oy+6,1,6,C.signD) px(ox+6,oy+12,C.signD); px(ox+9,oy+12,C.signD); px(ox+6,oy+15,C.signD); px(ox+9,oy+15,C.signD) end local function calendar(ox,oy) rect(ox+2,oy+2,12,12,C.paper); rect(ox+2,oy+2,12,1,C.signD); rect(ox+2,oy+2,1,12,C.signD); rect(ox+13,oy+2,1,12,C.signD) rect(ox+2,oy+5,12,1,C.signD) -- date digits "7/14" stylized rect(ox+4,oy+7,1,4,C.ink); rect(ox+7,oy+7,2,1,C.ink); rect(ox+9,oy+8,1,2,C.ink); rect(ox+7,oy+9,2,1,C.ink) rect(ox+11,oy+7,1,4,C.ink); px(ox+12,oy+8,C.ink); px(ox+11,oy+9,C.ink); px(ox+12,oy+10,C.ink) px(ox+3,oy+3,C.ink); px(ox+3,oy+4,C.ink) end local function paperSheet(ox,oy) rect(ox+2,oy+3,12,11,C.paper); rect(ox+2,oy+3,12,1,C.signD) for y=6,12,2 do rect(ox+3,oy+y,8,1,C.ink) end end local function chart(ox,oy) rect(ox+1,oy+2,14,12,C.paper); rect(ox+1,oy+2,14,1,C.signD); rect(ox+1,oy+2,1,12,C.signD); rect(ox+14,oy+2,1,12,C.signD) for y=5,12,2 do rect(ox+2,oy+y,12,1,C.ink) end -- redacted bars rect(ox+2,oy+5,5,1,C.black); rect(ox+8,oy+7,6,1,C.black) end local function fenceH(ox,oy) rect(ox,oy+6,16,1,C.fenceD) for x=0,15,4 do rect(ox+x,oy+5,1,5,C.fence) end rect(ox,oy+9,16,1,C.fence) end local function fenceV(ox,oy) rect(ox+6,oy,4,16,C.fence) rect(ox+6,oy+5,4,1,C.fenceD); rect(ox+6,oy+10,4,1,C.fenceD) end local function lamp(ox,oy) rect(ox+7,oy+4,2,12,C.lampD) rect(ox+5,oy+2,6,3,C.lamp); rect(ox+5,oy+2,6,1,C.lampD) px(ox+8,oy+5,C.lamp) end local function potPlant(ox,oy) rect(ox+4,oy+8,8,6,C.pot); rect(ox+4,oy+8,8,1,C.signD) rect(ox+5,oy+5,6,3,C.potP); px(ox+7,oy+3,C.potP); px(ox+9,oy+4,C.potP) end local function barrel(ox,oy) rect(ox+3,oy+2,10,13,C.barrel); rect(ox+3,oy+2,10,1,C.fenceD); rect(ox+3,oy+7,10,1,C.fenceD); rect(ox+3,oy+12,10,1,C.fenceD) px(ox+3,oy+2,C.fenceD); px(ox+12,oy+2,C.fenceD) end local function crate(ox,oy) rect(ox+2,oy+3,12,12,C.crate); rect(ox+2,oy+3,12,1,C.signD); rect(ox+2,oy+14,12,1,C.signD) rect(ox+2,oy+3,1,12,C.signD); rect(ox+13,oy+3,1,12,C.signD) -- X for i=0,10 do px(ox+3+i,oy+4+i,C.signD) end for i=0,10 do px(ox+3+i,oy+14-i,C.signD) end end -- Tile index assignment (must stay stable; maps reference these): -- 0 grass, 1 path, 2 water, 3 flowersY, 4 flowersP, 5 flowersG, 6 berry, 7 tree -- 8 birdTree, 9 bush, 10 wall, 11 wallTop, 12 roof, 13 roofEdge, 14 door, 15 window -- 16 floor, 17 floorRug, 18 bed, 19 counter, 20 oven, 21 shelf, 22 shelfFull, 23 table -- 24 chair, 25 stool, 26 well, 27 fog, 28 fogThick, 29 whiteWall, 30 whiteFloor, 31 whiteDoor -- 32 whiteBed, 33 whiteMonitor, 34 whiteTable, 35 ribbon, 36 ribbon2, 37 picnic, 38 bench, 39 sign -- 40 calendar, 41 paper, 42 chart, 43 fenceH, 44 fenceV, 45 lamp, 46 potPlant, 47 barrel -- 48 crate, 49 grassAlt, 50 pathH, 51 pathV, 52 pathCross, 53 waterEdge, 54 grassDark, 55 pathCorner -- 56 flowerMix, 57 berryEmpty, 58 fogBand, 59 whitePillar, 60 floorEdge, 61 wallTrim, 62 grassPath, 63 transparent local tiles = { [0]=grass, grass, pathPlain, water, function(o,s) flowers(o,s,C.flowerY) end, function(o,s) flowers(o,s,C.flowerP) end, function(o,s) flowers(o,s,C.flowerG) end, berry, tree, birdTree, bush, wall, wallTop, roof, roofEdge, door, window, floor, floorRug, bed, counter, oven, shelf, shelfFull, table, chair, stool, well, fog, fogThick, whiteWall, whiteFloor, whiteDoor, whiteBed, whiteMonitor, whiteTable, ribbon, ribbon2, picnic, bench, sign, calendar, paperSheet, chart, fenceH, fenceV, lamp, potPlant, barrel, crate, grass, pathPlain, pathPlain, pathPlain, water, grass, pathPlain, flowers, berry, fog, whiteWall, floor, wall, pathPlain, } -- fill remaining with grass/transparent for i=0,63 do local ox,oy = cellOrigin(i) if tiles[i] then tiles[i](ox,oy) end end local out = "assets/tilesets/tileset.png" spr:saveCopyAs(out) print("Saved " .. out .. " (64 tiles, 128x128)") app.exit()