[object Object]

← back to Neon Baguette Battle

Redesign fighters as Frenchmen in berets wielding baguettes; special now launches the baguette as a spinning missile (Baguette Missile)

d93d9acb84950f48ccc4a7a784ab22e181e1d6f6 · 2026-08-31 13:17:47 -0700 · Steve Abrams

- Fighters redrawn: beret + Breton-striped shirt + moustache, holding a baguette weapon (jab/whack animate the baguette)
- Special (H // ) launches the baguette as a spinning projectile instead of a crumb ball
- Character-select mini-portraits redrawn as little Frenchmen
- Voice + HUD + controls + copy updated (Baguette Missile)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files touched

Diff

commit d93d9acb84950f48ccc4a7a784ab22e181e1d6f6
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Aug 31 13:17:47 2026 -0700

    Redesign fighters as Frenchmen in berets wielding baguettes; special now launches the baguette as a spinning missile (Baguette Missile)
    
    - Fighters redrawn: beret + Breton-striped shirt + moustache, holding a baguette weapon (jab/whack animate the baguette)
    - Special (H // ) launches the baguette as a spinning projectile instead of a crumb ball
    - Character-select mini-portraits redrawn as little Frenchmen
    - Voice + HUD + controls + copy updated (Baguette Missile)
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
 .gitignore     |   3 +
 README.md      |  13 +--
 fight2p.png    | Bin 303502 -> 0 bytes
 index.html     | 281 +++++++++++++++++++++++++++++++--------------------------
 screenshot.png | Bin 304810 -> 0 bytes
 select.png     | Bin 279933 -> 0 bytes
 6 files changed, 161 insertions(+), 136 deletions(-)

diff --git a/.gitignore b/.gitignore
index 1924158..f9eb2e0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,6 @@ tmp/
 dist/
 build/
 .next/
+
+# scratch test screenshots
+*.png
diff --git a/README.md b/README.md
index 03b00a5..5f3583d 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,10 @@
 # Baguette Battle — Neon Paris 🥖⚔️
 
-A playable browser fighting game. Two artisanal baguettes duel beneath a neon
-Eiffel Tower while pies, french rolls, and croissants fly across the arena.
-Single self-contained `index.html` — no build step, no dependencies, no assets.
-Open it in any modern browser and play.
+A playable browser fighting game. Two mustachioed **Frenchmen in berets** duel
+with **baguettes** beneath a neon Eiffel Tower — jab, whack, block, and **launch
+your baguette like a spinning missile** — while pies, french rolls, and
+croissants fly across the arena. Single self-contained `index.html` — no build
+step, no dependencies, no assets. Open it in any modern browser and play.
 
 Built from a Model Arena challenge ("a game where baguettes in Paris fight each
 other"). The starting artifact (Qwen2.5-local) was just a title card with an
@@ -38,8 +39,8 @@ also click a card to choose P1's fighter. `Enter`/`Space` or **START FIGHT** beg
 
 ## Features
 - **Real combat**: startup/active/recovery attack frames, blocking with chip
-  damage, knockback, hit-stun, a build-up special meter, and a **Crumb Blast**
-  projectile.
+  damage, knockback, hit-stun, a build-up special meter, and a **launched
+  baguette missile** (spinning projectile) once the meter is full.
 - **CPU opponent** with an approach/attack/block/retreat/blast state machine.
 - **Flying food hazards**: pies (cream splat, big damage), french rolls (fast),
   and croissants arc in from off-screen and hit either fighter.
diff --git a/fight2p.png b/fight2p.png
deleted file mode 100644
index c8b8f2b..0000000
Binary files a/fight2p.png and /dev/null differ
diff --git a/index.html b/index.html
index a39ff66..872a307 100644
--- a/index.html
+++ b/index.html
@@ -98,8 +98,8 @@
   <div class="screen" id="menu">
     <h1>BAGUETTE BATTLE</h1>
     <div class="sub"><span class="flag"></span> Neon&nbsp;Paris&nbsp;Combat&nbsp;Arena <span class="flag"></span></div>
-    <p>Two artisanal baguettes settle their differences beneath a neon Eiffel Tower.
-       Poke, swing, block, and unleash the <b>Crumb Blast</b>. Best of 3 rounds wins.</p>
+    <p>Two Parisians settle their differences with baguettes beneath a neon Eiffel Tower.
+       Poke, whack, block — then <b>launch your baguette like a missile</b>. Best of 3 rounds wins.</p>
     <div class="btns">
       <button class="primary" id="btn1p">1 PLAYER · vs&nbsp;CPU</button>
       <button id="btn2p">2 PLAYERS · local</button>
@@ -110,9 +110,9 @@
           <tr><td>Move</td><td><span class="key">A</span><span class="key">D</span></td></tr>
           <tr><td>Jump</td><td><span class="key">W</span></td></tr>
           <tr><td>Block</td><td><span class="key">S</span></td></tr>
-          <tr><td>Poke</td><td><span class="key">F</span></td></tr>
-          <tr><td>Swing</td><td><span class="key">G</span></td></tr>
-          <tr><td>Crumb Blast</td><td><span class="key">H</span></td></tr>
+          <tr><td>Jab (baguette)</td><td><span class="key">F</span></td></tr>
+          <tr><td>Whack (baguette)</td><td><span class="key">G</span></td></tr>
+          <tr><td>Launch baguette 🚀</td><td><span class="key">H</span></td></tr>
         </table>
       </div>
       <div class="ctl p2"><h3>🥖 Player 2</h3>
@@ -120,9 +120,9 @@
           <tr><td>Move</td><td><span class="key">←</span><span class="key">→</span></td></tr>
           <tr><td>Jump</td><td><span class="key">↑</span></td></tr>
           <tr><td>Block</td><td><span class="key">↓</span></td></tr>
-          <tr><td>Poke</td><td><span class="key">,</span></td></tr>
-          <tr><td>Swing</td><td><span class="key">.</span></td></tr>
-          <tr><td>Crumb Blast</td><td><span class="key">/</span></td></tr>
+          <tr><td>Jab (baguette)</td><td><span class="key">,</span></td></tr>
+          <tr><td>Whack (baguette)</td><td><span class="key">.</span></td></tr>
+          <tr><td>Launch baguette 🚀</td><td><span class="key">/</span></td></tr>
         </table>
       </div>
     </div>
@@ -250,7 +250,7 @@
       taunt:  () => say(rnd(["Take zat!","Ooh la la!","On garde!","Zut alors!","Eat my baguette!","Ha! Too slow, mon ami!"]), {pitch:1.15}),
       hurt:   () => say(rnd(["Oh non!","Mon dieu!","Sacrebleu!","Ze pain!","Aïe!"]), {pitch:1.25, rate:1.05}),
       block:  () => say(rnd(["Non non non!","Not today!"]), {pitch:1.15}),
-      blast:  () => say("Crumb blast! Boom!", {rate:0.9, pitch:1.0, force:true}),
+      blast:  () => say(rnd(["Baguette missile! Allez!","Fire ze baguette!","Incoming! Ha ha!"]), {rate:0.95, pitch:1.05, force:true}),
       round:  () => say("Allez!", {force:true, pitch:1.1}),
       fight:  () => say("Fight, mon ami!", {force:true, pitch:1.15}),
       ko:     () => say("Oh la la! Magnifique!", {force:true, pitch:1.05}),
@@ -531,118 +531,132 @@
       if (koFall>0){ g.rotate(koFall*Math.PI*0.5*0.9); g.translate(0, koFall*10); }
       g.rotate(lean*Math.PI/180);
 
-      // ---- baguette body ----
-      const bx=0, by=-this.h, bw=this.w, bh=this.h;
+      // ===== Frenchman with beret, wielding a baguette =====
+      const legPhase = this.state==='walk' ? Math.sin(this.animT) : 0;
+      const armExt = this.armSwing;
+      const skin='#e8b892', skinDk='#c98f68', trouser='#242a42', shoe='#141414';
+      const shirt = hurtFlash ? '#ffffff' : '#f2efe6';
+      const hipY=-46, shoY=-86, headR=14, headCY=-104;
+
+      // ---- legs + shoes ----
+      g.lineCap='round';
+      g.strokeStyle=trouser; g.lineWidth=13;
+      g.beginPath(); g.moveTo(-8,hipY); g.lineTo(-9 - legPhase*7, -3); g.stroke();
+      g.beginPath(); g.moveTo( 8,hipY); g.lineTo( 9 + legPhase*7, -3); g.stroke();
+      g.strokeStyle=shoe; g.lineWidth=7;
+      g.beginPath(); g.moveTo(-9-legPhase*7,-2); g.lineTo(-14-legPhase*7,-1); g.stroke();
+      g.beginPath(); g.moveTo( 9+legPhase*7,-2); g.lineTo( 14+legPhase*7,-1); g.stroke();
+
+      // ---- back arm (behind torso) ----
+      const backHy = shoY+12+22+Math.sin(this.animT)*2;
+      g.strokeStyle=shirt; g.lineWidth=8; g.lineCap='round';
+      g.beginPath(); g.moveTo(-this.w*0.16, shoY+12); g.lineTo(-this.w*0.16-6, backHy); g.stroke();
+      g.fillStyle=skin; g.beginPath(); g.arc(-this.w*0.16-6, backHy, 4,0,Math.PI*2); g.fill();
+
+      // ---- torso: Breton-striped shirt ----
+      const tw=this.w*0.8, tx=-tw/2, ty=shoY, thh=hipY-shoY+6;
       g.save();
-      g.translate(0,0);
-      // body glow
-      g.shadowColor = c.glow; g.shadowBlur = hurtFlash?26:14;
-      roundRectPath(g, -bw/2, by, bw, bh, bw/2);
-      const grd = g.createLinearGradient(-bw/2,0,bw/2,0);
-      grd.addColorStop(0, c.crustDk); grd.addColorStop(0.5, c.crust); grd.addColorStop(1, c.crustDk);
-      g.fillStyle = hurtFlash ? '#ffffff' : grd; g.fill();
-      g.shadowBlur = 0;
-      // crust rim
-      g.lineWidth = 3; g.strokeStyle = 'rgba(90,55,15,.7)'; g.stroke();
-
-      // baguette diagonal score marks
+      g.shadowColor=c.glow; g.shadowBlur=hurtFlash?24:12;
+      roundRectPath(g, tx, ty, tw, thh, 9); g.fillStyle=shirt; g.fill();
+      g.shadowBlur=0;
       if (!hurtFlash){
-        g.strokeStyle = 'rgba(120,72,20,.85)'; g.lineWidth = 3;
-        for (let i=0;i<5;i++){
-          const yy = by + 22 + i*(bh-40)/4;
-          g.beginPath();
-          g.moveTo(-bw*0.22, yy);
-          g.quadraticCurveTo(0, yy-8, bw*0.24, yy-3);
-          g.stroke();
-        }
-        // flour speckles
-        g.fillStyle = 'rgba(255,248,230,.5)';
-        for (let i=0;i<8;i++){
-          const sx=(Math.sin(i*12.9+this.side.length)*0.5)*bw*0.7;
-          const sy=by+18+((i*37)%(bh-30));
-          g.beginPath(); g.arc(sx, sy, 1.6, 0, Math.PI*2); g.fill();
-        }
+        g.save(); roundRectPath(g, tx, ty, tw, thh, 9); g.clip();
+        g.fillStyle=c.accent;
+        for (let sy=ty+5; sy<ty+thh; sy+=10) g.fillRect(tx, sy, tw, 5);
+        g.restore();
       }
+      g.lineWidth=2; g.strokeStyle='rgba(0,0,0,.28)'; roundRectPath(g, tx, ty, tw, thh, 9); g.stroke();
       g.restore();
 
-      // ---- beret ----
-      g.save();
-      g.translate(0, by+4);
-      g.fillStyle = c.beret;
-      g.beginPath(); g.ellipse(2, 0, bw*0.42, 12, 0, 0, Math.PI*2); g.fill();
-      g.beginPath(); g.arc(2, -6, bw*0.34, Math.PI, 0); g.fill();
-      g.fillStyle = '#1a1a1a'; g.beginPath(); g.arc(bw*0.30, -8, 2.5, 0, Math.PI*2); g.fill(); // stalk
-      g.restore();
+      // ---- neckerchief ----
+      g.fillStyle=c.beret;
+      g.beginPath(); g.moveTo(-8, shoY+2); g.lineTo(8, shoY+2); g.lineTo(0, shoY+13); g.closePath(); g.fill();
 
-      // ---- face ----
-      const eyeY = by + 34;
-      g.fillStyle = '#20140a';
-      // eyes
-      g.beginPath(); g.ellipse(-9, eyeY, 4, 6, 0, 0, Math.PI*2); g.fill();
-      g.beginPath(); g.ellipse( 9, eyeY, 4, 6, 0, 0, Math.PI*2); g.fill();
-      if (this.state!=='ko'){
-        g.fillStyle='#fff';
-        g.beginPath(); g.arc(-8, eyeY-2, 1.6,0,Math.PI*2); g.fill();
-        g.beginPath(); g.arc(10, eyeY-2, 1.6,0,Math.PI*2); g.fill();
-      }
-      // angry brows
-      g.strokeStyle='#20140a'; g.lineWidth=3; g.beginPath();
-      g.moveTo(-15, eyeY-9); g.lineTo(-4, eyeY-5);
-      g.moveTo( 15, eyeY-9); g.lineTo( 4, eyeY-5); g.stroke();
-      // mouth
-      g.beginPath();
-      if (this.state==='ko'){ g.arc(0, eyeY+20, 6, 0, Math.PI, true); }
-      else if (this.state==='hurt'){ g.arc(0, eyeY+18, 7, 0, Math.PI*2); }
-      else if (this.attack){ g.arc(0, eyeY+16, 6, 0, Math.PI*2); }
-      else { g.arc(0, eyeY+20, 8, 0.15*Math.PI, 0.85*Math.PI); }
-      g.stroke();
-
-      // ---- scarf (accent) ----
-      g.fillStyle = c.accent;
-      g.fillRect(-bw/2, by+bh*0.52, bw, 10);
-      g.fillRect(bw/2-14, by+bh*0.52, 10, 26);
-
-      // ---- arms ----
-      const armExt = this.armSwing;
-      g.strokeStyle = c.crustDk; g.lineWidth = 8; g.lineCap='round';
-      // back arm
-      g.beginPath(); g.moveTo(-bw*0.35, by+bh*0.45); g.lineTo(-bw*0.35-8, by+bh*0.62); g.stroke();
-      // front arm (attacking)
-      const shoulderX = bw*0.35, shoulderY = by+bh*0.44;
-      let handX, handY;
-      if (this.state==='swing'){
-        const ang = -0.7 + armExt*2.0;
-        handX = shoulderX + Math.cos(ang)*(46+armExt*34);
-        handY = shoulderY + Math.sin(ang)*(46+armExt*34);
+      // ---- front arm + baguette weapon ----
+      const sx=this.w*0.2, sy=shoY+10;
+      let hx, hy, bang;
+      if (this.state==='swing'){                 // overhead whack that sweeps down
+        bang = -2.1 + armExt*2.7;
+        hx = sx + 6 + Math.cos(bang)*6; hy = sy + 2 + Math.sin(bang)*6;
       } else if (this.state==='poke' || (this.attack&&this.attack.type==='blast')){
-        handX = shoulderX + (34 + armExt*30);
-        handY = shoulderY + 6;
+        hx = sx + 12 + armExt*26; hy = sy + 8; bang = -0.12;   // thrust / throw
       } else if (this.state==='block'){
-        handX = shoulderX - 6; handY = shoulderY + 4;
+        hx = sx - 2; hy = sy + 4; bang = -1.45;                // raised guard
       } else {
-        handX = shoulderX + 6 + Math.sin(this.animT)*2; handY = shoulderY + 20;
+        hx = sx + 8 + Math.sin(this.animT)*2; hy = sy + 16; bang = -0.15;  // held ready
       }
-      g.beginPath(); g.moveTo(shoulderX, shoulderY); g.lineTo(handX, handY); g.stroke();
-      // little baguette-crumb fist
-      g.fillStyle = c.crust; g.beginPath(); g.arc(handX, handY, 7, 0, Math.PI*2); g.fill();
+      g.strokeStyle=shirt; g.lineWidth=9; g.lineCap='round';
+      g.beginPath(); g.moveTo(sx, sy); g.lineTo(hx, hy); g.stroke();
+      const hideBag = this.attack && this.attack.type==='blast';   // baguette is airborne as a missile
+      if (!hideBag) drawBaguetteWeapon(g, hx, hy, bang, 46, true);
+      g.fillStyle=skin; g.beginPath(); g.arc(hx, hy, 5, 0, Math.PI*2); g.fill();
 
-      // block shield shimmer
+      // block shimmer
       if (this.state==='block'){
-        g.strokeStyle='rgba(180,225,255,.8)'; g.lineWidth=3;
-        g.beginPath(); g.arc(bw*0.2, by+bh*0.5, bw*0.6, -0.7, 0.7); g.stroke();
+        g.strokeStyle='rgba(180,225,255,.85)'; g.lineWidth=3;
+        g.beginPath(); g.arc(this.w*0.12, shoY+thh*0.4, this.w*0.55, -0.7, 0.7); g.stroke();
       }
 
-      // ---- legs ----
-      g.strokeStyle=c.crustDk; g.lineWidth=8;
-      const legPhase = this.state==='walk'? Math.sin(this.animT):0;
-      g.beginPath(); g.moveTo(-10, by+bh-6); g.lineTo(-12 - legPhase*8, by+bh+10); g.stroke();
-      g.beginPath(); g.moveTo( 10, by+bh-6); g.lineTo( 12 + legPhase*8, by+bh+10); g.stroke();
+      // ---- head ----
+      g.save();
+      g.translate(2, headCY);
+      g.fillStyle=skin; g.fillRect(-4, headR-5, 8, 8);            // neck
+      g.fillStyle = hurtFlash ? '#ffffff' : skin;                 // face
+      g.beginPath(); g.arc(0,0,headR,0,Math.PI*2); g.fill();
+      g.strokeStyle=skinDk; g.lineWidth=1.5; g.stroke();
+      g.fillStyle=skin; g.beginPath(); g.arc(-headR+2, 2, 3, 0, Math.PI*2); g.fill();  // ear
+      if (this.state==='ko'){
+        g.strokeStyle='#20140a'; g.lineWidth=2;
+        for (const ex of [4,10]){ g.beginPath(); g.moveTo(ex-2,-5); g.lineTo(ex+2,-1); g.moveTo(ex+2,-5); g.lineTo(ex-2,-1); g.stroke(); }
+      } else {
+        g.fillStyle='#20140a';
+        g.beginPath(); g.arc(5,-3,2,0,Math.PI*2); g.fill();
+        g.beginPath(); g.arc(11,-3,2,0,Math.PI*2); g.fill();
+        g.strokeStyle='#20140a'; g.lineWidth=2.5;
+        g.beginPath(); g.moveTo(1,-8); g.lineTo(8,-5); g.moveTo(8,-6); g.lineTo(14,-8); g.stroke();  // brows
+      }
+      // grand moustache
+      g.strokeStyle='#3b2415'; g.lineWidth=3; g.lineCap='round';
+      g.beginPath(); g.moveTo(1,6); g.quadraticCurveTo(5,3,9,5);
+      g.moveTo(9,5); g.quadraticCurveTo(12,3,15,7); g.stroke();
+      // mouth
+      g.strokeStyle='#20140a'; g.lineWidth=2; g.beginPath();
+      if (this.state==='hurt') g.arc(7, 9, 3.5, 0, Math.PI*2);
+      else if (this.attack) g.arc(7, 9, 3, 0, Math.PI*2);
+      else g.arc(7, 8, 4, 0.1*Math.PI, 0.9*Math.PI);
+      g.stroke();
+      // ---- beret (hat) ----
+      g.fillStyle=c.beret;
+      g.beginPath(); g.ellipse(1, -headR+3, headR*0.98, 5.5, 0, 0, Math.PI*2); g.fill();
+      g.beginPath(); g.arc(1, -headR-2, headR*0.86, Math.PI, 0); g.fill();
+      g.fillStyle='#1a1a1a'; g.beginPath(); g.arc(headR*0.55, -headR-3, 2.2, 0, Math.PI*2); g.fill();  // stalk
+      g.restore();
 
       g.restore(); // bob/ko
       g.restore(); // translate/scale
     }
   }
 
+  // draws a baguette starting at (x,y) extending length `len` along +x, rotated by `angle`
+  function drawBaguetteWeapon(g, x, y, angle, len, glow){
+    g.save();
+    g.translate(x,y); g.rotate(angle);
+    const bw = 9;
+    g.shadowColor='#ffcf6b'; g.shadowBlur = glow?10:0;
+    roundRectPath(g, 0, -bw/2, len, bw, bw/2);
+    const grd = g.createLinearGradient(0,-bw/2,0,bw/2);
+    grd.addColorStop(0,'#e9c079'); grd.addColorStop(.5,'#d9a441'); grd.addColorStop(1,'#a9761f');
+    g.fillStyle = grd; g.fill();
+    g.shadowBlur = 0;
+    g.lineWidth = 1.5; g.strokeStyle = 'rgba(90,55,15,.65)'; g.stroke();
+    // score marks
+    g.strokeStyle = 'rgba(110,66,18,.8)'; g.lineWidth = 1.6;
+    for (let i=1;i<4;i++){ const xx = len*i/4; g.beginPath(); g.moveTo(xx-3,-2); g.quadraticCurveTo(xx, -bw*0.6, xx+3,-1); g.stroke(); }
+    // rounded tips highlight
+    g.fillStyle='rgba(255,245,220,.35)'; g.beginPath(); g.ellipse(len-3,0,2.5,bw*0.28,0,0,Math.PI*2); g.fill();
+    g.restore();
+  }
+
   function roundRectPath(g,x,y,w,h,r){
     r = Math.min(r, w/2, h/2);
     g.beginPath();
@@ -657,8 +671,8 @@
   // ---------- Projectiles & particles ----------
   let blasts = [], sparks = [], hazards = [], hazardTimer = 140, shake = 0;
   function spawnBlast(owner){
-    blasts.push({ x: owner.x + owner.facing*owner.w*0.5, y: owner.y - owner.h*0.5,
-                  vx: owner.facing*10, r: 16, owner, life: 90, t:0 });
+    blasts.push({ x: owner.x + owner.facing*owner.w*0.5, y: owner.y - owner.h*0.62,
+                  vx: owner.facing*11, r: 22, owner, life: 90, t:0, rot: 0 });
   }
   function spawnSpark(x,y,color,n){
     for (let i=0;i<n;i++){
@@ -668,7 +682,7 @@
   }
   function updateProjectiles(f1,f2){
     for (const b of blasts){
-      b.t++; b.x += b.vx; b.life--;
+      b.t++; b.x += b.vx; b.rot += 0.5*Math.sign(b.vx); b.life--;
       const foe = b.owner === f1 ? f2 : f1;
       const hb = foe.hurtbox();
       if (b.x+b.r > hb.x && b.x-b.r < hb.x+hb.w && b.y+b.r>hb.y && b.y-b.r<hb.y+hb.h){
@@ -684,14 +698,13 @@
     for (const b of blasts){
       const c = b.owner.colors;
       g.save();
-      g.globalAlpha = 0.9;
-      g.shadowColor = c.glow; g.shadowBlur = 24;
-      const grd = g.createRadialGradient(b.x,b.y,2,b.x,b.y,b.r);
-      grd.addColorStop(0,'#fff'); grd.addColorStop(0.4,c.crust); grd.addColorStop(1,c.glow);
-      g.fillStyle = grd;
-      g.beginPath(); g.arc(b.x,b.y,b.r,0,Math.PI*2); g.fill();
-      // trailing crumbs
-      for (let i=1;i<=3;i++){ g.globalAlpha=0.4/i; g.beginPath(); g.arc(b.x-b.vx*i*1.6,b.y,b.r*(1-i*0.2),0,Math.PI*2); g.fill(); }
+      // motion trail
+      g.fillStyle = c.glow;
+      for (let i=1;i<=4;i++){ g.globalAlpha = 0.28/i; g.beginPath(); g.arc(b.x-b.vx*i*1.5, b.y, 7-i, 0, Math.PI*2); g.fill(); }
+      // the spinning baguette missile
+      g.globalAlpha = 1;
+      g.translate(b.x, b.y); g.rotate(b.rot);
+      drawBaguetteWeapon(g, -24, 0, 0, 48, true);   // centered on flight path
       g.restore();
     }
     for (const s of sparks){
@@ -933,7 +946,7 @@
     if (val>=100){ g.shadowColor=c.glow; g.shadowBlur=10; }
     g.fillRect(bx,y,bw,h); g.shadowBlur=0;
     if (val>=100){ g.fillStyle=c.accent; g.font='700 9px Georgia'; g.textAlign=flip?'right':'left';
-      g.fillText('CRUMB BLAST READY', flip?x+w:x, y+18); g.textAlign='left'; }
+      g.fillText('BAGUETTE MISSILE READY', flip?x+w:x, y+18); g.textAlign='left'; }
   }
   function drawPips(g,x,y,n,flip){
     for (let i=0;i<2;i++){
@@ -959,23 +972,31 @@
 
   function drawMini(g, c){
     g.clearRect(0,0,56,70);
-    g.save(); g.translate(28, 37);
-    const bw = 24, bh = 52;
-    roundRectPath(g, -bw/2, -bh/2, bw, bh, bw/2);
-    const grd = g.createLinearGradient(-bw/2,0,bw/2,0);
-    grd.addColorStop(0,c.crustDk); grd.addColorStop(.5,c.crust); grd.addColorStop(1,c.crustDk);
-    g.fillStyle = grd; g.fill();
-    g.lineWidth = 2; g.strokeStyle = 'rgba(90,55,15,.7)'; g.stroke();
-    g.strokeStyle = 'rgba(120,72,20,.85)'; g.lineWidth = 2;
-    for (let i=0;i<4;i++){ const yy = -bh/2+11+i*11; g.beginPath(); g.moveTo(-5,yy); g.quadraticCurveTo(0,yy-4,6,yy-1); g.stroke(); }
-    g.fillStyle = c.beret; g.beginPath(); g.ellipse(1,-bh/2+1,bw*0.5,4.5,0,0,Math.PI*2); g.fill();
-    g.beginPath(); g.arc(1,-bh/2-3,bw*0.4,Math.PI,0); g.fill();
-    g.fillStyle = '#20140a';
-    g.beginPath(); g.arc(-4.5,-bh/2+15,2.2,0,Math.PI*2); g.fill();
-    g.beginPath(); g.arc(4.5,-bh/2+15,2.2,0,Math.PI*2); g.fill();
-    g.strokeStyle='#20140a'; g.lineWidth=2; g.beginPath();
-    g.moveTo(-8,-bh/2+9); g.lineTo(-2,-bh/2+12); g.moveTo(8,-bh/2+9); g.lineTo(2,-bh/2+12); g.stroke();
-    g.fillStyle = c.accent; g.fillRect(-bw/2, bh*0.16, bw, 4);
+    g.save(); g.translate(28, 64);           // feet near bottom
+    const skin='#e8b892';
+    // legs
+    g.strokeStyle='#242a42'; g.lineWidth=6; g.lineCap='round';
+    g.beginPath(); g.moveTo(-5,-20); g.lineTo(-6,-2); g.stroke();
+    g.beginPath(); g.moveTo( 5,-20); g.lineTo( 6,-2); g.stroke();
+    // striped torso
+    const tw=20, th=22, tx=-tw/2, ty=-44;
+    roundRectPath(g,tx,ty,tw,th,5); g.fillStyle='#f2efe6'; g.fill();
+    g.save(); roundRectPath(g,tx,ty,tw,th,5); g.clip(); g.fillStyle=c.accent;
+    for (let sy=ty+3; sy<ty+th; sy+=6) g.fillRect(tx,sy,tw,3); g.restore();
+    g.lineWidth=1.4; g.strokeStyle='rgba(0,0,0,.25)'; roundRectPath(g,tx,ty,tw,th,5); g.stroke();
+    // arm + held baguette
+    g.strokeStyle='#f2efe6'; g.lineWidth=5; g.beginPath(); g.moveTo(6,-40); g.lineTo(13,-34); g.stroke();
+    drawBaguetteWeapon(g, 13, -34, -0.15, 22, false);
+    g.fillStyle=skin; g.beginPath(); g.arc(13,-34,3,0,Math.PI*2); g.fill();
+    // head
+    g.save(); g.translate(0,-50);
+    g.fillStyle=skin; g.beginPath(); g.arc(0,0,9,0,Math.PI*2); g.fill();
+    g.strokeStyle='#3b2415'; g.lineWidth=2; g.lineCap='round';
+    g.beginPath(); g.moveTo(-4,3); g.quadraticCurveTo(-1,1,0,3); g.moveTo(0,3); g.quadraticCurveTo(1,1,4,3); g.stroke();  // moustache
+    g.fillStyle='#20140a'; g.beginPath(); g.arc(-3,-1,1.4,0,7); g.fill(); g.beginPath(); g.arc(3,-1,1.4,0,7); g.fill();
+    g.fillStyle=c.beret; g.beginPath(); g.ellipse(0,-8,10,3.5,0,0,Math.PI*2); g.fill();
+    g.beginPath(); g.arc(1,-11,8,Math.PI,0); g.fill();
+    g.restore();
     g.restore();
   }
 
diff --git a/screenshot.png b/screenshot.png
deleted file mode 100644
index 0a9643b..0000000
Binary files a/screenshot.png and /dev/null differ
diff --git a/select.png b/select.png
deleted file mode 100644
index 4c871e9..0000000
Binary files a/select.png and /dev/null differ

← b93e403 Add two-player character select: 6 baguette fighters with Sp  ·  back to Neon Baguette Battle  ·  Bigger, faster baguette missile + alternate 1P controls (arr 4fcd312 →