$ cat vfb_client_prettyprint.html
<html>
<head>
<title>Jupiter Lander</title>
<style>body{background:#111;color:#0f0;text-align:center;font-family:monosp
ace}canvas{background:#000;border:2px solid #333;image-rendering:pixelated;widt
h:704px;height:736px}</style>
</head>
<body>
<h2>JUPITER LANDER HUD</h2>
<p>Ohjaa: W (Kaasu), A/D (Sivuraketit)</p>
<canvas id="c" width="176" height="184"></canvas>
<script>const c=document.getElementById('c');const ctx=c.getContext('2d');c
onst es=new EventSource('/stream');es.onmessage=e=>{const d=JSON.parse(e.data);
if(d.type==='FRAME'){const raw=window.atob(d.vfb);const img=ctx.createImageData
(176,184);for(let i=0;i
<raw.length;i++){let p=raw.charCodeAt(i);let x=i*4;if(p===255){img.data[x]=2
55;img.data[x+1]=0;img.data[x+2]=0;img.data[x+3]=255;}else if(p===1){img.data[x
]=136;img.data[x+1]=136;img.data[x+2]=136;img.data[x+3]=255;}else
if(p>1){img.data[x]=0;img.data[x+1]=255;img.data[x+2]=0;img.data[x+3]=255;}else
{img.data[x+3]=255;}}ctx.putImageData(img,0,0);}};const k={'w':'W','W':'W','a':
'A','A':'A','d':'D','D':'D'};window.onkeydown=e=>{if(k[e.key]&&!e.repeat)fetch(
'/input?k='+k[e.key]+'&a=DOWN');};window.onkeyup=e=>{if(k[e.key])fetch('/input?
k='+k[e.key]+'&a=UP');};
</script>
</body>
</html>
$ cat jupiter_lander.bas
10 REM === JUPITER LANDER (VFB + OMEGA TERMINAL) ===
20 SCREEN 176, 184
30 SETGRAVITY 0.05
40 MAPGEN "CAVE", SEED 1337, WIDTH 40, ROUGHNESS 0
50 RECT 1, 20, 160, 40, 175, 2
60 SPRITE 1, "LANDER"
70 MOVE SPRITE 1, 84, 10
80 LET C = "ch_input"
90 STATE BIND "KEY" FROM C
100 LET FUEL = 100
200 REM --- GAME LOOP ---
210 STATE READ "KEY.W" INTO THRUST_UP
220 STATE READ "KEY.A" INTO THRUST_LEFT
230 STATE READ "KEY.D" INTO THRUST_RIGHT
240 IF FUEL <= 0 THEN GOTO 300
250 IF THRUST_UP == 1 THEN ADDSPEEDY 1, -0.15: LET FUEL = FUEL - 1
260 IF THRUST_LEFT == 1 THEN ADDSPEEDX 1, -0.05: LET FUEL = FUEL - 0.5
270 IF THRUST_RIGHT == 1 THEN ADDSPEEDX 1, 0.05: LET FUEL = FUEL - 0.5
300 WAIT VBLANK
310 BUFFER BLIT SCREEN
320 CHECKCOLLISION 1 INTO COL
330 IF COL == 0 THEN GOTO 200
400 REM --- END GAME ---
410 IF COL == -1 THEN PRINT ">>> RAJAHDIT KALLIOON! <<<"
420 IF COL > 1 THEN PRINT ">>> LASKEUDUIT TURVALLISESTI! <<<"
430 HALT
$