Skip to content

Instantly share code, notes, and snippets.

@rndmcnlly
Created January 24, 2026 00:04
Show Gist options
  • Select an option

  • Save rndmcnlly/7ec88268ab0b8760d17c06d5937fce12 to your computer and use it in GitHub Desktop.

Select an option

Save rndmcnlly/7ec88268ab0b8760d17c06d5937fce12 to your computer and use it in GitHub Desktop.
<!-- Vibe-coded with Gambit v1.3 (https://bayleaf.chat/?model=gambit) -->
<!-- DESIGN QUESTION: Does a bounded park with optional destinations feel like -->
<!-- peaceful contentment or subtle confinement? Watch how you move. Do you -->
<!-- visit things purposefully, or drift? Do you test the fences? -->
<!DOCTYPE html>
<html>
<head>
<title>Park Walk</title>
<style>
* { margin: 0; box-sizing: border-box; }
body { background: #2a3a2a; display: flex; justify-content: center; align-items: center; height: 100vh; }
canvas { border-radius: 8px; box-shadow: 0 0 40px rgba(0,0,0,0.5); }
</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const W = 480, H = 480;
const c = document.getElementById('c');
c.width = W; c.height = H;
const ctx = c.getContext('2d');
// === PARK DATA (edit these to reshape the world) ===
const GRASS = '#5a7a4a';
const PATH_COLOR = '#8b7355';
const FENCE_COLOR = '#4a3728';
const FENCE_MARGIN = 30;
const locations = [
{ x: 240, y: 120, type: 'fountain', label: 'Fountain' },
{ x: 80, y: 200, type: 'bench', label: 'Bench' },
{ x: 400, y: 200, type: 'tree', label: 'Old Oak' },
{ x: 140, y: 380, type: 'pond', label: 'Duck Pond' },
{ x: 360, y: 360, type: 'bench', label: 'Quiet Bench' },
];
// === PLAYER STATE ===
let player = { x: 240, y: 280, speed: 1.8 };
let keys = {};
let visitLog = [];
// === INPUT ===
window.addEventListener('keydown', e => keys[e.key] = true);
window.addEventListener('keyup', e => keys[e.key] = false);
// === HELPERS ===
function clamp(v, min, max) { return Math.max(min, Math.min(max, v)); }
function dist(a, b) { return Math.hypot(a.x - b.x, a.y - b.y); }
// === DRAWING ===
function drawFence() {
ctx.strokeStyle = FENCE_COLOR;
ctx.lineWidth = 6;
ctx.strokeRect(FENCE_MARGIN, FENCE_MARGIN, W - FENCE_MARGIN*2, H - FENCE_MARGIN*2);
// fence posts
ctx.fillStyle = FENCE_COLOR;
for (let i = FENCE_MARGIN; i <= W - FENCE_MARGIN; i += 40) {
ctx.fillRect(i - 3, FENCE_MARGIN - 5, 6, 10);
ctx.fillRect(i - 3, H - FENCE_MARGIN - 5, 6, 10);
}
for (let i = FENCE_MARGIN; i <= H - FENCE_MARGIN; i += 40) {
ctx.fillRect(FENCE_MARGIN - 5, i - 3, 10, 6);
ctx.fillRect(W - FENCE_MARGIN - 5, i - 3, 10, 6);
}
}
function drawLocation(loc) {
ctx.save();
ctx.translate(loc.x, loc.y);
if (loc.type === 'fountain') {
ctx.fillStyle = '#6688aa';
ctx.beginPath(); ctx.arc(0, 0, 20, 0, Math.PI*2); ctx.fill();
ctx.fillStyle = '#88aacc';
ctx.beginPath(); ctx.arc(0, 0, 10, 0, Math.PI*2); ctx.fill();
} else if (loc.type === 'bench') {
ctx.fillStyle = '#6b4423';
ctx.fillRect(-15, -5, 30, 10);
ctx.fillStyle = '#5a3a1a';
ctx.fillRect(-12, -8, 6, 3);
ctx.fillRect(6, -8, 6, 3);
} else if (loc.type === 'tree') {
ctx.fillStyle = '#3a2a1a';
ctx.fillRect(-4, -5, 8, 15);
ctx.fillStyle = '#2d5a2d';
ctx.beginPath(); ctx.arc(0, -15, 25, 0, Math.PI*2); ctx.fill();
ctx.fillStyle = '#3a6a3a';
ctx.beginPath(); ctx.arc(-8, -10, 15, 0, Math.PI*2); ctx.fill();
} else if (loc.type === 'pond') {
ctx.fillStyle = '#4a6a8a';
ctx.beginPath(); ctx.ellipse(0, 0, 35, 22, 0, 0, Math.PI*2); ctx.fill();
ctx.fillStyle = '#5a7a9a';
ctx.beginPath(); ctx.ellipse(5, -3, 20, 12, 0.2, 0, Math.PI*2); ctx.fill();
}
ctx.restore();
}
function drawPlayer() {
// shadow
ctx.fillStyle = 'rgba(0,0,0,0.2)';
ctx.beginPath(); ctx.ellipse(player.x, player.y + 8, 8, 4, 0, 0, Math.PI*2); ctx.fill();
// body
ctx.fillStyle = '#d4a574';
ctx.beginPath(); ctx.arc(player.x, player.y, 10, 0, Math.PI*2); ctx.fill();
// head highlight
ctx.fillStyle = '#e4b584';
ctx.beginPath(); ctx.arc(player.x - 2, player.y - 2, 4, 0, Math.PI*2); ctx.fill();
}
function drawUI() {
// nearby location label
let nearby = locations.find(l => dist(player, l) < 35);
if (nearby) {
ctx.fillStyle = 'rgba(255,255,255,0.9)';
ctx.font = '12px Georgia';
ctx.textAlign = 'center';
ctx.fillText(nearby.label, nearby.x, nearby.y - 30);
// log visit
if (!visitLog.includes(nearby.label)) {
visitLog.push(nearby.label);
}
}
// visit counter
ctx.fillStyle = 'rgba(0,0,0,0.5)';
ctx.fillRect(10, H - 25, 120, 18);
ctx.fillStyle = '#fff';
ctx.font = '11px monospace';
ctx.textAlign = 'left';
ctx.fillText(`Visited: ${visitLog.length}/${locations.length}`, 15, H - 12);
// subtle hint
ctx.fillStyle = 'rgba(255,255,255,0.3)';
ctx.font = '10px Georgia';
ctx.textAlign = 'center';
ctx.fillText('arrow keys to walk', W/2, H - 10);
}
// === UPDATE ===
function update() {
let dx = 0, dy = 0;
if (keys['ArrowUp'] || keys['w'] || keys['W']) dy -= 1;
if (keys['ArrowDown'] || keys['s'] || keys['S']) dy += 1;
if (keys['ArrowLeft'] || keys['a'] || keys['A']) dx -= 1;
if (keys['ArrowRight'] || keys['d'] || keys['D']) dx += 1;
// normalize diagonal
if (dx && dy) { dx *= 0.707; dy *= 0.707; }
player.x = clamp(player.x + dx * player.speed, FENCE_MARGIN + 15, W - FENCE_MARGIN - 15);
player.y = clamp(player.y + dy * player.speed, FENCE_MARGIN + 15, H - FENCE_MARGIN - 15);
}
// === MAIN LOOP ===
function frame() {
// grass
ctx.fillStyle = GRASS;
ctx.fillRect(0, 0, W, H);
// wandering paths
ctx.strokeStyle = PATH_COLOR;
ctx.lineWidth = 12;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(240, 50); ctx.quadraticCurveTo(240, 200, 140, 380);
ctx.moveTo(240, 200); ctx.quadraticCurveTo(320, 280, 360, 360);
ctx.moveTo(100, 200); ctx.lineTo(400, 200);
ctx.stroke();
drawFence();
locations.forEach(drawLocation);
update();
drawPlayer();
drawUI();
requestAnimationFrame(frame);
}
frame();
</script>
</body>
</html>

USER

make a walking in the park simulator

ASSISTANT

Thought for 4 seconds > The user wants a "walking in the park simulator." This is a vague prompt, which is perfect for Gambit's approach—I need to probe what design questions this prototype should answer. > > Let me think about what aspects of "walking in the park" could be prototyped and what questions each might answer: > > 1. **Movement feel** - How does the walk feel? Leisurely pace? Player control vs. auto-walk? > 2. **Visual mood** - What's the aesthetic? Peaceful? Lonely? Vibrant? > 3. **Soundscape** - Ambient audio experience? > 4. **Encounters** - Are there NPCs, wildlife, events? > 5. **Time/weather** - Dynamic environment changes? > 6. **Purpose** - Is there a goal, or is it purely meditative? > > Before I jump into code, I should clarify what design question this prototype should answer. This is a rapid prototyping assistant—I need to be curious about intent. > > Let me ask a few pointed questions to narrow down what aspect they want to explore, and maybe suggest a few different prototype directions they could take.
# Walking in the Park Simulator

Love the vibes! But before I throw a prototype together, I'm curious what design question you want this to answer. A few directions:

Movement & Feel

  • How leisurely should walking feel? (auto-scroll vs. player-controlled pace)
  • First-person immersion vs. third-person character watching?

Mood & Atmosphere

  • Is this meditative/calm, melancholic, or cozy-social?
  • Time of day? Weather? Seasonal palette?

Encounters & Interest

  • Pure scenery, or do you pass things (benches, ducks, strangers, dogs)?
  • Any interaction at all, or purely observational?

Purpose

  • Aimless wandering as the point? Or walking toward something?
  • Is this a core loop prototype for a larger game, or a self-contained vibe test?

Quick options I could spin up:

Prototype Tests
Side-scroll park stroll Parallax mood, pace feel, visual layering
Top-down park explorer Spatial freedom, encounter placement
First-person path walker Immersion, 3D mood with minimal geometry
Auto-walking screensaver Pure atmosphere/color/audio vibe check

Which direction resonates—or describe more about your game and I'll target the prototype to your actual question?

USER

You decide all that for me. This is just a demo for a student who tried to get the Basic model on BayLeaf to make a park-walking prototype rather than Gambit. Uh, top-down, a few locations to visit, and test the vibe of complacent existence within bounded freedom (fences?) or something.

ASSISTANT

Thought for 4 seconds > The user wants a quick demo prototype. They've specified: > - Top-down perspective > - A few locations to visit > - Testing the vibe of "complacent existence within bounded freedom" - fences as boundaries > - This is a demo for a student who was using the wrong model > > I should make a self-contained HTML/CSS/JS prototype that: > 1. Has a park with visible boundaries (fences) > 2. Top-down view with a walking character > 3. A few points of interest to visit > 4. Evokes "complacent existence within bounded freedom" > > Design question to test: Does the bounded park with optional destinations create a feeling of peaceful confinement or restless limitation? > > I'll keep it simple but evocative: > - Arrow keys or WASD to move > - Visible fence around the park > - A few spots: bench, pond, tree, maybe a fountain > - Soft colors, gentle movement > - Maybe some ambient details like drifting leaves > > Let me make this efficient and atmospheric.
Got it—one park, one soul, one fence. Let's see if bounded freedom feels like peace or a pretty cage.
<!-- Vibe-coded with Gambit v1.3 (https://bayleaf.chat/?model=gambit) -->
<!-- DESIGN QUESTION: Does a bounded park with optional destinations feel like -->
<!-- peaceful contentment or subtle confinement? Watch how you move. Do you -->
<!-- visit things purposefully, or drift? Do you test the fences? -->
<!DOCTYPE html>
<html>
<head>
<title>Park Walk</title>
<style>
* { margin: 0; box-sizing: border-box; }
body { background: #2a3a2a; display: flex; justify-content: center; align-items: center; height: 100vh; }
canvas { border-radius: 8px; box-shadow: 0 0 40px rgba(0,0,0,0.5); }
</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const W = 480, H = 480;
const c = document.getElementById('c');
c.width = W; c.height = H;
const ctx = c.getContext('2d');

// === PARK DATA (edit these to reshape the world) ===
const GRASS = '#5a7a4a';
const PATH_COLOR = '#8b7355';
const FENCE_COLOR = '#4a3728';
const FENCE_MARGIN = 30;

const locations = [
  { x: 240, y: 120, type: 'fountain', label: 'Fountain' },
  { x: 80, y: 200, type: 'bench', label: 'Bench' },
  { x: 400, y: 200, type: 'tree', label: 'Old Oak' },
  { x: 140, y: 380, type: 'pond', label: 'Duck Pond' },
  { x: 360, y: 360, type: 'bench', label: 'Quiet Bench' },
];

// === PLAYER STATE ===
let player = { x: 240, y: 280, speed: 1.8 };
let keys = {};
let visitLog = [];

// === INPUT ===
window.addEventListener('keydown', e => keys[e.key] = true);
window.addEventListener('keyup', e => keys[e.key] = false);

// === HELPERS ===
function clamp(v, min, max) { return Math.max(min, Math.min(max, v)); }

function dist(a, b) { return Math.hypot(a.x - b.x, a.y - b.y); }

// === DRAWING ===
function drawFence() {
  ctx.strokeStyle = FENCE_COLOR;
  ctx.lineWidth = 6;
  ctx.strokeRect(FENCE_MARGIN, FENCE_MARGIN, W - FENCE_MARGIN*2, H - FENCE_MARGIN*2);
  // fence posts
  ctx.fillStyle = FENCE_COLOR;
  for (let i = FENCE_MARGIN; i <= W - FENCE_MARGIN; i += 40) {
    ctx.fillRect(i - 3, FENCE_MARGIN - 5, 6, 10);
    ctx.fillRect(i - 3, H - FENCE_MARGIN - 5, 6, 10);
  }
  for (let i = FENCE_MARGIN; i <= H - FENCE_MARGIN; i += 40) {
    ctx.fillRect(FENCE_MARGIN - 5, i - 3, 10, 6);
    ctx.fillRect(W - FENCE_MARGIN - 5, i - 3, 10, 6);
  }
}

function drawLocation(loc) {
  ctx.save();
  ctx.translate(loc.x, loc.y);
  
  if (loc.type === 'fountain') {
    ctx.fillStyle = '#6688aa';
    ctx.beginPath(); ctx.arc(0, 0, 20, 0, Math.PI*2); ctx.fill();
    ctx.fillStyle = '#88aacc';
    ctx.beginPath(); ctx.arc(0, 0, 10, 0, Math.PI*2); ctx.fill();
  } else if (loc.type === 'bench') {
    ctx.fillStyle = '#6b4423';
    ctx.fillRect(-15, -5, 30, 10);
    ctx.fillStyle = '#5a3a1a';
    ctx.fillRect(-12, -8, 6, 3);
    ctx.fillRect(6, -8, 6, 3);
  } else if (loc.type === 'tree') {
    ctx.fillStyle = '#3a2a1a';
    ctx.fillRect(-4, -5, 8, 15);
    ctx.fillStyle = '#2d5a2d';
    ctx.beginPath(); ctx.arc(0, -15, 25, 0, Math.PI*2); ctx.fill();
    ctx.fillStyle = '#3a6a3a';
    ctx.beginPath(); ctx.arc(-8, -10, 15, 0, Math.PI*2); ctx.fill();
  } else if (loc.type === 'pond') {
    ctx.fillStyle = '#4a6a8a';
    ctx.beginPath(); ctx.ellipse(0, 0, 35, 22, 0, 0, Math.PI*2); ctx.fill();
    ctx.fillStyle = '#5a7a9a';
    ctx.beginPath(); ctx.ellipse(5, -3, 20, 12, 0.2, 0, Math.PI*2); ctx.fill();
  }
  ctx.restore();
}

function drawPlayer() {
  // shadow
  ctx.fillStyle = 'rgba(0,0,0,0.2)';
  ctx.beginPath(); ctx.ellipse(player.x, player.y + 8, 8, 4, 0, 0, Math.PI*2); ctx.fill();
  // body
  ctx.fillStyle = '#d4a574';
  ctx.beginPath(); ctx.arc(player.x, player.y, 10, 0, Math.PI*2); ctx.fill();
  // head highlight
  ctx.fillStyle = '#e4b584';
  ctx.beginPath(); ctx.arc(player.x - 2, player.y - 2, 4, 0, Math.PI*2); ctx.fill();
}

function drawUI() {
  // nearby location label
  let nearby = locations.find(l => dist(player, l) < 35);
  if (nearby) {
    ctx.fillStyle = 'rgba(255,255,255,0.9)';
    ctx.font = '12px Georgia';
    ctx.textAlign = 'center';
    ctx.fillText(nearby.label, nearby.x, nearby.y - 30);
    
    // log visit
    if (!visitLog.includes(nearby.label)) {
      visitLog.push(nearby.label);
    }
  }
  
  // visit counter
  ctx.fillStyle = 'rgba(0,0,0,0.5)';
  ctx.fillRect(10, H - 25, 120, 18);
  ctx.fillStyle = '#fff';
  ctx.font = '11px monospace';
  ctx.textAlign = 'left';
  ctx.fillText(`Visited: ${visitLog.length}/${locations.length}`, 15, H - 12);
  
  // subtle hint
  ctx.fillStyle = 'rgba(255,255,255,0.3)';
  ctx.font = '10px Georgia';
  ctx.textAlign = 'center';
  ctx.fillText('arrow keys to walk', W/2, H - 10);
}

// === UPDATE ===
function update() {
  let dx = 0, dy = 0;
  if (keys['ArrowUp'] || keys['w'] || keys['W']) dy -= 1;
  if (keys['ArrowDown'] || keys['s'] || keys['S']) dy += 1;
  if (keys['ArrowLeft'] || keys['a'] || keys['A']) dx -= 1;
  if (keys['ArrowRight'] || keys['d'] || keys['D']) dx += 1;
  
  // normalize diagonal
  if (dx && dy) { dx *= 0.707; dy *= 0.707; }
  
  player.x = clamp(player.x + dx * player.speed, FENCE_MARGIN + 15, W - FENCE_MARGIN - 15);
  player.y = clamp(player.y + dy * player.speed, FENCE_MARGIN + 15, H - FENCE_MARGIN - 15);
}

// === MAIN LOOP ===
function frame() {
  // grass
  ctx.fillStyle = GRASS;
  ctx.fillRect(0, 0, W, H);
  
  // wandering paths
  ctx.strokeStyle = PATH_COLOR;
  ctx.lineWidth = 12;
  ctx.lineCap = 'round';
  ctx.beginPath();
  ctx.moveTo(240, 50); ctx.quadraticCurveTo(240, 200, 140, 380);
  ctx.moveTo(240, 200); ctx.quadraticCurveTo(320, 280, 360, 360);
  ctx.moveTo(100, 200); ctx.lineTo(400, 200);
  ctx.stroke();
  
  drawFence();
  locations.forEach(drawLocation);
  update();
  drawPlayer();
  drawUI();
  
  requestAnimationFrame(frame);
}

frame();
</script>
</body>
</html>

What to notice:

  • Do you want to visit all 5 spots, or does the counter feel like pressure?
  • How often do you bump the fence? Does it feel like a hug or a wall?
  • Is the slow pace meditative or frustrating?

If this vibe is close, you could deepen it: add ambient sounds, drifting leaves, NPCs who ignore you, or a clock that does nothing. If it feels off, tell me what's missing—or better yet, tweak the locations array and player.speed directly and see what shifts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment