From 44b938f0e5ad0064593457e94e53822a49e22269 Mon Sep 17 00:00:00 2001 From: Richard Zink Date: Tue, 3 Nov 2026 11:41:29 +0100 Subject: [PATCH] Installable as an app (PWA): manifest, pixel-art icons, offline service worker - manifest.webmanifest (full screen, any orientation), icons 192/512/maskable/apple-touch - sw.js: network first, cache as offline fallback, the savegame API is never cached - registered only over HTTPS or on localhost; nginx serves the manifest type - README: installing, HTTPS requirement Co-Authored-By: Claude Opus 5.5 --- README.md | 6 +++++ nginx.conf | 5 ++++ www/icons/apple-touch-icon.png | Bin 0 -> 1570 bytes www/icons/icon-192.png | Bin 0 -> 1550 bytes www/icons/icon-512.png | Bin 0 -> 3316 bytes www/icons/maskable-512.png | Bin 0 -> 3332 bytes www/index.html | 13 +++++++++- www/manifest.webmanifest | 17 +++++++++++++ www/sw.js | 45 +++++++++++++++++++++++++++++++++ 9 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 www/icons/apple-touch-icon.png create mode 100644 www/icons/icon-192.png create mode 100644 www/icons/icon-512.png create mode 100644 www/icons/maskable-512.png create mode 100644 www/manifest.webmanifest create mode 100644 www/sw.js diff --git a/README.md b/README.md index 76e9e0e..556c6af 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,12 @@ docker compose up -d --build # open http://localhost:18093 ``` +### Install as an app (PWA) + +DungeonCraft is a progressive web app: browsers offer to install it (Chrome/Edge: install icon in the address bar or "Install app" in the menu; Android: "Add to home screen"; iOS Safari: Share → "Add to Home Screen"). The installed game starts in full screen and also works offline (the savegame list on the server then falls back to savegame files). + +Browsers only allow the installation over **HTTPS** (or on `localhost`), so a public installation needs a reverse proxy with a certificate in front of port 18093. + ### Building without Docker Requirements: Rust with the `wasm32-unknown-unknown` target. diff --git a/nginx.conf b/nginx.conf index 9ca393c..bd349a0 100644 --- a/nginx.conf +++ b/nginx.conf @@ -7,6 +7,11 @@ server { location / { try_files $uri $uri/ =404; } + # installable app (PWA) + location ~ \.webmanifest$ { + default_type application/manifest+json; + try_files $uri =404; + } # savegame service (server/). Resolved at request time, so the game still starts without it; # the game then falls back to savegame files. location /api/ { diff --git a/www/icons/apple-touch-icon.png b/www/icons/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5aec7c5207a6f69bdb9302908b16d41bd69c6680 GIT binary patch literal 1570 zcmZWpdr(q&7{#^BWz@u4E!Wm4D-ZX^^ubpe8cJqGiwxU+mpxnvnhD-aGS~d%oZIopZiZv;)7{ z9qtQxNx8Qa{U*Ug`s|)nTbhw1VV6zQdalh>Pz0#!ap!!8FI607k>~~{Ed#Nrj z-BJ>?xaAbEduh&N=JHnHcE49cD=@VGhb2pP-`o=k_Zl0L+K?W9xuq-gIO?hb0YQ_x z*C0#{lyVhBrLv~&dGg+kh3~Q%umqOt8jdFgxA;Y2#1({Y9ysT&zSt(0JDEf2=I!@a zM+Ct0qvn5ge(5aVn18PAIBY}Ad3A%3e*)nfV-MsKSx*wn{RFqq1o{Tp6+F2yK(>wV z=aGx;zbOcP?)s^YJrMfg%LT6*%~kuK2(`Z1Qs3x4 z`GL*o_}~LXLs}HT;s^AF_2hwODPASVhOZ)~mvKxAl8SetA^j0}qn0Fojp!^LUz}gM z%3f4Rj5WXNeydQZ2a4W^okVD@Ne)dn8W~o@Pm2@M6Gx1sLexEjZIc3j&iQ>a$Rua? zk{Hv}4^yH^q*K&q>p%l;dwC(k(kl#5+TVGV@sE&fOQV`n=+F0Uu8z2};`p zW@jgMdAgKSOky-nGqi7G2hV---WP_ViRiv=QLfLG^%yNw2-PldAE%<@fHmd;*C}z5 z8|hgT-3Od2pmkb!82|c2M?7Rzdy8=m+zc@59T#1WZ+6uL`xsXnEl8Rr`6wXiureD@ zPaLBbNXA!;>{_2aw}%~!Rhw4+pP+SXi`yT9`l>>s`fR@%Nz10?vF{G|(H8+->q2`P zFH9-rlP^iR$njPS&uE)T@#X6Ija(w=+t9lgF+pYzyav*&Xm(>VKpJj&5~ITs|B&gDF(aX%EbSJ^T6UuLN$rzkVKfTaZk+af%y;zHq;vSDdAy=G3&x=Ahi#3-<8DPH GocI^;*v}>a literal 0 HcmV?d00001 diff --git a/www/icons/icon-192.png b/www/icons/icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..ec49239108eadf8c73146a8e801de95aeec04a4e GIT binary patch literal 1550 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE4M+yv$zf+;V7=<;;uumf=k49od9y=B+7fTK zURlDq#q-H3kEu$E2U`S{uUID>6aAtkQNYQwqbts*wdF{M;9@UVr!s!eIn2HX&4k%_ zu65r~UHDG}aMrazYvCI~TM)^3L* zTb*}#iC^t4VGA%pHg@+0J%Pfv6aMv|ey3-}3^oW^8pQ^n#Poe)8L_zzf6s0BH`i&t zdj7(?T~TJWasSUr!rTefp?Bf_wzk8Y>?H4Ly|!NbtDN2T`L_k@CVxJ-YR&vLuYSEw zy(>Fwt(fn5&&NDSo&;(ZyUx0cKf6@!-m3OT2Uomfdh00u!nxw#5Boj0?e{kRlDWpT zw?*&5xlMKRpLg4z{v|SR|GGJ7-o3Vs+vV;&{{^=<^M7r>z-sk7WBZ!>ZQobUKlH*f zI$*xcUai-+H<)pjuV^i8N7uXSJ<~-#ov7Q+cjuk0p1jHL_p*1+fBCN5Z@2o%{Azi? zeCO~iVY~hH2HLMHCiiK<$IqXSoxglb@s{H^#w+fT^f1@!y!h9X<|WIo{yVs4 z&HKJr(MOkUDC@{e$d}Eq+TLDPbn%wlt8X^V9~T0xe>WFBF?^3zFk1RKYr$zp>)Cw^ ze{TdudVky3_aeI*=U(VDK$!4g$68Iaf?>UncJT zrrC>bO^o=9)4L~cy7yc2_}UDaI*!+T=zdw7EB=Cex9$6uV{ez6zQvFRCjDP`^3G3P zQ21}>=XVp(%{Px-;Q#j99gi=2|6KAcKY^K81N38AzaB*se|u@S!{+7v`oG;h-lHe* zw}*B)Om_Fzdlh(TY9U(c&3?zUbDR6?BWT9uTHKRZzwWo{lGl&Wik@%cf@_5L|1^!^ Q1D5j)p00i_>zopr0Gz_WQ~&?~ literal 0 HcmV?d00001 diff --git a/www/icons/icon-512.png b/www/icons/icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..98d180c018f4165cd1abd725394390cf40bebdef GIT binary patch literal 3316 zcmb_fe@qi+82&0`prLebQzu2w88)-v)WH-1=_x}Hjj+tcsZ)z?gC@>WL5nHE5iyX7 z+9epxtmVuY7)61lRnQI!Hp-Y{t^A6#dQ^o%us>LT9PRb)b~WPOny(I?wLa8~Pg>@c zndcU^9f3dOe3udx_3L_TZC(AvvumVD(@rd`h)kXxe>5`e;(HhB>aQO?xqfCw^0D@) z_g8g)8wy9GsrUgaG`ze@f88x^bsry#lSYFDLs_Fi03fS40IXr44+jGfJRN}0cK~=h z3V;Rc09gGK03{1v_JJst49TcUYB`z@fL1r2gB|mTU+2G<1|C>kR5D5&<77d~RfX3_ zEE>)$&|ey5GJlcE#i>12jK+YC9cYotH8a)pUyNQEQ@zy(HW+a{KFG0)p}oTwT9L;H z`2VzfCDLoDABb=-do-v`pb?m`ZTg5qKJTVEI?^lFj95PZnLm|E{wtdm8zAtJxS_wA z9QR4o+Ja?!Mn=8z%__3T*eg~eEefmfho)+>)0U@3tDsX)8P87LKa;5Ey6%UZvzldn z=j6N`p*bz2yqYX6ec+`(^LulT_2p~1c#g&@qPwM6wM|NrMi6hY8WH%tyKZo&>e)%m z=cZPjzEFuvCIkcw-EBRbSw?gOpcNWCji@%ruAEU8i)EBiM~>e{(}=_|w+Jax@4USE zv^~vf(O6xM#?=J23oe#ghkjIxcDY}8R0Zj&upZD z8g@8Qe_qUhFbt;sc^>}37KMQGEH>_S`}GCxlO5l+^VZ!*i94Ya9(i~+(V-(0vx6SSlAV}VIyro0Y<7<6?QihX`6H}Oov zlI;B1!>oOnHQXoblQi{@8K_L19&P1OeG=N+FFfHXC_`bl$gGFInQ&s^xJ5^%>B#mQ zdb`WsaZ{W)pjynX5PMGvKx}_GQQiBj=y6;bimVK%ttB7V8K`cv1&*-E%ZVB#4`*Oq zL@XJUQ0N;Dpob7$?Al<`3R4>XFPKSD!)v>9Q$kCx@T~~Hm@-IcaWj%=($2N%%ZQqd zdYGgY6jh6%IFr1;+fv}eOUXA;twT-otU`OX{au)WwKAQP0NI4xfJQwoOTaH^INpt6 zF52F2rrgh~#agdPw!0Gxp^40Y#)B#_HTG1yO-3^{vOZ(nTx((ag^n?yTs*EE!|Y{x zz00el$Sf_(sllwZEq#H>%M8QiPnB+&S{uJj-@>=)%ZWV<@B1+QKtk_sMpViq7!Jd` zEvHwox8`kGi}APz6ShLu262CJl^_E1(ivbbPaPYA1|Q@iS9}MWwcfuh2CB=G zr>4adBr1T}r|=1xu+L+1K9qWRVOV+br-ZAw&P?<`XQ`C~(4`!1>-@`>N8xxwIfmM= zsz{#kwt*tdc!A&FR>FD}mRubr?$I*hiGdmtC1I*d3LWX}u8fWkS=`R9^%yIyHo^kI zeCyKskx0h}wHSsdtF{}`2l0GXXN$nepb?`4halh0S;`=f!R7Vhqn)#qM;5*TFZhg( zqNj7d-XA`QD+F3PKIz&om5uT@umt?yPY4_p(Fq}qNG$?Wg|fW0i*`+CeX0c6zsvb0 zJTvR{uw|fAb$$cH0hEMwQY9Cj=v%k?LP28zd*v4CtCkc6gFp7MbB*too3E+iae)6f cb~(9_QtoW{&%#_IbDII_Yco>nld}&04UQMjaR2}S literal 0 HcmV?d00001 diff --git a/www/icons/maskable-512.png b/www/icons/maskable-512.png new file mode 100644 index 0000000000000000000000000000000000000000..9e30af4314641d489bcd16ca9374cfaa791be4ef GIT binary patch literal 3332 zcmds4`&W`@9DlrIme*=ajl}A-wU*_`Gp&hYTORV9)Y8srQE5R!rDk3hm=lQ%B z_r&A9mabX~0Pu?4wKEX_XZx!&aCfsm-qN0#0q~T>?%c7D#(q84QGR&x)1nF8^CKt{ zo#|G5?%XFEPbA*_F?(@ti*rNCy2|J)e~uIPtp9D_?ZmaqmJGi~jdr`qW0!4=`?)UU zarIH9=Jx!6vWL$yzS<=FM$wuz-3*GZr}vHHXOOS}s&jOu`wpqsTepYwCUOQ}L(7zCQ9>*6JyLP6Mnnu|x z5VtiodINFqqE3eRf#B(Bd-MN40mF+<$C@^$kNgZ{xMTN4;HSl~s2#rUqr3$AjXEdk%C!5MsVvOntCED%wRO7 z=RF~$jp3qD^4&a-hUFU&i&j$9yj6*n=Ff4a4UL@#ht!fHrT-R}vw09-u_{4pvWTUn zPZ7FC?vm5X#Y%kgJ`?3 zi(sf7;TzJaWkbBe`G4M_Ljt{_Y7}%)P+@gCw9Jv_Wi6+cT_PyA_Y--ejT|PW++Iw% zIvIW;j^wJUhV_tG`s;+zr%ZBfkT5+*Bi2(zEjVsoYZebLC&MRwSP_{4(rr#iC;xz3 zckBXV4UFj#tywU5mO>&^CVLCw`Us6)jSL-&;je(X>n_gBR zYWiI>Z7}p3eONfA&MCQYA1olztc0{kdaCf2rcd8p&?G0MS?SFR%}r*0 zdk2OO>BZ7M*p&3XEhwBklhGcUSzvicBb#k-#@`Xg>ji^PP3~C^onY?8Q6-b=eZJoq zlBpn3CZv~8p*k-=OP%1Jg7T_P#oEiDaDE~hR2J8$|*{8vdGY8qo6`-w^}(iPKS2{L&AXpCG!m~ zP6cyx{=2s$X4fHaxS`o%c6w*ZYsDCj1>%R`LI@omPNplW^6Ubj(X6G+e0HylABTfw zBE3xYrj}XFq0|WB2o6B=@KSqn z7vxYF(N5Q>Xc_~22ViIh1Dmj)mIYU#M z^xcYU%<81z)r2(N@GVK9aJadrlvzEB(n)JkI`vzt%2a;;I-;B5(H0Q@!loa7X&#bm zGRy-LUvXO^xz7#ItQn7*-}bP)M4;xS)|)iLro(V!I2p~8Db4=fGtYEnQ**5zPy~BMf`uh@#;#fOsH*U5VULW+O9)r; zIn*47_q~~`qeTUcd_V9emtJYKiiwrsLMt)XD(GtO^MNi#E)0=3%;j@spd z%Qv2S@Y%oil!7d&91HN>FP2@cNEyrf0c#ke5i`r|EQQVsJ765c`&|pN>vv&J>_XfG z-D~7BDO_6+x0J`?P}K=5-LqnlF`#uGPc$=CM$Ofcyl^<30V*#elFNqxmm1CPZanX? zFL-X^%W5IaXu@7t;Si#x6mP$py3`h*-P(d4+sR_z?~obRLW-<#!jPxjJLNn_a8y3C zvQ(m%crd;+2T`oCC!%!}k>%wtK~BK-5OI`ywDpG9JdO^3SiT84=<^4|PX&gU*Mg#_ h$UW`j3*%34Kz?~8ZtNg^ul?@^#Ky$$Z20y_$$!qKq1pfd literal 0 HcmV?d00001 diff --git a/www/index.html b/www/index.html index 234c41a..227a4e3 100644 --- a/www/index.html +++ b/www/index.html @@ -3,7 +3,14 @@ DungeonCraft - + + + + + + + +