From 38c3ee1f3f539e388781702ae460de9803b3dfe5 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Nov 2026 03:26:03 +0000 Subject: [PATCH 1/9] Draw a platformer's backdrop, foreground, and tileset from code A test of the pixel-art skill and the art-direction research on a Celeste-like platformer: 320x180, 8 px tiles, one Endesga 32 subset. The planes recede toward the haze and loop horizontally, and the terrain is a 47-tile blob autotile drawn per pixel from its neighbours, so one function decides every edge, rim, and corner. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01HendNaZcTpUubQBWodQy33 --- .../core/genres/platformer-assets/.gitignore | 2 + .../art/backdrop/backdrop-stacked.png | Bin 0 -> 4570 bytes .../art/backdrop/bg-0-sky.png | Bin 0 -> 1626 bytes .../art/backdrop/bg-1-far.png | Bin 0 -> 1556 bytes .../art/backdrop/bg-2-mid.png | Bin 0 -> 1284 bytes .../art/backdrop/bg-3-near.png | Bin 0 -> 1856 bytes .../art/foreground/fg-grass-boughs.png | Bin 0 -> 853 bytes .../platformer-assets/art/tiles/tileset.json | 86 ++ .../platformer-assets/art/tiles/tileset.png | Bin 0 -> 1472 bytes .../core/genres/platformer-assets/make.py | 1102 +++++++++++++++++ .../core/genres/platformer-assets/palette.hex | 28 + .../platformer-assets/pixel.config.json | 4 + .../previews/backdrop/backdrop-stacked@4x.png | Bin 0 -> 11140 bytes .../previews/backdrop/bg-0-sky@4x.png | Bin 0 -> 6934 bytes .../previews/backdrop/bg-1-far@4x.png | Bin 0 -> 7189 bytes .../previews/backdrop/bg-2-mid@4x.png | Bin 0 -> 5985 bytes .../previews/backdrop/bg-3-near@4x.png | Bin 0 -> 7133 bytes .../foreground/fg-grass-boughs@4x.png | Bin 0 -> 6027 bytes .../previews/tiles/tileset@8x.png | Bin 0 -> 4156 bytes 19 files changed, 1222 insertions(+) create mode 100644 packages/core/genres/platformer-assets/.gitignore create mode 100644 packages/core/genres/platformer-assets/art/backdrop/backdrop-stacked.png create mode 100644 packages/core/genres/platformer-assets/art/backdrop/bg-0-sky.png create mode 100644 packages/core/genres/platformer-assets/art/backdrop/bg-1-far.png create mode 100644 packages/core/genres/platformer-assets/art/backdrop/bg-2-mid.png create mode 100644 packages/core/genres/platformer-assets/art/backdrop/bg-3-near.png create mode 100644 packages/core/genres/platformer-assets/art/foreground/fg-grass-boughs.png create mode 100644 packages/core/genres/platformer-assets/art/tiles/tileset.json create mode 100644 packages/core/genres/platformer-assets/art/tiles/tileset.png create mode 100644 packages/core/genres/platformer-assets/make.py create mode 100644 packages/core/genres/platformer-assets/palette.hex create mode 100644 packages/core/genres/platformer-assets/pixel.config.json create mode 100644 packages/core/genres/platformer-assets/previews/backdrop/backdrop-stacked@4x.png create mode 100644 packages/core/genres/platformer-assets/previews/backdrop/bg-0-sky@4x.png create mode 100644 packages/core/genres/platformer-assets/previews/backdrop/bg-1-far@4x.png create mode 100644 packages/core/genres/platformer-assets/previews/backdrop/bg-2-mid@4x.png create mode 100644 packages/core/genres/platformer-assets/previews/backdrop/bg-3-near@4x.png create mode 100644 packages/core/genres/platformer-assets/previews/foreground/fg-grass-boughs@4x.png create mode 100644 packages/core/genres/platformer-assets/previews/tiles/tileset@8x.png diff --git a/packages/core/genres/platformer-assets/.gitignore b/packages/core/genres/platformer-assets/.gitignore new file mode 100644 index 00000000..78a0f77e --- /dev/null +++ b/packages/core/genres/platformer-assets/.gitignore @@ -0,0 +1,2 @@ +previews/parallax/ +fx/*.look/ diff --git a/packages/core/genres/platformer-assets/art/backdrop/backdrop-stacked.png b/packages/core/genres/platformer-assets/art/backdrop/backdrop-stacked.png new file mode 100644 index 0000000000000000000000000000000000000000..8317bcb36870ad9a68c61400e30b9f4f2b217615 GIT binary patch literal 4570 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%0A$xmcr~QaXf|GjU9Y_08{* z?yX+*#l|*oU1-kb(`WP%SoO=HbvjM6p(`OgVvb&|`}?)w~h!EKQqb-0ke z(QBiF9eBF(;Vn=9cF_Jd({IrS$HFee&i>}RxWcL*3R{q!hO`6>x}8CDbGmkGpwC z30qX`IL}8D?2Tp4WbOmcw1?NT*KM1eGCx)F<x<3%g+bsR#3M|>7Qp!TKYe( zviDDGRz0k*4&ojRYKb=F9xTz7x@jR={&R6f?(sVirOs+aB#-{Ig2Y9eI=FD_{4jx# zUa~OUO&LvzloI@|MNW=#?on+Rhpolofaqr4sgOSyK{o+>NXrrz2MB=E2GBpzFv;3 zgFz!6J{50J4$q55&c3~>KAJ1*QDRu`I?}+`ol!DiP5U=)jG3f%I989?ar73)NlM}n z@qcs{i#jaI`GaFWZv09<;S&qjY~mU5HzPa>$%*N8vdHwC`-b0v>5pu$Dd1Wok&=zl zIY?0hKqe6@aFslut{uifUfi=k%ekQ;t8Y>yeMu^|5t`4BQrh9PeLFE_XJxW**#P@I z>Pd9KPx-ee9_~AcYMiuB72)T@Ol)3pWK}ce9&9j(-L%)9mBbOLKLS2K7Dwl^yZfjr z%>`jP$k#YoxQF@m%-G#(^JG5mJrWJ8`aW^rcL8DRNYQ$OR4SsJYYKLvg^RQp!u`aH zyQ6v`vxUmiq{5D+Le@Wkr8Rm4-tcpr1Dq zd-L3S%XO1wqh7{}yjglj&KNjbehI3Kv)&dh%^5Cv!b5mt3e(3$85S3pKFf&3LR$W6!{11hQyWs!; literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/art/backdrop/bg-0-sky.png b/packages/core/genres/platformer-assets/art/backdrop/bg-0-sky.png new file mode 100644 index 0000000000000000000000000000000000000000..e16edee5d9ce099851e820a4b638c772271c2ba8 GIT binary patch literal 1626 zcmbtVdoP)2z)YYkhC zq0DO1AiF~-WE{qG8jr>^hQ?#O)}Gxxr+@lm&;IkBd+t5wJKw$cyXW3I?R;Xd#6bxF z0QR0bY2yk25X^2|3lrVN$q9ih0EnudvaxiJADka~ABG4*H1P*&H17F$huF(#O5P(F zhdV^`PiIW@SYS{k(3&ZVE$olH3Y+|Z&!kl=sujFeLekY-DwM}jppm!7-9$wz(=%>J_`^XY zDF9(gAe-2u1HCyOmrZYI%D`%Tm1Ru{#?En?he76-dL9-+5j%Vp)CM@Ro;3tON*b>3lX-A)?k6w5_E&66&6!UyxY=e%dS(=71pGioaL3I!`b>GNE(eE zD$ES8I1sIIJe#$h#=Kw=yhc+O)h7SGjgm=zls$F9ZNz9nN|h?^pG#Yv;%>$4%xQ3N zF`v4^mvf-^e{)7hzNY62TK#cXc%5wD7rT543R9&Pc#5{qL$lQ%rrXR3<0+@tFhHgx zX)zhFt4N}+?g%Wq^O=W^rgt(`2>_Gt495VWpR1MOO={)wozeW3+hU#0j)11y9UWM$ z5{VcWFs4P=Zv&BI3tOJF8jKn7me}zM#E|c%_MsdJ^2XB!vKBmpA0Z$Scw;l2(E^3} zflw&??Iyfi-L_DqdyjoP8F$O2va~>$aE1p!Ow%6UrUiBe@(A&*g4e*D(Xl8K$v`Ryilc=0)QXVDES;~K#r653G2WX zJQ)09I4^LOysJ?wuHMx&X|$z}E1el`4ia|62s`xiRrj1<>b%msaF%x!6)5aT@|2;A z2E2CZ^IDsCt=LSdR?*rd_gRYb>YwF}57jOAwO>A9Wlh^5K}I?lF`Qf^1bTZ?Pw}tI z-JR6`gs&M?g3t33Eh9zX83y6yn@Etj_K)d$$&I1Z0#AY|$qAJps@*zGo!)Tg?bl}c zmau%QNK#5KbK}zfc9Sa0ca)X*Rv$i&dp_D6S%99@ND=Yp8q%cgjW|KY2u?$BoP}^M z)k*ZMV3Ws~nekp2uKVQ#kQ_jl68&1tHyeBG)L*3oWhh`&2CMHcCBgj0l6rJxwq0qy4B-wvaJXB%QjObD34`$J|+M zOO$N9IFnxr-=C7o=|!Ws*9u~zuWeu(*uwTwX3CQ%C1zWsS6CePKg#^3{(lSKTwd;? ZPS>RV7xeeKL%Tl%IA!Z>Q)T6M<4?xPz%>8> literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/art/backdrop/bg-1-far.png b/packages/core/genres/platformer-assets/art/backdrop/bg-1-far.png new file mode 100644 index 0000000000000000000000000000000000000000..da2524890ae1bd7012c1493b460256945c1231ec GIT binary patch literal 1556 zcmb_ceKga182@fYW2uFfm%L0WZa79|iOfsh&YhQ(w}sWMDNA$;i(Q+SsO$1mPJ~2U zB@8*XmAq_ShkKGMrg^=Mgv#qR+uSkkI``lE*FE?7<2ldyoX`0@pYxpaeD3)BdTMIu zYXAT=y}jH|0RST?=VqjuvQK}K>;gb_%-h}NG;MU@kK?&I-e@)Qfg@R=Dk^zW+i|8r z9Kvh|Gqq10&y#z-qSifEOVq3LUYm~I6>Cbc@2l2%jEN~r{tJIE|j(iM~DmO!vFm6K6M^aoF_#tDjzu+lWr2Q)y*17mvm>rJ*CZmEfsIg@{7UVnZq$uw`HA_C1<)VD?gSo z+ZL!z;cl|5{DE)JOd%C7%p5L2w{F-gZQzONLq{vEY-altmP9dz_1~cIDQB)iolhSV zeOOqIz&o5n@+=I-ar>8S96O}R#%BjN$^wxT5!|?0MAzOFW^78QE2)%q>OgR;sBKdb z6}tXL?S+53Tdm6>pf|JdYN&6sR0h}VHfoaI2M?S1w@h4Z{6UKac1Ajj9RK{9vXd{= zyo&0?;BSIQSLG!8+GXuDj`Nskz;i;-`}K+AQ3M}@HwO(w_Rm;a=M9E6LUXSIi`a&k zU}Z;Z>!jr^BCoXk+Nuax5Aw<6hb4udCY4*E3sAh#JDioAW6{b>E6$;|$04MvD>PR$ zcGv>Qe4BTp@JTHO*79@}mF22EgOu|q9WxFu4>nw*9&B+wqhx^BZ|u7(2jbb7dRp2c3EV-YdFKcjPmwtdmlM~WWT1{y?Z6*7?v<# z?%{OxiKeo!4vq|{?>6NSNaP+PbEktNZILZn&x)c-7TF!|x&nr!L$(Odv*}`eZj!=Q z?&|RZ7kqhfgt~CKA;lpqz>8>r+n~rDgHVfl(CeX;6?(Rj`GH23`-3^CsDXbmhm=V! znsyz9i-k#ZP_V$hc?W;MZli+HG5JRDV?mf_{d0lKRz!;|e>PH%TeH>8nG>7DI2V2h zwET*}uiuEAJS3x19R&?YwnEad^@!^c?VNkB>OpaGeb^G~c^Ubh8<8=;a7XzY&W2jd z#6%kduv|e@I&>CYyrOwnp)LAY1h4@;}VHns}Jc{ z>#1E>;D&niKw@eLr6ZKM8t>W|Pg@)1Nic=NSZI7b#AmSN{RL=unkR$xrTXc;x4|ND z#0z?k)+8l|Q{=vre@Wu>QH)9Xaogn{dBj|n%=m;;cyf-`G$p?7nDzEBp}cy6R{td) z5onkiH5T%{lubRp^6Y{%zf(90)x}oF-l9772gl5haCq~vFuX=z^3H-w#JLddeTXQ1 z>sq>znFz!%a7QcdvSa=_jlaIeo-ehEgbE!1^Z`zkq_BfXrV{S}T7K&p@KDLu~rp_B=;y=Rp(bmlf*1K)DK08+UfLnPo|;`ah8jc-tR;xgPSUe zh=kQMf%X=qPHzW0lMgPnS@{QYuh&T4PIB3h^}0t{=kZfRXSb*gZJlbg+G|JR*TWjt zvOh|^eFX?IBnv-$1Z@gPS*6QAP(`2bw|37rMF&#TA3E}@x~6?0N^=YkF literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/art/backdrop/bg-2-mid.png b/packages/core/genres/platformer-assets/art/backdrop/bg-2-mid.png new file mode 100644 index 0000000000000000000000000000000000000000..9e9f1ea544349ded1c611679373af81cf5bd9d12 GIT binary patch literal 1284 zcmeAS@N?(olHy`uVBq!ia0y~yU~~Yow{Wll$)``g3NkRToc45a45_&F_U=XBI}QSD z346R0IXcxUmT_@8ENY(Oz&=rR{317JEZPgi^&DOOY>6|`E_`%n=y=_Zwe^F;)P1tcvwCM|8t;#H>ZU@6m|U~BgB*1lC@O*8w-S6(_$Z@>HJzi*p57$0t*y7fHk`FrL3{^#54 zvjzXoh(5|zrm6GCEhh2Io$~mrX1@%#uj18VX`O%iu-(?)nlrx4%71?OHir7|3+&(d z<@E-i#zX!bdC~X(UsZTyxc!x{4$Jeod)#Zjc_~^P_P;nwO|0p7)_h$S`FZpBmF+j5 zerR+2j!}-ovFmoHqg;N@+1&nM>G=olmd}h|U z(sP@h&r&PXtnvD*d@bXP>U*)^2ReTXUv2Dvw|v^h9Zmtgn__2$zuC*9-XONL^X~i8 zf@%}*t(&|s-H*5Ngkpu?-o^L%b7tKTsd#7Av*z*{^)oBBOQzX8Tk6F;|8xJE)is($ zr=n`Yj?XJSB~f#;I=_3C``@4?y&7rL)Ychrrd929S$bO~uxkDH)rXhuWjXid@f9t_ z7f*$pHazE4fAsgjw2c#v#7wrG9nODNF^XebkMvm)iE`g>D?*=skiJ^IIQ!n~9k=JP z&Utx!<>q~Rm8(9_`t$4iy?dtpCH4g;cb(KLJh#0_ep8+Co~yII)a=Qg_F?yu`&Hj# z&(B)F^7Osqca6jgj!0%~W51rhx5b$C+{W_ncJIup8CSO_TszL~TmSV}%8|NkQLYG6 z7Ui`k@BV$9n0xll_tl2J?iHyKvvU`79=wrVv?lG)`ug*s>nely{EUm<@_bfK;OgLI zj(bDDU)t{eLqD{u{EW_hp6?NpZQo_@-M?37v!7D+)$Fzp(tqca{G6|GMx^Ot-JyV5 zq5GS|rhkjM_ThHb{;g|{t~QwG9ydAiaF@;R+-}?Ji}JVl%-;1X*}KOwa?b7idy8t* z7;a^JOsP5CCmuh5s?Mh!J3j5(8u9ShU%J2R&)!aczxG#hzwuG- zgIs6Nl>HSeY`D2O{o1?zi|bYXJZeq2k{QEs?9KL5e~WVX>x64^p8opg#=%xx{=Z_y z9yNK(Z=nKuhxD(DWaLKN&aZmmv8W@-a92l5592gjh6I}D1-B9q!>?lS5^`O$o)78&qol`;+01>(@vH$=8 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/art/backdrop/bg-3-near.png b/packages/core/genres/platformer-assets/art/backdrop/bg-3-near.png new file mode 100644 index 0000000000000000000000000000000000000000..76025f6a1aae8a8ae8b37ab041b30dfe9dae724a GIT binary patch literal 1856 zcmd5-`#%#3AKsKp86~G2iaM5CGj+^FKIZbWP2`AFjHPohSuQ(~vNI`O=OuEc&|Eew z%4y@Ui(6EOP8Y**+s?))V(n(RY+?te-oN1e@qK=HKF=@D^Laks?+;IYNHEH1r^QYH z0ALh=_6r37fZm@q+d%I#&%IZh008>>0e(Jbu8EXlkK|eOZa_%DM-y90nvPx1^FI*% z)Dc1IOw35Yyzvw|yQb9dtomp181b1-*T>Mq7==uhSaRaP=cxY=Wb2|%g-pvQw5w~= zPZ3`1Z$YvLI{?66WWs6YmfrSf4-K+z9V%4%n-(4n8aMILbBoj18Rim_$|4l--Zja_ zw5s=A>L;ya^&4VV+pT)X-LTqqlDD2)fUQGLZgtSj)y~jNh}QH;Or_i6x@MEKiMtPI z7l0&c<%U*8o8B_aA}@!ba(f6f?61C&O61G4pVVuFzZaJU?_LgFIKI_TS`)1K^u;M! zs)>J{S{5qhyiBU0sJfCkQ00u@16ohiW=nb=Ve@YbNIg9+d36wynN=+NkFz&5&UWlX za8=H`ODgk|QhV{0=M6|pGGdyEvXTr~9o?cW+&%%9_QY#*H!>X|Km67XA;f;Y4b%QU^0(9C1=xm>w`>@`?9go9z$DG#wbg(GOW_rlV z<4p0T(0=*vE7!Xei=DJ;WXA_&*Vp`p5lSVD$Yl+NBToIwNxB--KTQareB-<}^#DvlB zw67YE<15AzCwS9FPHNn_@(qQ{@BVFRz{{sG1rJ67C7c&$!22IjYjaA!5(aXMjCmaW zaw?2oLW;xrl7)W_IHbzS3|!tQgoq(x$)^#^<`hN-_utlk+&AY;o>RFI-td}<@K{$5 zhiIg#J0^^Er(Iw?POLcN91_=BdG@w0d?G0?d=t)U>6fcrM*K6xe_=?Ac*B-%5#67! zWe70=o3pWc_i_n7rH zN$Q8g<$V;Ay3ll&nGZi!A4>aR|2jAkN?-kn%|u!f8jRuVE{*;-5wK&$$J%+VZ)l#> zS^D16lIrM`r>?ynlic@7yKPe9^IhiMUo{zF+cdPbB_}U%>&D#G`jqB;tUh@#5I@{%G^QdPdGP^pT~=Ac@q{@d(F?5e1N4aT)j3HKG87w}hQ5+VNZ zvN#@h5yQ(39(MS?+3v*2WLIbeQYF5K=bNBB7Er|?B(<$*`$UCdg3Y$@*ZXsj=27vO zx#IX6yI{|ll6lN{nKQ5v*ERMklbG=v+B?zx*q8Shu8?nbAh}#MWTH-cq*deD zRB4R0od8lZW>HVKJaPpqFiS~$|Hf&H)>cWVwI8(|a#1tG^Ex*fydXzbGc(?|(c-Pa z5Q7_qRIMdouD%y_<_J2CttppWJb1A_Q0@ST2L?H@7)#{`Q04n;VON%!Q@71_pecLb zip+vt)EO;27D!sO#g#37lznK+g9wYbQ zlsi8jk*+1A(=F2brmCGvh9|WM@Fr}l? zB4r&QI*yiOLGa`Th6x~0bFP!rP?X3GJB;?fQ@_&1Ouw7lkKm?7kqZ_47F=>!@dCa- zawhQc;J#{V(Xk@OfER5$vxG@tOGeyBy!*OWZ;Hdw=w^!ZScjNDmah^ojQ&~}=8=6h zzlRCC$JD@CC4hFd?1F~ea#>$4cE@$)1+v8a{Lpbwh-)@J+^UhtE@)q`t`LX&?2P~sPkQ*o`FF&K<7|4z~B%-=YN(V Zf*XB#kb(i;`R8A@EWkh5ugN#&)<6DKW32!H literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/art/foreground/fg-grass-boughs.png b/packages/core/genres/platformer-assets/art/foreground/fg-grass-boughs.png new file mode 100644 index 0000000000000000000000000000000000000000..4b2e7b644fd6e61c82be6c74da94593672ec7a81 GIT binary patch literal 853 zcmeAS@N?(olHy`uVBq!ia0y~yU~~Yow{Wll$)``g3NkP-%XqpthE&{od&_&%Vg&}) z3)4;s8J%F;^q)1ASu%zH<;2i!x^;pbbAqQH?AGt#2oKnO{O`}dn-Bf|{Hm?~`+n(q z{+R1mkJXyntk~P4utl^X{A6PW!?CoQLxL;`T&5|`=A{XTyN({ZxJIxg;gpZYM9IY0 ze%C`D{jDthtA2bci-x}0y3!T;5NY;$rkbZm(Qv1oegHw?-bv5I@y&Qc}nkZysmjfqfO;RrwvzF zqIe%^&12$@T%cL(U)ygZIPZ6FcznbEX$KfYX0YbXm1T;tV$cm|e8>Ten;{1#+7XF+2TV-Oo+;DzN%t`u_ZC;g~sc4OTO?)3x8O$o;(KCs5%&`}OOl6$n$tQ>%D;Wry^ZfB1$1>6_RFNNGF$c2Nw|%DW$>2Uf<@wPWP1kvfER;if0)ac(uFnYHuo({_;G>yLQ^S&lBtRJd;_gd;c|y l!{$Bg92^b|j2ss__TN2|I`1D>-x5%Kc)I$ztaD0e0s#EtKaT(a literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/art/tiles/tileset.json b/packages/core/genres/platformer-assets/art/tiles/tileset.json new file mode 100644 index 00000000..0c5c9c4c --- /dev/null +++ b/packages/core/genres/platformer-assets/art/tiles/tileset.json @@ -0,0 +1,86 @@ +{ + "tile": 8, + "columns": 10, + "terrain": { + "about": "47-tile blob autotile: the bits name which of the 8 neighbours are terrain; a corner bit counts only when both sides beside it are set.", + "bits": { + "N": 1, + "NE": 2, + "E": 4, + "SE": 8, + "S": 16, + "SW": 32, + "W": 64, + "NW": 128 + }, + "byMask": { + "0": 0, + "1": 1, + "4": 2, + "5": 3, + "7": 4, + "16": 5, + "17": 6, + "20": 7, + "21": 8, + "23": 9, + "28": 10, + "29": 11, + "31": 12, + "64": 13, + "65": 14, + "68": 15, + "69": 16, + "71": 17, + "80": 18, + "81": 19, + "84": 20, + "85": 21, + "87": 22, + "92": 23, + "93": 24, + "95": 25, + "112": 26, + "113": 27, + "116": 28, + "117": 29, + "119": 30, + "124": 31, + "125": 32, + "127": 33, + "193": 34, + "197": 35, + "199": 36, + "209": 37, + "213": 38, + "215": 39, + "221": 40, + "223": 41, + "241": 42, + "245": 43, + "247": 44, + "253": 45, + "255": 46 + }, + "fillVariants": [ + 46, + 47, + 48, + 49 + ] + }, + "tiles": { + "platform-left": 50, + "platform-mid": 51, + "platform-right": 52, + "platform-post": 53, + "spikes-up": 54, + "spikes-right": 55, + "spikes-down": 56, + "spikes-left": 57, + "deco-tuft": 58, + "deco-flowers": 59, + "deco-rock": 60, + "deco-vine": 61 + } +} diff --git a/packages/core/genres/platformer-assets/art/tiles/tileset.png b/packages/core/genres/platformer-assets/art/tiles/tileset.png new file mode 100644 index 0000000000000000000000000000000000000000..c60e4cf5fb7e51336fabd681dd978ad6b00180c3 GIT binary patch literal 1472 zcmV;x1wZeSA|5^60uN(rAC>K0)aq4YrC%){pivaGy$&Iaj(>>)so{}j0r)Y&7t(Ff=Mj5n1j#i2ru!Ehx6DEg}4JW6)!0ETbI#F#m41G6uW{`MQTML{0PZKwnmXBFZ+nY{W9_cx-R<9BuMPw}j1%s-hv?;kG@+CL?1o+R26 zd0b}cwP$@XI5Pj7;Mc#H2ZqH1gW^ea0-z6-`$VdgSvb~Ea zbHvK_uI*}FTCdy6m2rI#KjR&6EqTO)lIA77xNG8o{1amoM#d2t?0H;2wdZl5Ve`0g zeGq?3^iu$E#51ijx3awpq7`z~X_fL-vY+=NiuPFm)3g1){EK;@Umkc;JnOXZOfsWo zO(o153j=yzw}~o=tDsn-PV%OOCv)zQ$FUMk^hoVl$(g=ee*!-bbi!%lneiOx6CHM^ zDW&x~!juPbCKo2$_@>y=gmj_@sfF`Wo&*5t@_TT4t>}bwqQ^9*Y>tx2*$)usFwy@o zcUI{{4-}^}v#`(O{9tk@8R}Ngjs18I^veTJn#cX`1L%f#sayLnSjQ2MW9NlN$fqHG zzuLeTJYUg*}o*YiHvYf({7vWO&?pwnJ6 zDEr6tfPHP{j)TV?r@r{n(y5pOqcq2Q{V#K%Bjf|eR4l<>U{S2B>>=~Pd+sD@om0Oc0T}&eyLNxPZ$8c{eH>R zo}Hd($tDZ9h`YCLxYA!SUQj;kn=)=`Rwtr=mqzF@5O~JOx1}88*F~BTv{ObzVHwE12$FJIA+i4C=U%yPn z>)P5|sKZ^R?5ma!pcQhow)VCWc*iH1zJ8gi!(FJYy*(_=;V!TN0HE^2F9b2{!9N9d z%|EqvM$5-p?8^j}iR})>YSrWyft1#XGB*#zkZk1^CNDO268FAaMQI(4T?8Mr^37!; z2DPmN$bu*CNXX#(P@f+Lku4ZJ;!G4unBRu|_)n+lCfQ0W3u@a2@UznIt?x93yHJVa ahkpU41GtTOFH1!L0000= edge + (off if edge else 0): + col = name + c.px[y][x] = col + # Each band edge is a two-row checker, so the step reads as a soft gradient. + for i in range(1, len(bands)): + edge, name = bands[i] + above = bands[i - 1][1] + for x in range(W): + y = edge + edge_off(x) + if x % 2 == 0: + c.set(x, y - 1, name) + else: + c.set(x, y, above) + # Stars: few, in the dark bands only; a few brighter ones are crosses. + rng = random.Random(7) + for _ in range(60): + x, y = rng.randrange(W), rng.randrange(0, 64) + if c.px[y][x] in ("ink", "night") and all(c.get(x + dx, y + dy) in ("ink", "night") for dx in (-1, 0, 1) for dy in (-1, 0, 1)): + c.px[y][x] = "dusk" if rng.random() < 0.6 else "slate" + for x, y in ((40, 14), (131, 24), (212, 9), (290, 30), (166, 46)): + c.set(x, y, "haze") + for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)): + c.set(x + dx, y + dy, "dusk") + # The moon, upper left: the one light every asset is shaded from. + mx, my, r = 62, 30, 9 + for y in range(my - r, my + r + 1): + for x in range(mx - r, mx + r + 1): + if math.hypot(x - mx, y - my) <= r + 0.3: + lit = math.hypot(x - mx + 3, y - my + 3) <= r + 0.5 + c.set(x, y, "haze" if lit else "mist") + for x, y in ((59, 26), (60, 26), (59, 27), (64, 33), (65, 33), (63, 24)): + c.set(x, y, "mist") + return c + + +def ridge_plane(base, terms, ps, body, lit, snow=None, snow_shade=None, snow_line=None): + """A mountain plane of faceted peaks: each peak's face toward the moon (left) is lit, + split from its shaded face by a spine that wanders down from the summit.""" + c = Canvas(W, H) + top = [] + owner = [] + for x in range(W): + h0 = wave(x, terms) + best, who = 0, None + for i, (cx, ht, hw) in enumerate(ps): + d = min(abs(x - cx), W - abs(x - cx)) + if d < hw: + v = ht * (1 - d / hw) ** 1.15 + if v > best: + best, who = v, i + top.append(round(base - h0 - best)) + owner.append(who) + for x in range(W): + for y in range(max(0, top[x]), H): + c.px[y][x] = body + i = owner[x] + if i is None: + continue + cx, ht, hw = ps[i] + summit = base - ht + down = y - summit + # The spine drifts right as it falls, with a few kinks. + spine = cx + down * 0.35 + 2.5 * math.sin(down * 0.21 + i) + dx = x - cx + if dx > W / 2: + dx -= W + if dx < -W / 2: + dx += W + if cx + dx < spine and down < ht * 0.8: + c.px[y][x] = lit + if snow is not None: + line = snow_line + round(3 * math.sin(x * 0.45 + i * 2)) + (x % 5 == 0) + if y < line: + c.px[y][x] = snow if c.px[y][x] == lit else snow_shade + return c + + +def far_mountains(): + ps = [(18, 58, 44), (96, 82, 54), (168, 50, 38), (240, 92, 60), (300, 46, 34)] + return ridge_plane(150, [(3, 3, 0.4), (1.5, 7, 2.1)], ps, "slate", "mist", snow="haze", snow_shade="mist", snow_line=84) + + +def mid_mountains(): + ps = [(52, 50, 50), (136, 36, 40), (204, 58, 54), (276, 44, 44)] + return ridge_plane(152, [(4, 2, 1.1), (2, 6, 0.2), (1, 11, 2.6)], ps, "dusk", "slate") + + +def near_forest(): + """The near backdrop: a hill of pines, darker and with more contrast than the planes behind.""" + c = Canvas(W, H) + hill = [round(150 - wave(x, [(5, 1, 0.5), (3, 3, 2.0), (1.5, 8, 0.9)])) for x in range(W)] + for x in range(W): + for y in range(hill[x], H): + c.px[y][x] = "night" + rng = random.Random(3) + x = 0 + trees = [] + while x < W: + trees.append((x, rng.randint(18, 34))) + x += rng.randint(9, 17) + for tx, th in trees: + base = hill[tx % W] + 2 + top = base - th + for row in range(th): + y = top + row + # Tiers: the half width grows down each tier and steps back at the next. + tier = 6 + k = row % tier + half = (row // tier) * 1 + k * 0.7 + 1 + half = min(half, 9) + for dx in range(-int(half), int(half) + 1): + xx = (tx + dx) % W + lit_side = dx < 0 and k <= 2 and abs(dx) >= int(half) - 1 and row > 2 + if 0 <= y < H: + c.px[y][xx] = "dusk" if lit_side else "night" + # The trunk in shadow. + for y in range(base - 2, base + 1): + c.set(tx % W, y, "night") + return c + + + +# --- Tiles ------------------------------------------------------------------- +# Terrain is one 8x8 autotile drawn per pixel from its eight neighbours: grass +# where open sky is above, a lit clay rim on the left (the moon's side), a +# shaded rim on the right and below, an ink outline on every open side, and the +# outer corners cut round. + +N, NE, E, SE, S, SW, Wb, NW = 1, 2, 4, 8, 16, 32, 64, 128 +DIRS = {N: (0, -1), NE: (1, -1), E: (1, 0), SE: (1, 1), S: (0, 1), SW: (-1, 1), Wb: (-1, 0), NW: (-1, -1)} + +# The base texture under the rims: strata of short plum dashes on umber, in +# four variants that each loop on all four sides. Variant 0 is the quiet one. +STRATA = [ + ["........", "........", "........", "........", "........", "........", "........", "........"], + ["........", "...ppp..", "........", "........", "........", "........", "........", "........"], + ["........", "........", "........", "..pp....", ".pppp...", "........", "........", "........"], + ["........", "........", "........", "........", "........", "........", "pp....pp", "........"], +] +GRASS_DRIP = [0, 1, 0, 0, 2, 1, 0, 1] # how far grass hangs below the top, per column + + +def canonical(mask): + """Corners only count when both sides beside them are solid (the 47-tile blob set).""" + for corner, a, b in ((NE, N, E), (SE, S, E), (SW, S, Wb), (NW, N, Wb)): + if not (mask & a and mask & b): + mask &= ~corner + return mask + + +BLOB = sorted({canonical(m) for m in range(256)}) + + +def terrain_tile(mask, variant=0): + solid = [[False] * 24 for _ in range(24)] + for y in range(8, 16): + for x in range(8, 16): + solid[y][x] = True + for bit, (dx, dy) in DIRS.items(): + if mask & bit: + for y in range(8 + dy * 8, 16 + dy * 8): + for x in range(8 + dx * 8, 16 + dx * 8): + solid[y][x] = True + + def empty(x, y): + return not (0 <= x < 24 and 0 <= y < 24) or not solid[y][x] + + def run(x, y, dx, dy): + k = 1 + while k < 6 and not empty(x + dx * k, y + dy * k): + k += 1 + return k # 1: the next pixel that way is open + + def depth(x, y): + """How far the nearest open pixel is, counting diagonals (1: touching).""" + for d in range(1, 9): + for j in range(-d, d + 1): + for i in range(-d, d + 1): + if max(abs(i), abs(j)) == d and empty(x + i, y + j): + return d + return 9 + + c = Canvas(8, 8) + tex = STRATA[variant] + for ty in range(8): + for tx in range(8): + x, y = tx + 8, ty + 8 + up, down, left, right = run(x, y, 0, -1), run(x, y, 0, 1), run(x, y, -1, 0), run(x, y, 1, 0) + # Outer corners: cut the pixel where two open sides meet. + if (up == 1 or down == 1) and (left == 1 or right == 1): + continue + d = depth(x, y) + # Deep rock is dark, so the edges the player touches carry the contrast. + if d >= 5: + col = "umber" if tex[ty][tx] in "pc" else "plum" + else: + col = "umber" + # Rims, read from the nearest open side: lit toward the moon, shaded away from it. + if left == 2 or (up == 2 and left <= 3): + col = "clay" + if right == 2 or down == 2: + col = "plum" + if up <= 3 + GRASS_DRIP[tx]: + col = {1: "lime", 2: "leaf", 3: "leaf"}.get(up, "moss") + if up == 1 and (tx + ty) % 4 == 3: + col = "leaf" + elif left == 1 or right == 1 or down == 1 or d == 1: + col = "ink" + c.px[ty][tx] = col + return c + + +def platform_tiles(): + """A one-way plank: left end, middle, right end, and a post that holds it up.""" + keys = {"i": "ink", "s": "sand", "c": "clay", "u": "umber", "p": "plum"} + left = from_rows(["........", ".iiiiiii", "issssccs", "icuuuuuu", "ipiipiii", ".i......", "........", "........"], keys) + mid = from_rows(["........", "iiiiiiii", "sscssssc", "uuuuuuuu", "iipiiiip", "........", "........", "........"], keys) + right = left.flipped() + # The ends' shade side: the right end's rim is shaded, not lit. + # The post is support, behind the play: thin and dark, so it never reads as a wall. + post = from_rows(["...iui..", "...upi..", "...upi..", "...upi..", "...ppi..", "...upi..", "...upi..", "...upi.."], keys) + return {"platform-left": left, "platform-mid": mid, "platform-right": right, "platform-post": post} + + +def spike_tiles(): + """Spikes: pale steel, lit on the moon's side, on an ink base; one drawing turned four ways.""" + keys = {"w": "white", "h": "haze", "m": "mist", "s": "slate", "i": "ink"} + up = from_rows([ + "........", + ".w...w..", + ".w...w..", + "hwm.hwm.", + "hwm.hwm.", + "hwmmhwmm", + "hwmmhwmm", + "iiiiiiii", + ], keys) + + def rot(c): # 90 degrees clockwise + r = Canvas(c.h, c.w) + for y in range(c.h): + for x in range(c.w): + r.px[x][c.h - 1 - y] = c.px[y][x] + return r + + right = rot(up) + down = rot(right) + left = rot(down) + return {"spikes-up": up, "spikes-right": right, "spikes-down": down, "spikes-left": left} + + +def deco_tiles(): + """Decoration, drawn on its own layer over the terrain: never collides, never looks like it does.""" + keys = {"l": "lime", "f": "leaf", "m": "moss", "p": "pine", "h": "haze", "w": "white", "g": "gold", + "i": "ink", "u": "umber", "c": "clay", "s": "sand", "v": "violet", "a": "magenta"} + tuft = from_rows([ + "........", + "........", + "........", + "...l....", + ".l.f..l.", + ".fl.lf.f", + "f.ff.fff", + "fmffmfmf", + ], keys) + flowers = from_rows([ + "........", + "........", + ".h......", + "hwh..a..", + ".h..ava.", + ".f...a..", + ".f.l.f..", + "ff.ffmf.", + ], keys) + rock = from_rows([ + "........", + "........", + "........", + "..iiii..", + ".icssui.", + "icccuupi", + "icuuuppi", + "iiiiiiii", + ], keys) + vine = from_rows([ + "mfmmffmm", + ".f..f.m.", + ".f..l.f.", + ".l..f.f.", + ".f....l.", + ".m....f.", + "......m.", + "......f.", + ], keys) + return {"deco-tuft": tuft, "deco-flowers": flowers, "deco-rock": rock, "deco-vine": vine} + + +def sheet(tiles, columns, gap=0): + rows = (len(tiles) + columns - 1) // columns + c = Canvas(columns * (TILE + gap) - gap, rows * (TILE + gap) - gap) + for i, t in enumerate(tiles): + c.blit(t, (i % columns) * (TILE + gap), (i // columns) * (TILE + gap)) + return c + + +def tileset(): + """The atlas: the 47 terrain tiles, three more fills, then props on the last row.""" + terrain = [terrain_tile(m) for m in BLOB] + [terrain_tile(255, v) for v in (1, 2, 3)] + props = {} + props.update(platform_tiles()) + props.update(spike_tiles()) + props.update(deco_tiles()) + cols = 10 + names = [f"terrain-{m}" for m in BLOB] + ["terrain-255-v1", "terrain-255-v2", "terrain-255-v3"] + tiles = terrain[:] + # Props start on a new row. + while len(tiles) % cols: + tiles.append(Canvas(8, 8)) + names.append(None) + for name, t in props.items(): + tiles.append(t) + names.append(name) + atlas = sheet(tiles, cols) + index = {n: i for i, n in enumerate(names) if n} + data = { + "tile": TILE, + "columns": cols, + "terrain": { + "about": "47-tile blob autotile: the bits name which of the 8 neighbours are terrain; a corner bit counts only when both sides beside it are set.", + "bits": {"N": N, "NE": NE, "E": E, "SE": SE, "S": S, "SW": SW, "W": Wb, "NW": NW}, + "byMask": {str(m): index[f"terrain-{m}"] for m in BLOB}, + "fillVariants": [index["terrain-255"], index["terrain-255-v1"], index["terrain-255-v2"], index["terrain-255-v3"]], + }, + "tiles": {n: i for n, i in index.items() if not n.startswith("terrain")}, + } + return atlas, data, tiles, names, props + + + + +# --- The player -------------------------------------------------------------- +# A small climber in a red hooded coat with a scarf. Frames are 16x16 with the +# feet on the bottom row; each frame is drawn as fill (head and body parts) and +# the ink outline is added around the whole shape, so every frame has the same +# outline weight. The red ramp belongs to the player alone; the scarf is the +# dash: gold while a dash is ready, blue once it is spent. + +PKEYS = {"r": "red", "d": "wine", "l": "rose", "s": "skin", "t": "tan", "e": "ink", + "y": "yellow", "g": "gold", "p": "violet", "b": "plum", "k": "ink"} + +HEAD = [ + "..llrr..", + ".lrrrrr.", + "lrrrssss", + "rrrseses", + "drrsssst", +] +HEAD_BLINK = [ + "..llrr..", + ".lrrrrr.", + "lrrrssss", + "rrrststs", + "drrsssst", +] + + +def frame(body, head_at=(4, 4), head=HEAD, extra=()): + """One frame: body rows from row 9 (or the row given) down, then the head over them.""" + c = Canvas(16, 16) + start, rows = body + for j, row in enumerate(rows): + assert len(row) == 16, row + for i, k in enumerate(row): + if k != ".": + c.px[start + j][i] = PKEYS[k] + hx, hy = head_at + c.blit(from_rows(head, PKEYS), hx, hy) + for x, y, k in extra: + c.px[y][x] = PKEYS[k] + # The fill keeps a pixel clear of the frame's edge, so the outline is never cut off. + for y in range(16): + for x in range(16): + if c.px[y][x] is not None: + assert 0 < x < 15 and 0 < y < 15, ("fill touches the frame edge", x, y) + return outline(c) + + +def player_animations(): + idle_body = [ + ".....gyyyyy.....", + "....g.lrrrrs....", + "....g.lrrrrd....", + ".....lrrrrrdd...", + "......pp..pp....", + "......bb..bb....", + ] + idle_body_b = [ + ".....gyyyyy.....", + ".....glrrrrs....", + "....g.lrrrrd....", + ".....lrrrrrdd...", + "......pp..pp....", + "......bb..bb....", + ] + # Breathing: the head and coat sink a pixel, the legs stay. + idle_dip = [ + ".....gyyyyy.....", + "....g.lrrrrs....", + "....glrrrrrdd...", + "......pp..pp....", + "......bb..bb....", + ] + idle = [ + frame((9, idle_body)), + frame((9, idle_body_b)), + frame((10, idle_dip), head_at=(4, 5)), + frame((10, idle_dip), head_at=(4, 5), head=HEAD_BLINK), + ] + + # Running: the body leans a pixel forward; a stride, a bent step, and a + # passing pose, twice, with the scarf streaming behind. + run_stride = [ + "..ggyyyyyy......", + ".g...lrrrrrs....", + ".....lrrrrrd....", + "......lrrrrdd...", + ".....pp...pp....", + "....bb.....bb...", + ] + run_bent = [ + "...gggyyyyyy....", + "..g...lrrrrrs...", + "......lrrrrrdd..", + ".......pp.pp....", + "......bb..bb....", + ] + run_pass = [ + ".g.ggyyyyyy.....", + "..g..lrrrrrd....", + ".....slrrrrd....", + "......lrrrrdd...", + "........ppb.....", + ".......bb.......", + ] + run = [ + frame((9, run_stride), head_at=(5, 4)), + frame((10, run_bent), head_at=(6, 5)), + frame((8, run_pass), head_at=(5, 3)), + frame((9, run_stride), head_at=(5, 4)), + frame((10, run_bent), head_at=(6, 5)), + frame((8, run_pass), head_at=(5, 3)), + ] + + # In the air: rising, the legs tuck and the scarf hangs below; falling, the + # legs reach down and the scarf lifts. + rise = [ + "....gyyyyyys....", + "...g.lrrrrrr....", + "...g.lrrrrrd....", + "..g..lrrrrdd....", + ".....pp.pp......", + ".....bb..bb.....", + ] + fall_a = [ + ".gg..gyyyyy.s...", + "...gg.lrrrrr....", + "......lrrrrd....", + ".....lrrrrrdd...", + ".....pp...pp....", + ".....bb....bb...", + ] + fall_b = [ + "..gg.gyyyyy.s...", + ".g..g.lrrrrr....", + "......lrrrrd....", + ".....lrrrrrdd...", + ".....pp...pp....", + ".....bb....bb...", + ] + jump = [ + frame((8, rise), head_at=(4, 3)), + frame((8, rise), head_at=(4, 3), extra=[(2, 12, "g")]), + ] + fall = [ + frame((9, fall_a), head_at=(4, 4)), + frame((9, fall_b), head_at=(4, 4)), + ] + + # Dashing: stretched flat along the dash, the head out front, the legs and the + # scarf straight behind. + dash_a = [ + ".ggyyyy.........", + "....yglrrr......", + ".bpp.lrrrrd.....", + "......dddd......", + ] + dash_b = [ + "..gyyyy.........", + ".g..yglrrr......", + ".bpp.lrrrrd.....", + "......dddd......", + ] + dash = [ + frame((7, dash_a), head_at=(7, 4)), + frame((7, dash_b), head_at=(7, 4)), + ] + + # Sliding down a wall on the right: a hand up on the wall, a knee against + # it, the scarf lifted by the slide. + slide_a = [ + "..g..gyyyyy.....", + "...g.lrrrrr.....", + ".....lrrrrrs....", + ".....lrrrrdd....", + "......pp.ppb....", + "......bb........", + ] + slide_b = [ + ".g...gyyyyy.....", + "..gg.lrrrrr.....", + ".....lrrrrrs....", + ".....lrrrrdd....", + "......pp.ppb....", + "......bb........", + ] + wall_hand = [(12, 6, "s"), (12, 7, "r")] + slide = [ + frame((9, slide_a), head_at=(4, 4), extra=wall_hand), + frame((9, slide_b), head_at=(4, 4), extra=wall_hand), + ] + + # Landing: one squashed frame, wider as it flattens. + land_body = [ + "....ggyyyyyy....", + "...g.lrrrrrrs...", + "....lrrrrrrrdd..", + ".....pp....pp...", + ".....bb....bb...", + ] + land = [frame((10, land_body), head_at=(4, 6))] + + return { + "idle": (idle, 220, True), + "run": (run, 70, True), + "jump": (jump, 90, True), + "fall": (fall, 90, True), + "dash": (dash, 60, True), + "wall-slide": (slide, 120, True), + "land": (land, 80, False), + } + + +SPENT = {"yellow": "cyan", "gold": "blue"} + + +def recolor(c, swap): + out = c.copy() + out.px = [[swap.get(k, k) for k in row] for row in c.px] + return out + + +def player_sheet(anims, swap=None): + """Every animation on one row of its own; JSON in the hash format Pixi, Phaser, and Aseprite read.""" + cols = max(len(f) for f, _, _ in anims.values()) + c = Canvas(cols * 16, len(anims) * 16) + frames, tags, by_name = {}, [], {} + n = 0 + for row, (name, (fs, ms, loop)) in enumerate(anims.items()): + names = [] + for i, f in enumerate(fs): + c.blit(recolor(f, swap) if swap else f, i * 16, row * 16) + key = f"{name} {i}" + frames[key] = {"frame": {"x": i * 16, "y": row * 16, "w": 16, "h": 16}, "duration": ms, + "anchor": {"x": 0.5, "y": 1}} + names.append(key) + tags.append({"name": name, "from": n, "to": n + len(fs) - 1, "direction": "forward"}) + by_name[name] = {"frames": names, "msPerFrame": ms, "loop": loop} + n += len(fs) + data = {"frames": frames, "animations": {k: v["frames"] for k, v in by_name.items()}, + "timing": by_name, + "meta": {"size": {"w": c.w, "h": c.h}, "frameSize": {"w": 16, "h": 16}, "scale": "1", + "about": "Feet on the bottom row; the anchor is the middle of the feet. Hitbox 8x12 from x 4..11, y 4..15. Faces right; flip for left.", + "frameTags": tags}} + return c, data + + +# --- The mockup room --------------------------------------------------------- + +LEVEL = [ + "#######...........................######", + "#####.............................######", + "####...............................#####", + "###................................#####", + "##..................................####", + "##..................................####", + "#...................................####", + "#...................................####", + "#..................................#####", + "#..................................#####", + "#..................................#####", + "##.................................#####", + "##........------...................#####", + "###........|..|....................#####", + "###........|..|...................######", + "####.......|..|...................######", + "####.......|..|........^^^^.......######", + "#####......|..|.....###########...######", + "##########.|..|.....###########...######", + "##########.|..|.....###########...######", + "##########.|..|^^^^^###########...######", + "########################################", + "########################################", +] + + +def solid_at(level, x, y): + if y < 0 or y >= len(level) or x < 0 or x >= len(level[0]): + return True # the room's border counts as rock, so no outline runs along the screen's edge + return level[y][x] == "#" + + +def compose_terrain(level, tiles_by_mask): + c = Canvas(len(level[0]) * TILE, len(level) * TILE) + for y, row in enumerate(level): + for x, k in enumerate(row): + if k != "#": + continue + mask = 0 + for bit, (dx, dy) in DIRS.items(): + if solid_at(level, x + dx, y + dy): + mask |= bit + mask = canonical(mask) + variant = 0 + if mask == 255: + h = (x * 73856093 ^ y * 19349663) % 7 + variant = (0, 0, 0, 0, 1, 2, 3)[h] # a detail on about half the fill tiles + c.blit(tiles_by_mask[(mask, variant)], x * TILE, y * TILE) + return c + + +def foreground(): + """In front of the play: grass at the bottom edge and pine boughs hanging from the top, + flat ink silhouettes with no detail, kept to the margins the player cannot reach.""" + c = Canvas(W, H) + rng = random.Random(11) + # Grass: clumps of blades leaning a little, loop-safe (blades wrap at the edges). + x = 0 + while x < W: + clump = rng.randint(4, 8) + tall = rng.randint(6, 12) + for b in range(clump): + bx = x + b * 2 + rng.randint(0, 1) + h = max(4, tall - abs(b - clump // 2) * 3 + rng.randint(-1, 1)) + lean = rng.choice((-1, 1)) * rng.randint(0, 3) + for k in range(h): + xx = (bx + round(lean * (k / h) ** 2)) % W + c.set(xx, H - 1 - k, "ink") + if k < h // 2: + c.set((xx + 1) % W, H - 1 - k, "ink") + x += clump * 2 + rng.randint(0, 8) + for xx in range(W): + for y in range(H - 4, H): + c.set(xx, y, "ink") + + def bough(x0, x1, y0, y1): + n = x1 - x0 + for i in range(n + 1): + bx = (x0 + i) % W + by = round(y0 + (y1 - y0) * i / n) + c.set(bx, by, "ink") + if i < n // 2: + c.set(bx, by - 1, "ink") # thicker toward the trunk + # A sprig hangs every few pixels: a short stepped wedge of needles. + if i % 7 == 3: + length = 6 + (i * 7) % 5 + for k in range(length): + half = max(0, (length - k) // 3) + for dx in range(-half, half + 1): + c.set((bx + dx) % W, by + 1 + k, "ink") + for y in range(0, min(y0, y1)): + c.set(x0 % W, y, "ink") + c.set((x0 + 1) % W, y, "ink") + + bough(0, 60, 0, 9) + bough(14, 40, 3, 13) + bough(268, 330, 2, 7) + return c + + +def fx_frame(name, i): + """One frame of an effect, read back from the sheet `ritmo-tools fx render` wrote.""" + with open(os.path.join(ART, "fx", f"{name}.json")) as f: + data = json.load(f) + fr = data["frames"][f"{name} {i}"]["frame"] + img = Image.open(os.path.join(ART, "fx", f"{name}.png")).convert("RGBA") + return img.crop((fr["x"], fr["y"], fr["x"] + fr["w"], fr["y"] + fr["h"])) + + +def room_layer(): + """The play layer of the mockup room: terrain by autotile, then props and decoration.""" + tiles_by_mask = {(m, 0): terrain_tile(m) for m in BLOB} + for v in (1, 2, 3): + tiles_by_mask[(255, v)] = terrain_tile(255, v) + room = compose_terrain(LEVEL, tiles_by_mask) + _, _, _, _, tp = tileset() + for y, row in enumerate(LEVEL): + for x, k in enumerate(row): + if k == "^": + room.blit(tp["spikes-up"], x * 8, y * 8) + if k == "-": + left = row[x - 1] != "-" + right = x + 1 < len(row) and row[x + 1] != "-" + room.blit(tp["platform-left" if left else "platform-right" if right else "platform-mid"], x * 8, y * 8) + if k == "|": + room.blit(tp["platform-post"], x * 8, y * 8) + for name, cells in { + "deco-tuft": [(5, 17), (9, 17), (2, 12), (29, 16), (10, 20)], + "deco-flowers": [(8, 17), (30, 16), (4, 16)], + "deco-rock": [(21, 16), (33, 20)], + "deco-vine": [(5, 1), (3, 3), (34, 2), (35, 4)], + }.items(): + for cx, cy in cells: + # Decoration sits in an open cell, on the ground (or under a ceiling, for vines). + assert LEVEL[cy][cx] == ".", (name, cx, cy) + assert LEVEL[cy - 1 if name == "deco-vine" else cy + 1][cx] == "#", (name, cx, cy) + room.blit(tp[name], cx * 8, cy * 8) + p = props() + room.blit(p["checkpoint"], 7 * 8, 18 * 8 - 16) + room.blit(p["spring"], 32 * 8, 21 * 8 - 8) + room.blit(p["fruit"], 19 * 8 + 1, 8 * 8) + return room + + +def layers_at(camera, layers, fg): + """The whole screen for a camera x: each plane offset by its own parallax, rounded alone.""" + out = Image.new("RGBA", (W, H)) + for (img, factor) in layers: + off = round(camera * factor) % W + for k in (0, 1): + out.alpha_composite(img, (-off + k * W, 0)) + return out + + +PARALLAX = [("bg-0-sky.png", 0.0), ("bg-1-far.png", 0.1), ("bg-2-mid.png", 0.25), ("bg-3-near.png", 0.5)] + + +def mockup(anims): + imgs = [(Image.open(os.path.join(ART, "backdrop", n)).convert("RGBA"), f) for n, f in PARALLAX] + fg = Image.open(os.path.join(ART, "foreground", "fg-grass-boughs.png")).convert("RGBA") + scene = layers_at(0, imgs, fg) + scene.alpha_composite(room_layer().image()) + # The player mid-dash over the pit, the scarf already spent: the burst where the dash + # began, and two afterimages between (an engine effect: the frame's silhouette, tinted). + px, py = 150, 82 + scene.alpha_composite(fx_frame("dash", 2), (px - 26 - 14, py + 9 - 14)) + dash = recolor(anims["dash"][0][0], SPENT) + for k, tint in ((2, "dusk"), (1, "slate")): + ghost = dash.copy() + ghost.px = [[None if c is None else tint for c in row] for row in dash.px] + scene.alpha_composite(ghost.image(), (px - 9 * k, py)) + scene.alpha_composite(dash.image(), (px, py)) + scene.alpha_composite(fg) + return scene + + +def save_gif(frames, durations, path, scale): + """Writes an animated GIF, merging equal frames in a row into one longer frame.""" + merged, times = [], [] + for img, ms in zip(frames, durations): + if merged and img.tobytes() == merged[-1].tobytes(): + times[-1] += ms + else: + merged.append(img) + times.append(ms) + big = [m.convert("RGB").resize((m.width * scale, m.height * scale), Image.NEAREST) for m in merged] + os.makedirs(os.path.dirname(path), exist_ok=True) + big[0].save(path, save_all=True, append_images=big[1:], duration=times, loop=0, optimize=True, disposal=1) + + +def player_gif(anims, path, scale): + """Every animation playing side by side on its own clock: idle, run, jump, fall, dash, wall slide, land.""" + tile_top = terrain_tile(canonical(E | Wb | S | SE | SW)) + wall = terrain_tile(canonical(N | S | E | NE | SE)) + order = ["idle", "run", "jump", "fall", "dash", "wall-slide", "land"] + cw, ch = 24, 32 + step, total = 10, 1760 + frames = [] + for t in range(0, total, step): + c = Canvas(cw * len(order), ch, "dusk") + for i, name in enumerate(order): + fs, ms, loop = anims[name] + k = (t // ms) % len(fs) if loop else min(len(fs) - 1, t // ms) + x0 = i * cw + if name == "wall-slide": + for y in range(0, ch, 8): + c.blit(wall, x0 + 18, y) + elif name not in ("jump", "fall", "dash"): + for x in range(0, cw, 8): + c.blit(tile_top, x0 + x, 24) + y = 8 if name not in ("jump", "fall", "dash", "wall-slide") else 6 + c.blit(fs[k], x0 + 4, y) + frames.append(c.image()) + save_gif(frames, [step] * len(frames), path, scale) + + +def parallax_gif(path, scale): + """The planes scrolling under a camera that pans one screen to the right and back.""" + imgs = [(Image.open(os.path.join(ART, "backdrop", n)).convert("RGBA"), f) for n, f in PARALLAX] + fg = Image.open(os.path.join(ART, "foreground", "fg-grass-boughs.png")).convert("RGBA") + frames = [] + for i in range(96): + cam = round(W * (1 - math.cos(math.pi * 2 * i / 96)) / 2) + img = layers_at(cam, imgs, fg) + off = round(cam * 1.25) % W + for k in (0, 1): + img.alpha_composite(fg, (-off + k * W, 0)) + frames.append(img) + save_gif(frames, [40] * len(frames), path, scale) + + +def preview_strip(layers, scale=4): + """The planes stacked once, at the screen's size: what the backdrop looks like still.""" + out = Canvas(W, H) + for layer in layers: + out.blit(layer, 0, 0) + return out + + +def main(): + os.makedirs(ART, exist_ok=True) + os.makedirs(PREVIEWS, exist_ok=True) + # The palette as a file, and the project's rules for `ritmo-tools pixel` (lint, render, fx). + with open(os.path.join(HERE, "palette.hex"), "w") as f: + f.write("".join(v.lstrip("#") + "\n" for v in PALETTE.values())) + with open(os.path.join(HERE, "pixel.config.json"), "w") as f: + json.dump({"palette": "palette.hex", "maxColors": 16}, f, indent=2) + f.write("\n") + layers = { + "bg-0-sky.png": sky(), + "bg-1-far.png": far_mountains(), + "bg-2-mid.png": mid_mountains(), + "bg-3-near.png": near_forest(), + } + save(foreground(), "foreground/fg-grass-boughs.png") + for name, layer in layers.items(): + save(layer, "backdrop/" + name) + save(preview_strip(list(layers.values())), "backdrop/backdrop-stacked.png") + atlas, data, *_ = tileset() + save(atlas, "tiles/tileset.png", scale=8) + with open(os.path.join(ART, "tiles/tileset.json"), "w") as f: + json.dump(data, f, indent=2) + f.write("\n") + anims = player_animations() + psheet, pdata = player_sheet(anims) + save(psheet, "player/player.png", scale=8) + pdata["meta"]["image"] = "player.png" + with open(os.path.join(ART, "player/player.json"), "w") as f: + json.dump(pdata, f, indent=1) + f.write("\n") + save(anims["idle"][0][0], "player/player-idle.png", scale=8) + spent, _ = player_sheet(anims, SPENT) + save(spent, "player/player-spent.png", scale=8) + # The effects are drawn by `ritmo-tools fx render` (see the spec); the mockup reads its sheets. + save(mockup(anims), "mockup/mockup.png") + player_gif(anims, os.path.join(PREVIEWS, "player/player-animations@4x.gif"), 4) + # Previews of what other tools drew: the props (`pixel render`) and the effects (`fx render`). + p = props() + row = Canvas(sum(c.w for c in p.values()) + 4 * (len(p) + 1), 20) + x = 4 + for c in p.values(): + row.blit(c, x, 18 - c.h) + x += c.w + 4 + save(row, "props/props.png", scale=8, art=False) + for name in ("dash", "dust", "collect"): + save(Image.open(os.path.join(ART, "fx", f"{name}.png")).convert("RGBA"), f"fx/{name}.png", scale=4, art=False) + # Not committed (about 0.6 MB): written for a person to watch. + parallax_gif(os.path.join(PREVIEWS, "parallax/parallax@2x.gif"), 2) + + +if __name__ == "__main__": + main() diff --git a/packages/core/genres/platformer-assets/palette.hex b/packages/core/genres/platformer-assets/palette.hex new file mode 100644 index 00000000..1f057912 --- /dev/null +++ b/packages/core/genres/platformer-assets/palette.hex @@ -0,0 +1,28 @@ +181425 +262b44 +3a4466 +5a6988 +8b9bb4 +c0cbdc +ffffff +3e2731 +733e39 +b86f50 +e4a672 +193c3e +265c42 +3e8948 +63c74d +a22633 +e43b44 +f6757a +e8b796 +c28569 +be4a2f +f77622 +feae34 +fee761 +0099db +2ce8f5 +68386c +b55088 diff --git a/packages/core/genres/platformer-assets/pixel.config.json b/packages/core/genres/platformer-assets/pixel.config.json new file mode 100644 index 00000000..2a359857 --- /dev/null +++ b/packages/core/genres/platformer-assets/pixel.config.json @@ -0,0 +1,4 @@ +{ + "palette": "palette.hex", + "maxColors": 16 +} diff --git a/packages/core/genres/platformer-assets/previews/backdrop/backdrop-stacked@4x.png b/packages/core/genres/platformer-assets/previews/backdrop/backdrop-stacked@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..6d440c8bc991b56a8b5682332ccf1ab732bacc97 GIT binary patch literal 11140 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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/previews/backdrop/bg-1-far@4x.png b/packages/core/genres/platformer-assets/previews/backdrop/bg-1-far@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..45ec5b11a1975b8ae01221c72e4cdfb5621c5424 GIT binary patch literal 7189 zcmeHLYgAKL7CtvYUX7r&wM0}{V|8qY4$w<6@(LDhhapuv)S|1^gd$06MPfw=ujC@N zv=yYI9VG^mj&|s<+8PiGB9H{r@lg_j1x@6YP%A+RCN`K5@|t^TXVz+aFP*=$7QYVU z+;h&}``h2Q_c)y;elaBkgk<(D>KHSnIgiw7-zSJTV zfV4Zl;poy|)iNrA{>aVC%R5-wW-BQu&V3p2S%+(h3Nws#Vno1e?vs1(P81yRjW`yH zE&o+zWMkGuJ<{Ie8r0r+cxS*mJlPox)vU(fcuxOcJ%R3zJcW7uDL*kod-82fL90FK zN!HRK+(5xtP?1#HluE9Z?mC+&n3)+qO+I3n!+XmUXU|4z#pZqHX9A<}PjQ0CmIA_jWSt&MDmVUztQCR4BKmJ?Is$3__^ddpiQKm`f~@Eh4XWfh@Sc|F zW?xWC53zOJDOuo(Bn+z}W^WI#(0%XDW^c(oS&3&X#TVG(f^YBzqCIjZD-Pex_$2v- z!bS?X-F{KFe9Bmr2(t$%qMaO%d*(skNfHP$xhvKkpLw`9ehXvLbzoetZ=v?KU&KoKFnZ}*fHh`3+{77ByA#f<$5eOvnvd7@NKif4McTd=Ka8kqy&pG4 zsZ~>BQeZSW^9#m>$~1a#Rbn4kYt^*~5yd-gxV&NehAYbY*%n65*h0Xa_R4Za!VG$t zYSP}Cv&Jyym_n5|4LpL+2OV~sD9;8VyK;ODu_BlgG^wqY$aVu-ZiK0$DaI+5#&W!s zCO=S=|HHT^F2?yBK&+2j!tm4e8NRQfMYteZFmHNp7EFI`8rprq@SaMpzD!f2JK%EX`)G6sj7us+T>i7x{VDw3t? zk6N;bRqMXNKqH6HZ{rFc22a{^w#uyl-7$avIQ41;`|`7l3jA%`s7Sh~p=o_{=5eY& zP@1GEny)cFgMZ>T0kblk*&{D&P`d`%gOyLi^$LC$%{eJEX#q{Jm2O^s%KBL46~B??g9R&8WmGlik1wb6^2 zTo1CpCcwX&fT`m!P^)MW@M2)n8cHEUt}16uxW$OCO!3o{WY{Y{Azc5lZc8Jx+)XW! zL&o1rS~bN5_)gDOx^~_@;hSs#RoLKtewoOR{R5UB_f*%g38Fn{SHcB_8(6G~Mipg{(S!)8jQD zW)(T)L$?nST?4&q^)tx*I^8;kVweEqgT9|osoiYs#8a|{I(vTI-P@%QQ2CV9;-BDs zj@+w~E90gZq7)deDAh3){3>@yi5@bpc0LGE`MhoD>JmlfX%6-DtugL_3DTo0U|yH6=!o1xrHk?Ti-^#XhrVZ8sATlMOc43b!$Y!gvtzSK(G*6F3E4P5A*)z=cV|(~@7vW?$+MI$r#M`nm0G zXOlftFJRGa8N7?usk7e1Jls|hHB#81J|CSG*eD;6-s({`zlE6yjAvGxylM1mQ?ZzL z&wKOCUl*qG*4yV40*-s}$RC7Fc4zbjssRvs3Sq8;MADip$h zgjcfGqcIxrbn|{(Z%Z?-a!T!)86xIX9AP z_5+rFd~U#GZl>ys?+VykAzdz2B1A@lEygrwr~70RVRdePgWbbd@epM+`3k?v9t!G9 zl729DWgj34>S2+S5&9$YMIWkkUCvQAdI7>0JQXF`AI|ctS2B{F&x{!9+e885Zs1(C zrCC2Ha1ctTFS(RO_GPnV-_(VQ@v}v$5(>ifQlj<&- z?TSg$N8AG{dPk(PE?4CuBMu@!lBd-=7*h8`A#86#Vtmuus9wiqhYu(sJnF?#hfDoC z%2mb+v~gnX#jgwK?V(y%d&`cR)akJUkRGoGpgkVzJ$@BrX3%g=f#O6uyJ;UA-kT$q41R$T~73DvB*V;hDRqWZDQ7gP+B4`qS-uC}5 z4;gd5a?DTu);rLAgytiJ`$#wETiXA}WTTh-sN^xKk#p@aRCYk>rp+7AKF>PzZ@N&% AS^xk5 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/previews/backdrop/bg-2-mid@4x.png b/packages/core/genres/platformer-assets/previews/backdrop/bg-2-mid@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..33abba0d31a5595dd66264504b8ec432c9019fba GIT binary patch literal 5985 zcmeHLZA?>F7=CYCXe%H@vZ1R=om+Jo4gyIn0c>?R<|YicIkzFBiebxAq<&-;80`i5 z*b*aVpJ-imahonNAbt#VKno&sA{58aBBi}56Emdktk}Ti(w#fpkBuJx?Z=Y)>%I5% zx$k+;^M3YxoSBgpHtUI501&q3#ne{;g3u$cM-+^NwPf%OfT*QwQdhpNyFO}PxwrRC zSiMdaBUn@~?r8qPvGbdyNu`U{e|;{yR`G+M8NU4Xv3XDJ&97~73?K4O(j$>b3GBOn zA&r%g&6BdCTuibeLIyk}R5c)CUpH|-awKq(z@-CM6S%_2bqA8|iCl~1NZ^L0|9oP6 z(8tcFdu|R?yX&Ut56(_xg1R)4L~AoLP!0r;z2}^hSra>qBzTrDK??xVwID!(j3Xl0 zui7;1XnVB&^tcd?4-2I1+P|mXFckn5msKz|=r3vL?5hg3+&}nFB?5#15S=2>RCG6Q zq)Q3v{g1HfXn(QSjg0RhsJ)MXb=_@7R>kb#OH027k|+>02~I;bufLENsG7Pcs=-0x)`V{K4DW1VM)P-%_p1rLh!VlKVY@W zq?Eoj6z7GDJsJw_yUTXZd*+WImoRe(7iN{4KP8Y#K1nY-ehUZ6=#ue)Dydp*t{(X9 z_vZ<<4(C?^kPG@JB{Y3fEb=-GgW+?rL7DiNQ2{#~?)*Cx6YPt%Fi|F~hv#3CAq$x- z!`9bA+zERom>&&<_63{~TQ~!9~*eyY>l$u%|OMGaztRUE8U z3X1}BYt-|5ZWEI}cdJaQGd1QAjfNW~L31%Rt~Vd9CxgW+*yskA)3P?O&dvgaB1iQ~ zwgHtn`K}G922>Eb=$lUmPNVG-QXbCwS0)9Ryb-XP*gObyfNFFa)0bVkwj6ZkHaa8| zgViGJY^3nU756~L~7+dK< zEZ>Q`ljC+kdbsN@?#?gZ$ixl$Gl%5=)zz@AKzm{KciC?VlTr4=n$;PpwX4)+e*$3n B&2|6) literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/previews/backdrop/bg-3-near@4x.png b/packages/core/genres/platformer-assets/previews/backdrop/bg-3-near@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..ab36a6122bfdce55254763d3d880f590dc605fa9 GIT binary patch literal 7133 zcmeHMZB!Fy79P}sw9;xlXV=I_ILEH;*6l)_3RWS(u9muGYrFl>3K9Bo5(~t%MfnQJ zq{UN@M^@VHZY2fDcJ0TyA%G1DU`T>mNvnw?Y7&z`5{;6;Bt#k}lVq684&8q}lRan8 z*`LXuJCiqa-+P~X-{;<&IricUr5O*deGmYEj9t&|_!9s;KwU1mwmg**uxRo%0Lc7u z*N*M4G};3b+y1g~=UU0QJpGB3G;D2P{^2ppKCW$Oi+_8^cfVe;_ON!7zQ~Y@DlRuq zAHNRaK@S8oDK$XJb;!SD@xu2gkV1*vGGG}cB>5>T7r(u*tYlFvU!7b`f{@IFHW{A49$e}}?0>uRQi62Qv! zz~ZD*(g7@AynSOy?xHx7E?E>mUu@6-Zect^401@aQcS$_4fSaMHUX^$Y0C2ZdHhpR zY}VVEPU#-a8A+krf}5HP9Bpji{zH0{+R<>Ix}`opH-I4lAkQSDzLXS!KT_+FhZF6( z2Af?0f@4+s&>O0d05R?WA4viJ{=97HvqIW&%LpuUm#eQX2(gf9@duHdgqoFy*PoP@ zyBC%Mz_nM;P=3XF^w^X`>Hf z<&KB?r-(1ZgwGdn2@{wazPF+T{ATRi!(`_NOFUhbD1}-4U6KOAC2L{c;z7+z>1I}c ze3q69%(5WY>`OUyyd_PXDqlKm5NAN zF?icYyz1y4S6k8Lqr?y4X5F$0+2hteZ66#Ichkphww&!o3k}@ovXB`@#iA-D>F`<) zAOa{$qwmrK67MQxbEtWGbzML}A5v}c(*AH~HTdY7>4-fRemlEm$%^r}B2N_r~}GG*=FZDcD$!af?uI40xAHC8wp1w~?$I*u|V+^lora&}fw zZ4G^e-Y>fF2Sn8@Tf@g)lPr3hCS3$`KNKo*v`G|t8%u}}ignVJb=j4R0B^QNH{;QU z`S?&Qq80`4^R;jq5YgSnkD%8#WXXd51ddJ)ibs9m66163G9J7mzx7IVO9;Jz{&LaB z8lgeY3~GsP41kYY7ZRk&Pm#kGM$KH{gql$DgEL@o27hZnn!X3_kp`N1M zoH|=CEH7qWn~L9bI&HE%jvzbOYe0IfGhXt5p_LxTSs~;`1YK}EBW%{6bqeuP+4;k0 zGkg$<*-7?w?@7d@!cP}?=6z^3(fo>#1yp5ld&~Piu{T%2+!);H(>$oqN&=LOBW0Wcu$27;|l!cXj5$%Kf|!qumy^+Xd*roUSJZ9^jv?7 z@Uid5GJWH`UvRX95_WHG*76$WsXS01M-kI7m353)m9X(#>_2&M!h1Dc+yqPr@fwE)3%9Xud{MCU+S~yl&&iZ48i?ird+5Bz(SQ=~%|k(- zw-vv!&+4_EaGAR|bl{P_0epyf&yO~$0~mePBmC^4Sle=NQxEnx2%2XcyUKQKyAjQ| z8~ewtxDOfk8#IUt2lK~>LqVielzO)sUZ?UJ%sO_Dm_+H7YSr6Mn;z>BJ$s?nQ8RY) zEN&3bWltD_-&+TjeR>`|!XRARVk`R1+BUSu61iLrW@1y324a9{d%yTwT^*BDX6MOWf>PPjO=$S@be$yx1@P~EptZQt zw|e0cJy&41!m4@c=03=^;vDn$ilfBYKxBZ;VRM*0!Tn?o^2cbb9}DH?2T^@J$sq6} zK~LDg<_D|c)&$LmsD;&Ce{qZP?zj7aOUR9J5U!wz3uNZW;i`Rnp{eTu>=El*y>5E0 z(Qw{<0tA7*x5Yoku=eis1B9B;YOO*lya#4rNM7uk6%mkeQ@ZuBn>BCKR zUt0Lc8B6JDEVgf5eFZ&veeO=SJVxgRL$>zi>!2_X4YI=yTt=ay?HckP9tMB&M$DoxjDTao*5dc!n7B@)#l s1He=CRGfSnlAP~pN3s9mwU~c*qX0k45WIV4G0}GId|^lLGgTk{8y5!GFaQ7m literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/previews/foreground/fg-grass-boughs@4x.png b/packages/core/genres/platformer-assets/previews/foreground/fg-grass-boughs@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..beab9155f8bbf1e57a7288f3b72b7bb7677c52ad GIT binary patch literal 6027 zcmeHLdrVVT7(b;*5zAvUnZpNV51oIwX}k$O5H3tMM_{tZ7$B%1kLwIrv&zFl9}%-< z(G24@CYzRQZY*&Ym<-G0(JG_OLZLvG7VKKOU_`hr49hLn_TIa5CzxO^f9=2J{`K8^ z&-b14`@Zx0ot*o9`riJ1p&@HS005!M?<5@nU$l}g4$#9WsNBqpO+rXNdX;vG)yD~V!9S~&=SZwZ&ck|0~0 zwp&Kdg*U2BH%Rr>lL#^HLw)t+4;BVi$lTeOxPol<(9kLcPhuJoxl$k5kqEJ^8<~S4 z+emj;eT{V(sVfph!}q7SHa%H?ByVM18&OYQ?O%UtlL#gg7a!hC#;!Q7?QxWtETh<~ z)1=?Zo|!RjuWSx+N=%n#WWIDumCI1kH-tsQymZf%+P0dhJz8R-tm_`O3}A^^XVf%k zySq%4&1(6__VbAlU*5H=WLQY-lUk>OK=?_yjTgZ{zY~;l@(rT?Ob$xrAe6Bkj_v#; z2N|xTI@<{Hkjs1Uv0Fk?Cw}HXabLP`B@cx1(o<=dTv$8uPVY=(}TtD}xQc9)Wr-nlfz1SpJRu>bhoTN^smKfJ=?sZGUYUUZ1CXhLPX&njP^qCB>1@7i_`)w6dqOZcAdHy8c`` ztzi5H`dO>h(lKGtZ0#FtBZRu2`q!^V?QJ5Hd7goBxnYBniHula?K7%bklHhYH5-rl zh`EO@Q-f#*rQ+OXO*yl?&O6FV=i;E~bK4~ha~xUhSs?tsj~X3}5Zhm1C#Vq=W)z1p z!gltt=D5h@rPN%c%L2{0L8x`E2wV}^j&V*a@D9Qifhz**4T(E7xl@xnHJ|=4aB|?} zz{!D=1N=vfM=ubrRm+7CCH}D=9cLN|-{c;%S zq)yh>(>i7rEJl@&={Epf1$*zVG@gHQ&*v)ub)W1>-Ks2Ws%_E$L#L`EzDoOb4{PhA zr56LcYeIoe)i{uPjrLDXNOVMSvuHUKw{Kp~7UZUZu^F=@SyQ|=pb6b~y0cP&q3n=C z(@mFSuZ9`QJTqyQH8|g|$wBP7;kjbKMzzdKW!JHHqI!mkhYz`gv4=%|+I^asu;Mmf@0Th? zZN=U3D^*>mWV7zki}*PCJARwct=LRwJZELgm7EI rV4)zIv5Sr6XS!WWyUzc4a76rL@5b*f->L5~YbL+7KdI@>yfgm*T>iM& literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/previews/tiles/tileset@8x.png b/packages/core/genres/platformer-assets/previews/tiles/tileset@8x.png new file mode 100644 index 0000000000000000000000000000000000000000..68339ffffd0362d23c3a0a529b2c19858b515b2c GIT binary patch literal 4156 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 literal 0 HcmV?d00001 From 59426acdcf7de8c979b24e19f75c91d6f4c4547c Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Nov 2026 03:26:03 +0000 Subject: [PATCH 2/9] Add the platformer's props as sprite sources and effects as an fx bank The fruit, spring, and checkpoint are sprite sources rendered by `ritmo-tools pixel render`; dash, dust, and collect are fx drafts checked and rendered by `ritmo-tools fx`, with the player as stand-in, so these use the tools' own paths rather than the generator. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01HendNaZcTpUubQBWodQy33 --- .../platformer-assets/art/fx/collect.gif | Bin 0 -> 3346 bytes .../platformer-assets/art/fx/collect.json | 345 ++++++++++++++++++ .../platformer-assets/art/fx/collect.png | Bin 0 -> 1033 bytes .../genres/platformer-assets/art/fx/dash.gif | Bin 0 -> 2819 bytes .../genres/platformer-assets/art/fx/dash.json | 241 ++++++++++++ .../genres/platformer-assets/art/fx/dash.png | Bin 0 -> 1017 bytes .../genres/platformer-assets/art/fx/dust.gif | Bin 0 -> 1279 bytes .../genres/platformer-assets/art/fx/dust.json | 215 +++++++++++ .../genres/platformer-assets/art/fx/dust.png | Bin 0 -> 473 bytes .../art/props/checkpoint.png | Bin 0 -> 266 bytes .../platformer-assets/art/props/fruit.png | Bin 0 -> 365 bytes .../platformer-assets/art/props/spring-up.png | Bin 0 -> 198 bytes .../platformer-assets/art/props/spring.png | Bin 0 -> 157 bytes .../platformer-assets/fx/drafts/collect.a.js | 29 ++ .../platformer-assets/fx/drafts/dash.a.js | 27 ++ .../platformer-assets/fx/drafts/dash.b.js | 33 ++ .../platformer-assets/fx/drafts/dust.a.js | 26 ++ .../platformer-assets/fx/drafts/dust.b.js | 16 + .../platformer-assets/fx/platformer.fx.json | 111 ++++++ .../previews/fx/collect@4x.png | Bin 0 -> 1653 bytes .../platformer-assets/previews/fx/dash@4x.png | Bin 0 -> 1445 bytes .../platformer-assets/previews/fx/dust@4x.png | Bin 0 -> 514 bytes .../previews/props/props@8x.png | Bin 0 -> 1235 bytes .../props/checkpoint.sprite.txt | 28 ++ .../platformer-assets/props/fruit.sprite.txt | 27 ++ .../props/spring-up.sprite.txt | 19 + .../platformer-assets/props/spring.sprite.txt | 20 + 27 files changed, 1137 insertions(+) create mode 100644 packages/core/genres/platformer-assets/art/fx/collect.gif create mode 100644 packages/core/genres/platformer-assets/art/fx/collect.json create mode 100644 packages/core/genres/platformer-assets/art/fx/collect.png create mode 100644 packages/core/genres/platformer-assets/art/fx/dash.gif create mode 100644 packages/core/genres/platformer-assets/art/fx/dash.json create mode 100644 packages/core/genres/platformer-assets/art/fx/dash.png create mode 100644 packages/core/genres/platformer-assets/art/fx/dust.gif create mode 100644 packages/core/genres/platformer-assets/art/fx/dust.json create mode 100644 packages/core/genres/platformer-assets/art/fx/dust.png create mode 100644 packages/core/genres/platformer-assets/art/props/checkpoint.png create mode 100644 packages/core/genres/platformer-assets/art/props/fruit.png create mode 100644 packages/core/genres/platformer-assets/art/props/spring-up.png create mode 100644 packages/core/genres/platformer-assets/art/props/spring.png create mode 100644 packages/core/genres/platformer-assets/fx/drafts/collect.a.js create mode 100644 packages/core/genres/platformer-assets/fx/drafts/dash.a.js create mode 100644 packages/core/genres/platformer-assets/fx/drafts/dash.b.js create mode 100644 packages/core/genres/platformer-assets/fx/drafts/dust.a.js create mode 100644 packages/core/genres/platformer-assets/fx/drafts/dust.b.js create mode 100644 packages/core/genres/platformer-assets/fx/platformer.fx.json create mode 100644 packages/core/genres/platformer-assets/previews/fx/collect@4x.png create mode 100644 packages/core/genres/platformer-assets/previews/fx/dash@4x.png create mode 100644 packages/core/genres/platformer-assets/previews/fx/dust@4x.png create mode 100644 packages/core/genres/platformer-assets/previews/props/props@8x.png create mode 100644 packages/core/genres/platformer-assets/props/checkpoint.sprite.txt create mode 100644 packages/core/genres/platformer-assets/props/fruit.sprite.txt create mode 100644 packages/core/genres/platformer-assets/props/spring-up.sprite.txt create mode 100644 packages/core/genres/platformer-assets/props/spring.sprite.txt diff --git a/packages/core/genres/platformer-assets/art/fx/collect.gif b/packages/core/genres/platformer-assets/art/fx/collect.gif new file mode 100644 index 0000000000000000000000000000000000000000..280fc5a9fcd6b120fba8e637e23448ea4c2f6387 GIT binary patch literal 3346 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 HOu_tDGa|}9 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/art/fx/collect.json b/packages/core/genres/platformer-assets/art/fx/collect.json new file mode 100644 index 00000000..6d0a3b0c --- /dev/null +++ b/packages/core/genres/platformer-assets/art/fx/collect.json @@ -0,0 +1,345 @@ +{ + "frames": { + "collect 0": { + "frame": { + "x": 0, + "y": 0, + "w": 24, + "h": 24 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 24, + "h": 24 + }, + "sourceSize": { + "w": 24, + "h": 24 + }, + "duration": 50, + "anchor": { + "x": 0.5208, + "y": 0.5417 + } + }, + "collect 1": { + "frame": { + "x": 24, + "y": 0, + "w": 24, + "h": 24 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 24, + "h": 24 + }, + "sourceSize": { + "w": 24, + "h": 24 + }, + "duration": 50, + "anchor": { + "x": 0.5208, + "y": 0.5417 + } + }, + "collect 2": { + "frame": { + "x": 48, + "y": 0, + "w": 24, + "h": 24 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 24, + "h": 24 + }, + "sourceSize": { + "w": 24, + "h": 24 + }, + "duration": 50, + "anchor": { + "x": 0.5208, + "y": 0.5417 + } + }, + "collect 3": { + "frame": { + "x": 72, + "y": 0, + "w": 24, + "h": 24 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 24, + "h": 24 + }, + "sourceSize": { + "w": 24, + "h": 24 + }, + "duration": 50, + "anchor": { + "x": 0.5208, + "y": 0.5417 + } + }, + "collect 4": { + "frame": { + "x": 96, + "y": 0, + "w": 24, + "h": 24 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 24, + "h": 24 + }, + "sourceSize": { + "w": 24, + "h": 24 + }, + "duration": 50, + "anchor": { + "x": 0.5208, + "y": 0.5417 + } + }, + "collect 5": { + "frame": { + "x": 120, + "y": 0, + "w": 24, + "h": 24 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 24, + "h": 24 + }, + "sourceSize": { + "w": 24, + "h": 24 + }, + "duration": 50, + "anchor": { + "x": 0.5208, + "y": 0.5417 + } + }, + "collect 6": { + "frame": { + "x": 144, + "y": 0, + "w": 24, + "h": 24 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 24, + "h": 24 + }, + "sourceSize": { + "w": 24, + "h": 24 + }, + "duration": 50, + "anchor": { + "x": 0.5208, + "y": 0.5417 + } + }, + "collect 7": { + "frame": { + "x": 168, + "y": 0, + "w": 24, + "h": 24 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 24, + "h": 24 + }, + "sourceSize": { + "w": 24, + "h": 24 + }, + "duration": 50, + "anchor": { + "x": 0.5208, + "y": 0.5417 + } + }, + "collect 8": { + "frame": { + "x": 192, + "y": 0, + "w": 24, + "h": 24 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 24, + "h": 24 + }, + "sourceSize": { + "w": 24, + "h": 24 + }, + "duration": 50, + "anchor": { + "x": 0.5208, + "y": 0.5417 + } + }, + "collect 9": { + "frame": { + "x": 216, + "y": 0, + "w": 24, + "h": 24 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 24, + "h": 24 + }, + "sourceSize": { + "w": 24, + "h": 24 + }, + "duration": 50, + "anchor": { + "x": 0.5208, + "y": 0.5417 + } + }, + "collect 10": { + "frame": { + "x": 240, + "y": 0, + "w": 24, + "h": 24 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 24, + "h": 24 + }, + "sourceSize": { + "w": 24, + "h": 24 + }, + "duration": 50, + "anchor": { + "x": 0.5208, + "y": 0.5417 + } + }, + "collect 11": { + "frame": { + "x": 264, + "y": 0, + "w": 24, + "h": 24 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 24, + "h": 24 + }, + "sourceSize": { + "w": 24, + "h": 24 + }, + "duration": 50, + "anchor": { + "x": 0.5208, + "y": 0.5417 + } + } + }, + "animations": { + "collect": [ + "collect 0", + "collect 1", + "collect 2", + "collect 3", + "collect 4", + "collect 5", + "collect 6", + "collect 7", + "collect 8", + "collect 9", + "collect 10", + "collect 11" + ] + }, + "meta": { + "app": "https://ritmo.typeonce.dev/tools/pixel/", + "version": "1", + "image": "collect.png", + "format": "RGBA8888", + "size": { + "w": 288, + "h": 24 + }, + "scale": "1", + "frameTags": [ + { + "name": "collect", + "from": 0, + "to": 11, + "direction": "forward" + } + ], + "fps": { + "collect": 20 + }, + "loop": { + "collect": false + } + } +} diff --git a/packages/core/genres/platformer-assets/art/fx/collect.png b/packages/core/genres/platformer-assets/art/fx/collect.png new file mode 100644 index 0000000000000000000000000000000000000000..5a516defb5185be1827caf8d82a3bf570e2d5e3f GIT binary patch literal 1033 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 S?gvEIkZbEG^$lM{s{RX=xVeM? literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/art/fx/dash.json b/packages/core/genres/platformer-assets/art/fx/dash.json new file mode 100644 index 00000000..5dc9fe09 --- /dev/null +++ b/packages/core/genres/platformer-assets/art/fx/dash.json @@ -0,0 +1,241 @@ +{ + "frames": { + "dash 0": { + "frame": { + "x": 0, + "y": 0, + "w": 28, + "h": 28 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 28 + }, + "sourceSize": { + "w": 28, + "h": 28 + }, + "duration": 42, + "anchor": { + "x": 0.5179, + "y": 0.5357 + } + }, + "dash 1": { + "frame": { + "x": 28, + "y": 0, + "w": 28, + "h": 28 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 28 + }, + "sourceSize": { + "w": 28, + "h": 28 + }, + "duration": 42, + "anchor": { + "x": 0.5179, + "y": 0.5357 + } + }, + "dash 2": { + "frame": { + "x": 56, + "y": 0, + "w": 28, + "h": 28 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 28 + }, + "sourceSize": { + "w": 28, + "h": 28 + }, + "duration": 42, + "anchor": { + "x": 0.5179, + "y": 0.5357 + } + }, + "dash 3": { + "frame": { + "x": 84, + "y": 0, + "w": 28, + "h": 28 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 28 + }, + "sourceSize": { + "w": 28, + "h": 28 + }, + "duration": 42, + "anchor": { + "x": 0.5179, + "y": 0.5357 + } + }, + "dash 4": { + "frame": { + "x": 112, + "y": 0, + "w": 28, + "h": 28 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 28 + }, + "sourceSize": { + "w": 28, + "h": 28 + }, + "duration": 42, + "anchor": { + "x": 0.5179, + "y": 0.5357 + } + }, + "dash 5": { + "frame": { + "x": 140, + "y": 0, + "w": 28, + "h": 28 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 28 + }, + "sourceSize": { + "w": 28, + "h": 28 + }, + "duration": 42, + "anchor": { + "x": 0.5179, + "y": 0.5357 + } + }, + "dash 6": { + "frame": { + "x": 168, + "y": 0, + "w": 28, + "h": 28 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 28 + }, + "sourceSize": { + "w": 28, + "h": 28 + }, + "duration": 42, + "anchor": { + "x": 0.5179, + "y": 0.5357 + } + }, + "dash 7": { + "frame": { + "x": 196, + "y": 0, + "w": 28, + "h": 28 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 28 + }, + "sourceSize": { + "w": 28, + "h": 28 + }, + "duration": 42, + "anchor": { + "x": 0.5179, + "y": 0.5357 + } + } + }, + "animations": { + "dash": [ + "dash 0", + "dash 1", + "dash 2", + "dash 3", + "dash 4", + "dash 5", + "dash 6", + "dash 7" + ] + }, + "meta": { + "app": "https://ritmo.typeonce.dev/tools/pixel/", + "version": "1", + "image": "dash.png", + "format": "RGBA8888", + "size": { + "w": 224, + "h": 28 + }, + "scale": "1", + "frameTags": [ + { + "name": "dash", + "from": 0, + "to": 7, + "direction": "forward" + } + ], + "fps": { + "dash": 24 + }, + "loop": { + "dash": false + } + } +} diff --git a/packages/core/genres/platformer-assets/art/fx/dash.png b/packages/core/genres/platformer-assets/art/fx/dash.png new file mode 100644 index 0000000000000000000000000000000000000000..f50455ecc80341792ef12f63e022fb1310be610a GIT binary patch literal 1017 zcmeAS@N?(olHy`uVBq!ia0vp^4}e&PgAGVl)NXEOU|>Gr>Eakt!T9#z?um~rL|8BU zj_W-v@ItAvOyJ;*TqS0;MuizH#toKf?hNTd3r-6>*t>g$?$v2w%B9^`mYWKlbG*E# ztN*+CqD;BK&b}R+A`OWA@K)V%vsY)I#X{+HM`p)j<7qagDF@Yc zDjzkp>D*Z0ay)Mi>--H*I+>+5B{T!||NHYbx?q8ed&pf2ZaE$d|b8wQn7H{MR$Id>W1z}njH%g};ii7q)L81#@W;vq*^g}^QUru+qp-0#)^gHQG^FwQ59K97C?O&|1R`yp7P>G@8$bt)9Q*p)@gz;5vZ8fv|b z=ZGK>_kEk3z|0$|Q<=oF}za7-!qfy48~u}H6y zH^(A308=n9Nz6Kal*>Hrv_mx8Eu#z58i6LW0?q7K_4l4<(F`I%DFnv8vBJeY2blO~ zJ)5Uf8TILi;4~ZE%A}=2vV~1xMTbD?6qGvqfGJsf%8L%;nmzjk{XH(!XakJ^hF{*1 zN$PwVCz`aiASqqgtHk9h(66nWv;4uS`NA4t4EO=vcmb59{sR-qvdlPVU|w4c%40L?PBGU7M0o2J$uW6(|7*=|8J*mSZrsxBR}BDvLZcE~u$4{I*bvj)Uo0I1d z?c`ND5$hwgjZW)2?7pe{*_Xuk8*6=~h`*Cel7yrF2-`Vh~Y z9sav^`|jQ6ec<4cqsM?wK8V%9vx#=FmI}zhrl-#`?Y^fe@kciM=(7#_zBe|l-%~za z)BN$PS1R*rZXcdr7gOF?(iqWP*V>kD*4EYCQQhBH+tSe8V>-oa#!QphRdXj+OrF-e zY~hT;%)Fx1vW#{1IcxLRCvV*nvU|_oeftj_JaicBU@NTd-AK^An@lpS=ATXF@sj

#Olob5Zd+4(mrjpy zRloYgtj;N|4KqC^&vBkN-*Mq0`z1?PtX#Ev&DwSAH*DOrdCS&q+aoD;o^S*!-JKUm vbm&3Lh0|}V_CMHA;iEVE{EIDBXY+R7|FEORZ~g7}Klap}fB!pPk--`OZ;E2R literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/art/fx/dust.json b/packages/core/genres/platformer-assets/art/fx/dust.json new file mode 100644 index 00000000..42039f3b --- /dev/null +++ b/packages/core/genres/platformer-assets/art/fx/dust.json @@ -0,0 +1,215 @@ +{ + "frames": { + "dust 0": { + "frame": { + "x": 0, + "y": 0, + "w": 28, + "h": 10 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 10 + }, + "sourceSize": { + "w": 28, + "h": 10 + }, + "duration": 50, + "anchor": { + "x": 0.5179, + "y": 1 + } + }, + "dust 1": { + "frame": { + "x": 28, + "y": 0, + "w": 28, + "h": 10 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 10 + }, + "sourceSize": { + "w": 28, + "h": 10 + }, + "duration": 50, + "anchor": { + "x": 0.5179, + "y": 1 + } + }, + "dust 2": { + "frame": { + "x": 56, + "y": 0, + "w": 28, + "h": 10 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 10 + }, + "sourceSize": { + "w": 28, + "h": 10 + }, + "duration": 50, + "anchor": { + "x": 0.5179, + "y": 1 + } + }, + "dust 3": { + "frame": { + "x": 84, + "y": 0, + "w": 28, + "h": 10 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 10 + }, + "sourceSize": { + "w": 28, + "h": 10 + }, + "duration": 50, + "anchor": { + "x": 0.5179, + "y": 1 + } + }, + "dust 4": { + "frame": { + "x": 112, + "y": 0, + "w": 28, + "h": 10 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 10 + }, + "sourceSize": { + "w": 28, + "h": 10 + }, + "duration": 50, + "anchor": { + "x": 0.5179, + "y": 1 + } + }, + "dust 5": { + "frame": { + "x": 140, + "y": 0, + "w": 28, + "h": 10 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 10 + }, + "sourceSize": { + "w": 28, + "h": 10 + }, + "duration": 50, + "anchor": { + "x": 0.5179, + "y": 1 + } + }, + "dust 6": { + "frame": { + "x": 168, + "y": 0, + "w": 28, + "h": 10 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 28, + "h": 10 + }, + "sourceSize": { + "w": 28, + "h": 10 + }, + "duration": 50, + "anchor": { + "x": 0.5179, + "y": 1 + } + } + }, + "animations": { + "dust": [ + "dust 0", + "dust 1", + "dust 2", + "dust 3", + "dust 4", + "dust 5", + "dust 6" + ] + }, + "meta": { + "app": "https://ritmo.typeonce.dev/tools/pixel/", + "version": "1", + "image": "dust.png", + "format": "RGBA8888", + "size": { + "w": 196, + "h": 10 + }, + "scale": "1", + "frameTags": [ + { + "name": "dust", + "from": 0, + "to": 6, + "direction": "forward" + } + ], + "fps": { + "dust": 20 + }, + "loop": { + "dust": false + } + } +} diff --git a/packages/core/genres/platformer-assets/art/fx/dust.png b/packages/core/genres/platformer-assets/art/fx/dust.png new file mode 100644 index 0000000000000000000000000000000000000000..59fbd8ca510e24c5f15fdfa0f5d6f9f15ceca0b8 GIT binary patch literal 473 zcmeAS@N?(olHy`uVBq!ia0vp^M}U}%gAGW&cKNuTfq`*>r;B4q1>@U;8`m})h_GJx zZN#m8As{fosIhv24Z|e&4M!NJE%?qdMPyyZo~H83`AvtMYFb@dmVB`En55!4$+_i8 za?6#TUem4*YKo@G$-PP{^3Fd5&#@m{cEGUs(B)sp-Rp39~i= z)$Z}|ID2EGn;;*@%9~QIJ31!JS{v9>FA{qCw2gpXP>8PnXNMn)*!>FZHhgZJ%iqI% zj=c=T{K)p4S@}^-g3ZI41eZDdJ?g&-lU#s!&jNY%V}AC2J+nDiN?JQ*9rN-yy8~pE zP>?Yn(9{Ug(9=5{0=M>r0G26mtTimVH{KLQKX?_Cr}fJl*C4^C=r;7a*>2xPGO@ z1Bk^-e0^`coHeW9fRt-T#A1&8O>Tlp*EA0Kt_f_B)&=@c2_8y)pBp!7e(os{e$Jd6 i{7h2ObCSx=bMkMMw+Brsy!jOvWelFKelF{r5}E){LdT#0 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/art/props/checkpoint.png b/packages/core/genres/platformer-assets/art/props/checkpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..9e9e364356a92890edef57badd0ac50e92a7600f GIT binary patch literal 266 zcmeAS@N?(olHy`uVBq!ia0vp^96&6)`^aY%Jf(x01X3-#BGK3Q1 z&=QGI&KyLkMe+Oijgs0bsV#r#vPMa5FCR`2`@7UnVzj8rF>3@ZCAFn>e0_xTa`VcU zyhsHtK|@Jxr^6**4)3}+)8P`wBtBtWkr%0;A(Yg1I$Yv-gB}EZzL^PiRALezCyXod zA{8B4-k=9TAEEB}7WDB3J%ZCYt2(T)`H=r~Xw^{(X2K68HzYu{LP^p zQqrjA!Nb@3nnC4$IZK;^kz=i}$|Anj!wQ~Rf}(d9?wMcHsPUZRl+<;}6>B>p9#`FA zcRQrK$?fi|_Ij4o-q$Op7*GCwCQG|1Y9WxQ+IMfsoS&*1*)jf>#+B#SY*W%{X*FFp v|D1T)ZQjY>uY|FvUfWS;!RGev`U&yL4%(@*`n$S-4rB0i^>bP0l+XkKL8MAf literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/art/props/spring.png b/packages/core/genres/platformer-assets/art/props/spring.png new file mode 100644 index 0000000000000000000000000000000000000000..0d3f0e0d07d51b12718df7f8dd91a932e327765d GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqDV{ElAr*|t3v3fo7??N(um0zW zIM8jrT~bojCFKA4t)6KI*e3O#Nli#(XgaGu&)@;mnfQHsvui#*u5~_qNt5UPQWlAp zo)C#UlWQcR)Xa_cR20vi80h5kb$@V%5wqEb{I4-=43*pEeD~R|O9k4;;OXk;vd$@? F2>`S4Hdz1w literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/fx/drafts/collect.a.js b/packages/core/genres/platformer-assets/fx/drafts/collect.a.js new file mode 100644 index 00000000..fbf0bc4c --- /dev/null +++ b/packages/core/genres/platformer-assets/fx/drafts/collect.a.js @@ -0,0 +1,29 @@ +// collect, draft a: the fruit is taken: a white flash, a gold ring, and glints +// that hang a moment where it was. +export default { + label: "glints", + size: [24, 24], + frames: 12, + fps: 20, + loop: false, + anchor: [12, 12], + params: { + glints: { min: 2, max: 7, value: 5, step: 1 }, + reach: { min: 5, max: 11, value: 9 } + }, + draw(fx) { + if (fx.frame === 0) fx.disc(fx.cx, fx.cy, 4, "white") + if (fx.frame > 0 && fx.t < 0.45) fx.ring(fx.cx, fx.cy, 4 + (fx.t / 0.45) * (fx.p.reach - 3), fx.ramp("glow", fx.t / 0.45), 1) + for (let i = 0; i < fx.p.glints; i++) { + const angle = fx.range(0, Math.PI * 2) + const dist = fx.range(0.4, 1) * fx.p.reach + const start = fx.range(0.05, 0.3) + const life = (fx.t - start) / (1 - start) + if (life < 0 || life >= 1) continue + const x = fx.cx + Math.cos(angle) * dist + const y = fx.cy + Math.sin(angle) * dist - life * 2 + if (life < 0.5) fx.sparkle(x, y, 1, fx.ramp("glow", life), "gold") + else fx.px(x, y, fx.ramp("glow", life)) + } + } +} diff --git a/packages/core/genres/platformer-assets/fx/drafts/dash.a.js b/packages/core/genres/platformer-assets/fx/drafts/dash.a.js new file mode 100644 index 00000000..a828c0ae --- /dev/null +++ b/packages/core/genres/platformer-assets/fx/drafts/dash.a.js @@ -0,0 +1,27 @@ +// dash, draft a: a white flash where the dash starts, a ring that widens and +// cools through the scarf's glow, and a few sparks thrown out. +export default { + label: "ring", + size: [28, 28], + frames: 8, + fps: 24, + loop: false, + anchor: [14, 14], + params: { + reach: { min: 6, max: 11, value: 10, step: 1 }, + sparks: { min: 0, max: 8, value: 5, step: 1 } + }, + draw(fx) { + if (fx.frame === 0) fx.disc(fx.cx, fx.cy, 3, "white") + const r = 2 + fx.ease.out(fx.t) * (fx.p.reach - 2) + if (fx.frame > 0 && fx.t < 0.85) fx.ring(fx.cx, fx.cy, r, fx.ramp("glow", fx.t), fx.t < 0.4 ? 2 : 1) + for (let i = 0; i < fx.p.sparks; i++) { + const angle = (i / fx.p.sparks) * Math.PI * 2 + fx.range(-0.3, 0.3) + const speed = fx.range(0.7, 1) + const life = fx.t / speed + if (fx.frame === 0 || life >= 1) continue + const d = 3 + fx.ease.out(life) * (fx.p.reach + 1) + fx.px(fx.cx + Math.cos(angle) * d, fx.cy + Math.sin(angle) * d, fx.ramp("glow", life)) + } + } +} diff --git a/packages/core/genres/platformer-assets/fx/drafts/dash.b.js b/packages/core/genres/platformer-assets/fx/drafts/dash.b.js new file mode 100644 index 00000000..9c42be95 --- /dev/null +++ b/packages/core/genres/platformer-assets/fx/drafts/dash.b.js @@ -0,0 +1,33 @@ +// dash, draft b: a starburst of short rays from where the dash starts, the +// rays sliding outward and shortening as they cool. +export default { + label: "rays", + size: [28, 28], + frames: 7, + fps: 24, + loop: false, + anchor: [14, 14], + params: { + rays: { min: 4, max: 10, value: 8, step: 1 }, + reach: { min: 6, max: 11, value: 10, step: 1 } + }, + draw(fx) { + if (fx.frame === 0) { + fx.disc(fx.cx, fx.cy, 2, "white") + return + } + for (let i = 0; i < fx.p.rays; i++) { + const angle = (i / fx.p.rays) * Math.PI * 2 + const far = 3 + fx.ease.out(fx.t) * fx.p.reach + const near = 3 + fx.ease.in(fx.t) * fx.p.reach + if (far - near < 1) continue + fx.line( + fx.cx + Math.cos(angle) * near, + fx.cy + Math.sin(angle) * near, + fx.cx + Math.cos(angle) * far, + fx.cy + Math.sin(angle) * far, + fx.ramp("glow", fx.t) + ) + } + } +} diff --git a/packages/core/genres/platformer-assets/fx/drafts/dust.a.js b/packages/core/genres/platformer-assets/fx/drafts/dust.a.js new file mode 100644 index 00000000..cd73f942 --- /dev/null +++ b/packages/core/genres/platformer-assets/fx/drafts/dust.a.js @@ -0,0 +1,26 @@ +// dust, draft a: puffs kicked out to both sides of the feet on a jump or a +// landing, rising a little as they shrink. +export default { + label: "puffs", + size: [28, 10], + frames: 7, + fps: 20, + loop: false, + anchor: [14, 9], + params: { + puffs: { min: 2, max: 6, value: 4, step: 1 }, + spread: { min: 4, max: 9, value: 8 } + }, + draw(fx) { + for (let i = 0; i < fx.p.puffs; i++) { + const side = i % 2 === 0 ? -1 : 1 + const reach = fx.range(0.5, 1) * fx.p.spread + const size = fx.range(1.5, 2.4) + const x = fx.cx + side * (4 + fx.ease.out(fx.t) * reach) + const y = 6.5 - fx.ease.out(fx.t) * fx.range(0.5, 2.5) + const r = size * (1 - fx.ease.in(fx.t)) + if (r < 0.5) continue + fx.disc(x, y, r, fx.ramp("dust", fx.t)) + } + } +} diff --git a/packages/core/genres/platformer-assets/fx/drafts/dust.b.js b/packages/core/genres/platformer-assets/fx/drafts/dust.b.js new file mode 100644 index 00000000..ed346188 --- /dev/null +++ b/packages/core/genres/platformer-assets/fx/drafts/dust.b.js @@ -0,0 +1,16 @@ +// dust, draft b: a flat ring of dust spreading along the ground from the feet, +// breaking up as it goes. +export default { + label: "flat ring", + size: [28, 10], + frames: 6, + fps: 20, + loop: false, + anchor: [14, 9], + params: { spread: { min: 5, max: 11, value: 10 } }, + draw(fx) { + const rx = 2 + fx.ease.out(fx.t) * fx.p.spread + const ry = 1 + fx.ease.out(fx.t) * 2 + if (fx.t < 0.85) fx.ovalRing(fx.cx, 6, rx, ry, fx.ramp("dust", fx.t), fx.t < 0.3 ? 2 : 1) + } +} diff --git a/packages/core/genres/platformer-assets/fx/platformer.fx.json b/packages/core/genres/platformer-assets/fx/platformer.fx.json new file mode 100644 index 00000000..81c37f8b --- /dev/null +++ b/packages/core/genres/platformer-assets/fx/platformer.fx.json @@ -0,0 +1,111 @@ +{ + "version": 1, + "palette": { + "ink": "#181425", + "night": "#262b44", + "dusk": "#3a4466", + "slate": "#5a6988", + "mist": "#8b9bb4", + "haze": "#c0cbdc", + "white": "#ffffff", + "plum": "#3e2731", + "umber": "#733e39", + "clay": "#b86f50", + "sand": "#e4a672", + "pine": "#193c3e", + "moss": "#265c42", + "leaf": "#3e8948", + "lime": "#63c74d", + "wine": "#a22633", + "red": "#e43b44", + "rose": "#f6757a", + "skin": "#e8b796", + "tan": "#c28569", + "rust": "#be4a2f", + "orange": "#f77622", + "gold": "#feae34", + "yellow": "#fee761", + "blue": "#0099db", + "cyan": "#2ce8f5", + "violet": "#68386c", + "magenta": "#b55088" + }, + "ramps": { + "glow": [ + "white", + "yellow", + "gold", + "orange", + "rust" + ], + "spent": [ + "white", + "cyan", + "blue", + "slate" + ], + "dust": [ + "haze", + "mist", + "slate", + "dusk" + ] + }, + "backdrops": { + "sky": "#3a4466", + "forest": "#262b44", + "rock": "#3e2731", + "mountain": "#8b9bb4" + }, + "standIn": { + "file": "../art/player/player-idle.png", + "anchor": [ + 8, + 15 + ] + }, + "effects": { + "dash": { + "about": "The dash starts: a burst where the player leaves, in the scarf's glow (the scarf turns blue after). Celeste's dash burst is the reference for size and speed: about the player's size, gone in a third of a second.", + "standIn": [ + 0, + 4 + ], + "drafts": { + "a": { + "file": "drafts/dash.a.js" + }, + "b": { + "file": "drafts/dash.b.js" + } + }, + "use": "a" + }, + "dust": { + "about": "Dust at the feet on a jump or a landing: small and quick, never hiding the feet.", + "standIn": [ + 0, + 0 + ], + "drafts": { + "a": { + "file": "drafts/dust.a.js" + }, + "b": { + "file": "drafts/dust.b.js" + } + }, + "use": "a" + }, + "collect": { + "about": "The lantern fruit is taken: a flash, a ring, glints that hang a moment.", + "standIn": false, + "drafts": { + "a": { + "file": "drafts/collect.a.js" + } + }, + "use": "a" + } + } +} diff --git a/packages/core/genres/platformer-assets/previews/fx/collect@4x.png b/packages/core/genres/platformer-assets/previews/fx/collect@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..7f81f6f6999573375f81f50b7d0ffb3a926ee4a7 GIT binary patch literal 1653 zcmb7^eN0nl6vkgH6i_G_KjOzKI5*L#BeO%aEp45h44DO$%}7(rfC)|+eo!kQw3TIr z=*Bj1M(_&NVeLd5;6sRS#{c*@ zYc@zc4-XFPuCk9m;ambBsgn{;6p=m-k`e-r)4&Wu0(kzRt+YD!V1!l3EJNvMR3a=(t{jW z;ncG;wUxG#up6Y*F=QMWT)HFKKXw#(8f%aovPiVndQ3Zo`$>z(pA*o7f0fMv^uublK!B&5|e) z&?VTub-GeFs0@rIN;P(@f@-U=R?6e5vTID;VKE++z+TxN1|FwnUv zE*rLYJ3k_E6k>GIWfy-}?QprX2TEwpp)MyZ?rDOTC*uW{p}e`6dnXQB+r3krpQe#1 z7?O(Jnr2@3r4oHG+8KtDK$F^QPx-|FEEsSq-RW0ou{hXoLTy=URz5RyOUeNOr9cZ!kxOw$TH`E`&6P?7!0vR^;qOZDfT1?Z;?anSEE&Xb`vLSJoPqg#6(0oSZ}tPWiRkSEhQ8 zIlmky!}@d05Qi>V*U1n!4|eR}TMWY742Y5@W{sR(u_^@Z)C^<$3ty0)r;SA9lbwatL^ ztH)pwhKcT#=P&_q?RoV&u|Mi?4z|&rTECn)h8!6(5!h}DiI@~qIn&Ag?~bH|OEcaP zO*YQEGNin$V2E=t01|0lQ@)<4Fju8&P_Ch}0WkjNo!8PCV9WOn{)EvquSQ?FoRP)I W7m*X|jF!#QUgO^5aqHeqIsO+t&YcMW literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/previews/fx/dash@4x.png b/packages/core/genres/platformer-assets/previews/fx/dash@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..a08be436ba9174dc6c894e5890163dfbb9dff01e GIT binary patch literal 1445 zcmZuwdo-JO82&|wtkYr~J;BPHQI*aV$EAoAr7Vj}jn!IguGJ}(7Ij(D9jnbYWnC9p z1+}xfwK|Osbv?|bl7?#CDVNU-H?PoVI^__Ro9X^E>bRd!P4tpXa+Es^9Ki z#=8IjyZw*(gaCkLAbBbthr~eYzQ+J)ed+IWBs6nMG<)c*iK`(lI{Q5#IZ4xH>6U5F zZR|@On+rH>P3{j9?2zh5m;UKKZS<*bhG??5nm}5I4r{FO#KCwmS&=#3B+Qo)0jM}O zz16{aYRW9=egKDPs0N!O!I+GMO4b1kD9Sq3c77})|6Zl0mABD#iN$_r#_Iw{RhCCf z-eV4!e`LF#AFHeSrV@1hH3N{35&;H)VO6GA=*j>m^LS?9=YG}i44fX)r=Ig{0BH11 zcywMEtAk9AVrs?rGYQgM)imt(ga50o_K-9olVomdrEMG8d{XD20REj&U*izQPbm@Q z%$-On$ZYU^HKKl3nZ>T~%ob3jS!8uieAw(O+8bdO}2hA?rM(uRq0&Sskynm~= z_KMDR`H?!b2&m1jj1~ua?hx}Wo^V7;DX0HC_cj1Nf1`i_^QMUTnD_A4@jZE*dSKWjU&(&Dl>7%7;V2dq@Zyae!ZYd9p zWR`K5kc>PV3)^@`u{vu96unjw?dLmgsJ6K#6Im&hiqBt zMC!MdBP35k&f!7Iicip(6T+r1$F}v2I*+HknDM2(%l#>SrH?-$je`O8TKrh-RL4zH zkS-eN@mW*y7sXpd?lAAv3T6Ju>W6TSO*t`vzUgd9aF$*Q+i@4xJ9d_=_BK9ynh8T4 zl&2Fkc?4I1Sva&;JP6;=N5kqjC42b`aD#eOVg_#bWM}UQ`u3eHBd7cirewAG5~zBU zQpz)H+@UkXuc1lHyf6`=p}`@9e`i@zP{txEp(aUgLc6Q2vT6?t4b7B5X820uIxZ(A z7nVyFeses|G~OOP65ZV1|t}ZawYl8kV$x)<~?%*2d4!&xmxo z4y0en=VwV9gA9RnDcWMi7|r?j?dc8ewvmU0tvwOJ8k2k(Te{dBYB*0nhjuR=I8nI^ Un+&&g#HhgkDAlLlEBfpI00kF7G5`Po literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/previews/fx/dust@4x.png b/packages/core/genres/platformer-assets/previews/fx/dust@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..f83b5c4a0774784e9198c23b8ceafa95d89ef383 GIT binary patch literal 514 zcmeAS@N?(olHy`uVBq!ia0y~yU={$fH8|LSWS)i00tN=glb$Y)Ar-gY-u3r7>>$Ga zz@F!-KF)#s;Oe~j&}-co&W9e{8VeLc<{{Zyt+N+K6kgo z#xpW7{5jk#1T>O~g@HlA0W0IqreLOqN*g=-RNMcbzpk}=#T+0b%fZ0l&;V4<0%Rym zFc!G;<=@9iU;o^Gz5MH$7X^3HZR_n~!@mAL6Z`+p*AsJJ?*IPpR@%SmVe_}XKYr); z+PV!fRzUAGFaRCE0c1EV*p<0^-xB_=d4ch_d;VN`t-seUJNo>Eng6d`I_J`}_utCb zh9$@BpYj~p^R-Cdb!pv!`6UWK+ZmY{7zBWf28V~=9eCyj`rki4H?aTTe}*ZVb5EA{ zAKdZPd!@ckJ0G&=1TvPhFu0tUJ5m2_wPgAJtK!p~*`daO&Et5&!xDa}TBqp!$pZdk zTh1*%ef56(w6yi`} z_;YiDJHrJZ`Rj2hd;dMTk;;FOPl$m919_$M2`vb?IOp-=rAya*-*0If`}*%xyY@_W zY!zduLiLI}`( zlfU~*|NWhg-CY@fWK!N$_D;+=xAEO;b9c^=rEiP-$|f)eN6$OD6*tW;uAW-= z@5EjH$o1#T|PM{`oGyezvOic76OC1x5!9w18vldB-r@=M^6=75tL# zneVMvziVn`^XbmfHW3CR0GhoD{p)2b?7Ejo%{qnQW;?H7>KTB=aU7sGi|FfLt%}3v+wKvGZG$036 zz|vd5nD~6n?cMV8i*L`l?Y%Djyk}aMo&EJQufDH&e!JviW$RMyzrQ=zy+3*D@|y4U zTeeJz0i~UnU#;H@0;5*|18KxPKHuDP&RfR*x9QHfuXB>#ef_>07+uykGr#;Tt-AZ9 z>N3#p@84g&b^A%x)#6FH?9P9Rfd4C>9 z?11vy{b$mDW>n6*dFZHfV5v>&)XO6x5pk1POqOU6hA!|I4gP0x1aGlF9N-9TYpFQ z*Zbq2^?(1|KG)KNL1O|&COYsRm`@q7CP~ah3dvXv`#*DQ>V57B*J&027FG Date: Sun, 1 Nov 2026 03:26:03 +0000 Subject: [PATCH 3/9] Add the platformer's player animations and the composed mockup The player is drawn as fill parts with one generated outline, so every frame keeps the same outline weight; the mockup stacks every plane as the game would, so the whole look can be judged at once. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01HendNaZcTpUubQBWodQy33 --- .../platformer-assets/art/mockup/mockup.png | Bin 0 -> 7998 bytes .../art/player/player-idle.png | Bin 0 -> 269 bytes .../art/player/player-spent.png | Bin 0 -> 1534 bytes .../platformer-assets/art/player/player.json | 406 ++++++++++++++++++ .../platformer-assets/art/player/player.png | Bin 0 -> 1522 bytes .../previews/mockup/mockup@4x.png | Bin 0 -> 16131 bytes .../previews/player/player-animations@4x.gif | Bin 0 -> 29897 bytes .../previews/player/player-idle@8x.png | Bin 0 -> 578 bytes .../previews/player/player-spent@8x.png | Bin 0 -> 7036 bytes .../previews/player/player@8x.png | Bin 0 -> 7030 bytes 10 files changed, 406 insertions(+) create mode 100644 packages/core/genres/platformer-assets/art/mockup/mockup.png create mode 100644 packages/core/genres/platformer-assets/art/player/player-idle.png create mode 100644 packages/core/genres/platformer-assets/art/player/player-spent.png create mode 100644 packages/core/genres/platformer-assets/art/player/player.json create mode 100644 packages/core/genres/platformer-assets/art/player/player.png create mode 100644 packages/core/genres/platformer-assets/previews/mockup/mockup@4x.png create mode 100644 packages/core/genres/platformer-assets/previews/player/player-animations@4x.gif create mode 100644 packages/core/genres/platformer-assets/previews/player/player-idle@8x.png create mode 100644 packages/core/genres/platformer-assets/previews/player/player-spent@8x.png create mode 100644 packages/core/genres/platformer-assets/previews/player/player@8x.png diff --git a/packages/core/genres/platformer-assets/art/mockup/mockup.png b/packages/core/genres/platformer-assets/art/mockup/mockup.png new file mode 100644 index 0000000000000000000000000000000000000000..383e3b43ae67522f8588da18d9c13abf35b2512b GIT binary patch literal 7998 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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/art/player/player-idle.png b/packages/core/genres/platformer-assets/art/player/player-idle.png new file mode 100644 index 0000000000000000000000000000000000000000..2b1f78fcf543cc187dff413c026beb9bfbc2e9f6 GIT binary patch literal 269 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 Y0eXsWM%R?y9RL6T07*qoM6N<$g7;7E%>V!Z literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/previews/mockup/mockup@4x.png b/packages/core/genres/platformer-assets/previews/mockup/mockup@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..b9c664a8a5a5b985affeccdef43102759d71da7b GIT binary patch literal 16131 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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/previews/player/player-animations@4x.gif b/packages/core/genres/platformer-assets/previews/player/player-animations@4x.gif new file mode 100644 index 0000000000000000000000000000000000000000..f3c710665334de51d969688ba3b72b872dfb8907 GIT binary patch literal 29897 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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/previews/player/player-idle@8x.png b/packages/core/genres/platformer-assets/previews/player/player-idle@8x.png new file mode 100644 index 0000000000000000000000000000000000000000..6d7ae4b3211b16a7e0d5d7d5163449e976fe1f6e GIT binary patch literal 578 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVB++2aSW-r_4e*Yufq-u4T;)! zj~+az*Tmt+$}YZJlQmpWMs`<;sJQz5gRuplSYt{rxXQXLQLqqs`9f*S3+^lCClu4G z#6Q<&pIAC=K6m-78!t+JU$)H3z89{*z|z1Vz`*3dz`?+XgA)?D`IY^FjDqQ3eyx_i zoyNcd*YTUdIO=(S6?@?0e);)}&fVv!*>~qV=NX1PMwn?E_yd-f*1fT^yY~5)*HR3* z<)w9>OZH#+$lmx^x;@vq(-Xy~V!c?;H`i`;k#PUw>_U z{pG^X!_&i!8JJ-HaL|*Qn^!;U6LZTv=^qyH8gdD%=YAExlXYKQ?t2}=2Mv;5|LPhp zSna?1UrTQP_LvHruhlHc^R+)9tI>MPeC6)hi>;CjjIa<=5Wi_JKH>L&ULMZ9{}rC3 z{E4lw`SzX_)#no?U$8rP?^fQGAK~w>2R@%(TYH`rW`G03pM|IF#Xp!;uK4;D*=PSV u=d#Wzp$P!JzS27Y literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets/previews/player/player-spent@8x.png b/packages/core/genres/platformer-assets/previews/player/player-spent@8x.png new file mode 100644 index 0000000000000000000000000000000000000000..16c72c95f318334d7ed3bc923af88d18b93935ab GIT binary patch literal 7036 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 Date: Sun, 1 Nov 2026 03:26:03 +0000 Subject: [PATCH 4/9] Write down the platformer asset set's decisions and how to regenerate it Keeps each choice (grid, palette, light, outlines, read order) tied to the research it came from, and names what still looks weak. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01HendNaZcTpUubQBWodQy33 --- packages/core/genres/PLATFORMER-ASSETS.md | 53 +++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 packages/core/genres/PLATFORMER-ASSETS.md diff --git a/packages/core/genres/PLATFORMER-ASSETS.md b/packages/core/genres/PLATFORMER-ASSETS.md new file mode 100644 index 00000000..b2220313 --- /dev/null +++ b/packages/core/genres/PLATFORMER-ASSETS.md @@ -0,0 +1,53 @@ +# A first asset set for a Celeste-like platformer + +This file is for the maintainers and the agents working on this repo. It is not published (`package.json` `files` leaves `genres/` out). It is a test of what the [`ritmo-pixel-art`](../skills/ritmo-pixel-art/SKILL.md) skill, the art-direction research (`PIXEL-ART-DIRECTION.md`, `PIXEL-ART-EFFECTS.md`, `PLATFORMER.md` on their branches), and `ritmo-tools` produce for a platformer. Every asset is original. Celeste is the reference for scale, proportion, and grid only. + +![The mockup room at 4x](platformer-assets/previews/mockup/mockup@4x.png) + +## Decisions + +| | Choice | Why | +| --- | --- | --- | +| Screen | 320×180 art pixels, scaled by a whole number (6× on 1080p, 12× on 4K) | Celeste's size (Berry, quoted in `PIXEL-ART.md`). It is 16:9, and at 8 px tiles it shows a 40×22.5-tile room on one screen, so the whole challenge is visible (`PLATFORMER.md`, "the camera shows what is coming"). | +| Tile | 8×8 | Celeste's tile. The smallest detail that must read is the player's eyes, one pixel each. At 8 px tiles a 16 px hero is two tiles tall. | +| Player | 16×16 frames. The body is about 10×12 with the outline, and the feet are on the bottom row. Hitbox 8×12. | About 1.5 tiles tall, as in Celeste. The head is half the body (Schlitter: "a third to half" at small sizes), so the face reads. | +| Palette | 28 colors of Endesga 32 (`platformer-assets/palette.hex`), in 6 ramps: night (sky and every backdrop plane), earth (ground), moss (grass), coat (the player only), glow (the scarf, the fruit, the dash), and steel/violet (spikes, spring, flag). Each asset uses 16 colors or fewer (`pixel.config.json`). | The skill says to start from an existing palette. The ramps shift hue: the night ramp runs from violet-black to blue-white, and the earth ramp from plum to sand. The cold sky against the warm ground keeps the play layer apart from the backdrop. | +| Light | One moon at the upper left. Every asset is lit on its left and top and shaded on its right and below. | The skill's "one light". | +| Outlines | Things in the play layer (terrain edges, the player, props, spikes) have a 1 px `ink` outline on open sides. The outline goes on the 4 sides only, so corners come out round. Backdrop planes have no outlines. The foreground is flat `ink`. | Direction research, "Outlines by plane": an outline means "this is in play". | +| Read order | Spikes are the brightest value (white/haze on ink). The player is the most saturated thing and the only red. The fruit carries the glow ramp. Terrain is dark inside with lit rims where the player touches it. The backdrop recedes toward the haze, and each plane further back has less contrast. | Skill "What the player must notice is read first"; Dead Cells's contrast ladder (direction research). | +| Dash signal | The scarf is gold while a dash is ready and blue once it is spent (`player-spent.png` is the same sheet with the scarf recolored). | One look per meaning. The scarf belongs to the player, as Celeste's hair does. | +| Parallax | Sky 0, far 0.1, mid 0.25, near 0.5, play 1, foreground 1.25 (`PARALLAX` in `make.py`). Each plane's offset is rounded on its own. | Plane speed follows depth (direction research). Whole-pixel offsets (skill). | + +## Files (`platformer-assets/`) + +- `make.py`: draws everything below from code and palette names (Python 3 with Pillow). The same run always makes the same bytes. +- `palette.hex`, `pixel.config.json`: the palette and the project's rules, written by `make.py`. `ritmo-tools` reads them. +- `art/backdrop/bg-0-sky.png` … `bg-3-near.png`: four 320×180 planes. Each one loops horizontally, because every wave in it has a whole number of cycles across 320. +- `art/foreground/fg-grass-boughs.png`: grass along the bottom 12 px and pine boughs at the top corners, which are margins the player cannot reach. It loops. +- `art/tiles/tileset.png` and `.json`: the 47-tile blob autotile for terrain. `byMask` maps an 8-neighbour mask to a tile, and 3 more fill variants follow the 47. After the terrain come a one-way plank (left, middle, right, post), spikes facing 4 ways, and decoration (tuft, flowers, rock, vine). +- `art/player/player.png` and `.json`: idle 4×220 ms, run 6×70, jump 2×90, fall 2×90, dash 2×60, wall-slide 2×120, land 1×80. The JSON uses the hash format that Pixi, Phaser, and Aseprite read, plus `timing` (ms per frame and loop for each animation). `player-spent.png` is the same sheet with the dash spent. `player-idle.png` is the stand-in for `fx`. +- `props/*.sprite.txt` → `art/props/*.png`: the lantern fruit (the collectible), a spring at rest and thrown, and a checkpoint pennant. +- `fx/platformer.fx.json` and `fx/drafts/`: an effects bank with dash (2 drafts), dust (2), and collect (1). The drafts in use are rendered to `art/fx/*.png`, `.json`, and `.gif`. +- `art/mockup/mockup.png`: one room with every layer stacked as in the game. Previews are in `previews/`: 4× or 8× nearest-neighbour, with sprites on the sky's dusk, plus `player-animations@4x.gif`. `previews/parallax/parallax@2x.gif` (about 0.6 MB) is regenerated and gitignored. + +## Regenerate + +From `packages/core/genres/platformer-assets/`, with the repo's `pnpm install` done: + +```sh +rt() { node "$(git rev-parse --show-toplevel)/packages/tools/bin/ritmo-tools.mjs" "$@"; } +for n in fruit spring spring-up checkpoint; do rt pixel render props/$n.sprite.txt -o /tmp/props/$n; cp /tmp/props/$n.png art/props/; done +(cd fx && rt fx check platformer.fx.json && rt fx render platformer.fx.json -o ../art/fx) +python3 make.py # everything else, the mockup and the GIFs last +for f in $(find art -name '*.png'); do rt pixel lint $f; done +``` + +The props and the effects come first, because the mockup reads them. `fx review platformer.fx.json` opens the drafts for a person to pick and comment on. No draft is approved yet. + +## What is weak + +- The player has a readable silhouette and accent, but the poses are stiff. Jump differs from fall by little more than the scarf. In wall-slide, the hand on the wall reads as a nose. Dash reads as a red bullet. Run has 6 frames and no arm swing. A person should redraw the key poses. +- The terrain interior is a flat dark plum with sparse stones. It is quiet as intended, but large rock masses look empty. The grass drip pixels count as lone pixels for `pixel lint`. +- The mountains are clean facets from code. They have no rock detail and their snow lines are regular. The 2-row checker between sky bands shows as a comb at 4×. +- The spring and the checkpoint are small and plain. The fruit is the strongest prop. +- Nothing has been judged on a phone, or in motion inside a running game. The mockup is a still composite, and the afterimages in it are an engine effect drawn by hand. From b48d6758612b34400ed3e9fa78e03fb7d447e490 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Nov 2026 03:54:27 +0000 Subject: [PATCH 5/9] Draw a detailed platformer set's backdrop, foreground, and tileset from code A second asset set at a larger scale (384x216, 16 px tiles, a 48 px player frame), to show what Metal Slug's density of detail changes against the first set's 8 px grid. The palette is 60 colors of AAP-64, whose long ramps give each material five or six steps. The terrain is the same per-pixel blob autotile as set one, with a facing of cut blocks over dark earth, so one function still decides every edge. make.py also draws the player, props, and mockup; those land next. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01HendNaZcTpUubQBWodQy33 --- .../platformer-assets-detailed/.gitignore | 2 + .../art/backdrop/backdrop-stacked.png | Bin 0 -> 12530 bytes .../art/backdrop/bg-0-sky.png | Bin 0 -> 3004 bytes .../art/backdrop/bg-1-far.png | Bin 0 -> 2185 bytes .../art/backdrop/bg-2-mid.png | Bin 0 -> 4634 bytes .../art/backdrop/bg-3-near.png | Bin 0 -> 7540 bytes .../art/foreground/fg-jungle.png | Bin 0 -> 1614 bytes .../art/tiles/tileset.json | 87 + .../art/tiles/tileset.png | Bin 0 -> 4522 bytes .../genres/platformer-assets-detailed/make.py | 2042 +++++++++++++++++ .../platformer-assets-detailed/palette.hex | 60 + .../pixel.config.json | 4 + .../previews/backdrop/backdrop-stacked@3x.png | Bin 0 -> 20587 bytes .../previews/backdrop/bg-0-sky@3x.png | Bin 0 -> 7425 bytes .../previews/backdrop/bg-1-far@3x.png | Bin 0 -> 6359 bytes .../previews/backdrop/bg-2-mid@3x.png | Bin 0 -> 9964 bytes .../previews/backdrop/bg-3-near@3x.png | Bin 0 -> 13780 bytes .../previews/foreground/fg-jungle@3x.png | Bin 0 -> 5955 bytes .../previews/tiles/tileset@6x.png | Bin 0 -> 12697 bytes 19 files changed, 2195 insertions(+) create mode 100644 packages/core/genres/platformer-assets-detailed/.gitignore create mode 100644 packages/core/genres/platformer-assets-detailed/art/backdrop/backdrop-stacked.png create mode 100644 packages/core/genres/platformer-assets-detailed/art/backdrop/bg-0-sky.png create mode 100644 packages/core/genres/platformer-assets-detailed/art/backdrop/bg-1-far.png create mode 100644 packages/core/genres/platformer-assets-detailed/art/backdrop/bg-2-mid.png create mode 100644 packages/core/genres/platformer-assets-detailed/art/backdrop/bg-3-near.png create mode 100644 packages/core/genres/platformer-assets-detailed/art/foreground/fg-jungle.png create mode 100644 packages/core/genres/platformer-assets-detailed/art/tiles/tileset.json create mode 100644 packages/core/genres/platformer-assets-detailed/art/tiles/tileset.png create mode 100644 packages/core/genres/platformer-assets-detailed/make.py create mode 100644 packages/core/genres/platformer-assets-detailed/palette.hex create mode 100644 packages/core/genres/platformer-assets-detailed/pixel.config.json create mode 100644 packages/core/genres/platformer-assets-detailed/previews/backdrop/backdrop-stacked@3x.png create mode 100644 packages/core/genres/platformer-assets-detailed/previews/backdrop/bg-0-sky@3x.png create mode 100644 packages/core/genres/platformer-assets-detailed/previews/backdrop/bg-1-far@3x.png create mode 100644 packages/core/genres/platformer-assets-detailed/previews/backdrop/bg-2-mid@3x.png create mode 100644 packages/core/genres/platformer-assets-detailed/previews/backdrop/bg-3-near@3x.png create mode 100644 packages/core/genres/platformer-assets-detailed/previews/foreground/fg-jungle@3x.png create mode 100644 packages/core/genres/platformer-assets-detailed/previews/tiles/tileset@6x.png diff --git a/packages/core/genres/platformer-assets-detailed/.gitignore b/packages/core/genres/platformer-assets-detailed/.gitignore new file mode 100644 index 00000000..78a0f77e --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/.gitignore @@ -0,0 +1,2 @@ +previews/parallax/ +fx/*.look/ diff --git a/packages/core/genres/platformer-assets-detailed/art/backdrop/backdrop-stacked.png b/packages/core/genres/platformer-assets-detailed/art/backdrop/backdrop-stacked.png new file mode 100644 index 0000000000000000000000000000000000000000..8477f1841b800dba2b77ca86a14dbda2e4e8503c GIT binary patch literal 12530 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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/backdrop/bg-0-sky.png b/packages/core/genres/platformer-assets-detailed/art/backdrop/bg-0-sky.png new file mode 100644 index 0000000000000000000000000000000000000000..e8551a891db768f09d08aa69e70b16e397f1b61c GIT binary patch literal 3004 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 Fe*to5+u{HK literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/backdrop/bg-2-mid.png b/packages/core/genres/platformer-assets-detailed/art/backdrop/bg-2-mid.png new file mode 100644 index 0000000000000000000000000000000000000000..cfa510478eede82261655dc9caf122eadcee8289 GIT binary patch literal 4634 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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/backdrop/bg-3-near.png b/packages/core/genres/platformer-assets-detailed/art/backdrop/bg-3-near.png new file mode 100644 index 0000000000000000000000000000000000000000..9486a78e13b19d5bca4a5fc97672f460d48d3c19 GIT binary patch literal 7540 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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/tiles/tileset.json b/packages/core/genres/platformer-assets-detailed/art/tiles/tileset.json new file mode 100644 index 00000000..0a5e9587 --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/art/tiles/tileset.json @@ -0,0 +1,87 @@ +{ + "tile": 16, + "columns": 10, + "terrain": { + "about": "47-tile blob autotile: the bits name which of the 8 neighbours are terrain; a corner bit counts only when both sides beside it are set.", + "bits": { + "N": 1, + "NE": 2, + "E": 4, + "SE": 8, + "S": 16, + "SW": 32, + "W": 64, + "NW": 128 + }, + "byMask": { + "0": 0, + "1": 1, + "4": 2, + "5": 3, + "7": 4, + "16": 5, + "17": 6, + "20": 7, + "21": 8, + "23": 9, + "28": 10, + "29": 11, + "31": 12, + "64": 13, + "65": 14, + "68": 15, + "69": 16, + "71": 17, + "80": 18, + "81": 19, + "84": 20, + "85": 21, + "87": 22, + "92": 23, + "93": 24, + "95": 25, + "112": 26, + "113": 27, + "116": 28, + "117": 29, + "119": 30, + "124": 31, + "125": 32, + "127": 33, + "193": 34, + "197": 35, + "199": 36, + "209": 37, + "213": 38, + "215": 39, + "221": 40, + "223": 41, + "241": 42, + "245": 43, + "247": 44, + "253": 45, + "255": 46 + }, + "fillVariants": [ + 46, + 47, + 48, + 49 + ] + }, + "tiles": { + "platform-left": 50, + "platform-mid": 51, + "platform-right": 52, + "platform-post": 53, + "spikes-up": 54, + "spikes-right": 55, + "spikes-down": 56, + "spikes-left": 57, + "deco-fern": 58, + "deco-flowers": 59, + "deco-rubble": 60, + "deco-vine": 61, + "deco-pipe": 62 + } +} diff --git a/packages/core/genres/platformer-assets-detailed/art/tiles/tileset.png b/packages/core/genres/platformer-assets-detailed/art/tiles/tileset.png new file mode 100644 index 0000000000000000000000000000000000000000..342b4be94e054890f671b09b1070b25dbf4df5a4 GIT binary patch literal 4522 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 IM6N<$g47BK?*IS* literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/make.py b/packages/core/genres/platformer-assets-detailed/make.py new file mode 100644 index 00000000..7d7dd169 --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/make.py @@ -0,0 +1,2042 @@ +"""Draws the detailed platformer asset set from code: every asset from one palette. + +Run from this folder: `python3 make.py` (Pillow). It writes the 1x art under +`art/`, nearest-neighbour previews under `previews/`, the composed mockup, and +the comparisons with the first set (`../platformer-assets/`). Everything is a +function of fixed seeds, so a run makes the same bytes. + +The first set draws 8 px tiles and a 16 px climber; this one draws 16 px tiles +and a 48 px frame, so most things here are built from shapes and rules (a +puppet for the player, materials for the tiles) rather than typed pixel by +pixel: at this size a typed grid is too slow to pose and too easy to make +inconsistent. +""" + +import json +import math +import os +import random +import sys + +from PIL import Image + +HERE = os.path.dirname(os.path.abspath(__file__)) +ART = os.path.join(HERE, "art") +PREVIEWS = os.path.join(HERE, "previews") +SET_ONE = os.path.join(HERE, "..", "platformer-assets") + +# --- The palette ------------------------------------------------------------- +# 60 colors of AAP-64 (Adigun A. Polack), by name, in ramps from dark to light. +# AAP-64 has long ramps (six steps of brown, khaki, green, teal, and grey), which +# is what a larger sprite needs: a material gets a contour, a shade, a base, a +# light, and a highlight. Set one's Endesga 32 has three or four. +RAMPS = { + # The shared darks: outlines on the shaded side, and the deepest shadow. + "ink": ["#141013"], + # Daylight sky, toward the haze: lavender at the top to cream at the horizon. + "sky": ["#849be4", "#b9bffb", "#e3e6ff", "#fef3c0"], + # Steel: girders, spikes, the backpack, the far city (cool grey). + "steel": ["#333941", "#4a5462", "#6d758d", "#8b93af", "#b3b9d1", "#dae0ea", "#ffffff"], + # Teal: the jungle and ruins behind the play (backdrop only). + "teal": ["#122020", "#24523b", "#23674e", "#328464", "#477d85", "#5daf8d", "#92dcba", "#cdf7e2"], + # Leaf: live green on the play layer (grass, moss, ferns). + "leaf": ["#1a7a3e", "#14a02e", "#59c135", "#9cdb43", "#d6f264"], + # Earth: soil and wood, warm. + "earth": ["#221c1a", "#322b28", "#71413b", "#bb7547", "#dba463"], + # Stone: the masonry the player stands on (khaki). + "stone": ["#423934", "#5a4e44", "#796755", "#a08662", "#c7b08b", "#e4d2aa"], + # Rose: skin shadows, rust. + "rose": ["#422433", "#5b3138", "#8e5252", "#ba756a", "#e9b5a3", "#fad6b8"], + # Blue: the player's jacket, hers alone. + "blue": ["#143464", "#285cc4", "#249fde", "#20d6c7", "#a6fcdb"], + # Fire: the player's hair, warning paint, embers. + "fire": ["#3b1725", "#73172d", "#b4202a", "#df3e23", "#fa6a0a"], + # Gold: what can be taken (the cog), the dash while it is ready, the beacon. + "gold": ["#f9a31b", "#ffd541", "#fffc40"], + # Violet: the enemy, alone. + "violet": ["#242234", "#403353", "#793a80", "#bc4a9b", "#e86a73"], +} + +# Every color by a short name: the ramp's name and the step, from 0 (darkest). +PALETTE = {} +for _ramp, _colors in RAMPS.items(): + for _i, _hex in enumerate(_colors): + PALETTE[_ramp if len(_colors) == 1 else f"{_ramp}{_i}"] = _hex + + +def rgb(name): + h = PALETTE[name].lstrip("#") + return tuple(int(h[i : i + 2], 16) for i in (0, 2, 4)) + + +def ramp_of(name): + """The ramp's name and the step of a color name ("blue2" -> ("blue", 2)).""" + if name == "ink": + return "ink", 0 + base = name.rstrip("0123456789") + return base, int(name[len(base):]) + + +def shade(name, by): + """The same material, `by` steps lighter (positive) or darker, kept inside its ramp.""" + base, i = ramp_of(name) + if base == "ink": + return name + n = len(RAMPS[base]) + return f"{base}{max(0, min(n - 1, i + by))}" + + +class Canvas: + """A grid of palette names (None is transparent).""" + + def __init__(self, w, h, fill=None): + self.w, self.h = w, h + self.px = [[fill] * w for _ in range(h)] + + def get(self, x, y): + if 0 <= x < self.w and 0 <= y < self.h: + return self.px[y][x] + return None + + def set(self, x, y, c): + if 0 <= x < self.w and 0 <= y < self.h: + self.px[y][x] = c + + def rect(self, x, y, w, h, c): + for j in range(y, y + h): + for i in range(x, x + w): + self.set(i, j, c) + + def blit(self, other, x, y, wrap=False): + for j in range(other.h): + for i in range(other.w): + c = other.px[j][i] + if c is not None: + tx = (x + i) % self.w if wrap else x + i + self.set(tx, y + j, c) + + def copy(self): + c = Canvas(self.w, self.h) + c.px = [row[:] for row in self.px] + return c + + def flipped(self): + c = Canvas(self.w, self.h) + c.px = [row[::-1] for row in self.px] + return c + + def crop(self, x, y, w, h): + c = Canvas(w, h) + for j in range(h): + for i in range(w): + c.px[j][i] = self.get(x + i, y + j) + return c + + def image(self): + img = Image.new("RGBA", (self.w, self.h), (0, 0, 0, 0)) + img.putdata([(0, 0, 0, 0) if c is None else rgb(c) + (255,) for row in self.px for c in row]) + return img + + +def from_rows(rows, keys): + """A canvas from text rows, one key per pixel ('.' is transparent).""" + c = Canvas(len(rows[0]), len(rows)) + for y, row in enumerate(rows): + assert len(row) == c.w, (rows, row) + for x, k in enumerate(row): + if k != ".": + c.px[y][x] = keys[k] + return c + + +def recolor(c, swap): + out = c.copy() + out.px = [[swap.get(k, k) for k in row] for row in c.px] + return out + + +# A ramp whose darkest step is still bright gets a darker outline on its lit side. +LIT_OUTLINE = {"gold": "fire2", "sky": "steel1", "rose": "rose1"} + + +def selout(c, light=(1, -1)): + """A selective outline: a one-pixel line on the four sides (round corners), dark ink + on the side away from the light and the material's own darkest step on the lit + side, so a sprite keeps a hard edge without a black cut-out look (Metal Slug's way).""" + out = c.copy() + lx, ly = light + for y in range(c.h): + for x in range(c.w): + if c.px[y][x] is not None: + continue + best = None + for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)): + n = c.get(x + dx, y + dy) + if n is None: + continue + # This empty pixel lies on the side (-dx, -dy) of the shape; that side is lit + # when it faces the light. + lit = (-dx * lx + -dy * ly) > 0 + col = "ink" + if lit: + base, _ = ramp_of(n) + col = "ink" if base == "ink" else LIT_OUTLINE.get(base, f"{base}0") + # Ink wins over a colored outline where they meet, so the shadow side stays solid. + if best is None or col == "ink": + best = col + if best is not None: + out.px[y][x] = best + return out + + +def save(c, rel, scale=4, bg="sky2", art=True): + """Writes the 1x art and an enlarged preview; previews of sprites sit on a mid sky tone.""" + img = c.image() if isinstance(c, Canvas) else c + if art: + path = os.path.join(ART, rel) + os.makedirs(os.path.dirname(path), exist_ok=True) + img.save(path, optimize=True) + if scale: + prev = os.path.join(PREVIEWS, rel.replace(".png", f"@{scale}x.png")) + os.makedirs(os.path.dirname(prev), exist_ok=True) + shown = Image.new("RGBA", img.size, rgb(bg) + (255,)) + shown.alpha_composite(img.convert("RGBA")) + shown.resize((img.width * scale, img.height * scale), Image.NEAREST).save(prev, optimize=True) + return img + + +def save_gif(frames, durations, path, scale): + """Writes an animated GIF, merging equal frames in a row into one longer frame.""" + merged, times = [], [] + for img, ms in zip(frames, durations): + if merged and img.tobytes() == merged[-1].tobytes(): + times[-1] += ms + else: + merged.append(img) + times.append(ms) + big = [m.convert("RGB").resize((m.width * scale, m.height * scale), Image.NEAREST) for m in merged] + os.makedirs(os.path.dirname(path), exist_ok=True) + big[0].save(path, save_all=True, append_images=big[1:], duration=times, loop=0, optimize=True, disposal=1) + + +# --- The game's grid --------------------------------------------------------- + +W, H = 384, 216 # the screen in art pixels +TILE = 16 +FRAME = 48 # the player's frame +LIGHT = (1, -1) # the sun: high, ahead of the player (upper right) + + +# --- The player -------------------------------------------------------------- +# A scavenger in a blue jacket, khaki cargo trousers, boots, and a backpack +# whose cell glows gold while a dash is ready, with a red ponytail that trails +# every move. She is a puppet: limbs are tapered capsules between joints, posed +# by angles (so lengths never change from frame to frame), shaded in bands +# along each limb from the one light, and joined with a contour where a part +# crosses another. The head is drawn by hand. Each frame gets one selective +# outline at the end, so every frame has the same edge. + +THIGH, SHIN, FOOT = 7.5, 7.0, 4.0 +UPPER, FORE = 6.0, 5.5 +SPINE = 11.0 +TAIL = [3.0, 3.0, 2.8, 2.6] +GROUND = 46 # the soles' last row; the outline takes row 47 + +HEAD_KEYS = { + "1": "fire1", "2": "fire2", "3": "fire3", "4": "fire4", + "s": "rose5", "m": "rose4", "d": "rose3", "r": "rose3", "n": "rose1", + "e": "ink", "w": "steel6", "k": "steel1", "f": "steel3", "g": "blue2", "G": "blue3", +} +# Facing right, lit from the upper right. The goggles ride on the hair. +HEAD = [ + "....11122.....", + "..11223333....", + ".1122ffff33...", + ".122fgGGf43...", + "1122ffff4443..", + "112223333443..", + "1122233sss34..", + "112223ssssss3.", + "11222dsss11ss.", + "1122dmssssess.", + ".112dmmsssesss", + "..12ddmsssssm.", + "...1rdmmssnm..", + "....rddmmmm...", + ".....rrdd.....", +] +HEAD_NECK = (7, 14) # the head pixel that sits on the neck +HEAD_TAIL = (2, 3) # where the ponytail leaves the head + + +def head_variant(kind): + rows = list(HEAD) + if kind == "blink": + rows[9] = "1122dmssssmss." + rows[10] = ".112dmmsssnsss" + if kind == "grit": # dash and landing: the brow down, the mouth set + rows[8] = "11222dss111ss." + rows[12] = "...1rdmmsnnm.." + return rows + + +def vec(deg, length): + """A limb from its angle: 0 points straight down, positive swings forward (to +x).""" + a = math.radians(deg) + return (math.sin(a) * length, math.cos(a) * length) + + +def add(p, q): + return (p[0] + q[0], p[1] + q[1]) + + +class Body: + """Parts painted back to front. Each part is a set of pixels with colors; a part's + edge pixels that cover an earlier part become its contour (its darkest step).""" + + def __init__(self): + self.c = Canvas(FRAME, FRAME) + self.owner = [[None] * FRAME for _ in range(FRAME)] + self.n = 0 + + def paint(self, pixels, contour=True): + self.n += 1 + keys = set(pixels) + for (x, y), col in pixels.items(): + if not (0 <= x < FRAME and 0 <= y < FRAME): + continue + edge = False + if contour: + for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)): + if (x + dx, y + dy) not in keys and self.c.get(x + dx, y + dy) is not None: + edge = True + if edge: + base, _ = ramp_of(col) + col = "ink" if base in ("ink",) else f"{base}0" if base not in ("rose",) else "rose1" + self.c.px[y][x] = col + self.owner[y][x] = self.n + + +def capsule(a, b, ra, rb, color_at, light=LIGHT): + """A tapered limb from a to b. color_at(t, side) gives the color, where t runs 0..1 along + the limb and side runs -1 (away from the light) to 1 (toward it).""" + out = {} + dx, dy = b[0] - a[0], b[1] - a[1] + ln2 = dx * dx + dy * dy or 1e-9 + ln = math.sqrt(ln2) + # The perpendicular that faces the light. + nx, ny = -dy / ln, dx / ln + if nx * light[0] + ny * light[1] < 0: + nx, ny = -nx, -ny + r = max(ra, rb) + for y in range(int(min(a[1], b[1]) - r - 2), int(max(a[1], b[1]) + r + 3)): + for x in range(int(min(a[0], b[0]) - r - 2), int(max(a[0], b[0]) + r + 3)): + px, py = x + 0.5, y + 0.5 + t = max(0.0, min(1.0, ((px - a[0]) * dx + (py - a[1]) * dy) / ln2)) + qx, qy = a[0] + dx * t, a[1] + dy * t + rr = ra + (rb - ra) * t + d = math.hypot(px - qx, py - qy) + if d <= rr: + side = ((px - qx) * nx + (py - qy) * ny) / rr + out[(x, y)] = color_at(t, side) + return out + + +def banded(base, lit=0.35, dark=-0.45): + """Three bands along a limb: the light step toward the sun, the shade away from it.""" + def f(t, side): + if side > lit: + return shade(base, 1) + if side < dark: + return shade(base, -1) + return base + return f + + +def pose_points(p): + """Joint positions for a pose.""" + hip = p["hip"] + lean = p.get("lean", 0) + neck = add(hip, vec(180 - lean, SPINE)) # straight up, tipped forward by the lean + pts = {"hip": hip, "neck": neck} + for side, off in (("far", -1.0), ("near", 1.0)): + th, sh, ft = p["legs"][side] + h = add(hip, (off * 0.5, 0)) + k = add(h, vec(th, THIGH)) + an = add(k, vec(sh, SHIN)) + toe = add(an, vec(ft, FOOT)) + pts[side + "-leg"] = (h, k, an, toe) + up, fo = p["arms"][side] + sh_pt = add(add(hip, vec(180 - lean, SPINE - 2.0)), (off * 0.8 - 0.5, 0)) + el = add(sh_pt, vec(up, UPPER)) + hand = add(el, vec(fo, FORE)) + pts[side + "-arm"] = (sh_pt, el, hand) + return pts + + +def leg_part(h, k, an, toe, far): + dim = -1 if far else 0 + trousers = shade("stone3", dim) + boot = shade("earth2", dim) + thigh = capsule(h, k, 3.2, 2.6, banded(trousers)) + shin = capsule(k, an, 2.6, 2.3, lambda t, s: banded(boot if t > 0.6 else trousers)(t, s)) + # The boot: a rounded toe and a heel, with a dark sole on the side toward the ground. + foot = capsule(add(an, vec(0, 0.6)), toe, 2.5, 2.1, lambda t, s: shade(boot, 1) if s > 0.5 else boot) + sole_dir = vec(0, 1) + for (x, y) in list(foot): + below = (x, y + 1) + if below not in foot and below not in shin: + foot[(x, y)] = "earth0" + out = {} + out.update(thigh) + out.update(shin) + out.update(foot) + # A knee pad: the lit side of the knee, a cluster, not a line. + return out + + +def arm_part(sh, el, hand, far): + dim = -1 if far else 0 + # The near sleeve is a step lighter than the jacket, so the arm reads over the body. + sleeve = "blue0" if far else "blue2" + skin = shade("rose4", dim) + glove = shade("earth2", dim) + upper = capsule(sh, el, 2.4, 2.1, banded(sleeve)) + # The sleeve is rolled to the elbow: a cuff, then the forearm. + fore = capsule(el, hand, 1.9, 1.7, lambda t, s: banded(sleeve, 0.2)(t, s) if t < 0.25 else banded(skin)(t, s)) + fist = capsule(hand, add(hand, (0.01, 0.01)), 2.1, 2.1, banded(glove, 0.2, -0.3)) + out = {} + out.update(upper) + out.update(fore) + out.update(fist) + return out + + +def torso_part(p, pts): + """The jacket over a belt and the top of the trousers, drawn in the torso's own frame: + u runs up the spine (0 hip, 1 neck), v across it (positive in front).""" + hip, neck = pts["hip"], pts["neck"] + sx, sy = neck[0] - hip[0], neck[1] - hip[1] + ln = math.hypot(sx, sy) + ux, uy = sx / ln, sy / ln + fx_, fy_ = -uy, ux # front: the spine turned a quarter toward +x + if fx_ < 0: + fx_, fy_ = -fx_, -fy_ + breath = p.get("breath", 0) + + def half(u, front): + # The profile of the body: hips, waist, chest, shoulders. + pts_ = [(-0.12, 3.4), (0.0, 4.8), (0.3, 4.5), (0.62, 5.4 + breath * 0.6), (0.92, 5.0), (1.06, 3.0)] if front else \ + [(-0.12, 3.4), (0.0, 4.8), (0.3, 4.0), (0.7, 4.6), (0.95, 4.2), (1.06, 2.4)] + for (u0, w0), (u1, w1) in zip(pts_, pts_[1:]): + if u0 <= u <= u1: + return w0 + (w1 - w0) * (u - u0) / (u1 - u0) + return None + + out = {} + for y in range(FRAME): + for x in range(FRAME): + px, py = x + 0.5 - hip[0], y + 0.5 - hip[1] + u = (px * ux + py * uy) / ln + v = px * fx_ + py * fy_ + w = half(u, v >= 0) + if w is None or abs(v) > w: + continue + s = v / w # -1 back .. 1 front + # Light from the upper right lights the front and the shoulders. + if u < 0.13: + col = "stone3" # the trousers' seat, under the belt + if s < -0.3: + col = "stone2" + elif u < 0.24: + col = "earth1" if s < -0.2 else "earth2" # the belt + if s > 0.55 and u > 0.15: + col = "gold0" # the buckle + else: + col = "blue1" + if s > 0.35 or (u > 0.82 and s > -0.2): + col = "blue2" + if s > 0.8 and 0.5 < u < 0.85: + col = "blue3" + if s < -0.55: + col = "blue0" + # The hem's shadow under the jacket's flap. + if u < 0.32 and s < 0.4: + col = "blue0" + # The collar and a pale shirt at the throat. + if u > 0.88 and s > 0.2: + col = "stone4" + # The backpack strap over the shoulder. + if -0.45 <= s <= -0.1 and 0.5 < u < 0.97: + col = "earth2" if u > 0.85 else "earth1" + out[(x, y)] = col + return out + + +def pack_part(p, pts, charged): + """The backpack against the shoulders, with the dash cell on top.""" + hip, neck = pts["hip"], pts["neck"] + lean = p.get("lean", 0) + up = vec(180 - lean, 1) + back = (-up[1], up[0]) if -up[1] < 0 else (up[1], -up[0]) # the side away from the front + centre = add(add(hip, (up[0] * 7.2, up[1] * 7.2)), (back[0] * 4.6, back[1] * 4.6)) + out = {} + for y in range(FRAME): + for x in range(FRAME): + dx, dy = x + 0.5 - centre[0], y + 0.5 - centre[1] + a = dx * up[0] + dy * up[1] # along the spine + b = dx * back[0] + dy * back[1] # away from the body + if abs(a) <= 4.6 and abs(b) <= 3.0 and not (abs(a) > 3.8 and abs(b) > 2.2): + col = "steel2" + if a > 2.6 or b < -1.0: + col = "steel3" + if b > 1.6 and a < 2.6: + col = "steel1" + if -0.2 < a < 0.8: + col = "steel1" # the flap's seam + out[(x, y)] = col + # The cell: a glowing canister strapped to the back of the pack. + if 3.0 < b <= 5.4 and -3.0 <= a <= 2.6 and not (b > 4.6 and abs(a) > 2.2): + lit = a > 0.8 and b < 4.6 + if charged: + out[(x, y)] = "gold2" if lit else "gold1" if a > -1.6 else "gold0" + else: + out[(x, y)] = "steel4" if lit else "steel3" if a > -1.6 else "steel2" + return out + + +def tail_part(start, angles): + out = {} + p = start + r = 2.2 + n = len(TAIL) + for i, (a, ln) in enumerate(zip(angles, TAIL)): + q = add(p, vec(a, ln)) + r1 = 2.2 - 1.3 * (i + 1) / n + seg = capsule(p, q, r, r1, banded("fire2", 0.25, -0.35)) + for k, v in seg.items(): + out.setdefault(k, v) + p, r = q, r1 + return out + + +def head_part(at, kind): + rows = head_variant(kind) + hx = round(at[0]) - HEAD_NECK[0] + hy = round(at[1]) - HEAD_NECK[1] + out = {} + for j, row in enumerate(rows): + for i, k in enumerate(row): + if k != ".": + out[(hx + i, hy + j)] = HEAD_KEYS[k] + return out, (hx + HEAD_TAIL[0] + 0.5, hy + HEAD_TAIL[1] + 0.5) + + +def draw_pose(p, charged=True, raw=False): + pts = pose_points(p) + b = Body() + neck = pts["neck"] + hd = p.get("head", (0, 0, "normal")) + head_at = add(neck, (hd[0] + 0.6, hd[1] + 1.5)) + head, tail_root = head_part(head_at, hd[2]) + tail = tail_part(tail_root, p.get("tail", [-30, -25, -20, -15, -10])) + b.paint(tail, contour=False) + b.paint(arm_part(*pts["far-arm"], far=True)) + b.paint(leg_part(*pts["far-leg"], far=True)) + b.paint(pack_part(p, pts, charged)) + b.paint(leg_part(*pts["near-leg"], far=False)) + b.paint(torso_part(p, pts)) + neck_px = capsule(neck, add(neck, (hd[0] * 0.5, -2.5)), 2.0, 2.0, banded("rose3")) + b.paint(neck_px) + b.paint(head) + b.paint(arm_part(*pts["near-arm"], far=False)) + c = b.c + if raw: + return c + for y in range(FRAME): + for x in range(FRAME): + if c.px[y][x] is not None: + assert 0 < x < FRAME - 1 and 0 < y < FRAME - 1, ("fill touches the frame edge", x, y, p) + return selout(c) + + +def fitted(p): + """Moves an airborne pose up or down the fewest pixels that keep it inside the frame.""" + steps = sorted(((dx, dy) for dx in range(-6, 7) for dy in range(-6, 7)), key=lambda d: (abs(d[0]) + abs(d[1]), d)) + for dx, dy in steps: + q = dict(p) + q["hip"] = (p["hip"][0] + dx, p["hip"][1] + dy) + try: + draw_pose(q) + return q + except AssertionError: + continue + raise AssertionError(("no room for the pose", p)) + + +def fill_box(p): + """The pose's drawn pixels before the outline: (left, right, top, bottom).""" + c = draw_pose(p, raw=True) + pts = [(x, y) for y in range(FRAME) for x in range(FRAME) if c.px[y][x] is not None] + return min(x for x, _ in pts), max(x for x, _ in pts), min(y for _, y in pts), max(y for _, y in pts) + + +def grounded(p): + """Moves a standing pose's hips so its lowest sole sits exactly on the ground row.""" + q = dict(p) + q["hip"] = (p["hip"][0], 0.0) + pts = pose_points(q) + low = max(max(pts[s + "-leg"][2][1] + 0.6 + 2.5, pts[s + "-leg"][3][1] + 2.1) for s in ("far", "near")) + q["hip"] = (p["hip"][0], round(GROUND + 0.5 - low) + 0.0) + for _ in range(3): + bottom = fill_box(q)[3] + if bottom == GROUND: + break + q["hip"] = (q["hip"][0], q["hip"][1] + GROUND - bottom) + return q + + +WALL = 29 # the wall-slide frames press a wall whose first column is here, right of the hitbox + + +def against_wall(p): + """Moves a wall pose sideways so its hands and boot touch the wall at WALL.""" + q = dict(p) + right = fill_box(q)[1] + q["hip"] = (q["hip"][0] + WALL - 1 - right, q["hip"][1]) + return q + + +def idle_poses(): + """Breathing: the chest swells and the shoulders rise a pixel, the arms follow, + and the ponytail sways a beat behind. One blink.""" + frames = [] + for i in range(6): + ph = math.sin(2 * math.pi * i / 6) + lag = math.sin(2 * math.pi * (i - 1) / 6) + p = grounded({ + "hip": (21.5, 0), "lean": 2 + ph * 0.6, "breath": 0.5 + ph * 0.5, + "legs": {"far": (-4, -12, 86), "near": (12, 2, 94)}, + "arms": {"far": (-6 + ph, 6), "near": (10 + ph * 1.5, 22 + ph * 2)}, + "head": (0, round(-ph * 0.6), "blink" if i == 4 else "normal"), + "tail": [-60 + lag * 4, -30 + lag * 6, -12 + lag * 8, -4 + lag * 10], + }) + frames.append(p) + return frames + + +# Eight frames of a run: contact, down, pass, up, then the same on the other leg. +# Thigh and shin angles of one leg over the cycle; the other leg is four frames on. +RUN_LEG = [(38, 14, 108), (20, -4, 92), (2, -12, 90), (-24, -40, 50), (-36, -78, 20), (-12, -100, -10), (30, -48, 30), (50, 10, 100)] +RUN_BOB = [0.5, 2.0, 1.0, -1.0, 0.5, 2.0, 1.0, -1.0] +RUN_AIR = [0, 0, 0, 1.0, 0, 0, 0, 1.0] + + +def run_poses(): + frames = [] + for i in range(8): + ph = 2 * math.pi * i / 8 + swing = math.cos(ph) # near leg forward at 1 + near, far = RUN_LEG[i], RUN_LEG[(i + 4) % 8] + lag = math.cos(ph - 1.2) + p = { + "hip": (22, 30.5 + RUN_BOB[i]), "lean": 14, + "legs": {"far": far, "near": near}, + # Arms swing against the legs, bent at the elbow. + "arms": {"far": (38 * swing, 38 * swing + 85), "near": (-44 * swing, -44 * swing + 90)}, + "head": (1, 0, "normal"), + "tail": [-80 + lag * 6, -88 + lag * 12, -94 + lag * 16, -98 + lag * 22], + "breath": 0.6, + } + p = grounded(p) + # The up frames leave the ground: both feet off it for a moment. + p["hip"] = (p["hip"][0], p["hip"][1] - RUN_AIR[i]) + frames.append(p) + return frames + + +def air_poses(): + """Jump: the push off (one knee driven up, the reaching arm high, the ponytail + dragged down), the rise, and the top, where both legs tuck. Fall: the legs reach + for the ground, the arms go up and out, the ponytail streams up; two frames flutter.""" + jump = [ + {"hip": (22, 30), "lean": 4, "breath": 1, + "legs": {"far": (-14, -18, 30), "near": (62, -8, 70)}, + "arms": {"far": (150, 165), "near": (-40, -10)}, + "head": (1, -1, "normal"), "tail": [-30, -12, 0, 6]}, + {"hip": (22, 29), "lean": 6, "breath": 1, + "legs": {"far": (-4, -30, 40), "near": (70, 0, 80)}, + "arms": {"far": (130, 115), "near": (-60, -30)}, + "head": (1, -1, "normal"), "tail": [-45, -25, -10, -2]}, + {"hip": (22, 28), "lean": 8, "breath": 0.6, + "legs": {"far": (28, -40, 50), "near": (74, 10, 90)}, + "arms": {"far": (-100, -70), "near": (100, 80)}, + "head": (1, 0, "normal"), "tail": [-80, -70, -60, -55]}, + ] + fall = [] + for k in range(2): + f = k * 2 - 1 + fall.append({"hip": (22, 29), "lean": -4, "breath": 0.8, + "legs": {"far": (-6, -28, 40), "near": (36, 6, 70)}, + "arms": {"far": (-112 + f * 6, -132 + f * 10), "near": (108 - f * 6, 128 + f * 8)}, + "head": (0, 0, "normal"), + "tail": [-118 + f * 4, -126 - f * 6, -120 + f * 10, -112 - f * 12]}) + return [fitted(p) for p in jump], [fitted(p) for p in fall] + + +def dash_poses(): + """A lunge: the body tips nearly flat behind a thrown fist, legs and ponytail straight back.""" + return [fitted(p) for p in [ + {"hip": (18, 30), "lean": 30, "breath": 1, + "legs": {"far": (-30, -60, 20), "near": (40, -20, 90)}, + "arms": {"far": (-70, -40), "near": (70, 100)}, + "head": (1, 0, "grit"), "tail": [-110, -100, -95, -90]}, + {"hip": (16, 28), "lean": 58, "breath": 1, + "legs": {"far": (-80, -96, -30), "near": (-58, -96, -20)}, + "arms": {"far": (-96, -80), "near": (92, 92)}, + "head": (2, 1, "grit"), "tail": [-100, -96, -92, -90]}, + {"hip": (16, 28), "lean": 58, "breath": 1, + "legs": {"far": (-84, -100, -30), "near": (-62, -92, -25)}, + "arms": {"far": (-100, -84), "near": (92, 92)}, + "head": (2, 1, "grit"), "tail": [-96, -100, -88, -96]}, + ]] + + +def slide_poses(): + """Sliding down a wall on the right: both hands drag on it, a boot braces against it, + and the ponytail lifts with the slide.""" + out = [] + for k in range(2): + out.append({"hip": (22, 28), "lean": 4, "breath": 0.5, + "legs": {"far": (-4, -18, 40), "near": (38, -6, 70)}, + "arms": {"far": (150, 158), "near": (70 + k * 4, 128 + k * 4)}, + "head": (0, 0, "normal"), + "tail": [-124 + k * 6, -128 - k * 6, -118 + k * 8, -110 - k * 8]}) + return [against_wall(fitted(p)) for p in out] + + +def land_poses(): + """The squash: knees deep, the body folded over them, arms down for balance; then up.""" + return [ + grounded({"hip": (22, 0), "lean": 24, "breath": 0, + "legs": {"far": (-10, -76, 90), "near": (70, -14, 92)}, + "arms": {"far": (-30, 20), "near": (40, 70)}, + "head": (1, 1, "grit"), "tail": [10, 25, 35, 40]}), + grounded({"hip": (22, 0), "lean": 12, "breath": 0.3, + "legs": {"far": (-8, -40, 90), "near": (42, -2, 92)}, + "arms": {"far": (-14, 10), "near": (24, 46)}, + "head": (1, 0, "normal"), "tail": [-20, -5, 10, 20]}), + ] + + +def player_animations(charged=True): + """Every animation as (frames, ms per frame, loops).""" + jump, fall = air_poses() + anims = { + "idle": (idle_poses(), 160, True), + "run": (run_poses(), 70, True), + "jump": (jump, 80, False), + "fall": (fall, 110, True), + "dash": (dash_poses(), 50, False), + "wall-slide": (slide_poses(), 120, True), + "land": (land_poses(), 70, False), + } + return {k: ([draw_pose(p, charged) for p in ps], ms, loop) for k, (ps, ms, loop) in anims.items()} + + +def player_sheet(anims): + """Every animation on a row of its own; JSON in the hash format Pixi, Phaser, and Aseprite read.""" + cols = max(len(f) for f, _, _ in anims.values()) + c = Canvas(cols * FRAME, len(anims) * FRAME) + frames, tags, timing = {}, [], {} + n = 0 + for row, (name, (fs, ms, loop)) in enumerate(anims.items()): + names = [] + for i, f in enumerate(fs): + c.blit(f, i * FRAME, row * FRAME) + key = f"{name} {i}" + frames[key] = {"frame": {"x": i * FRAME, "y": row * FRAME, "w": FRAME, "h": FRAME}, "duration": ms, + "anchor": {"x": 0.5, "y": 1}} + names.append(key) + tags.append({"name": name, "from": n, "to": n + len(fs) - 1, "direction": "forward"}) + timing[name] = {"frames": names, "msPerFrame": ms, "loop": loop} + n += len(fs) + data = {"frames": frames, "animations": {k: v["frames"] for k, v in timing.items()}, "timing": timing, + "meta": {"image": "player.png", "size": {"w": c.w, "h": c.h}, "frameSize": {"w": FRAME, "h": FRAME}, "scale": "1", + "about": "Soles on row 46, outline on row 47; the anchor is the middle of the bottom row. " + "Hitbox 12x34 from x 17..28, y 13..46. Faces right; flip for left. " + "The wall-slide frames press a wall whose first column is x 29, just right of the hitbox. player-spent.png is the same sheet with the dash spent.", + "frameTags": tags}} + return c, data + + +# --- Tiles ------------------------------------------------------------------- +# Terrain is one 16x16 autotile drawn per pixel from its eight neighbours: cut +# stone blocks (the ruins) under a mat of grass and moss where open air is +# above, a lit rim on the right (the sun's side), a shaded rim on the left and +# below, a selective outline on every open side, and outer corners rounded by +# two pixels. Deep inside, the blocks sink into shadow, so the edges the +# player touches carry the contrast. + +N, NE, E, SE, S, SW, Wb, NW = 1, 2, 4, 8, 16, 32, 64, 128 +DIRS = {N: (0, -1), NE: (1, -1), E: (1, 0), SE: (1, 1), S: (0, 1), SW: (-1, 1), Wb: (-1, 0), NW: (-1, -1)} + + +def canonical(mask): + """Corners only count when both sides beside them are solid (the 47-tile blob set).""" + for corner, a, b in ((NE, N, E), (SE, S, E), (SW, S, Wb), (NW, N, Wb)): + if not (mask & a and mask & b): + mask &= ~corner + return mask + + +BLOB = sorted({canonical(m) for m in range(256)}) + +# How far the grass mat hangs down each column (it loops across the tile). +GRASS = [4, 5, 5, 4, 3, 4, 6, 7, 6, 4, 4, 5, 4, 3, 4, 5] +# Blade tips: columns where the top row of grass is open, so the mat's top is ragged. +BLADE_GAP = {2, 6, 11, 14} + + +JOINTS = {0: (0, 10), 1: (5, 13)} # where blocks meet in each course of a tile: blocks of 10, 6, 8, and 8 + + +def block_texture(x, y, variant): + """The stone under the rims, in tile coordinates, as (step, mortar). Two courses of + blocks 8 high with their joints staggered and uneven, each block bevelled toward the + sun (lit top and right, shaded bottom and left). The pattern loops on all four sides.""" + course = y // 8 + by = y % 8 + js = JOINTS[course] + start = max((j for j in js if j <= x), default=js[-1] - 16) + nxt = min((j for j in js if j > x), default=js[0] + 16) + bx, w = x - start, nxt - start + if by == 0 or bx == 0: + return 0, True + step = 3 + if by == 1 or bx == w - 1: + step = 4 + if by == 7 or bx == 1: + step = 2 + # Worn pits: a small cluster in the wider blocks. + if w >= 8 and (bx, by) in ((3, 4), (4, 4), (4, 5)): + step = 2 + if w >= 8 and (bx, by) == (3, 3): + step = 4 if course else 3 + if variant == 1: # a crack down the first block + if course == 0 and (bx, by) in ((5, 1), (5, 2), (6, 3), (6, 4), (7, 5), (7, 6)): + return 0, True + if course == 0 and (bx, by) in ((6, 2), (7, 4), (8, 5)): + step = 4 + if variant == 2: # a chipped corner: a dark hole where a piece fell out + if course == 1 and bx >= w - 5 and by <= 4 and (w - 1 - bx) + by <= 4: + return (1 if (w - 1 - bx) + by >= 1 else 0), True + if variant == 3: # moss in a joint + if course == 1 and by <= 2 and 1 <= bx <= 6 and not (by == 2 and bx in (1, 6)): + return -1, False + return step, False + + +# Buried stones in the earth behind the facing, per fill variant; each loops on its tile. +EARTH_STONES = [ + ["................", "................", "..........eee...", "................", + "................", "....cdd.........", "...bccdd........", "...abbcc........", + "....aab.........", "................", "...........ee...", "eee.............", + "............cd..", "...........bccd.", "...........abb..", "................"], + ["................", "..cdd...........", ".bccdd..........", ".abbcc..........", + "..aab...........", "...........eeee.", "................", "................", + "........cdd.....", ".......bccdd....", ".......abbccd...", "........aabb....", + "................", "..eee...........", "................", "................"], + ["................", "...........cd...", "..........bccd..", "..........abb...", + "................", "..eeee..........", "................", "................", + "................", "...........eee..", "..cdd...........", ".bccdd..........", + ".abbcc..........", "..aab...........", "................", "................"], + ["................", "................", "................", ".....eeee.......", + "................", "................", "............cd..", "...........bccd.", + "...........abb..", "................", "................", "................", + "....cdd.........", "...bccdd........", "...abbcc........", "....aab........."], +] + + +def terrain_tile(mask, variant=0): + solid = [[False] * 48 for _ in range(48)] + for dy in (-1, 0, 1): + for dx in (-1, 0, 1): + bit = next((b for b, d in DIRS.items() if d == (dx, dy)), None) + if (dx, dy) == (0, 0) or (bit is not None and mask & bit): + for y in range(16 + dy * 16, 32 + dy * 16): + for x in range(16 + dx * 16, 32 + dx * 16): + solid[y][x] = True + + def empty(x, y): + return not (0 <= x < 48 and 0 <= y < 48) or not solid[y][x] + + def run(x, y, dx, dy): + k = 1 + while k < 12 and not empty(x + dx * k, y + dy * k): + k += 1 + return k # 1: the next pixel that way is open + + def depth(x, y): + for d in range(1, 20): + for j in range(-d, d + 1): + for i in range(-d, d + 1): + if max(abs(i), abs(j)) == d and empty(x + i, y + j): + return d + return 20 + + c = Canvas(16, 16) + for ty in range(16): + for tx in range(16): + x, y = tx + 16, ty + 16 + up, down, left, right = run(x, y, 0, -1), run(x, y, 0, 1), run(x, y, -1, 0), run(x, y, 1, 0) + # Round the outer corners by two pixels. + vert = min(up, down) + horiz = min(left, right) + if (vert == 1 and horiz <= 2) or (vert == 2 and horiz == 1): + continue + d = depth(x, y) + step, mortar = block_texture(tx, ty, variant) + if d > 12: + # Behind the facing: packed dark earth with a few buried stones, quiet. + col = "earth1" + stone = EARTH_STONES[variant][ty][tx] + if stone != ".": + col = {"a": "earth0", "b": "stone0", "c": "stone1", "d": "stone2", "e": "earth2"}[stone] + elif step == -1: + col = "leaf1" if (tx + ty) % 3 else "leaf0" + else: + # The facing of cut blocks, darker as it goes in. + if d > 9: + step -= 2 + elif d > 5: + step -= 1 + col = "stone0" if mortar else f"stone{max(0, min(5, step))}" + if mortar and d > 9: + col = "earth1" + # Rims: lit toward the sun (right), shaded away from it (left) and below. + if right == 2 and up > 2: + col = "stone5" + elif right == 3 and up > 3 and not mortar: + col = "stone4" + if left == 2 or down == 2: + col = "stone1" + if down == 3 and not mortar: + col = "stone2" if col not in ("stone0", "earth1") else col + # The grass mat on every top that has open air above. + g = GRASS[tx] + if up <= g: + if up == 1 and tx in BLADE_GAP: + continue + col = {1: "leaf4", 2: "leaf3", 3: "leaf2"}.get(up, "leaf1") + if up == 1 and tx % 5 == 0: + col = "leaf3" + if up == g: + col = "leaf0" # the mat's shadow on the stone + if right <= 2: + col = "leaf3" if up < g else col + # The outline on open sides: ink away from the sun, the material's darkest toward it. + if left == 1 or down == 1: + col = "ink" + elif up == 1 or right == 1: + col = "leaf0" if up <= g else "stone0" + if up == 1: + col = "leaf0" + elif d == 1: + col = "ink" + c.px[ty][tx] = col + return c + + +def platform_tiles(): + """A one-way catwalk: a steel girder with a lit deck, a truss web with rivets, and a + post that holds it up. Thin and open below, so it never reads as a solid block.""" + def girder(kind): + c = Canvas(16, 16) + for x in range(16): + c.set(x, 0, "steel0") # outline on top (lit side: the steel's darkest) + c.set(x, 1, "steel6" if x % 4 else "steel5") # the deck's lit edge, plate joints + c.set(x, 2, "steel4") + c.set(x, 3, "steel3") + c.set(x, 4, "steel1") # the deck's underside + c.set(x, 5, "ink") + c.set(x, 10, "steel0") # the bottom chord + c.set(x, 11, "steel2") + c.set(x, 12, "ink") + # The truss web between the chords: diagonals that meet every 8 pixels. + for k in range(4): + for x in range(16): + if (x + k) % 8 == 0 or (x - k) % 8 == 0: + c.set(x, 6 + k, "steel2" if (x - k) % 8 == 0 else "steel1") + for x in (3, 11): + c.set(x, 3, "steel5") # rivet heads catch the sun + if kind == "left": + for y in range(0, 13): + for x in range(0, 2): + c.set(x, y, None) + for y in range(1, 12): + c.set(1, y, "ink") + c.set(2, 1, "steel5") + if kind == "right": + for y in range(0, 13): + for x in range(14, 16): + c.set(x, y, None) + for y in range(1, 12): + c.set(14, y, "steel0") + c.set(13, 2, "steel6") + return c + + post = Canvas(16, 16) + for y in range(16): + post.set(5, y, "ink") + post.set(6, y, "steel1") + post.set(7, y, "steel2") + post.set(8, y, "steel3") + post.set(9, y, "steel4") + post.set(10, y, "steel0") + if y % 8 == 3: + post.set(8, y, "steel5") + if y % 8 == 4: + post.set(7, y, "steel1") + return {"platform-left": girder("left"), "platform-mid": girder("mid"), "platform-right": girder("right"), "platform-post": post} + + +def spike_tiles(): + """Spikes: two steel blades, the brightest thing in the room, lit on the sun's side, + on a rusted base plate. One drawing turned four ways.""" + up = Canvas(16, 16) + tone = {-3: "steel2", -2: "steel3", -1: "steel3", 0: "steel6", 1: "steel5", 2: "steel5", 3: "steel4"} + for y in range(0, 13): + half = -1 if y < 1 else 0 if y < 3 else 1 if y < 6 else 2 if y < 9 else 3 + for x in range(16): + c = min((4, 12), key=lambda cc: abs(x - cc)) + dx = x - c + if abs(dx) <= half: + up.set(x, y, tone[dx]) + elif abs(dx) == half + 1 or (dx == 0 and y == 0): + # The outline: ink on the shaded left, the steel's darkest on the lit right. + if up.get(x, y) is None: + up.set(x, y, "ink" if dx < 0 else "steel0") + # The base plate in warning paint: the hazard's own stripes, gold and ink. + for x in range(16): + up.set(x, 13, "gold1" if (x // 2) % 2 == 0 else "ink") + up.set(x, 14, "gold0" if ((x + 1) // 2) % 2 == 0 else "ink") + up.set(x, 15, "ink") + + def rot(c): # 90 degrees clockwise + r = Canvas(c.h, c.w) + for y in range(c.h): + for x in range(c.w): + r.px[x][c.h - 1 - y] = c.px[y][x] + return r + + right = rot(up) + down = rot(right) + left = rot(down) + return {"spikes-up": up, "spikes-right": right, "spikes-down": down, "spikes-left": left} + + +def selout_tile(c): + """An outline that stays inside the tile: the shape's own edge pixels in the dark.""" + out = c.copy() + for y in range(c.h): + for x in range(c.w): + if c.px[y][x] is None: + continue + for dx, dy in ((1, 0), (-1, 0), (0, -1)): + n = c.get(x + dx, y + dy) + if n is None and 0 <= x + dx < c.w and 0 <= y + dy < c.h: + out.px[y][x] = "ink" if dx < 0 else "steel1" + return out + + +def deco_tiles(): + """Decoration on its own layer over the terrain: never collides, never looks like it does.""" + keys = {"a": "leaf0", "b": "leaf1", "c": "leaf2", "d": "leaf3", "e": "leaf4", "i": "ink", + "s": "stone1", "t": "stone2", "u": "stone3", "v": "stone4", "w": "stone5", "o": "stone0", + "f": "fire4", "g": "gold1", "y": "sky3", "r": "fire2", "h": "earth2", "k": "steel1", "m": "steel3", "n": "steel4", "j": "steel0", "p": "fire1"} + fern = from_rows([ + "................", + "................", + "................", + "........e.......", + ".......ed.......", + "...e...dc...e...", + "..edd..dc..dd...", + "....cd.c..dc..e.", + ".e...ccbc.c..dd.", + "..dd..cbbcb.dc..", + "....cc.bbb.cc...", + "..e..cbbabbc..e.", + "...dc.bbabc.cd..", + ".....cbaaab.c...", + "..dcbbaaaaabbcd.", + ".cbbaaaaaaaaabc.", + ], keys) + flowers = from_rows([ + "................", + "................", + "................", + "................", + "................", + "....y...........", + "...ygy......f...", + "....y......fgf..", + "....c...y...f...", + "....c..ygy..c...", + "...dc...y...c...", + "....cd..c..dc...", + "..d.c.d.c.d.c...", + "...dcd.dcd..cd..", + "..cbcbccbcbcbc..", + ".cbbbbbbbbbbbbc.", + ], keys) + rubble = from_rows([ + "................", + "................", + "................", + "................", + "................", + "................", + "................", + "................", + "......iiii......", + ".....ituvwo.....", + "...iiituuvo.....", + "..ituvituvvoii..", + ".ituuvoisttituo.", + ".isttuoostuuvvo.", + "itssttoosstuuvvo", + "iiiiiiiiiiiiiiii", + ], keys) + vine = from_rows([ + "abbcabbcbaabcbba", + ".bc.cbd..bc.cb..", + ".c..bd...c..d...", + ".d..c....cd.e...", + ".c..dc....c.....", + ".b...c....d.....", + ".cd..d....c.....", + "..c..e....bd....", + "..d.......c.....", + "..c.......d.....", + "..be......e.....", + "..c.............", + "..d.............", + "...e............", + "................", + "................", + ], keys) + pipe = from_rows([ + "................", + "................", + "................", + "................", + "................", + "................", + "....jjjjjj......", + "...jkmmnnkj.....", + "...jkkmmnkj.....", + "....jkmnkj......", + "....jkmnkjd.....", + "....jkpmkjcd....", + "....jkppkj.c....", + "...jkkmnnkj.d...", + "..bjkkmnnnkjcb..", + ".cbjjjjjjjjjbbc.", + ], keys) + return {"deco-fern": fern, "deco-flowers": flowers, "deco-rubble": rubble, "deco-vine": vine, "deco-pipe": pipe} + + +def sheet(tiles, columns): + rows = (len(tiles) + columns - 1) // columns + c = Canvas(columns * TILE, rows * TILE) + for i, t in enumerate(tiles): + c.blit(t, (i % columns) * TILE, (i // columns) * TILE) + return c + + +def tileset(): + """The atlas: the 47 terrain tiles, three more fills, then the props on new rows.""" + terrain = [terrain_tile(m) for m in BLOB] + [terrain_tile(255, v) for v in (1, 2, 3)] + props = {} + props.update(platform_tiles()) + props.update(spike_tiles()) + props.update(deco_tiles()) + cols = 10 + names = [f"terrain-{m}" for m in BLOB] + ["terrain-255-v1", "terrain-255-v2", "terrain-255-v3"] + tiles = terrain[:] + while len(tiles) % cols: + tiles.append(Canvas(TILE, TILE)) + names.append(None) + for name, t in props.items(): + tiles.append(t) + names.append(name) + atlas = sheet(tiles, cols) + index = {n: i for i, n in enumerate(names) if n} + data = { + "tile": TILE, + "columns": cols, + "terrain": { + "about": "47-tile blob autotile: the bits name which of the 8 neighbours are terrain; a corner bit counts only when both sides beside it are set.", + "bits": {"N": N, "NE": NE, "E": E, "SE": SE, "S": S, "SW": SW, "W": Wb, "NW": NW}, + "byMask": {str(m): index[f"terrain-{m}"] for m in BLOB}, + "fillVariants": [index["terrain-255"], index["terrain-255-v1"], index["terrain-255-v2"], index["terrain-255-v3"]], + }, + "tiles": {n: i for n, i in index.items() if not n.startswith("terrain")}, + } + return atlas, data, props + + +# --- Backdrop planes --------------------------------------------------------- +# A jungle that has swallowed an industrial city, in hazy afternoon light. Each +# plane loops over the screen's width (every wave has a whole number of cycles +# across W, and every shape wraps), and each plane back has less contrast and +# moves toward the sky's colors. + + +def wave(x, terms): + return sum(a * math.sin(2 * math.pi * (k * x / W) + p) for a, k, p in terms) + + +def wrapdx(x, cx): + d = (x - cx) % W + return d - W if d > W / 2 else d + + +def blobs_shade(c, circles, tones, base_y=None, light=LIGHT, scallop=0.0): + """Paints lumps (cx, cy, r) one over another, each shaded as pixel artists shade a ball: + the base, a lit disc pushed toward the sun, a small top light further on, and a shadow + crescent on the far side. tones: (shadow, base, light, top). Lumps drawn later cover + earlier ones, so a bush or a cloud reads as a pile of rounded masses. A flat underside + at base_y if given. Wraps horizontally.""" + lx, ly = light[0] / math.hypot(*light), light[1] / math.hypot(*light) + for n_, (cx, cy, r) in enumerate(circles): + for y in range(int(cy - r - 1), int(cy + r + 2)): + if base_y is not None and y > base_y: + continue + for xx in range(int(cx - r - 1), int(cx + r + 2)): + px, py = xx + 0.5, y + 0.5 + # A scalloped edge for leaves: the radius ripples around the lump. + ang = math.atan2(py - cy, px - cx) + edge = r * (1 + scallop * math.sin(ang * max(5, round(r * 0.9)) + n_)) + if math.hypot(px - cx, py - cy) > edge: + continue + t = tones[1] + if math.hypot(px - (cx - lx * r * 0.35), py - (cy - ly * r * 0.35)) > r: + t = tones[0] + if math.hypot(px - (cx + lx * r * 0.3), py - (cy + ly * r * 0.3)) < r * 0.62: + t = tones[2] + if r >= 6 and math.hypot(px - (cx + lx * r * 0.5), py - (cy + ly * r * 0.5)) < r * 0.28: + t = tones[3] + c.set(xx % W, y, t) + + +def sky(): + c = Canvas(W, H) + bands = [(0, "sky0"), (46, "sky1"), (104, "sky2"), (150, "sky3"), (186, "rose5")] + for x in range(W): + off = round(wave(x, [(2.0, 2, 0.4), (1.0, 5, 1.9)])) + for y in range(H): + col = "sky0" + for edge, name in bands: + if y >= edge + (off if edge else 0): + col = name + c.px[y][x] = col + # Thin streaks where two bands meet, instead of a checker: a lighter line across the darker band. + rng = random.Random(5) + for edge, name in bands[1:]: + for k in range(6): + x0, ln = rng.randrange(W), rng.randint(20, 70) + y0 = edge - rng.randint(3, 7) + for x in range(x0, x0 + ln): + yy = y0 + round(wave(x, [(2.0, 2, 0.4), (1.0, 5, 1.9)])) + c.set(x % W, yy, name) + # The sun, high on the right: the one light. A white disc in a cream halo. + sx, sy = 296, 38 + for y in range(sy - 22, sy + 23): + for x in range(sx - 22, sx + 23): + d = math.hypot(x + 0.5 - sx, y + 0.5 - sy) + if d <= 11: + c.set(x, y, "steel6") + elif d <= 14: + c.set(x, y, "sky3") + elif d <= 19 and c.get(x, y) == "sky0": + c.set(x, y, "sky1") + # Clouds: a bank along the horizon and a few drifting high, lit from the sun's side. + rng = random.Random(9) + tones = ("sky1", "sky2", "steel6", "steel6") + x = 0 + while x < W: + cx, w = x + rng.randint(10, 30), rng.randint(40, 80) + base = rng.randint(150, 168) + circles = [] + for k in range(rng.randint(4, 7)): + px = cx + rng.uniform(-w / 2, w / 2) + r = rng.uniform(7, 15) * (1 - abs(px - cx) / w) + circles.append((px, base - r * 0.5, max(4, r))) + blobs_shade(c, sorted(circles, key=lambda q: q[2]), ("sky2", "sky3", "steel6", "steel6"), base_y=base) + x += w + rng.randint(10, 40) + for cx, cy, w in ((60, 70, 70), (180, 52, 44), (330, 92, 56)): + circles = [] + for k in range(5): + px = cx + (k - 2) * w / 6 + rng.uniform(-3, 3) + r = (w / 5) * (1 - abs(k - 2) * 0.22) + circles.append((px, cy - r * 0.4, r)) + blobs_shade(c, sorted(circles, key=lambda q: q[2]), ("sky1", "sky2", "steel6", "steel6"), base_y=cy) + return c + + +def far_city(): + """Far: a broken skyline in the haze, flat lavender with lit faces and a few windows.""" + c = Canvas(W, H) + rng = random.Random(21) + base = 192 + x = 0 + while x < W: + w = rng.randint(14, 34) + h = rng.randint(30, 92) + top = base - h + broken = rng.random() < 0.5 + for xx in range(x, x + w): + t = top + if broken: + # A broken top: the roof falls away in steps on one side. + t = top + max(0, round((xx - x - w * 0.4) * 0.9)) if rng.random() < 2 else top + for y in range(t, H): + lit = xx >= x + w - 3 + c.set(xx % W, y, "sky2" if lit else "sky1") + # Windows: a sparse grid of dark slots. + for wy in range(top + 6, base - 4, 6): + for wx in range(x + 3, x + w - 4, 5): + if rng.random() < 0.55 and c.get(wx % W, wy - 1) is not None: + c.set(wx % W, wy, "sky0") + c.set(wx % W, wy + 1, "sky0") + if rng.random() < 0.3: + ax = x + w // 2 + for y in range(top - rng.randint(6, 14), top): + c.set(ax % W, y, "sky1") + x += w + rng.randint(0, 6) + # Haze at the foot of the city. + for xx in range(W): + for y in range(base - 6, H): + if c.get(xx, y) is not None and y > base - 6 + (xx % 3 == 0) + 2 * ((xx // 7) % 2): + c.set(xx, y, "sky2") + return c + + +def girder_line(c, x0, y0, x1, y1, col): + n = max(abs(x1 - x0), abs(y1 - y0)) or 1 + for k in range(n + 1): + c.set(round(x0 + (x1 - x0) * k / n) % W, round(y0 + (y1 - y0) * k / n), col) + + +def mid_ruins(): + """Mid: the industrial ruin, grey-blue steel and concrete with teal growth: a cooling + tower, a broken truss bridge, chimneys, and cranes.""" + c = Canvas(W, H) + rng = random.Random(33) + ground = [round(186 - wave(x, [(4, 2, 0.3), (2, 5, 2.0)])) for x in range(W)] + body, lit, dark = "steel3", "steel4", "steel2" + # The cooling tower: a waisted shell, lit on the right. + tx, top, bottom = 92, 96, 196 + for y in range(top, bottom): + t = (y - top) / (bottom - top) + half = 16 + 9 * (t - 0.42) ** 2 * 4.2 + for x in range(round(tx - half), round(tx + half) + 1): + dx = (x - tx) / half + col = lit if dx > 0.45 else dark if dx < -0.55 else body + if y < top + 2: + col = dark + c.set(x % W, y, col) + if y > top + 4 and y % 9 == 0: # the shell's rings of stained concrete + for x in range(round(tx - half) + 1, round(tx + half)): + if c.get(x % W, y) == body: + c.set(x % W, y, dark) + # A broken bite out of the tower's rim. + for y in range(top, top + 14): + for x in range(tx + 2, tx + 20): + if (x - tx - 2) * 0.9 + (top + 14 - y) * 1.3 > 14 and (x - tx) < 18: + c.set(x % W, y, None) + # Chimneys. + for cx, h, w in ((150, 92, 6), (162, 70, 5), (318, 104, 7)): + for y in range(ground[cx] - h, H): + for x in range(cx, cx + w): + c.set(x % W, y, lit if x == cx + w - 1 else dark if x == cx else body) + if (y - ground[cx] + h) % 12 == 3: + for x in range(cx, cx + w): + c.set(x % W, y, dark) + # The broken bridge: a truss from the right that stops in mid-air. + by = 132 + for x in range(196, 300): + c.set(x, by, lit) + c.set(x, by + 1, body) + c.set(x, by + 12, body) + c.set(x, by + 13, dark) + for k in range(196, 296, 12): + girder_line(c, k, by + 1, k + 6, by + 12, body) + girder_line(c, k + 6, by + 12, k + 12, by + 1, dark) + girder_line(c, k, by, k, by + 13, body) + for px in (230, 276): # its piers + for y in range(by + 14, H): + for x in range(px, px + 7): + c.set(x, y, lit if x == px + 6 else dark if x == px else body) + # The broken end: bent girders hanging. + girder_line(c, 196, by + 12, 188, by + 24, body) + girder_line(c, 196, by, 186, by + 6, body) + # A crane: a mast and a jib, its hook line down. + mx = 352 + for y in range(80, H): + c.set(mx, y, dark) + c.set(mx + 3, y, lit) + if y % 6 == 0: + girder_line(c, mx, y, mx + 3, y + 3, body) + for x in range(mx - 40, mx + 14): + c.set(x % W, 80, lit) + c.set(x % W, 84, body) + if x % 6 == 0: + girder_line(c, x, 80, x + 3, 84, body) + for y in range(85, 120): + c.set((mx - 34) % W, y, dark) + # The ground of rubble, and teal growth over everything: mounds and creepers. + for x in range(W): + for y in range(ground[x], H): + c.set(x, y, "teal3" if y < ground[x] + 2 else "teal4" if (x + y) % 2 and y < ground[x] + 4 else "teal3") + circles = [] + for k in range(30): + x = rng.randrange(W) + circles.append((x, ground[x] - rng.uniform(0, 4), rng.uniform(4, 10))) + for (x, y, r) in ((80, 101, 5), (90, 99, 4), (240, 131, 4), (262, 131, 3)): + circles.append((x, y, r)) + blobs_shade(c, circles, ("teal3", "teal4", "teal5", "teal5"), scallop=0.15) + # Creepers hanging from the bridge and the tower. + for x0, y0, ln in ((210, 146, 18), (222, 146, 9), (252, 146, 24), (268, 146, 12), (84, 108, 26), (98, 108, 14), (290, 146, 16)): + for k in range(ln): + c.set((x0 + round(1.5 * math.sin(k * 0.4))) % W, y0 + k, "teal3" if k % 4 else "teal4") + return c + + +def near_jungle(): + """Near: the jungle at the edge of the ruin, darker and with more contrast: a ridge of + broad leaves, trunks rising out of it, and a canopy that frames the top.""" + c = Canvas(W, H) + rng = random.Random(44) + ridge = [round(178 - wave(x, [(6, 1, 0.8), (4, 3, 2.2), (2, 7, 0.1)])) for x in range(W)] + tones = ("teal1", "teal2", "teal3", "teal5") + # Trunks, thin and tall, leaning a little, lit on the right. + for tx, w in ((40, 11), (196, 8), (300, 13)): + lean = rng.uniform(-0.08, 0.08) + for y in range(0, H): + x0 = tx + round(lean * (H - y)) + ww = w + max(0, (y - 150) // 6) # the trunk flares into its roots + x0 -= max(0, (y - 150) // 12) + for x in range(x0, x0 + ww): + col = "teal2" + if x >= x0 + ww - 3: + col = "teal3" + if x == x0 + ww - 2 and (y // 3) % 3: + col = "teal5" if y > 30 else "teal3" + if x <= x0 + 1: + col = "teal1" + # Bark: short dark grooves along the trunk, staggered. + if (x - x0) in (3, 6) and (y + x * 7) % 11 < 4: + col = "teal1" + c.set(x % W, y, col) + # The canopy along the top: big lumps, lit on the sun's side. + circles = [] + x = 0 + while x < W: + r = rng.uniform(7, 15) + circles.append((x, rng.uniform(-6, 8) + (6 if r < 10 else 0), r)) + x += rng.uniform(6, 14) + blobs_shade(c, circles, tones, scallop=0.12) + # Vines from the canopy. + for k in range(7): + x0, ln = rng.randrange(W), rng.randint(16, 46) + for j in range(ln): + xx = (x0 + round(2 * math.sin(j * 0.25 + k))) % W + c.set(xx, 14 + j, "teal1") + if j % 6 == 3: # a leaf on the vine + c.set((xx + 1) % W, 14 + j, "teal3") + c.set((xx + 2) % W, 13 + j, "teal3") + # The ridge: broad-leaf bushes on a dark slope. + for x in range(W): + for y in range(ridge[x], H): + c.set(x, y, "teal1") + circles = [] + for k in range(110): + x = rng.randrange(W) + circles.append((x, ridge[x] + rng.uniform(-3, 10), rng.uniform(4, 10))) + blobs_shade(c, sorted(circles, key=lambda q: q[1]), tones, scallop=0.12) + return c + + +def foreground(): + """In front of the play: big leaves hanging into the top corners and a fringe of ferns + along the bottom, flat dark teal silhouettes with one rim of light, kept to margins the + player cannot reach. It loops.""" + c = Canvas(W, H) + rng = random.Random(55) + + def frond(x0, y0, ang, ln, reach, bend): + """A palm frond: a rib that arcs down from where it hangs, leaflets along both sides, + longest in the middle, swept toward the tip.""" + pts = [] + for j in range(ln): + t = j / ln + a = ang + bend * t + if pts: + px, py = pts[-1] + else: + px, py = x0, y0 + pts.append((px + math.cos(a), py + math.sin(a))) + for j, (px, py) in enumerate(pts): + c.set(round(px) % W, round(py), "teal0") + c.set(round(px) % W, round(py) + 1, "teal0") + t = j / ln + if j % 2 == 0 and 0.08 < t < 0.97: + a = ang + bend * t + l = reach * math.sin(math.pi * min(1.0, t * 1.15)) + 2 + for side in (-1, 1): + la = a + side * 1.05 + for q in range(int(l)): + # Leaflets droop a little and sweep toward the tip. + qx = px + math.cos(la) * q + math.cos(a) * q * 0.45 + qy = py + math.sin(la) * q + math.sin(a) * q * 0.45 + q * q * 0.03 + c.set(round(qx) % W, round(qy), "teal0") + if q < l * 0.5: + c.set(round(qx) % W, round(qy) + 1, "teal0") + + for (x, y, a, ln, reach, bend) in ((-4, -2, 0.35, 70, 9, 0.9), (-2, 10, 0.05, 50, 7, 1.1), (6, -4, 0.9, 44, 7, 0.7), + (W + 4, -2, math.pi - 0.4, 64, 9, -0.9), (W + 2, 6, math.pi - 0.05, 44, 7, -1.1)): + frond(x, y, a, ln, reach, bend) + # Ferns along the bottom: fronds that arc out from clumps. + x = 0 + while x < W: + n = rng.randint(3, 6) + for k in range(n): + ang = math.pi * (1.0 + (k + 0.5) / n) # from left to right, up + ln = rng.randint(10, 22) + for j in range(ln): + t = j / ln + px = x + math.cos(ang) * j * 0.9 + py = H - 1 + math.sin(ang) * j * 0.7 + t * t * 6 + c.set(round(px) % W, round(py), "teal0") + if t < 0.7: + c.set(round(px) % W, round(py) + 1, "teal0") + if j % 3 == 1 and t < 0.85: # leaflets + for q in (1, 2): + c.set(round(px - math.sin(ang) * q) % W, round(py + math.cos(ang) * q) + 1, "teal0") + x += rng.randint(18, 40) + for x in range(W): + for y in range(H - 3, H): + c.set(x, y, "teal0") + # One rim of light on the edges that face the sun (up and right). + out = c.copy() + for y in range(H): + for x in range(W): + if c.px[y][x] == "teal0" and c.get((x + 1) % W, y) is None and c.get(x, y - 1) is None and y > 0: + out.px[y][x] = "teal1" + return out + + +# --- Props and the enemy ----------------------------------------------------- + + +def cog_frames(): + """The collectible: a brass cog that spins on its axis (eight frames over half a turn, + since it looks the same from behind), with a glint on the sun's side.""" + frames = [] + for k in range(8): + th = math.pi * k / 8 + sx = math.cos(th) + c = Canvas(16, 16) + cx, cy = 8.0, 8.0 + thick = 1.6 * abs(math.sin(th)) # the cog's edge shows as it turns + for y in range(16): + for x in range(16): + px, py = x + 0.5 - cx, y + 0.5 - cy + face = None + if abs(sx) > 0.12: + u = px / abs(sx) if abs(sx) > 0 else 99 + ang = math.atan2(py, u) + rad = math.hypot(u, py) + tooth = (math.cos(ang * 8) > 0.25) + outer = 6.6 if tooth else 5.2 + if 2.0 < rad <= outer: + face = "gold1" + if rad > outer - 1.1 or (not tooth and rad > 4.4): + face = "gold0" + if px * 0.7 - py * 0.7 > 2.2 and rad < 4.6: + face = "gold2" + if rad <= 3.0: + face = "gold0" + # The edge: a band beside the face, darker, on the side turning away. + if face is None and thick > 0.4: + off = px + (thick if sx > 0 else -thick) + if abs(sx) > 0.12: + u = off / abs(sx) + rad = math.hypot(u, py) + ang = math.atan2(py, u) + outer = 6.6 if math.cos(ang * 8) > 0.25 else 5.2 + if 2.0 < rad <= outer and math.hypot(px / abs(sx), py) > 2.0: + face = "fire3" + elif abs(px) <= 1.2 and abs(py) <= 6.6 and not (abs(py) > 5.2 and int(py + 8) % 2): + face = "fire3" if px < 0.2 else "gold0" + if face: + c.set(x, y, face) + frames.append(selout(c)) + return frames + + +def spring_frames(): + """A spring pad: a steel base, a red coil, and a plate. At rest, pressed, and thrown up.""" + out = [] + for coil_h, plate_up in ((7, 0), (3, 0), (12, 0)): + c = Canvas(16, 24) + base = 22 + for x in range(1, 15): + c.set(x, base, "steel1") + c.set(x, base - 1, "steel3" if x < 12 else "steel4") + top = base - 2 - coil_h + # The coil: a front wire every other row, lit, and the back wire's ends between. + for j, y in enumerate(range(base - 2, top, -1)): + if j % 2 == 0: + for x in range(4, 12): + c.set(x, y, "fire3" if x > 6 else "fire2") + else: + c.set(4, y, "fire1") + c.set(11, y, "fire1") + for x in range(2, 14): + c.set(x, top, "steel5" if x > 9 else "steel4") + c.set(x, top - 1, "steel6" if x > 9 else "steel5") + for x in range(3, 13): + c.set(x, top - 2, "fire3" if x > 8 else "fire2") # the pad's warning stripe + out.append(selout(c)) + return out + + +def beacon_frames(): + """The checkpoint: a radio beacon on a pole. Off, its lamp is dull steel; on, it glows + gold and blinks (two frames).""" + out = [] + for state in ("off", "on-a", "on-b"): + c = Canvas(16, 32) + for y in range(10, 31): + c.set(7, y, "steel1") + c.set(8, y, "steel3") + c.set(9, y, "steel4") + for x in range(4, 13): + c.set(x, 30, "steel2" if x < 9 else "steel3") + c.set(x, 29, "steel3" if x < 10 else "steel4") + # The antenna and the lamp's cage. + for y in range(1, 5): + c.set(8, y, "steel3") + lamp_on = state != "off" + for y in range(5, 11): + for x in range(5, 12): + d = math.hypot(x + 0.5 - 8.5, y + 0.5 - 8) + if d <= 3.4: + if lamp_on: + col = "gold2" if (x > 8 and y < 8) else "gold1" if d < 2.6 else "gold0" + else: + col = "steel5" if (x > 8 and y < 8) else "steel3" if d < 2.6 else "steel2" + c.set(x, y, col) + for y in (6, 9): + for x in range(5, 12): + if c.get(x, y): + c.set(x, y, "steel1") # the cage bars + c.set(9, 7, "steel6") + # A pennant in the hazard's gold would lie; the beacon carries a small blue tag instead. + for y in range(13, 17): + for x in range(10, 10 + (17 - y)): + c.set(x, y, "blue2" if y < 15 else "blue1") + if state == "on-b": + for (x, y) in ((3, 8), (14, 8), (8, 0), (4, 4), (13, 4)): + c.set(x, y, "gold2") + out.append(selout(c)) + return out + + +def enemy_frames(): + """A scrap beetle: a dented violet shell on six steel legs, one big eye. Four idle frames: + the shell breathes on its legs and the eye glances.""" + out = [] + for k in range(4): + c = Canvas(32, 24) + bob = (0, 1, 1, 0)[k] + cx, cy, rx, ry = 15.5, 15 + bob, 11.5, 9.0 + # Legs first, under the shell: three a side, bent at the knee. + for i, lx in enumerate((7, 13, 21)): + kx = lx + (-2 if i < 1 else 2 if i > 1 else 0) + ((k + i) % 2) + girder = [(lx, 15 + bob), (kx, 18), (kx + (1 if i else -1), 22)] + for (x0, y0), (x1, y1) in zip(girder, girder[1:]): + n = max(abs(x1 - x0), abs(y1 - y0)) or 1 + for t in range(n + 1): + c.set(round(x0 + (x1 - x0) * t / n), round(y0 + (y1 - y0) * t / n), "steel2") + for y in range(24): + for x in range(32): + px, py = x + 0.5 - cx, y + 0.5 - cy + if py > 1.5: + continue + if (px / rx) ** 2 + (py / ry) ** 2 > 1: + continue + col = "violet2" + if (px - 3) ** 2 / (rx * 0.7) ** 2 + (py + 3) ** 2 / (ry * 0.6) ** 2 < 1: + col = "violet3" + if (px - 5) ** 2 + (py + 6) ** 2 < 3.2: + col = "violet4" + if (px / rx) ** 2 + (py / ry) ** 2 > 0.72 and px < 0: + col = "violet1" + if py > 0.5: + col = "violet1" # the shell's rim, in its own shade + # Plate seams. + if abs(px + 3 - py * 0.3) < 0.5 and py < -1: + col = "violet1" + c.set(x, y, col) + # The eye on the front, low: a red-pink lens with a white glint. + ex, ey = 24, 12 + bob + for y in range(ey - 1, ey + 2): + for x in range(ex - 1, ex + 3): + if not ((x in (ex - 1, ex + 2)) and y in (ey - 1, ey + 1)): + c.set(x, y, "fire3") + c.set(ex - 1, ey, "fire2") + c.set(ex, ey + 1, "fire2") + gx = ex + (1 if k != 2 else 0) + c.set(gx, ey - 1, "steel6") + c.set(gx, ey, "fire4") + out.append(selout(c)) + return out + + +def strip(frames, gap=0): + w = sum(f.w for f in frames) + gap * (len(frames) - 1) + h = max(f.h for f in frames) + c = Canvas(w, h) + x = 0 + for f in frames: + c.blit(f, x, h - f.h) + x += f.w + gap + return c + + +def frames_json(name, frames, ms, loop, about): + """The strip's frames in the hash format, like the player's.""" + data = {"frames": {}, "animations": {name: []}, "meta": {"size": {}, "about": about, "loop": loop}} + x = 0 + for i, f in enumerate(frames): + key = f"{name} {i}" + data["frames"][key] = {"frame": {"x": x, "y": 0, "w": f.w, "h": f.h}, "duration": ms, "anchor": {"x": 0.5, "y": 1}} + data["animations"][name].append(key) + x += f.w + data["meta"]["size"] = {"w": x, "h": max(f.h for f in frames)} + data["meta"]["image"] = f"{name}.png" + return data + + +# --- The mockup room --------------------------------------------------------- +# 24 x 14 tiles; the screen shows 13.5 rows, so the last row is half off screen. + +LEVEL = [ + "###..................###", + "##...................###", + "#.....................##", + "#.....................##", + "#.....................##", + "#.....................##", + "#.....................##", + "##.........-----......##", + "###.........|.|.......##", + "####........|.|...######", + "#####.......|.|...######", + "######......|.|^^^######", + "########################", + "########################", +] + + +def solid_at(level, x, y): + if y < 0 or y >= len(level) or x < 0 or x >= len(level[0]): + return True # the room's border counts as rock, so no outline runs along the screen's edge + return level[y][x] == "#" + + +def compose_terrain(level): + cache = {} + c = Canvas(len(level[0]) * TILE, len(level) * TILE) + for y, row in enumerate(level): + for x, k in enumerate(row): + if k != "#": + continue + mask = 0 + for bit, (dx, dy) in DIRS.items(): + if solid_at(level, x + dx, y + dy): + mask |= bit + mask = canonical(mask) + variant = 0 + if mask == 255: + h = (x * 73856093 ^ y * 19349663) % 7 + variant = (0, 0, 0, 0, 1, 2, 3)[h] + if (mask, variant) not in cache: + cache[(mask, variant)] = terrain_tile(mask, variant) + c.blit(cache[(mask, variant)], x * TILE, y * TILE) + return c + + +PARALLAX = [("bg-0-sky.png", 0.0), ("bg-1-far.png", 0.15), ("bg-2-mid.png", 0.35), ("bg-3-near.png", 0.6)] +FG_PARALLAX = 1.3 + + +def layers_at(camera, imgs): + out = Image.new("RGBA", (W, H)) + for img, factor in imgs: + off = round(camera * factor) % W + for k in (0, 1): + out.alpha_composite(img, (-off + k * W, 0)) + return out + + +def fx_frame(name, i): + """One frame of an effect, read back from the sheet `ritmo-tools fx render` wrote.""" + path = os.path.join(ART, "fx", f"{name}.json") + if not os.path.exists(path): + return None, None + with open(path) as f: + data = json.load(f) + fr = data["frames"][f"{name} {i}"] + img = Image.open(os.path.join(ART, "fx", f"{name}.png")).convert("RGBA") + box = fr["frame"] + anchor = fr.get("anchor", {"x": 0.5, "y": 0.5}) + return img.crop((box["x"], box["y"], box["x"] + box["w"], box["y"] + box["h"])), \ + (round(anchor["x"] * box["w"]) if anchor["x"] <= 1 else anchor["x"], round(anchor["y"] * box["h"]) if anchor["y"] <= 1 else anchor["y"]) + + +def room_layer(props): + room = compose_terrain(LEVEL) + tp = props + for y, row in enumerate(LEVEL): + for x, k in enumerate(row): + if k == "^": + room.blit(tp["spikes-up"], x * TILE, y * TILE) + if k == "-": + left = row[x - 1] != "-" + right = x + 1 < len(row) and row[x + 1] != "-" + room.blit(tp["platform-left" if left else "platform-right" if right else "platform-mid"], x * TILE, y * TILE) + if k == "|": + room.blit(tp["platform-post"], x * TILE, y * TILE) + for name, cells in { + "deco-fern": [(3, 8), (6, 11), (20, 8)], + "deco-flowers": [(4, 9), (8, 11)], + "deco-rubble": [(9, 11), (21, 8)], + "deco-vine": [(2, 1), (21, 2)], + "deco-pipe": [(18, 8)], + }.items(): + for cx, cy in cells: + assert LEVEL[cy][cx] == ".", (name, cx, cy) + assert LEVEL[cy - 1 if name == "deco-vine" else cy + 1][cx] == "#", (name, cx, cy) + room.blit(tp[name], cx * TILE, cy * TILE) + return room + + +def mockup(anims, extra): + imgs = [(Image.open(os.path.join(ART, "backdrop", n)).convert("RGBA"), f) for n, f in PARALLAX] + fg = Image.open(os.path.join(ART, "foreground", "fg-jungle.png")).convert("RGBA") + scene = layers_at(0, imgs) + _, _, tprops = tileset() + scene.alpha_composite(room_layer(tprops).image()) + # Props: the beacon on the left mound, a spring in the pit, cogs over the catwalk, the beetle on the ledge. + scene.alpha_composite(extra["beacon"][1].image(), (2 * TILE, 9 * TILE - 32)) + scene.alpha_composite(extra["spring"][0].image(), (10 * TILE, 12 * TILE - 24)) + for k, (cx, cy) in enumerate(((180, 84), (200, 78), (220, 84))): + scene.alpha_composite(extra["cog"][(0, 7, 1)[k]].image(), (cx, cy)) + scene.alpha_composite(extra["enemy"][0].image(), (19 * TILE + 4, 9 * TILE - 24)) + # The player mid-run on the pit floor, dust at the back foot; and a second capture of + # her mid-jump off the catwalk would crowd the room, so one is enough. + run = anims["run"][0] + px, py = 6 * TILE - 2, 12 * TILE - FRAME + dust, anchor = fx_frame("dust", 2) + if dust is not None: + scene.alpha_composite(dust, (px + 18 - anchor[0], py + 47 - anchor[1])) + scene.alpha_composite(run[3].image(), (px, py)) + scene.alpha_composite(fg) + return scene + + +def player_gif(anims, path, scale): + """Every animation playing side by side on its own clock, on a strip of ground (or a wall).""" + ground = terrain_tile(canonical(E | Wb | S | SE | SW)) + wall = terrain_tile(canonical(N | S | E | NE | SE)) + order = ["idle", "run", "jump", "fall", "dash", "wall-slide", "land"] + cw, ch = 56, 72 + step, total = 10, 2240 + frames = [] + for t in range(0, total, step): + c = Canvas(cw * len(order), ch, "sky2") + for i, name in enumerate(order): + fs, ms, loop = anims[name] + hold = 400 if not loop else 0 # one-shots hold their last frame, then play again + span = len(fs) * ms + hold + k = (t // ms) % len(fs) if loop else min(len(fs) - 1, (t % span) // ms) + x0 = i * cw + if name == "wall-slide": + for y in range(0, ch, TILE): + c.blit(wall, x0 + 4 + WALL, y) + elif name not in ("jump", "fall", "dash"): + for x in range(0, cw, TILE): + c.blit(ground, x0 + x, 56) + y = 56 - FRAME if name not in ("jump", "fall", "dash", "wall-slide") else 8 + c.blit(fs[k], x0 + 4, y) + frames.append(c.image()) + save_gif(frames, [step] * len(frames), path, scale) + + +def parallax_gif(path, scale): + imgs = [(Image.open(os.path.join(ART, "backdrop", n)).convert("RGBA"), f) for n, f in PARALLAX] + fg = Image.open(os.path.join(ART, "foreground", "fg-jungle.png")).convert("RGBA") + frames = [] + for i in range(96): + cam = round(W * (1 - math.cos(math.pi * 2 * i / 96)) / 2) + img = layers_at(cam, imgs) + off = round(cam * FG_PARALLAX) % W + for k in (0, 1): + img.alpha_composite(fg, (-off + k * W, 0)) + frames.append(img) + save_gif(frames, [40] * len(frames), path, scale) + + +def comparisons(anims): + """Set one's player beside this one at the same zoom, and the two mockups side by side, + so the change of scale is plain.""" + one = os.path.join(SET_ONE, "art") + if not os.path.exists(os.path.join(one, "player", "player.png")): + return + p1 = Image.open(os.path.join(one, "player", "player.png")).convert("RGBA") + zoom = 6 + bg = rgb("sky2") + (255,) + # Players: set one's idle, run, jump, and dash frames, then this set's. + one_frames = [p1.crop((0, 0, 16, 16)), p1.crop((0, 16, 16, 32)), p1.crop((32, 16, 48, 32)), p1.crop((0, 32, 16, 48)), p1.crop((0, 64, 16, 80))] + two_frames = [anims["idle"][0][0].image(), anims["run"][0][1].image(), anims["run"][0][5].image(), anims["jump"][0][0].image(), anims["dash"][0][1].image()] + pad = 4 + img = Image.new("RGBA", (pad + len(two_frames) * (FRAME + pad), pad + 16 + pad + FRAME + pad), bg) + for k, f in enumerate(one_frames): + img.alpha_composite(f, (pad + k * (FRAME + pad) + (FRAME - 16) // 2, pad)) + for k, f in enumerate(two_frames): + img.alpha_composite(f, (pad + k * (FRAME + pad), pad + 16 + pad)) + os.makedirs(os.path.join(PREVIEWS, "compare"), exist_ok=True) + img.resize((img.width * zoom, img.height * zoom), Image.NEAREST).save(os.path.join(PREVIEWS, "compare", "players@6x.png"), optimize=True) + # Mockups: each at its own native size, both at 3x, the same pixel size on screen. + m1 = Image.open(os.path.join(one, "mockup", "mockup.png")).convert("RGBA") + m2 = Image.open(os.path.join(ART, "mockup", "mockup.png")).convert("RGBA") + both = Image.new("RGBA", (m1.width + 8 + m2.width, max(m1.height, m2.height)), (20, 16, 19, 255)) + both.alpha_composite(m1, (0, (both.height - m1.height) // 2)) + both.alpha_composite(m2, (m1.width + 8, 0)) + both.resize((both.width * 3, both.height * 3), Image.NEAREST).save(os.path.join(PREVIEWS, "compare", "mockups@3x.png"), optimize=True) + + +def main(): + os.makedirs(ART, exist_ok=True) + os.makedirs(PREVIEWS, exist_ok=True) + with open(os.path.join(HERE, "palette.hex"), "w") as f: + f.write("".join(v.lstrip("#") + "\n" for v in PALETTE.values())) + with open(os.path.join(HERE, "pixel.config.json"), "w") as f: + json.dump({"palette": "palette.hex", "maxColors": 32}, f, indent=2) + f.write("\n") + layers = {"bg-0-sky.png": sky(), "bg-1-far.png": far_city(), "bg-2-mid.png": mid_ruins(), "bg-3-near.png": near_jungle()} + for name, layer in layers.items(): + save(layer, "backdrop/" + name, scale=3) + stacked = Canvas(W, H) + for layer in layers.values(): + stacked.blit(layer, 0, 0) + save(stacked, "backdrop/backdrop-stacked.png", scale=3) + save(foreground(), "foreground/fg-jungle.png", scale=3) + atlas, data, _ = tileset() + save(atlas, "tiles/tileset.png", scale=6) + with open(os.path.join(ART, "tiles", "tileset.json"), "w") as f: + json.dump(data, f, indent=2) + f.write("\n") + anims = player_animations() + psheet, pdata = player_sheet(anims) + save(psheet, "player/player.png", scale=4) + with open(os.path.join(ART, "player", "player.json"), "w") as f: + json.dump(pdata, f, indent=1) + f.write("\n") + spent, _ = player_sheet(player_animations(charged=False)) + save(spent, "player/player-spent.png", scale=0) + save(anims["idle"][0][0], "player/player-idle.png", scale=0) + extra = {"cog": cog_frames(), "spring": spring_frames(), "beacon": beacon_frames(), "enemy": enemy_frames()} + about = { + "cog": ("The collectible: a brass cog, spinning. Loops.", 80, True), + "spring": ("Spring pad: 0 at rest, 1 pressed, 2 thrown. Frames are picked by the game.", 0, False), + "beacon": ("Checkpoint beacon: 0 off; 1 and 2 on, blinking.", 300, True), + "enemy": ("Scrap beetle, idle. Loops.", 180, True), + } + props_row = [] + for name, frames in extra.items(): + text, ms, loop = about[name] + save(strip(frames), f"props/{name}.png", scale=0) + with open(os.path.join(ART, "props", f"{name}.json"), "w") as f: + json.dump(frames_json(name, frames, ms, loop, text), f, indent=1) + f.write("\n") + props_row.append(strip(frames, 3)) + shown = Canvas(max(r.w for r in props_row) + 8, sum(r.h + 4 for r in props_row) + 4) + y = 4 + for r in props_row: + shown.blit(r, 4, y) + y += r.h + 4 + save(shown, "props/props.png", scale=6, art=False) + save(mockup(anims, extra), "mockup/mockup.png", scale=4) + for name in ("dash", "dust", "collect"): + p = os.path.join(ART, "fx", f"{name}.png") + if os.path.exists(p): + save(Image.open(p).convert("RGBA"), f"fx/{name}.png", scale=4, art=False) + player_gif(anims, os.path.join(PREVIEWS, "player", "player-animations@3x.gif"), 3) + comparisons(anims) + # Not committed (large): written for a person to watch. + parallax_gif(os.path.join(PREVIEWS, "parallax", "parallax@2x.gif"), 2) + + +def debug_sheet(rows, path, scale=6): + cols = max(len(r) for r in rows) + c = Canvas(cols * FRAME, len(rows) * FRAME, "sky2") + for j, r in enumerate(rows): + for i, f in enumerate(r): + c.blit(f, i * FRAME, j * FRAME) + for x in range(FRAME): + if c.get(i * FRAME + x, j * FRAME + 47) is None or c.get(i * FRAME + x, j * FRAME + 47) == "sky2": + c.set(i * FRAME + x, j * FRAME + 47, "sky1") + c.image().resize((c.w * scale, c.h * scale), Image.NEAREST).save(path) + + +if __name__ == "__main__" and len(sys.argv) == 1: + main() + +if __name__ == "__main__" and "props" in sys.argv: + rows = [cog_frames(), spring_frames(), beacon_frames(), enemy_frames()] + c = Canvas(160, 110, "sky2") + y = 2 + for r in rows: + st = strip(r, 4) + c.blit(st, 2, y) + y += st.h + 4 + c.image().resize((c.w * 6, c.h * 6), Image.NEAREST).save("/tmp/props.png") + +if __name__ == "__main__" and "bg" in sys.argv: + layers = [sky(), far_city(), mid_ruins(), near_jungle(), foreground()] + out = Canvas(W, H) + for l in layers: + out.blit(l, 0, 0) + out.image().resize((W * 3, H * 3), Image.NEAREST).save("/tmp/bg.png") + for k, l in enumerate(layers): + l.image().resize((W * 2, H * 2), Image.NEAREST).save(f"/tmp/bg{k}.png") + +if __name__ == "__main__" and "tiles" in sys.argv: + atlas, data, props = tileset() + sh = Canvas(atlas.w, atlas.h, "sky2") + sh.blit(atlas, 0, 0) + sh.image().resize((sh.w * 5, sh.h * 5), Image.NEAREST).save("/tmp/tiles.png") + +if __name__ == "__main__" and "debug" in sys.argv: + j, f = air_poses() + rows = [[draw_pose(p) for p in idle_poses()], [draw_pose(p) for p in run_poses()], + [draw_pose(p) for p in j + f + land_poses()], [draw_pose(p) for p in dash_poses() + slide_poses()]] + debug_sheet(rows, "/tmp/pl.png") diff --git a/packages/core/genres/platformer-assets-detailed/palette.hex b/packages/core/genres/platformer-assets-detailed/palette.hex new file mode 100644 index 00000000..58db1d80 --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/palette.hex @@ -0,0 +1,60 @@ +141013 +849be4 +b9bffb +e3e6ff +fef3c0 +333941 +4a5462 +6d758d +8b93af +b3b9d1 +dae0ea +ffffff +122020 +24523b +23674e +328464 +477d85 +5daf8d +92dcba +cdf7e2 +1a7a3e +14a02e +59c135 +9cdb43 +d6f264 +221c1a +322b28 +71413b +bb7547 +dba463 +423934 +5a4e44 +796755 +a08662 +c7b08b +e4d2aa +422433 +5b3138 +8e5252 +ba756a +e9b5a3 +fad6b8 +143464 +285cc4 +249fde +20d6c7 +a6fcdb +3b1725 +73172d +b4202a +df3e23 +fa6a0a +f9a31b +ffd541 +fffc40 +242234 +403353 +793a80 +bc4a9b +e86a73 diff --git a/packages/core/genres/platformer-assets-detailed/pixel.config.json b/packages/core/genres/platformer-assets-detailed/pixel.config.json new file mode 100644 index 00000000..05e12680 --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/pixel.config.json @@ -0,0 +1,4 @@ +{ + "palette": "palette.hex", + "maxColors": 32 +} diff --git a/packages/core/genres/platformer-assets-detailed/previews/backdrop/backdrop-stacked@3x.png b/packages/core/genres/platformer-assets-detailed/previews/backdrop/backdrop-stacked@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..59485f1bc2eafe33bd822eafbde80310f7ec256f GIT binary patch literal 20587 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 Q*b!s!boFyt=akR{0Dk@5;s5{u literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/previews/backdrop/bg-0-sky@3x.png b/packages/core/genres/platformer-assets-detailed/previews/backdrop/bg-0-sky@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..429846e8447c038ea7db31a2c51fe5f1835bd823 GIT binary patch literal 7425 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 L9S-LGioX0GPon-? literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/previews/backdrop/bg-1-far@3x.png b/packages/core/genres/platformer-assets-detailed/previews/backdrop/bg-1-far@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..8054642be5fe54e2692d401bb48ea7084f665234 GIT binary patch literal 6359 zcmeHLYgAKL7Cwo*d>a+ZOK^;%RjN=CP!Q+@mB)~Pfh72XjwGp7 z3#cScX)RR

n``5S6DO)E9wB2mvuQganNtz=dRjU2E1HbglmHB0uiAH#ujYy}$kK z{hi#eKi?C$aGuRP0KmeXfA{|a024X@=sXKE<2M$LIST=>V(;|#+m|68miYbKuEmX3F)MJXi3cF+TZ-RX1wap!oxAI8z_z&uUv_UD%$(V zf%dVKHa_w8?INR9dRg5V#yEl-bA6|W6!a3~)%OxGF%C=C0hDp5pZ#eTjahEYmcwjw znC*wN>hLEK#CN)1JwB}S5g5h?%%A@ST<$RWfALRvX>B|otatlK=a7$1ZryeB&ZXA_UMFg~r?1JK4HFU@2D&~MQMZwTlf zeq{wf0p;Ffd^79`*VZ_*&-}BdyZ?YHkV&6DpVY)?2MBBF#yik&vdVa+y9El312|mS zpW^%>N1Qp{G(<12GYpFc@rX)dzI-rQIO2$I@glaPgw!5+jZ zn!}#70)2M|b_KFmRDB;2Sdid}CcRLjgNEEjwE7_9kbps;905F74WT{I`TD8{~BM;niv1Dqj_6$Qo5YkY|sxosv?5cSyc zELjM=iA!wF$Sch)HBF%X`BUA|;cBuEwHy-&LSDF8T~iKbMTLw@P#mXg(Ys0n2~f%| zxyOAMQ;(slsF`bYYsWsBBb3ii+YIeqYj~r5)xwHdS;9F7-^?7 zy(MJ``7P~%T-2^pcB_9zTBinGQrd~J=Q+TwI>W8~jPnwedWy+}oVYlFtE7GoR4a4$-P|W14rThYHkfj&G8;wO~ zfTo`3v3Yga)SX6~7^*6mp00~65y&kK0`4|-@l@duZ8;1?(WaZRWf=BDubT?*hFUY< zmNQz~Q{r&bQJ7UP`Nskn1r=lI4A*;;@zp^qnonUwxZj)$I%XJ@qrx7S4iK2%08qIa_6bV>AkMg^jqr5YT-@9dZpc8I#; z+T{H4Yi^rYyD4}jWvS{K5{pmnle--=*{4e#{U$?Qsp3_{z)rfXT0+j;_pr)ollAjP zo}Aj9GjJA+v_VZv?q!iwpW^J+j#&dhNE}3oG&7T}gKkzrHc{UeJ(S;pZCZ!wn^7RQ z7vsm?jz8D=_@pYwn?)ncg!QoP z5v5C``*klZ8V=okdtZFxdD{@X%=CJ?gqzuznzRgYyj%~(PM%1T9mYNh*j6O7p}xqL zUuepf=p*M4lr#kaRN~I{EBsAfMZP;GzSK-VUu)R@euXKUuOUZr`Kx4{SF^M}bRsH_kjU?!vQS(mq-9G{pC_hpjN6q>G4x>3W?8 z$fNH%8Y#)Vl7vc*V?@2?wY5ON$}Pga!T14Se>*oaMg4#+vgPI$iyR=QdO8DzRAh=J zGZ)sY zC`VzR+ED9A!5`tw{{xyjB~u*D09$MyDLTcM}pE?W0n98new+yQMDE zjl?New@CB_q9#Ihs##vS&5CGJm=MKVTWv<7Y;1Bzx3m*K68;rNe1D)YBC1=ZcAWa!1v9$Z?^cybw@T)z!h1xj-2l9V zd)stcThB&=vLa>>x|2k-nbG{2bW?_n%-$8BScUzr=ABdUfrCje zZcbdCKiJ~b84&5i#SzykYxH5d5kVSU7362eP>&O>UGL!(;!^xs_Eo^IKp|B)T@F<} zB6uQL6c}|MuC^eQ=b1N==D@JKxMy8i*d%DW|3dWy%e~scw6QMI&$=s2#qKQC$qx`$>!>6;@6zm_qn@c zPT3KL=vc`EN~+0Hj%cP32Roo#erayE+YfZw1r?^?@?B_K`TA)w=6pA3v4+4nnec%C z6Z=c60tU_jFuIT5o4m0+bt7YfJu`{5cN16B)6ZveQB91F0qTif@k!Sen_&KPJyiu2G$UWDc<>@Ltn$#OCJ9_*vZ;OJm6>9OB^SW&F*P_Ehi{v)R zJ%thO;KhLX8KRh62eaplqrdFqJF^YSwDyEvbS3s?PoXpa_Q$ zB|}J!Hi6%-^HOAUhA9G(PSZS;^-?#bBn~J!vO4_~M@`eqee@pBE__}q4UKdOy)8`; z6of|0cM)Hf2esZ2X=x7)^5)kq-JQvZ2jVd_d7y4_?+}u8h=D^AG8)e=k*H%~G^n@Z zmydKB;-BUXw1rqN#!qEe=r56}($JbZyyxb=Y;s-2m_R-0@)q}8)GfMAF4G9)-JK@7 zYGld+?o8`lb~$>lk8Plx6im28rkqnL)rWE^O;dtSUhTxPGt9|al0Zt@Z_ZHaV4M%}kb+hsiX>12xmsn4%RS<_Q}!QzT3C9AJmBx7Sf> z%=3Yo5*1X`!b2)*CyP{4LJ|}z4|qaS1QG>i2{94!E8}?r7exB#P z?`N%Rhusf;wS4_@006#n`E~zM09c#|0E_;$bP0H8>5hwE0f6Z}m;L*W#d1Y`(9;`Z za`es)T5a>~XO!z-^!t{#@8RNyYwNnkzp?*U%UL_jum5f?tXN@~)W5X1@a$&8nCstd z#Dg;9Qbu0(F-5A3><-~Wr=gc!+(Z{waiixZoc;O#J@~L4MU@@PlqG zD!r9Ro}pzPbdov4B6!RiL4}W@LdKBifV6PYQt&66@_>&+FB-3Y!G!wEsVV7hm|p!k zRSwbMedGk6=Z_K46$80>X{N?5qM|m)=xu` z?w8=zw=nh^s|WMfp10NteDa$}3>_IrpoX0}?sf{My9&Iu*G}itU>*QoJ?6f)!@mD6kuqX zwWix}K8T-QbH|L=0@+ZXew0GIbxEEZRc59M5#3eajM=MD5!F1j3RQt+r^5*8_tcqmeye<8G*(X`mVJZ zdu%)QDEP^S`u_N!$QQpY0vdi|1)FO_Yj?XUzlacBVQonWf1)6+hYBbA@Ay0)y-!Hj z7>bw%0N_=nQf;M(lq)xuSBLvHojSMV*1X&VFkPGfwPh>!MZC} zXqp=1*)CuL8*k^)8POFHjO~3#b>>okl{@fhSn=&2773%Ktg2oF2oF=SH z1!DYa6mi?V{&>&&46gnXFg`iev6=T1()KS*L90tEpvG>UWb3a>I~JEi1WLAI4@G2a z&~gYN3WS+sj(!UOJ7Kxej$F7F1f^kmI}o%ac6Kv6y{eItx3n9Lkk z9K5>_^5NH_+!{|_j2J_pLzx_6^i*V0n3B9}a91aYmpcvsic2mOSP~_c{#ItCmJ1ho zc@^8-JM()%I3l~)b09Z{XW`s|H&n*+H850ogb~pE{H7>Cz2;}UR$Z=$ z8XB}$F4Hid9=KOxKsp9APupN7%N712ep~*+R|agV3Fmub1dTOL3bi8&?>##-efUFO2qf~AzmPsfwrsV`rph&FJj$MbZG7xL=b z0ba0x3Ie4}Re@D^;K<+5*uGk-|Al*8oU+K3BAT*%@6mFH1vRQC&Q-FGE|6#yVkB10J}dIPCj7qM@%wB8{N{X z*MoX9p@s3=jt0kIs1A_WnJsg$(8_~a;h0A<-mjWy^}SN*vA*%?V+asn!L*f|IQn7) zwYc_oU+!I4r_Db!#3+oD0gXq#%Q}$DNjgBAM~@6qeL1drgs^aqn|yn`rR?PJ)LF>; zWC*;5>>s|!@KaJaB-F3HyH%^ObnPWmdA}qgi>;$5ClBcYZYb7TFXz$fhytM

}79`4uMx@%<^?eZVQ80u?f}q;S@~; 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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/previews/backdrop/bg-3-near@3x.png b/packages/core/genres/platformer-assets-detailed/previews/backdrop/bg-3-near@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..29b4d178d1515cada611c6ae57ff18222ab70370 GIT binary patch literal 13780 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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/previews/foreground/fg-jungle@3x.png b/packages/core/genres/platformer-assets-detailed/previews/foreground/fg-jungle@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..b4568b9bc10f4282112f43ac5f0c1ec20d27a455 GIT binary patch literal 5955 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 literal 0 HcmV?d00001 From 4b2360a6783db9b60a40c2751987c2e0702d2e5f Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Nov 2026 03:54:27 +0000 Subject: [PATCH 6/9] Add the detailed set's player as a posed puppet The first set's player was stiff because each frame was typed by hand. Here limbs are capsules posed by joint angles, so lengths hold from frame to frame and each animation is its key poses: an 8-frame run with arm swing, a jump distinct from the fall, a flat dash, a wall slide, and a squash on landing. The ponytail lags a frame for secondary motion, and the backpack's cell shows whether a dash is ready. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01HendNaZcTpUubQBWodQy33 --- .../art/player/player-idle.png | Bin 0 -> 1107 bytes .../art/player/player-spent.png | Bin 0 -> 17610 bytes .../art/player/player.json | 511 ++++++++++++++++++ .../art/player/player.png | Bin 0 -> 17722 bytes .../previews/player/player-animations@3x.gif | Bin 0 -> 178279 bytes .../previews/player/player@4x.png | Bin 0 -> 33451 bytes 6 files changed, 511 insertions(+) create mode 100644 packages/core/genres/platformer-assets-detailed/art/player/player-idle.png create mode 100644 packages/core/genres/platformer-assets-detailed/art/player/player-spent.png create mode 100644 packages/core/genres/platformer-assets-detailed/art/player/player.json create mode 100644 packages/core/genres/platformer-assets-detailed/art/player/player.png create mode 100644 packages/core/genres/platformer-assets-detailed/previews/player/player-animations@3x.gif create mode 100644 packages/core/genres/platformer-assets-detailed/previews/player/player@4x.png diff --git a/packages/core/genres/platformer-assets-detailed/art/player/player-idle.png b/packages/core/genres/platformer-assets-detailed/art/player/player-idle.png new file mode 100644 index 0000000000000000000000000000000000000000..2a940c93555d97d4eda6a35541656d6bc043f1ac GIT binary patch literal 1107 zcmV-Z1g!gsP)O;#9y_Pi2VOA!VU z#J8GkD$>q^km|h#Pnu?)xavi%W{do-%S?kOjcPI#^6s7cRPSy6_&H5Q7_Wu=;_c$z zxsMOBEBL$WEC9`Yzhf_-WMU*=KQRy`KRRxr{lcaBeIHirPtKl#zR2^l?s@?1<&zvC zp9aLogE3k1TTM1b$HNKjW$(PG+W!;eV=tdXmszO)LOO71NxS|1j+l_Anj=CycHsij zlKuNNSz(+7A-0$Pbw%Wr@%B$RQu-iMgk-FrKE=%qIqU`~1G)K@3szVm<6r3kaFtEcPx0b!}skW3IC zH0LQE*uA$?W&iZG=Xs@ZBaii8RFglvnaAr}0qFI42}nVqbs(w5tY(Wm@opv=TS|D~ z(INnf9ZtIY-2l{vN9av2$K3n^08&RAwc!x}23w9Ib+i#U*=a~=3}oDT^OCmjoNuef z*@vH?H@%#}mZM60k@6r0z!Uq4Klw&edZ4-HG+OL%#+Ua#|FQ{4x|O&%^yB=KBO!U! z;)8km@<2ce8tl)^#m#T2DT@XAElmV|I0&HH_gaZb+5-_078!ad-lq0Ilz1XYJ1T{z z(5vo7qeQy*x5)rG*(M5da}@h{)*Y(9K5D#^&&_!}C1vM2R zR6v!>q1s9>KYbt4pELA$eVU0dYO$#2%y~)+uZv`!_jUkK*Yvt3bwH>G&P+}(X>*l1 z^uL7)^H;@fBi(nSsm6+c%LOukXUwf{0amj`zW1)R|8EZr42>}`G#0sXnNOb!F?;+A ze)-i;(Hfgvw8kd%YEeipl#^{@Q%NjM_IQ1mb8~p({=$Uci0p}k6tacnqgY6OaTVTF z;-Cj)5h8>LICd`npmMp^p~ow(P8gRn;G)E5W<$c-3SlvDC778Fsg9(&5D*oS%vo9_ Z{sn5>e%Jb8fwTYs002ovPDHLkV1hW+8OHzs literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/player/player-spent.png b/packages/core/genres/platformer-assets-detailed/art/player/player-spent.png new file mode 100644 index 0000000000000000000000000000000000000000..f197285befc2aac2b8f3ac22bee390818bf00a26 GIT binary patch literal 17610 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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/player/player.json b/packages/core/genres/platformer-assets-detailed/art/player/player.json new file mode 100644 index 00000000..9e873d59 --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/art/player/player.json @@ -0,0 +1,511 @@ +{ + "frames": { + "idle 0": { + "frame": { + "x": 0, + "y": 0, + "w": 48, + "h": 48 + }, + "duration": 160, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "idle 1": { + "frame": { + "x": 48, + "y": 0, + "w": 48, + "h": 48 + }, + "duration": 160, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "idle 2": { + "frame": { + "x": 96, + "y": 0, + "w": 48, + "h": 48 + }, + "duration": 160, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "idle 3": { + "frame": { + "x": 144, + "y": 0, + "w": 48, + "h": 48 + }, + "duration": 160, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "idle 4": { + "frame": { + "x": 192, + "y": 0, + "w": 48, + "h": 48 + }, + "duration": 160, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "idle 5": { + "frame": { + "x": 240, + "y": 0, + "w": 48, + "h": 48 + }, + "duration": 160, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "run 0": { + "frame": { + "x": 0, + "y": 48, + "w": 48, + "h": 48 + }, + "duration": 70, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "run 1": { + "frame": { + "x": 48, + "y": 48, + "w": 48, + "h": 48 + }, + "duration": 70, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "run 2": { + "frame": { + "x": 96, + "y": 48, + "w": 48, + "h": 48 + }, + "duration": 70, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "run 3": { + "frame": { + "x": 144, + "y": 48, + "w": 48, + "h": 48 + }, + "duration": 70, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "run 4": { + "frame": { + "x": 192, + "y": 48, + "w": 48, + "h": 48 + }, + "duration": 70, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "run 5": { + "frame": { + "x": 240, + "y": 48, + "w": 48, + "h": 48 + }, + "duration": 70, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "run 6": { + "frame": { + "x": 288, + "y": 48, + "w": 48, + "h": 48 + }, + "duration": 70, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "run 7": { + "frame": { + "x": 336, + "y": 48, + "w": 48, + "h": 48 + }, + "duration": 70, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "jump 0": { + "frame": { + "x": 0, + "y": 96, + "w": 48, + "h": 48 + }, + "duration": 80, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "jump 1": { + "frame": { + "x": 48, + "y": 96, + "w": 48, + "h": 48 + }, + "duration": 80, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "jump 2": { + "frame": { + "x": 96, + "y": 96, + "w": 48, + "h": 48 + }, + "duration": 80, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "fall 0": { + "frame": { + "x": 0, + "y": 144, + "w": 48, + "h": 48 + }, + "duration": 110, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "fall 1": { + "frame": { + "x": 48, + "y": 144, + "w": 48, + "h": 48 + }, + "duration": 110, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "dash 0": { + "frame": { + "x": 0, + "y": 192, + "w": 48, + "h": 48 + }, + "duration": 50, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "dash 1": { + "frame": { + "x": 48, + "y": 192, + "w": 48, + "h": 48 + }, + "duration": 50, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "dash 2": { + "frame": { + "x": 96, + "y": 192, + "w": 48, + "h": 48 + }, + "duration": 50, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "wall-slide 0": { + "frame": { + "x": 0, + "y": 240, + "w": 48, + "h": 48 + }, + "duration": 120, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "wall-slide 1": { + "frame": { + "x": 48, + "y": 240, + "w": 48, + "h": 48 + }, + "duration": 120, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "land 0": { + "frame": { + "x": 0, + "y": 288, + "w": 48, + "h": 48 + }, + "duration": 70, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "land 1": { + "frame": { + "x": 48, + "y": 288, + "w": 48, + "h": 48 + }, + "duration": 70, + "anchor": { + "x": 0.5, + "y": 1 + } + } + }, + "animations": { + "idle": [ + "idle 0", + "idle 1", + "idle 2", + "idle 3", + "idle 4", + "idle 5" + ], + "run": [ + "run 0", + "run 1", + "run 2", + "run 3", + "run 4", + "run 5", + "run 6", + "run 7" + ], + "jump": [ + "jump 0", + "jump 1", + "jump 2" + ], + "fall": [ + "fall 0", + "fall 1" + ], + "dash": [ + "dash 0", + "dash 1", + "dash 2" + ], + "wall-slide": [ + "wall-slide 0", + "wall-slide 1" + ], + "land": [ + "land 0", + "land 1" + ] + }, + "timing": { + "idle": { + "frames": [ + "idle 0", + "idle 1", + "idle 2", + "idle 3", + "idle 4", + "idle 5" + ], + "msPerFrame": 160, + "loop": true + }, + "run": { + "frames": [ + "run 0", + "run 1", + "run 2", + "run 3", + "run 4", + "run 5", + "run 6", + "run 7" + ], + "msPerFrame": 70, + "loop": true + }, + "jump": { + "frames": [ + "jump 0", + "jump 1", + "jump 2" + ], + "msPerFrame": 80, + "loop": false + }, + "fall": { + "frames": [ + "fall 0", + "fall 1" + ], + "msPerFrame": 110, + "loop": true + }, + "dash": { + "frames": [ + "dash 0", + "dash 1", + "dash 2" + ], + "msPerFrame": 50, + "loop": false + }, + "wall-slide": { + "frames": [ + "wall-slide 0", + "wall-slide 1" + ], + "msPerFrame": 120, + "loop": true + }, + "land": { + "frames": [ + "land 0", + "land 1" + ], + "msPerFrame": 70, + "loop": false + } + }, + "meta": { + "image": "player.png", + "size": { + "w": 384, + "h": 336 + }, + "frameSize": { + "w": 48, + "h": 48 + }, + "scale": "1", + "about": "Soles on row 46, outline on row 47; the anchor is the middle of the bottom row. Hitbox 12x34 from x 17..28, y 13..46. Faces right; flip for left. The wall-slide frames press a wall whose first column is x 29, just right of the hitbox. player-spent.png is the same sheet with the dash spent.", + "frameTags": [ + { + "name": "idle", + "from": 0, + "to": 5, + "direction": "forward" + }, + { + "name": "run", + "from": 6, + "to": 13, + "direction": "forward" + }, + { + "name": "jump", + "from": 14, + "to": 16, + "direction": "forward" + }, + { + "name": "fall", + "from": 17, + "to": 18, + "direction": "forward" + }, + { + "name": "dash", + "from": 19, + "to": 21, + "direction": "forward" + }, + { + "name": "wall-slide", + "from": 22, + "to": 23, + "direction": "forward" + }, + { + "name": "land", + "from": 24, + "to": 25, + "direction": "forward" + } + ] + } +} diff --git a/packages/core/genres/platformer-assets-detailed/art/player/player.png b/packages/core/genres/platformer-assets-detailed/art/player/player.png new file mode 100644 index 0000000000000000000000000000000000000000..5f4f748f4e3d13998dd3c0d0804103afced58cf6 GIT binary patch literal 17722 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

wkJ(6bP}zdFfxb9l*kXk_`XKGx9^b zUJX*jRL>{`UZ*G)6VR93!$EA-x};RzM2SeGG-1cFhhm8F2V|cUcCX@8;2bl_MAU_K z`CCh*IOG}NaMhoc7W>@GWD6y{H9Wk@7JNSaWAy)|1$kUx0ojrRb3)SRKSn)oh-6|~ zf4)n)KKA1mT2|#NGJd){{s9odxK3vr2`3=Mfk^<9`fU|sMDjY;t9HG=@mZb6 z2n#x0N^KNeg&neKO;Dk)K$r*GBg^I`w4lx}l ztxuvV-_PB+^Y!<=O6Hzl7a{NzHZ6>Vqaew#asN9_+Eom%P21gAb*WD9sTLbfzVQ?} z`^|LFzkmb_m_@`#Y=T-nx>OG-|%Y8~rgKf-S(@PE)3pLsMb;aLjjne3&=u^Hx)vEi=Iy8h4 znt+Mv)R9Q4rG2#t0L#3;9^G--G}yGJz<1!2`Bre!wFSkP*$(!oWoPrQIk4kGW}q@E zuwxA)Q^tYJb8_B1d0ctJHngxUNfTIqp3ZmV?zFW3Rq z4jjA`l>WZ8mfJ*Ff4^0{mfgX}Uzi$Am2siybwDZHV-Eh?h7j&Gj}84Z1S6;?A=l!$ z&@y*6kTi3FCS21G(i{u|j&r+^Hc(dh=Rq{o74uU#P;h%1W4uQ}Bwy=|;UPe6Tvglh zGVdH1z=mRg(*mk`vGhz^yD8CQltu^wdbBDX3^49jAdLT^UXH0-8k|X>e18ZwDLJ{@ zb2#M&tO{j7CqQowC|uV9Is!&&VD55%BK@E~Rp`qKPALc){YuSFNkys5NGn6%;k z_5pS)Mb!5km{dS@Vq)L?M(#DBtO!97Kbe3D`PXdY3T;I#&=oK!49Ve)i?RA!utvw9 zmDYRJ5qra^Z~cxTgfQ*2!a|J}&uS_q_(7+0-|EH_b>M=)Cl$fkGiG|v;E4bBNy0wn zrBy`qeyYd$tK_x281n$;XBmlGfA-n~Q*OR@YrR)OsOJDdJ%!V-$!c#Z4Dx<5%(8@O z$F}AFigV$=fc+=+1oS0Xr`lR{@H(X>TAe-+sJPfJVqi(4Tl_Q~28haN46Ziju|byC zHhwnnVc6Ncfhp;jp?drGM$ZI|Y;6o74fXtMMSZ5u84xe14{nEvydxRKV?OjH1WURC zwI>%$pGu;BeSGpL2yj)_D%uHwVjaLMyf)8K^2-BkVo^e|C1GE?s5wrc5GPLLgmbsD z_0zapWh~OdsO#nCW2BHrsbfF}P|PHPf@^GnrwxPS;+qbK=wOL literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/previews/player/player-animations@3x.gif b/packages/core/genres/platformer-assets-detailed/previews/player/player-animations@3x.gif new file mode 100644 index 0000000000000000000000000000000000000000..91d8747764703dd6e3f07ca50599477ffca90728 GIT binary patch literal 178279 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

{v%-u|iW^y$F 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�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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/previews/player/player@4x.png b/packages/core/genres/platformer-assets-detailed/previews/player/player@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..3fdc2d2dac39be41b61acd3c21c51fbb477df465 GIT binary patch literal 33451 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%0Ab&332IS4$i&h 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 Date: Sun, 1 Nov 2026 03:54:27 +0000 Subject: [PATCH 7/9] Add the detailed set's props and effects The cog, spring, beacon, and scrap beetle are drawn in make.py with the player's outline rule; dash, dust, and collect are fx drafts checked and rendered by ritmo-tools fx against the new player as stand-in. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01HendNaZcTpUubQBWodQy33 --- .../art/fx/collect.gif | Bin 0 -> 6177 bytes .../art/fx/collect.json | 345 ++++++++++++++++++ .../art/fx/collect.png | Bin 0 -> 2368 bytes .../art/fx/dash.gif | Bin 0 -> 4056 bytes .../art/fx/dash.json | 241 ++++++++++++ .../art/fx/dash.png | Bin 0 -> 1031 bytes .../art/fx/dust.gif | Bin 0 -> 2885 bytes .../art/fx/dust.json | 241 ++++++++++++ .../art/fx/dust.png | Bin 0 -> 1297 bytes .../art/props/beacon.json | 59 +++ .../art/props/beacon.png | Bin 0 -> 631 bytes .../art/props/cog.json | 129 +++++++ .../art/props/cog.png | Bin 0 -> 1095 bytes .../art/props/enemy.json | 73 ++++ .../art/props/enemy.png | Bin 0 -> 738 bytes .../art/props/spring.json | 59 +++ .../art/props/spring.png | Bin 0 -> 416 bytes .../fx/detailed.fx.json | 148 ++++++++ .../fx/drafts/collect.a.js | 30 ++ .../fx/drafts/dash.a.js | 28 ++ .../fx/drafts/dash.b.js | 31 ++ .../fx/drafts/dust.a.js | 27 ++ .../fx/drafts/dust.b.js | 28 ++ .../previews/fx/collect@4x.png | Bin 0 -> 3219 bytes .../previews/fx/dash@4x.png | Bin 0 -> 2299 bytes .../previews/fx/dust@4x.png | Bin 0 -> 1233 bytes .../previews/props/props@6x.png | Bin 0 -> 7612 bytes 27 files changed, 1439 insertions(+) create mode 100644 packages/core/genres/platformer-assets-detailed/art/fx/collect.gif create mode 100644 packages/core/genres/platformer-assets-detailed/art/fx/collect.json create mode 100644 packages/core/genres/platformer-assets-detailed/art/fx/collect.png create mode 100644 packages/core/genres/platformer-assets-detailed/art/fx/dash.gif create mode 100644 packages/core/genres/platformer-assets-detailed/art/fx/dash.json create mode 100644 packages/core/genres/platformer-assets-detailed/art/fx/dash.png create mode 100644 packages/core/genres/platformer-assets-detailed/art/fx/dust.gif create mode 100644 packages/core/genres/platformer-assets-detailed/art/fx/dust.json create mode 100644 packages/core/genres/platformer-assets-detailed/art/fx/dust.png create mode 100644 packages/core/genres/platformer-assets-detailed/art/props/beacon.json create mode 100644 packages/core/genres/platformer-assets-detailed/art/props/beacon.png create mode 100644 packages/core/genres/platformer-assets-detailed/art/props/cog.json create mode 100644 packages/core/genres/platformer-assets-detailed/art/props/cog.png create mode 100644 packages/core/genres/platformer-assets-detailed/art/props/enemy.json create mode 100644 packages/core/genres/platformer-assets-detailed/art/props/enemy.png create mode 100644 packages/core/genres/platformer-assets-detailed/art/props/spring.json create mode 100644 packages/core/genres/platformer-assets-detailed/art/props/spring.png create mode 100644 packages/core/genres/platformer-assets-detailed/fx/detailed.fx.json create mode 100644 packages/core/genres/platformer-assets-detailed/fx/drafts/collect.a.js create mode 100644 packages/core/genres/platformer-assets-detailed/fx/drafts/dash.a.js create mode 100644 packages/core/genres/platformer-assets-detailed/fx/drafts/dash.b.js create mode 100644 packages/core/genres/platformer-assets-detailed/fx/drafts/dust.a.js create mode 100644 packages/core/genres/platformer-assets-detailed/fx/drafts/dust.b.js create mode 100644 packages/core/genres/platformer-assets-detailed/previews/fx/collect@4x.png create mode 100644 packages/core/genres/platformer-assets-detailed/previews/fx/dash@4x.png create mode 100644 packages/core/genres/platformer-assets-detailed/previews/fx/dust@4x.png create mode 100644 packages/core/genres/platformer-assets-detailed/previews/props/props@6x.png diff --git a/packages/core/genres/platformer-assets-detailed/art/fx/collect.gif b/packages/core/genres/platformer-assets-detailed/art/fx/collect.gif new file mode 100644 index 0000000000000000000000000000000000000000..98199e219c4cb7b916ed2cf12a125fddba776937 GIT binary patch literal 6177 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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/fx/collect.json b/packages/core/genres/platformer-assets-detailed/art/fx/collect.json new file mode 100644 index 00000000..b3c90717 --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/art/fx/collect.json @@ -0,0 +1,345 @@ +{ + "frames": { + "collect 0": { + "frame": { + "x": 0, + "y": 0, + "w": 40, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 40 + }, + "sourceSize": { + "w": 40, + "h": 40 + }, + "duration": 42, + "anchor": { + "x": 0.5125, + "y": 0.525 + } + }, + "collect 1": { + "frame": { + "x": 40, + "y": 0, + "w": 40, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 40 + }, + "sourceSize": { + "w": 40, + "h": 40 + }, + "duration": 42, + "anchor": { + "x": 0.5125, + "y": 0.525 + } + }, + "collect 2": { + "frame": { + "x": 80, + "y": 0, + "w": 40, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 40 + }, + "sourceSize": { + "w": 40, + "h": 40 + }, + "duration": 42, + "anchor": { + "x": 0.5125, + "y": 0.525 + } + }, + "collect 3": { + "frame": { + "x": 120, + "y": 0, + "w": 40, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 40 + }, + "sourceSize": { + "w": 40, + "h": 40 + }, + "duration": 42, + "anchor": { + "x": 0.5125, + "y": 0.525 + } + }, + "collect 4": { + "frame": { + "x": 160, + "y": 0, + "w": 40, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 40 + }, + "sourceSize": { + "w": 40, + "h": 40 + }, + "duration": 42, + "anchor": { + "x": 0.5125, + "y": 0.525 + } + }, + "collect 5": { + "frame": { + "x": 200, + "y": 0, + "w": 40, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 40 + }, + "sourceSize": { + "w": 40, + "h": 40 + }, + "duration": 42, + "anchor": { + "x": 0.5125, + "y": 0.525 + } + }, + "collect 6": { + "frame": { + "x": 240, + "y": 0, + "w": 40, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 40 + }, + "sourceSize": { + "w": 40, + "h": 40 + }, + "duration": 42, + "anchor": { + "x": 0.5125, + "y": 0.525 + } + }, + "collect 7": { + "frame": { + "x": 280, + "y": 0, + "w": 40, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 40 + }, + "sourceSize": { + "w": 40, + "h": 40 + }, + "duration": 42, + "anchor": { + "x": 0.5125, + "y": 0.525 + } + }, + "collect 8": { + "frame": { + "x": 320, + "y": 0, + "w": 40, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 40 + }, + "sourceSize": { + "w": 40, + "h": 40 + }, + "duration": 42, + "anchor": { + "x": 0.5125, + "y": 0.525 + } + }, + "collect 9": { + "frame": { + "x": 360, + "y": 0, + "w": 40, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 40 + }, + "sourceSize": { + "w": 40, + "h": 40 + }, + "duration": 42, + "anchor": { + "x": 0.5125, + "y": 0.525 + } + }, + "collect 10": { + "frame": { + "x": 400, + "y": 0, + "w": 40, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 40 + }, + "sourceSize": { + "w": 40, + "h": 40 + }, + "duration": 42, + "anchor": { + "x": 0.5125, + "y": 0.525 + } + }, + "collect 11": { + "frame": { + "x": 440, + "y": 0, + "w": 40, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 40 + }, + "sourceSize": { + "w": 40, + "h": 40 + }, + "duration": 42, + "anchor": { + "x": 0.5125, + "y": 0.525 + } + } + }, + "animations": { + "collect": [ + "collect 0", + "collect 1", + "collect 2", + "collect 3", + "collect 4", + "collect 5", + "collect 6", + "collect 7", + "collect 8", + "collect 9", + "collect 10", + "collect 11" + ] + }, + "meta": { + "app": "https://ritmo.typeonce.dev/tools/pixel/", + "version": "1", + "image": "collect.png", + "format": "RGBA8888", + "size": { + "w": 480, + "h": 40 + }, + "scale": "1", + "frameTags": [ + { + "name": "collect", + "from": 0, + "to": 11, + "direction": "forward" + } + ], + "fps": { + "collect": 24 + }, + "loop": { + "collect": false + } + } +} diff --git a/packages/core/genres/platformer-assets-detailed/art/fx/collect.png b/packages/core/genres/platformer-assets-detailed/art/fx/collect.png new file mode 100644 index 0000000000000000000000000000000000000000..59c8ed75938ab0008cd411a9fb6a73631c64c939 GIT binary patch literal 2368 zcmbtWZCF$18BX|!fdIln&9Q)hD8Y6nLG6`PuqKcYbrcW~+7W^YRySRdFM**g1QQJy zp;W8U_9`J#Dt;jL!vX~g$CP%%Zp2olovVFfQhH-o|O-MU4d%3v^uaU8{F;XjgCGs|FjE!irUrI#^(?vw2uS9N+0 zc3)q+e1m7{%J0~-KEpHeq#w>y@h#%_Z+gTUJ}DB6-D1>+`!*KGdg^A}KDX7CwWr>x z(0)~N@~13LKap#Se(JBsmn4cZUa#jI+;t$H$bEAaP786m0wS^jGhFBkcKWnAw`&>+TupukY zxPE*feW*S?Mfy>{1s&*146(Y6b2Y>Snb=MfuF ztdqn+y|9Zx4)?(B`3DUPaj6GvehOiyG*Oz<3@%0dhxy%uzf7GKohUXey~(by1iVzO z&NGw_4qVO;cR>kpx<#i>lgqz36@+CC?id|%Y-C<)=ZLGUJXVeRmDo5tN9i0$mq=af zX|Zz`0%Fk9QElPa>OblXXMq+aLLHy1TlgikD}iTBz70*cT&Oj-^&}d+4z{b=G5>71 zW7BU^3H6~9-k}!ek1}_a8Hn5=h-AG&XmX(mat&UuXBKHh$dY<1Z&_W+G^vBo(L=5G zNiXE4iK2a&TD?->KOO@l3`!w6&&aP5_{TWi9{veG`Jkt^3dBZU5~gXOUbJlK9gZe{ zp(`?SVx&BLqP;@R-8}S6Z4=Ya!W77%SHN`P^D0JmSOUHC{a9i3*& zzG9u3(J5636a6VIZuC*%C+7e7a^leSnKxQok13JEaWrLG*GL983Dc08L{VJk?3(x4zh0r^YqvSwuJ&BdSyV(1 zdf!;mDMikCWQW}@1y?p)vO>V^P=otUddLZ|Gd5D*cy!#bv*+aVj|0VSw@Z7Ei(V+! zQS0gi{@i$;F%!t3m&VkGeEs)d_i3#wT6yJ2nfsenBm9nlW>B9~Ni$|!Q{G2RwP43x zkPlDvnM;u#Mpqta$-wTmGQE`-nPlhmn?pyvmBS2t_w?s{QN48d%01iiHRU6ynS2c` zaRlH8)A04Umw;dx`-q}-nIazK;#xU2uO~9Wz^?YVXNUdxd$`|W*h6r5%SJ8yYm%i9 zPT=V;;F?t4mmP)e$WSxYbeT|YOj%Jftz^IXL_1k8>19fK4U>2FJJ^qB-fc&!1ViNp zJ%~X?QmRcFUz5b3G@uJ z@QN@Ej%*ICn+->Cb&=2^+3GZe6zj?qb`DClAb|o(d5`qT0cApqmV47h=Azl5RXO%k z7U^JvO0*RtH*L|?&mp_00(dcoJoKzW*u~8b6YPXM=fFhQw{)|RG{T3rqpB#kHKA&2 zX=|07putyD;`ef8Ja%qRr7NUOEd77lmV`?gGLb8&745D=PwD#h4;|rup-58#NDP2X zAX6kd0N4)psy|T(Ofb_o&-Wyvb~HD{a$@QT=1oxDl0$ddt4b(Xi)P2&cT6=@k0#fI z`61|*yFYrgZb#|?eY7&nG*<-*{Z6Kb6eQ4Oxqs@4Zkn^ue4SZ^w}MunsY5i*-ean= z)fa=bb%>S;6s9>Qs<4x?$Uu$h#SUC{e{J#I!{@12k*8l&iZ(8=emfdQx;=ik8E;06 Nt%@XhYuwJN{{n#ZCz${M literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/fx/dash.gif b/packages/core/genres/platformer-assets-detailed/art/fx/dash.gif new file mode 100644 index 0000000000000000000000000000000000000000..b0bbbec9b09f6d0363626102a4f853f302769327 GIT binary patch literal 4056 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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/fx/dash.json b/packages/core/genres/platformer-assets-detailed/art/fx/dash.json new file mode 100644 index 00000000..0dd77bde --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/art/fx/dash.json @@ -0,0 +1,241 @@ +{ + "frames": { + "dash 0": { + "frame": { + "x": 0, + "y": 0, + "w": 56, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 56, + "h": 40 + }, + "sourceSize": { + "w": 56, + "h": 40 + }, + "duration": 33, + "anchor": { + "x": 0.7232, + "y": 0.525 + } + }, + "dash 1": { + "frame": { + "x": 56, + "y": 0, + "w": 56, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 56, + "h": 40 + }, + "sourceSize": { + "w": 56, + "h": 40 + }, + "duration": 33, + "anchor": { + "x": 0.7232, + "y": 0.525 + } + }, + "dash 2": { + "frame": { + "x": 112, + "y": 0, + "w": 56, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 56, + "h": 40 + }, + "sourceSize": { + "w": 56, + "h": 40 + }, + "duration": 33, + "anchor": { + "x": 0.7232, + "y": 0.525 + } + }, + "dash 3": { + "frame": { + "x": 168, + "y": 0, + "w": 56, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 56, + "h": 40 + }, + "sourceSize": { + "w": 56, + "h": 40 + }, + "duration": 33, + "anchor": { + "x": 0.7232, + "y": 0.525 + } + }, + "dash 4": { + "frame": { + "x": 224, + "y": 0, + "w": 56, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 56, + "h": 40 + }, + "sourceSize": { + "w": 56, + "h": 40 + }, + "duration": 33, + "anchor": { + "x": 0.7232, + "y": 0.525 + } + }, + "dash 5": { + "frame": { + "x": 280, + "y": 0, + "w": 56, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 56, + "h": 40 + }, + "sourceSize": { + "w": 56, + "h": 40 + }, + "duration": 33, + "anchor": { + "x": 0.7232, + "y": 0.525 + } + }, + "dash 6": { + "frame": { + "x": 336, + "y": 0, + "w": 56, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 56, + "h": 40 + }, + "sourceSize": { + "w": 56, + "h": 40 + }, + "duration": 33, + "anchor": { + "x": 0.7232, + "y": 0.525 + } + }, + "dash 7": { + "frame": { + "x": 392, + "y": 0, + "w": 56, + "h": 40 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 56, + "h": 40 + }, + "sourceSize": { + "w": 56, + "h": 40 + }, + "duration": 33, + "anchor": { + "x": 0.7232, + "y": 0.525 + } + } + }, + "animations": { + "dash": [ + "dash 0", + "dash 1", + "dash 2", + "dash 3", + "dash 4", + "dash 5", + "dash 6", + "dash 7" + ] + }, + "meta": { + "app": "https://ritmo.typeonce.dev/tools/pixel/", + "version": "1", + "image": "dash.png", + "format": "RGBA8888", + "size": { + "w": 448, + "h": 40 + }, + "scale": "1", + "frameTags": [ + { + "name": "dash", + "from": 0, + "to": 7, + "direction": "forward" + } + ], + "fps": { + "dash": 30 + }, + "loop": { + "dash": false + } + } +} diff --git a/packages/core/genres/platformer-assets-detailed/art/fx/dash.png b/packages/core/genres/platformer-assets-detailed/art/fx/dash.png new file mode 100644 index 0000000000000000000000000000000000000000..2515fc2df6fe5c02bbd53a5df7dba6462aec6065 GIT binary patch literal 1031 zcmeAS@N?(olHy`uVBq!ia0y~yU_1b1YjCgu$xK%*4F(40bDl1aAr*{o4;tnz@sMbH zxIHGWD9I^h!ZjBaZ6Onx!|6Ay^X4vU?&R2cWXr#`PO%*u_b7XB{^oH0yG;i{a6^2m}eZnwPWS3)-!FBmb{QQTf6a7;~7_(8#dS6 zLQ1(ic~w0xny-mUe#+e0ZLzR&P49|VVmTU`zu2Of69(UURixy_WDTnx3}FBYf5)K ze;^JYwEJJ-Oleq~{Ob7)ky=2vpCG zh$5hOfl&ksKA96hO}xcrD_m!y_fX z47qIORl8WFy+A?-*oDLk)t_zLwkmqV!X*`zO!5VSpEPBFeys+ELBe_0Idfvw9*cgL zk=cI$ZUZR2Ky7dU+K{&@PjTZy70q95q1kI{6bc2|&HJ|shTe5bat0?CaN6)Zo1E(s zx;+6TbV2GzL-!8h&k@mAb^m<)9{=IF{SJ6zO9z87#bgMvRckS;aU~>Mmgx$r(rOugu&e`yGg4qnJ-~{Ji?jN0oWxjnnGl3bL N!PC{xWt~$(698)5>5c#Z literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/fx/dust.gif b/packages/core/genres/platformer-assets-detailed/art/fx/dust.gif new file mode 100644 index 0000000000000000000000000000000000000000..85d3f7fd71225fa58b58f99246046cd76d29cfdd GIT binary patch literal 2885 zcmchZX*?9_9>;aGQm1aI?uly5P)L>#L&ptSa}nwgZKB1Vt#VMZFGZAX7R!t=W--jd zET&<`HfF{cW8aOP>{95HqkHb>e(sC&_Vm1co;T0;_xt?+UrTEX1Ms~XsmoHIE=kE9 zIuZ*Rqp>zeC$_$=)aZasY@9v(LSLt35=b;r@9@ml*4AMFK*`Yv^w91?tfysU+%3ZE zjDEV{v*bj$v0QECPs`<%Rc0NQ?Tw$yDQHhUN4CEXe>_| zYr~i->9}bdym54-hk8#_5F4FTIbBZ`_d2EgK|p6C>T93TapmCS=g9!IA!E>nx6C?1 zeyhV|>+5ADpzdWIr{{(*t8E}t-oaA;cNDi|?aZB>%uF22FKB2<@7TUlT;I8Gm((RG z_3zKVe^YAr)@690mHLUaCS(xT*D${o9b$vON$AFf@#ex=!{yIxH6X$%a=5^sF|e5sBSE^KbSjD8gp8yBCDn3SB7`ua^;`rC}mcki>Zb8_<_P#8SFps)ymEJl@} z?*g$nJhn8Yj0h}GCY4c=s_--yJgBCYUE^NGX#_EySWWDDlAxve8ehb9Yv}9}+joeB z#NNJs>p@AIW6vaK%yMFO)L~|^Zq9sR)_G-h?K5t53T-0oLKrZ9wj72B?oI6?$E?#; zM33IakN^lN5d-;>L-t&Cxp_vN1^?9~cDW zDxbEKDDq!#`83?O5)uShZy&TRuZ0W%$WN+P)d7@*#8aCg>{kN7=bCy@; zI@J7+5>Fn^zR^o}pIk=I$_BVH{mx>NWxtdTYevY*yQbund%OseXGFRuXnPrDX^Ocx z*PkbUHTl6A0Jk$J0+pakOP(PyWuU@hA_0R#kV`9wcq;a3HIvRjG0Rz1^-xYteOVx1 zK+EPei6{ZBoef#-b-id|$57w<0pRFxw`AzuL{FzLXX-=7{A}+MV`VITZE$q`fxu@n z;7*O>?z8Jg`irTwNaV&*-$xT8)ro1x&fvNaNK}&6E@o9E{)|AxEjZ^YfGfJR(p4aM zB}7FxFI8nrlm|wkcz14TMM@;97E^WwGQk=~==PJfC}NIj@mk1CquveJ8G)LOT9;!^ zUfX(aXl6Iq(_F>LFzaJ4)Q|PbG$hQwh#q!uMBw&F^A2<1n*^yweM@7wY(-L%LGL*Rq z!q1P%Rvk=ZMedl}@BEts0QX|w=J|JB4kKo<(EWC)*RM&=CH`{K?rX^ssKFk1Ji~Un z#r=w*Jb3WFYm1jvinc27ckmtsJx^!l;BVE_qVCpfCihRBHy4lDIa=#$yq*d9XKNVv zPA!kFcdk9)HY5DsyRv+GDm+DT*DE_)YdjtdOvFGkH4GT?OU6!mrN{4FjoNaQQFl2! z!cIJL?!U}ISK+p_piICI0slzx&w=v}3Pb?&VG*cOjA9`KS&T(vNl<(qfkY&eD;22~ zPZy5{xMdkfgZDRQD2bf)W7y!0f4ptex3x6< zM0@ub485Lq8*iO3i%fb}ZS#{n-;40aUmj{cMH3&xA9GTM}J#4s}tFoK2$T(<<(Q$SHILCiJMkj zUgqDQUn%~ww6VWu^Qr%7TIj^y53@HkVeGion#CAPt-G9ngPUH&r-wW=qZK-ylU1}m z@j?6d@YDOpfm8a07XOO34qrXwRIHr8 zY^rwjwX>Tz<0exkR3yf`-%{HMKcj9oj;`aA%Hwco+5lZ1v4l# zzo4iP2|=MtF#sGshOnJLRX(0VsPJa6u+%DgO)cEFp2g;%xiFefOC_(hsEz5>)|C&< z>1!|X=xsp_WDm7_j&jE#gJZ)Z_h#$o@)kZW&8*IT>0JY?Er}-%!oW|Y_rcxvINW7> z?izV+Xs|G%>2XZ@4VNm5Fi%jhejc&+0+R7SL1dMw7dMvsUL8TzmDZWa%6ngpe^UjbF%4jrtYA$g;*dv9@@d3-^OuvOG1Ztv*q O>h9SVHg6Ltqdx#9%N`y8 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/fx/dust.json b/packages/core/genres/platformer-assets-detailed/art/fx/dust.json new file mode 100644 index 00000000..d2c577e5 --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/art/fx/dust.json @@ -0,0 +1,241 @@ +{ + "frames": { + "dust 0": { + "frame": { + "x": 0, + "y": 0, + "w": 48, + "h": 16 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 48, + "h": 16 + }, + "sourceSize": { + "w": 48, + "h": 16 + }, + "duration": 50, + "anchor": { + "x": 0.5104, + "y": 1 + } + }, + "dust 1": { + "frame": { + "x": 48, + "y": 0, + "w": 48, + "h": 16 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 48, + "h": 16 + }, + "sourceSize": { + "w": 48, + "h": 16 + }, + "duration": 50, + "anchor": { + "x": 0.5104, + "y": 1 + } + }, + "dust 2": { + "frame": { + "x": 96, + "y": 0, + "w": 48, + "h": 16 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 48, + "h": 16 + }, + "sourceSize": { + "w": 48, + "h": 16 + }, + "duration": 50, + "anchor": { + "x": 0.5104, + "y": 1 + } + }, + "dust 3": { + "frame": { + "x": 144, + "y": 0, + "w": 48, + "h": 16 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 48, + "h": 16 + }, + "sourceSize": { + "w": 48, + "h": 16 + }, + "duration": 50, + "anchor": { + "x": 0.5104, + "y": 1 + } + }, + "dust 4": { + "frame": { + "x": 192, + "y": 0, + "w": 48, + "h": 16 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 48, + "h": 16 + }, + "sourceSize": { + "w": 48, + "h": 16 + }, + "duration": 50, + "anchor": { + "x": 0.5104, + "y": 1 + } + }, + "dust 5": { + "frame": { + "x": 240, + "y": 0, + "w": 48, + "h": 16 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 48, + "h": 16 + }, + "sourceSize": { + "w": 48, + "h": 16 + }, + "duration": 50, + "anchor": { + "x": 0.5104, + "y": 1 + } + }, + "dust 6": { + "frame": { + "x": 288, + "y": 0, + "w": 48, + "h": 16 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 48, + "h": 16 + }, + "sourceSize": { + "w": 48, + "h": 16 + }, + "duration": 50, + "anchor": { + "x": 0.5104, + "y": 1 + } + }, + "dust 7": { + "frame": { + "x": 336, + "y": 0, + "w": 48, + "h": 16 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 48, + "h": 16 + }, + "sourceSize": { + "w": 48, + "h": 16 + }, + "duration": 50, + "anchor": { + "x": 0.5104, + "y": 1 + } + } + }, + "animations": { + "dust": [ + "dust 0", + "dust 1", + "dust 2", + "dust 3", + "dust 4", + "dust 5", + "dust 6", + "dust 7" + ] + }, + "meta": { + "app": "https://ritmo.typeonce.dev/tools/pixel/", + "version": "1", + "image": "dust.png", + "format": "RGBA8888", + "size": { + "w": 384, + "h": 16 + }, + "scale": "1", + "frameTags": [ + { + "name": "dust", + "from": 0, + "to": 7, + "direction": "forward" + } + ], + "fps": { + "dust": 20 + }, + "loop": { + "dust": false + } + } +} diff --git a/packages/core/genres/platformer-assets-detailed/art/fx/dust.png b/packages/core/genres/platformer-assets-detailed/art/fx/dust.png new file mode 100644 index 0000000000000000000000000000000000000000..6341f549a9985781bc81c90010ee68107bf55a61 GIT binary patch literal 1297 zcmeAS@N?(olHy`uVBq!ia0y~yU~B-g1vuD%r2MrN9t;dDH#}V&Ln;{G9yH8&945j3 z;s12LxlFQ;be$d?y}{mgNLR{8H1FD?g2e{xYS|9WrZ>AyZB9s;gjDEU{Pb;-?uTUp zClnUCDok0scVWuwPoZqmEtbpsbboui`&)Ox#P>2Ly2szNOjkowf_vIq!7`KCd=l9^ z>Rd8znYx$(&_!9?!OFB>*K_$9c|2q@3JPG0a^f|;yA7*OGjiy1Erv}8X^ z00m9fI{i2ZGRf`skxQBX=WJkAWtGkq_Fn$C*y->TkseW)xUwqi;-oFUI&;6B=Zv1^ z%id#ZwO4PGO6zO)mbNp?nBRTbbz+i;_uM$~$VrF3Dj(7Yin;kNzwSD1NyIC#9MCc; zkW;nc`gnWW_#R7JJu{pZW3Tk)B+yY=Kn{?-=TOFr0)b;Kvo2nEsL;b1m0WkIe8G|j z`t$93_t*S0`S-WqUfn`Kl{NWb#_Scl_Y@opzy6VB{emS4i*pyf`*cV$KK8hT^KVE)pn=h9SqCPS~VniZW*uUSrhdCg~ zKx)a7gf}xMHEm4y;yT6+j6Jqg&#s-o^xz*kDM`;e=#7$h&=sgqK19ewReN5cN94zz zoj^A(Ycf#N0Xagb#c&}ICxYA%D9J19mTFQW@&1Zn8PEby5Q41d_2P0n3Jm}1sy&H& z6d@M!1<*Yg41kiLe0U>3;Fw5@A<(}-XYlEOofIGpbPX@iZ6Eps%YX@02N-MK zsc{E3**f)3Y6?sSW-OpzLH1NHTavH_=(Z1Dz%Y>l=5J7>u1UNpw~!Gizy(y1e*u_q zb$}LCG^br=Og{KkxoO#3#zc3h^nIZ5AoUM>1A`30fIhBR3`_~EK#jAO?ac-yB5<)0 z2T}&I#|@Y-K;;Oql)1+N%4Z2WKuw@>hwq*J>_{G_7m0PTz@m=9)78&qol`;+08FVz Ad;kCd literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/props/beacon.json b/packages/core/genres/platformer-assets-detailed/art/props/beacon.json new file mode 100644 index 00000000..f57dab77 --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/art/props/beacon.json @@ -0,0 +1,59 @@ +{ + "frames": { + "beacon 0": { + "frame": { + "x": 0, + "y": 0, + "w": 16, + "h": 32 + }, + "duration": 300, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "beacon 1": { + "frame": { + "x": 16, + "y": 0, + "w": 16, + "h": 32 + }, + "duration": 300, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "beacon 2": { + "frame": { + "x": 32, + "y": 0, + "w": 16, + "h": 32 + }, + "duration": 300, + "anchor": { + "x": 0.5, + "y": 1 + } + } + }, + "animations": { + "beacon": [ + "beacon 0", + "beacon 1", + "beacon 2" + ] + }, + "meta": { + "size": { + "w": 48, + "h": 32 + }, + "about": "Checkpoint beacon: 0 off; 1 and 2 on, blinking.", + "loop": true, + "image": "beacon.png" + } +} diff --git a/packages/core/genres/platformer-assets-detailed/art/props/beacon.png b/packages/core/genres/platformer-assets-detailed/art/props/beacon.png new file mode 100644 index 0000000000000000000000000000000000000000..b58f29b4967b7df7416b3b5958f4f8da5d9c008d GIT binary patch literal 631 zcmV--0*L*IP)7b2n@ntPeyb zFhkGEW1qKD&K0B=zjh3O@N!hTa039-%u_sm0Dw~IG;dzL6e@u%PizKY)9wM-(TwF; z{|X~jO9Zh1e!QV)W!-KFR{@5emHQ4CJtwFwSA0bz&1-Ih`g(U^ntA8<^@}I?wD`^0 zg&>w;T)Y;gNbPHT)pIdsURi+l{A+XT%Ed^N$Hj-b z%tf6%PCnDg!G{viGdR@NH90Om{h&z&qyka_sen{KN1Nu=4_f^2-m_Qa*HuWG7wf-* z#%@izI^H?3+NBsDzv>#qzu-6QfLrImH1m9%SL;Y5%?q#2nD5Qd=T@0C{}*zzi{Ezf RL-YUu002ovPDHLkV1jiED$f7_ literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/props/cog.json b/packages/core/genres/platformer-assets-detailed/art/props/cog.json new file mode 100644 index 00000000..0cdf68bf --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/art/props/cog.json @@ -0,0 +1,129 @@ +{ + "frames": { + "cog 0": { + "frame": { + "x": 0, + "y": 0, + "w": 16, + "h": 16 + }, + "duration": 80, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "cog 1": { + "frame": { + "x": 16, + "y": 0, + "w": 16, + "h": 16 + }, + "duration": 80, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "cog 2": { + "frame": { + "x": 32, + "y": 0, + "w": 16, + "h": 16 + }, + "duration": 80, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "cog 3": { + "frame": { + "x": 48, + "y": 0, + "w": 16, + "h": 16 + }, + "duration": 80, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "cog 4": { + "frame": { + "x": 64, + "y": 0, + "w": 16, + "h": 16 + }, + "duration": 80, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "cog 5": { + "frame": { + "x": 80, + "y": 0, + "w": 16, + "h": 16 + }, + "duration": 80, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "cog 6": { + "frame": { + "x": 96, + "y": 0, + "w": 16, + "h": 16 + }, + "duration": 80, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "cog 7": { + "frame": { + "x": 112, + "y": 0, + "w": 16, + "h": 16 + }, + "duration": 80, + "anchor": { + "x": 0.5, + "y": 1 + } + } + }, + "animations": { + "cog": [ + "cog 0", + "cog 1", + "cog 2", + "cog 3", + "cog 4", + "cog 5", + "cog 6", + "cog 7" + ] + }, + "meta": { + "size": { + "w": 128, + "h": 16 + }, + "about": "The collectible: a brass cog, spinning. Loops.", + "loop": true, + "image": "cog.png" + } +} diff --git a/packages/core/genres/platformer-assets-detailed/art/props/cog.png b/packages/core/genres/platformer-assets-detailed/art/props/cog.png new file mode 100644 index 0000000000000000000000000000000000000000..3579086e388ed93f4bb1cb80c4b0e542410f3445 GIT binary patch literal 1095 zcmV-N1i1T&P)5l|5>qa&{`EdTF`FNi8e z6m-%%p0L{HHku~V+0Bua8Motg>&fTphBFwbrIPB{%ttdWtHWy-9JOG%M4#11qmtjR> zS{`mve10!sxwH|)a&o$bP6jN?zlkYs062Xe0C0?o|Lb9@$*?^CHl}d;Z@FRd8@!TY zql(3Ff?}fzi~-dAP!Yx&7Q;y*>BUAB`#)YEF!=qW0N*~Fq$Z=-sK)RZYXBaU2prT6 z6dQZNgPO05U8RIEyxKq9yGQFuoH+IP?-S#;dwMGWrZtHaW2^uu`C+1muTC9Rf?$Sn z$DO_o(@MsdTOMYv9V21pK5ESo{6XD_`Y>c{XAs^#u=Sw@5Vx;q!ph=rj$F*#MG=NiCprVLJ%FL5AM<qmPwRG-owV-#q z5j=b1WYx(IfuzIf>xo0A2pgXx;(F3>tCaA>arT|Qj^@aPYzP$LMDdIC@K_c8Nk@Sc z@B;`H0VSWE4bF{H1VexG#Itz*YD!BU1;O`35mqLwec_3CXW`?oZEhO&{H4KaUZj-VWF&P4GiTz zGnS7ZxW}Mw;CQ?pTPOLGF5_Qm4dibE_F0n98W{ZVMey`2IK{T6vO@9pRaQA#C+#6W zeXnT^48O*y-(K?g^_1HqSOb&zclyyaFjhtU%0?RjZ%j7Hrs0!FVDU7~vv^ek={8|M zM`vjryg$oeDVF1L0V*GXSS;~JSASLxRq|KhU(i2(qLjT8;VEblKJE01e#6fkszSXk zZvqE(L;Br9gVx literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/props/enemy.json b/packages/core/genres/platformer-assets-detailed/art/props/enemy.json new file mode 100644 index 00000000..941aa7ed --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/art/props/enemy.json @@ -0,0 +1,73 @@ +{ + "frames": { + "enemy 0": { + "frame": { + "x": 0, + "y": 0, + "w": 32, + "h": 24 + }, + "duration": 180, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "enemy 1": { + "frame": { + "x": 32, + "y": 0, + "w": 32, + "h": 24 + }, + "duration": 180, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "enemy 2": { + "frame": { + "x": 64, + "y": 0, + "w": 32, + "h": 24 + }, + "duration": 180, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "enemy 3": { + "frame": { + "x": 96, + "y": 0, + "w": 32, + "h": 24 + }, + "duration": 180, + "anchor": { + "x": 0.5, + "y": 1 + } + } + }, + "animations": { + "enemy": [ + "enemy 0", + "enemy 1", + "enemy 2", + "enemy 3" + ] + }, + "meta": { + "size": { + "w": 128, + "h": 24 + }, + "about": "Scrap beetle, idle. Loops.", + "loop": true, + "image": "enemy.png" + } +} diff --git a/packages/core/genres/platformer-assets-detailed/art/props/enemy.png b/packages/core/genres/platformer-assets-detailed/art/props/enemy.png new file mode 100644 index 0000000000000000000000000000000000000000..9550a603ff86ec7c89d9c2442b77e37f549084b4 GIT binary patch literal 738 zcmV<80v-K{P)fCU;%K~;Cd%<5z_LP#eas?b#BMib2W7Kx=eFFwaq2~MA{AF z0H{`aXrqbNzdJI@g-Fw1CVxFBiM!3!b2U63y z%jB=Kwmk1Mj<@*3=5s%v;A{T_F4b=k6#=N`FPp#4V;)t%zB~f}>@Vf9eryL;E!e}5?t z0C;)f4_6b&=C6lc2<`OCT15ZE!`LuoG@uCox34Pz5ZhlAe?2UOsPK|fS`DazzX<-+ z7eSr9uK)j|F4EGbGYowaPqG1J`pe=!(EzqH)~x<}0syz}KEm4S3Uy+XaoZVdssT{R zpO=3Sds-Y9|DsVK_Z~bYMWaB1Vpu0@o*3FZ?;89*tT9$BuRl-zC^2Ce(Ab6H$`ea{ z1eE6&V0X5pZ}YY@)?8TS`2~FHY-xv!qK)|h;EnaGpEidlZyax#I`SUC-8SMb+IGg; z+Ug3fT)P?hC6LU#(^|hy>;7rJ2-8%*uIknlbP@h{rB;8~!%C9*MCDC0R`vS-0?@aC U?WjcUxBvhE07*qoM6N<$f;8J^5C8xG literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/art/props/spring.json b/packages/core/genres/platformer-assets-detailed/art/props/spring.json new file mode 100644 index 00000000..8643a60d --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/art/props/spring.json @@ -0,0 +1,59 @@ +{ + "frames": { + "spring 0": { + "frame": { + "x": 0, + "y": 0, + "w": 16, + "h": 24 + }, + "duration": 0, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "spring 1": { + "frame": { + "x": 16, + "y": 0, + "w": 16, + "h": 24 + }, + "duration": 0, + "anchor": { + "x": 0.5, + "y": 1 + } + }, + "spring 2": { + "frame": { + "x": 32, + "y": 0, + "w": 16, + "h": 24 + }, + "duration": 0, + "anchor": { + "x": 0.5, + "y": 1 + } + } + }, + "animations": { + "spring": [ + "spring 0", + "spring 1", + "spring 2" + ] + }, + "meta": { + "size": { + "w": 48, + "h": 24 + }, + "about": "Spring pad: 0 at rest, 1 pressed, 2 thrown. Frames are picked by the game.", + "loop": false, + "image": "spring.png" + } +} diff --git a/packages/core/genres/platformer-assets-detailed/art/props/spring.png b/packages/core/genres/platformer-assets-detailed/art/props/spring.png new file mode 100644 index 0000000000000000000000000000000000000000..ca7f6bcca8cd70e3c1dd230d031df4548f3979b7 GIT binary patch literal 416 zcmV;R0bl-!P)S0DEt@()&DS0Fb)>S zAG>fJuNqZ(Q53$3l@r6+S0TBV={|pQa4Dswz3=4lg!>R^Z?#+j{ zm`RA7Ohj!@ED#XKnf4hN7#L!1GGWie^wkj2v9o@4M+^U`S6x8G2DsbJT#y& zKxrPLs1!1`bo|f2z`*eE`XvTpN`W6rG7Jn13=FU|JdpYsMFfQZmp9KLI*n?mDZ$wd z4FwDjuU}#qNc}7f3=9nW4{jztlO4n+HgNhGkt;D$0W2d9q<#QoS{k%k*lSh*0000< KMNUMnLSTZs&!bfU literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/fx/detailed.fx.json b/packages/core/genres/platformer-assets-detailed/fx/detailed.fx.json new file mode 100644 index 00000000..8922116e --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/fx/detailed.fx.json @@ -0,0 +1,148 @@ +{ + "version": 1, + "palette": { + "ink": "#141013", + "sky0": "#849be4", + "sky1": "#b9bffb", + "sky2": "#e3e6ff", + "sky3": "#fef3c0", + "steel0": "#333941", + "steel1": "#4a5462", + "steel2": "#6d758d", + "steel3": "#8b93af", + "steel4": "#b3b9d1", + "steel5": "#dae0ea", + "steel6": "#ffffff", + "teal0": "#122020", + "teal1": "#24523b", + "teal2": "#23674e", + "teal3": "#328464", + "teal4": "#477d85", + "teal5": "#5daf8d", + "teal6": "#92dcba", + "teal7": "#cdf7e2", + "leaf0": "#1a7a3e", + "leaf1": "#14a02e", + "leaf2": "#59c135", + "leaf3": "#9cdb43", + "leaf4": "#d6f264", + "earth0": "#221c1a", + "earth1": "#322b28", + "earth2": "#71413b", + "earth3": "#bb7547", + "earth4": "#dba463", + "stone0": "#423934", + "stone1": "#5a4e44", + "stone2": "#796755", + "stone3": "#a08662", + "stone4": "#c7b08b", + "stone5": "#e4d2aa", + "rose0": "#422433", + "rose1": "#5b3138", + "rose2": "#8e5252", + "rose3": "#ba756a", + "rose4": "#e9b5a3", + "rose5": "#fad6b8", + "blue0": "#143464", + "blue1": "#285cc4", + "blue2": "#249fde", + "blue3": "#20d6c7", + "blue4": "#a6fcdb", + "fire0": "#3b1725", + "fire1": "#73172d", + "fire2": "#b4202a", + "fire3": "#df3e23", + "fire4": "#fa6a0a", + "gold0": "#f9a31b", + "gold1": "#ffd541", + "gold2": "#fffc40", + "violet0": "#242234", + "violet1": "#403353", + "violet2": "#793a80", + "violet3": "#bc4a9b", + "violet4": "#e86a73" + }, + "ramps": { + "glow": [ + "steel6", + "gold2", + "gold1", + "gold0", + "fire4", + "fire3" + ], + "dust": [ + "stone5", + "stone4", + "stone3", + "stone2" + ], + "spark": [ + "steel6", + "gold2", + "fire4", + "fire2" + ] + }, + "backdrops": { + "sky": "#b9bffb", + "haze": "#e3e6ff", + "jungle": "#23674e", + "earth": "#322b28", + "stone": "#a08662" + }, + "standIn": { + "file": "../art/player/player-idle.png", + "anchor": [ + 24, + 47 + ] + }, + "effects": { + "dash": { + "about": "The dash starts: a burst behind the player in the cell's gold (the cell goes grey after). Metal Slug's muzzle flashes and Celeste's dash are the references for speed: a white frame, then gone in a quarter second. About the player's size.", + "standIn": [ + 26, + 22 + ], + "drafts": { + "a": { + "file": "drafts/dash.a.js", + "accept": { + "holes": "gaps where two sparks cross for a frame; they part on the next" + } + }, + "b": { + "file": "drafts/dash.b.js" + } + }, + "use": "b" + }, + "dust": { + "about": "Dust at the boots on a jump, a landing, or a turn: chunky puffs in the stone's colors, never hiding the boots.", + "standIn": [ + 0, + 0 + ], + "drafts": { + "a": { + "file": "drafts/dust.a.js" + }, + "b": { + "file": "drafts/dust.b.js" + } + }, + "use": "a" + }, + "collect": { + "about": "A cog is taken: a white flash, a gold ring, and sparks that fall a little.", + "standIn": false, + "drafts": { + "a": { + "file": "drafts/collect.a.js" + } + }, + "use": "a" + } + } +} \ No newline at end of file diff --git a/packages/core/genres/platformer-assets-detailed/fx/drafts/collect.a.js b/packages/core/genres/platformer-assets-detailed/fx/drafts/collect.a.js new file mode 100644 index 00000000..805de0b8 --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/fx/drafts/collect.a.js @@ -0,0 +1,30 @@ +// collect, draft a: a cog is taken: a white flash, a gold ring, and sparks +// that fly out and fall a little. +export default { + label: "flash ring", + size: [40, 40], + frames: 12, + fps: 24, + loop: false, + anchor: [20, 20], + params: { + sparks: { min: 2, max: 10, value: 7, step: 1 }, + reach: { min: 8, max: 18, value: 15 } + }, + draw(fx) { + if (fx.frame === 0) fx.disc(fx.cx, fx.cy, 7, "steel6") + if (fx.frame === 1) fx.disc(fx.cx, fx.cy, 7, "gold2") + if (fx.frame > 0 && fx.t < 0.5) fx.ring(fx.cx, fx.cy, 6 + (fx.t / 0.5) * (fx.p.reach - 4), fx.ramp("glow", fx.t / 0.5), 2) + for (let i = 0; i < fx.p.sparks; i++) { + const angle = fx.range(0, Math.PI * 2) + const dist = fx.range(0.5, 1) * fx.p.reach + const start = fx.range(0.05, 0.25) + const life = (fx.t - start) / (1 - start) + if (life < 0 || life >= 1) continue + const x = fx.cx + Math.cos(angle) * dist * fx.ease.out(life) + const y = fx.cy + Math.sin(angle) * dist * fx.ease.out(life) + life * life * 6 + if (life < 0.5) fx.sparkle(x, y, 1, fx.ramp("spark", life), "gold1") + else fx.px(x, y, fx.ramp("spark", life)) + } + } +} diff --git a/packages/core/genres/platformer-assets-detailed/fx/drafts/dash.a.js b/packages/core/genres/platformer-assets-detailed/fx/drafts/dash.a.js new file mode 100644 index 00000000..39af73e0 --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/fx/drafts/dash.a.js @@ -0,0 +1,28 @@ +// dash, draft a: a white flash where the dash starts, a ring that widens and +// cools through the gold glow, and sparks thrown backward. +export default { + label: "ring", + size: [60, 56], + frames: 8, + fps: 30, + loop: false, + anchor: [36, 28], + params: { + reach: { min: 10, max: 22, value: 16, step: 1 }, + sparks: { min: 0, max: 12, value: 7, step: 1 } + }, + draw(fx) { + if (fx.frame === 0) fx.disc(fx.cx, fx.cy, 6, "steel6") + for (let i = 0; i < fx.p.sparks; i++) { + const angle = Math.PI + fx.range(-1.1, 1.1) + const speed = fx.range(0.6, 1) + const life = fx.t / speed + if (fx.frame === 0 || life >= 1) continue + const d = 6 + fx.ease.out(life) * (fx.p.reach + 4) + fx.streak(fx.cx + Math.cos(angle) * d, fx.cy + Math.sin(angle) * d, Math.cos(angle) * 4, Math.sin(angle) * 4, "spark") + } + // The ring last, over the sparks, so they never punch holes in it. + const r = 4 + fx.ease.out(fx.t) * (fx.p.reach - 4) + if (fx.frame > 0 && fx.t < 0.85) fx.ring(fx.cx, fx.cy, r, fx.ramp("glow", fx.t), 2) + } +} diff --git a/packages/core/genres/platformer-assets-detailed/fx/drafts/dash.b.js b/packages/core/genres/platformer-assets-detailed/fx/drafts/dash.b.js new file mode 100644 index 00000000..5210e0a1 --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/fx/drafts/dash.b.js @@ -0,0 +1,31 @@ +// dash, draft b: a burst that kicks backward: a white star, then speed lines +// streaming back behind the player, cooling from gold to ember as they thin. +export default { + label: "speed lines", + size: [56, 40], + frames: 8, + fps: 30, + loop: false, + anchor: [40, 20], + params: { + lines: { min: 3, max: 9, value: 6, step: 1 }, + length: { min: 10, max: 34, value: 26, step: 1 } + }, + draw(fx) { + if (fx.frame === 0) { + fx.disc(fx.cx + 16, fx.cy, 5, "steel6") + fx.sparkle(fx.cx + 16, fx.cy, 8, "gold2", "gold1") + return + } + if (fx.frame === 1) fx.disc(fx.cx + 16, fx.cy, 4, "gold1") + for (let i = 0; i < fx.p.lines; i++) { + const y = fx.cy + Math.round(fx.range(-12, 12)) + const delay = fx.range(0, 0.3) + const life = (fx.t - delay) / (1 - delay) + if (life <= 0 || life >= 1) continue + const head = fx.cx + 14 - fx.ease.out(life) * 22 + const len = fx.p.length * (1 - life) * fx.range(0.5, 1) + fx.streak(head, y, len, 0, "glow") + } + } +} diff --git a/packages/core/genres/platformer-assets-detailed/fx/drafts/dust.a.js b/packages/core/genres/platformer-assets-detailed/fx/drafts/dust.a.js new file mode 100644 index 00000000..b0ae3c2f --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/fx/drafts/dust.a.js @@ -0,0 +1,27 @@ +// dust, draft a: chunky puffs kicked out to both sides of the boots, rising a +// little as they shrink; each puff is lit on its top. +export default { + label: "puffs", + size: [48, 16], + frames: 8, + fps: 20, + loop: false, + anchor: [24, 15], + params: { + puffs: { min: 2, max: 8, value: 6, step: 1 }, + spread: { min: 6, max: 18, value: 14 } + }, + draw(fx) { + for (let i = 0; i < fx.p.puffs; i++) { + const side = i % 2 === 0 ? -1 : 1 + const reach = fx.range(0.4, 1) * fx.p.spread + const size = fx.range(2.5, 4.2) + const x = fx.cx + side * (6 + fx.ease.out(fx.t) * reach) + const y = 11 - fx.ease.out(fx.t) * fx.range(1, 4) + const r = size * (1 - fx.ease.in(fx.t)) + if (r < 0.8) continue + fx.disc(x, y, r, fx.ramp("dust", fx.t * 0.7 + 0.25)) + if (r > 2) fx.disc(x + 1, y - 1, r - 1.5, fx.ramp("dust", fx.t * 0.7)) + } + } +} diff --git a/packages/core/genres/platformer-assets-detailed/fx/drafts/dust.b.js b/packages/core/genres/platformer-assets-detailed/fx/drafts/dust.b.js new file mode 100644 index 00000000..25d2a0d6 --- /dev/null +++ b/packages/core/genres/platformer-assets-detailed/fx/drafts/dust.b.js @@ -0,0 +1,28 @@ +// dust, draft b: a skid: a low wave of dust thrown back along the ground, with +// grit flicked up. +export default { + label: "skid", + size: [56, 16], + frames: 7, + fps: 20, + loop: false, + anchor: [40, 15], + params: { + grit: { min: 0, max: 8, value: 5, step: 1 } + }, + draw(fx) { + const back = fx.ease.out(fx.t) * 16 + const r = 4 * (1 - fx.ease.in(fx.t)) + if (r >= 1) { + fx.oval(fx.cx - 4 - back, 11, r * 2, r * 0.8, fx.ramp("dust", fx.t * 0.8 + 0.2)) + fx.oval(fx.cx - 3 - back, 10, r * 1.2, r * 0.5, fx.ramp("dust", fx.t * 0.8)) + } + for (let i = 0; i < fx.p.grit; i++) { + const life = fx.t / fx.range(0.6, 1) + if (life >= 1) continue + const x = fx.cx - 2 - fx.ease.out(life) * fx.range(8, 20) + const y = 13 - Math.sin(life * Math.PI) * fx.range(4, 9) + fx.px(x, y, fx.ramp("dust", life)) + } + } +} diff --git a/packages/core/genres/platformer-assets-detailed/previews/fx/collect@4x.png b/packages/core/genres/platformer-assets-detailed/previews/fx/collect@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..630a5bd0ae5a8632a5bf93093065d3d27395c61e GIT binary patch literal 3219 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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/previews/props/props@6x.png b/packages/core/genres/platformer-assets-detailed/previews/props/props@6x.png new file mode 100644 index 0000000000000000000000000000000000000000..e7eb027636fcb9dba17067401bf2343a2697c5d9 GIT binary patch literal 7612 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 literal 0 HcmV?d00001 From e10373649c79f319aff8721aed6e41736522515a Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Nov 2026 03:54:27 +0000 Subject: [PATCH 8/9] Add the detailed set's mockup room and comparisons with set one Every plane stacked as the game would, plus set one's player and room beside this set's at the same zoom, so the change in scale is seen, not described. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01HendNaZcTpUubQBWodQy33 --- .../art/mockup/mockup.png | Bin 0 -> 21083 bytes .../previews/compare/mockups@3x.png | Bin 0 -> 51176 bytes .../previews/compare/players@6x.png | Bin 0 -> 11672 bytes .../previews/mockup/mockup@4x.png | Bin 0 -> 41208 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/core/genres/platformer-assets-detailed/art/mockup/mockup.png create mode 100644 packages/core/genres/platformer-assets-detailed/previews/compare/mockups@3x.png create mode 100644 packages/core/genres/platformer-assets-detailed/previews/compare/players@6x.png create mode 100644 packages/core/genres/platformer-assets-detailed/previews/mockup/mockup@4x.png diff --git a/packages/core/genres/platformer-assets-detailed/art/mockup/mockup.png b/packages/core/genres/platformer-assets-detailed/art/mockup/mockup.png new file mode 100644 index 0000000000000000000000000000000000000000..6d508d192c6e6c99b46d160a9a7a7b1f91863518 GIT binary patch literal 21083 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

B*Ux>Zr$w)Q5zad?(qpM?Kgx$_PbffVYjl34!t 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 B_>BMn literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/previews/compare/mockups@3x.png b/packages/core/genres/platformer-assets-detailed/previews/compare/mockups@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..0850a1ece2bf374a69f8d0f257ae5fe54b24a38c GIT binary patch literal 51176 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 z�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 d)Q4i&f%n_Q4zu%5e0=n3I^66QumFGEU@BJJ0 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 literal 0 HcmV?d00001 diff --git a/packages/core/genres/platformer-assets-detailed/previews/mockup/mockup@4x.png b/packages/core/genres/platformer-assets-detailed/previews/mockup/mockup@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..a075d77b30d73d3664122963d88e9817c67d2103 GIT binary patch literal 41208 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 POP%%}{;K55Z!Y~Gfx19s literal 0 HcmV?d00001 From 43eaccd684d9041a080c2f2f9f9dc66a70148646 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Nov 2026 03:55:37 +0000 Subject: [PATCH 9/9] Write down the detailed platformer set's decisions and how to regenerate it Ties each choice (grid, palette, light, sel-out, detail budget) to the Metal Slug reference and the research, says what changed with scale against set one, and names what still looks weak. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01HendNaZcTpUubQBWodQy33 --- .../core/genres/PLATFORMER-ASSETS-DETAILED.md | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 packages/core/genres/PLATFORMER-ASSETS-DETAILED.md diff --git a/packages/core/genres/PLATFORMER-ASSETS-DETAILED.md b/packages/core/genres/PLATFORMER-ASSETS-DETAILED.md new file mode 100644 index 00000000..ea8962e0 --- /dev/null +++ b/packages/core/genres/PLATFORMER-ASSETS-DETAILED.md @@ -0,0 +1,73 @@ +# A detailed asset set for a platformer + +This file is for the maintainers and the agents working on this repo. It is not published (`package.json` `files` leaves `genres/` out). It is the second test of the [`ritmo-pixel-art`](../skills/ritmo-pixel-art/SKILL.md) skill and `ritmo-tools` on a platformer, after [`PLATFORMER-ASSETS.md`](PLATFORMER-ASSETS.md): the same kind of asset list at a larger scale, with Metal Slug as the reference for proportion, detail density, shading, and how lively the motion is. Every asset is original; no Metal Slug sprite, character, or palette is copied. + +![The mockup room at 4x](platformer-assets-detailed/previews/mockup/mockup@4x.png) + +## Decisions + +| | Choice | Why | +| --- | --- | --- | +| Screen | 384×216 art pixels: 5× on 1080p, 10× on 4K | 16:9 with a whole-number scale on the common screens. Metal Slug's 304×224 is about 4:3. 384 is 1.2× set one's width, so the larger sprites still leave a wide view: 24×13.5 tiles. | +| Tile | 16×16 | Double set one's. A block, a rivet, a crack, and a grass blade can each be a cluster, not a single pixel. | +| Player | 48×48 frames. The figure is about 40 px tall (2.5 tiles). The soles are on row 46 and the outline on row 47. Hitbox 12×34 (x 17..28, y 13..46). | Metal Slug's infantry is about 40 px. The head is about a third of the height, chunky as in Metal Slug, so the face, the goggles, and the hands read. | +| Palette | 60 colors of AAP-64 (`palette.hex`). The ramps are sky, steel, teal (backdrop growth only), leaf (play-layer grass), earth, stone, rose (skin), blue (the player's jacket only), fire (hair, warning paint), gold (cog, dash cell, beacon), and violet (the enemy only). The limit is 32 colors per asset (`pixel.config.json`). The player uses 30–31. | A bigger sprite needs longer ramps. AAP-64 has five or six steps of brown, khaki, green, teal, and grey, where Endesga 32 has three or four. Each material gets a contour, a shade, a base, a light, and a highlight. | +| Light | The sun, high on the right, ahead of the player | The player faces right and runs right, so her face and front are lit. A sprite flipped to face left takes its light with it; that is the usual compromise, and it is accepted here. | +| Outlines | Selective (sel-out): ink on the side away from the sun, and the material's own darkest step on the lit side (`selout` in `make.py`). Parts that overlap inside a sprite get a contour in the front part's darkest step. Terrain is outlined only on open sides. Backdrop planes have no outlines. The foreground is a flat dark teal with one rim of light. | This is how Metal Slug keeps a hard edge without a black cut-out look. An outline still means "in play" (direction research). | +| Detail budget | Clusters of 2 px or more. Every material gets one detail type: block bevels, pits and cracks in stone, rivets and a truss in steel, bark grooves in trunks, plate seams in the shell. Large masses rest: deep terrain turns into dark earth with a few buried stones. | Metal Slug's density, not its micro-detail. The skill says a crack is a cluster, like a fold in a cloak. | +| Read order | Spikes are the brightest value (white steel on gold-and-ink warning paint). The player is the only blue, and her hair is the strongest red. The cog and the dash cell share the gold. The enemy is the only violet. Terrain has lit rims where it is touched. The backdrop moves toward the sky's lavender. | The skill's read order and the contrast ladder from the direction research. | +| Dash signal | The cell on the backpack glows gold while a dash is ready and turns grey once it is spent (`player-spent.png`). | One look per meaning, on the player's own silhouette. It is not set one's scarf color, so the two sets stay distinct. | +| Parallax | Sky 0, far city 0.15, mid ruins 0.35, near jungle 0.6, play 1, foreground 1.3 (`PARALLAX` in `make.py`). | Plane speed follows depth. | + +## The player: a posed puppet + +Set one typed every frame by hand, and its weak spot was stiffness. Here the player is a puppet. Each limb is a tapered capsule between joints, posed by angles, so limb lengths never change from frame to frame. Each limb is shaded in bands along its length, from the one light. The jacket, belt, and trousers are drawn in the torso's own frame, so the torso can lean. The head is drawn by hand. Each frame gets one outline at the end. A pose is a few numbers (`RUN_LEG`, `air_poses`, ...). Standing poses are moved onto the ground row by measuring their pixels, and the wall-slide poses are moved so the hand and boot touch the wall. The animations: + +- idle: 6×160 ms of breathing, with one blink; +- run: 8×70 ms (contact, down, pass, up, and the same for the other leg), with the arms swinging against the legs and the ponytail lagging a beat behind; +- jump: 3×80 ms (push-off, rise, tuck), then held; +- fall: 2×110 ms with the legs reaching down and the arms flailing up; +- dash: 3×50 ms (wind-up, then flat behind a thrown fist); +- wall-slide: 2×120 ms; +- land: 2×70 ms (squash, recover). + +## Files (`platformer-assets-detailed/`) + +- `make.py`: draws everything from code and palette names (Python 3 with Pillow). The same run makes the same bytes. `python3 make.py debug|tiles|props|bg` writes quick contact sheets to `/tmp` while iterating. +- `art/backdrop/bg-0-sky.png` … `bg-3-near.png`: the sky with the sun and clouds, a far ruined skyline, mid industrial ruins (a cooling tower, chimneys, a broken truss bridge, a crane), and near jungle (trunks, canopy, vines, a bush ridge). Each plane is 384×216 and loops. +- `art/foreground/fg-jungle.png`: palm fronds in the top corners and ferns along the bottom. It loops. +- `art/tiles/tileset.png` and `.json`: the 47-tile blob autotile plus 3 fill variants (a crack, a chip, moss), with the same JSON format as set one. Then a steel catwalk (left, middle, right, post), spikes facing 4 ways, and decoration (fern, flowers, rubble, vine, pipe). +- `art/player/player.png` and `.json`: the hash format plus `timing`, as in set one. `player-spent.png` is the same sheet with the dash spent. `player-idle.png` is the stand-in for `fx`. +- `art/props/`: `cog` (8 frames of spin), `spring` (rest, pressed, thrown), `beacon` (the checkpoint: off, then on with a blink), and `enemy` (a scrap beetle, 4 idle frames). Each comes with JSON. +- `fx/detailed.fx.json` and `fx/drafts/`: dash (a ring, or speed lines; the speed lines are in use), dust (puffs in use, or a skid), and collect. They are rendered to `art/fx/`. +- `art/mockup/mockup.png`: one room with every layer stacked. Previews are in `previews/`. `previews/compare/players@6x.png` shows set one's player above this one at the same zoom, and `mockups@3x.png` shows the two rooms side by side at the same pixel size. `previews/player/player-animations@3x.gif` plays every animation. `previews/parallax/parallax@2x.gif` (about 2.6 MB) is regenerated and gitignored. + +## Regenerate + +From `packages/core/genres/platformer-assets-detailed/`, with the repo's `pnpm install` done: + +```sh +rt() { node "$(git rev-parse --show-toplevel)/packages/tools/bin/ritmo-tools.mjs" "$@"; } +python3 make.py # the art, the stand-in, and the palette +(cd fx && rt fx check detailed.fx.json && rt fx render detailed.fx.json -o ../art/fx) +python3 make.py # again, so the mockup reads the effects +for f in $(find art -name '*.png'); do rt pixel lint $f; done +``` + +## What changed with scale (against set one) + +- **Proportion:** set one's climber is a head on legs, 1.5 tiles tall, with 1-pixel eyes. This player is 2.5 tiles tall, with a torso, separate arms, a ponytail, a backpack, goggles, and gloves. Silhouettes now carry pose: arm swing, a knee drive, a reach. +- **Motion:** at 16 px a pose is a few moved pixels, so jump and fall barely differed. At 48 px each animation has distinct key poses, and the hair gives secondary motion. +- **Shading:** a material went from 3–4 tones to 5–6, with contours between overlapping parts and a selective outline instead of a uniform ink one. +- **Tiles:** an 8 px tile holds a texture. A 16 px tile holds objects: cut blocks with bevels, cracks, chips, and rivets. The terrain needed a resting area (the dark earth inside) so masses do not turn to noise. +- **What stayed:** one palette, one light, outlines by plane, the read order, the blob autotile, the frame JSON, and the fx path. + +## What is weak + +- The player's hands cover the lower face in the wall slide and in the jump's reach. The far arm is almost always hidden, so the run's arm swing reads mostly from the near arm. The run's passing frames are narrow. A person should redraw the head for the dash (it stays upright while the body tips) and add in-betweens for jump-to-fall. +- The torso's cyan rim (`blue3`) reads as a stripe in some frames. +- The terrain's block facing is regular: two block patterns, repeated on every edge tile. Long walls show the repeat. The buried stones still read as dots at 1×. +- The backdrop's foliage is built from shaded circles. The canopy and the ridge read as piles of balls more than as leaves. Clouds are plain. The cooling tower's broken rim is crude. +- The spring is a red drum more than a coil. The beetle's legs are single-pixel lines and thin against its shell. +- `fx check` reports `teal0` (#122020) and `earth0` (#221c1a) as near-duplicates. Both are AAP-64 colors, kept apart by where they are used. +- No asset has been judged on a phone or in motion inside a running game.