<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ishaan</title>
    <description>The latest articles on DEV Community by Ishaan (@ishaan-jindal).</description>
    <link>https://dev.to/ishaan-jindal</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4085933%2F7bfd9d65-1faf-4f07-b7f6-6cefd4f36f9e.jpg</url>
      <title>DEV Community: Ishaan</title>
      <link>https://dev.to/ishaan-jindal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ishaan-jindal"/>
    <language>en</language>
    <item>
      <title>Pincode Garden: what to plant this week, from your pincode</title>
      <dc:creator>Ishaan</dc:creator>
      <pubDate>Wed, 07 Oct 2026 15:32:35 +0000</pubDate>
      <link>https://dev.to/ishaan-jindal/pincode-garden-what-to-plant-this-week-from-your-pincode-3847</link>
      <guid>https://dev.to/ishaan-jindal/pincode-garden-what-to-plant-this-week-from-your-pincode-3847</guid>
      <description>&lt;h2&gt;
  
  
  Pincode Garden: what to plant this week, from your pincode
&lt;/h2&gt;

&lt;p&gt;Live demo: &lt;a href="https://pincode-garden.onrender.com/" rel="noopener noreferrer"&gt;https://pincode-garden.onrender.com/&lt;/a&gt;&lt;br&gt;
Repo: &lt;a href="https://github.com/ishaan-jindal/pincode-garden" rel="noopener noreferrer"&gt;https://github.com/ishaan-jindal/pincode-garden&lt;/a&gt; (MIT)&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;I have killed every plant I ever touched. The advice online is always "zone 9b, last frost March" — useless when your pincode is 110016 and your garden is a balcony with three hours of sun.&lt;/p&gt;

&lt;p&gt;So for Hacktoberfest Week 1 (Touch Grass) I built the smallest thing that answers one question: given my pincode, my minutes per week, my sun, and my experience, what should I sow this week?&lt;/p&gt;

&lt;p&gt;You enter four fields, you get up to three crops with a sow-by date, one short tip, and the frost window it was grounded in. Then you are supposed to close the laptop and go sow something. The screen part takes twenty seconds. That is the point.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;Input: pincode, minutes per week, sun (full / partial / shade), experience (new / some / green).&lt;/p&gt;

&lt;p&gt;Output: three ranked crops, each with why it fits, a sow-by date, and a fit score — plus one tip line, the last/first frost for your prefix, weeks left in the window, and two flags: smart advice on/off, yield check on/off.&lt;/p&gt;

&lt;p&gt;Example — 110016, 30 min, partial sun, new gardener — returns coriander, lettuce, marigold with a tip like "Sow coriander 3in apart; keep moist, harvest in about 35 days." Completing a planting logs a streak in a flat file. No accounts, no database, no keys.&lt;/p&gt;

&lt;p&gt;The read-aloud button reads the tip plus the top pick, so you can listen once and put the phone away.&lt;/p&gt;

&lt;h2&gt;
  
  
  How open-source AI is at the core
&lt;/h2&gt;

&lt;p&gt;Two open pieces do the actual work, both with the same honest pattern: try the real model, fall back to a deterministic stub, label which path ran.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Gemma 4 via Ollama writes the tip. The prompt is grounded in the top-ranked crops only, strict JSON, one line. Model and host come from GEMMA_MODEL (default gemma4:e2b) and OLLAMA_HOST. No cloud calls, no keys, no per-token bill.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TabPFN V2 (CPU) ranks the candidates. Features are tabular and small: sun match, frost-window fit, harvest fit, experience, month. The training table (data/history.csv, 32 rows) is reference outcomes encoded from planting guides, not fake telemetry. Fit happens once and is cached; any failure falls back to a weighted stdlib scorer over the same features.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Why open mattered here: the whole brain runs on-device or not at all. Nothing about your pincode or garden leaves your network. The stub path means the demo works with Wi-Fi off — Gemma makes tips warmer when home, TabPFN sharpens ranking when torch is around. On Render free the deployed demo runs the deterministic fallback by design, and the UI says so. Locally, uv sync --extra tabpfn plus ollama run gemma4:e2b enables both real paths with zero code changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frost dates without an API
&lt;/h2&gt;

&lt;p&gt;data/frost.csv is ten rows: pincode prefix to first/last frost (MM-DD), plus a fallback row for unknown prefixes. North prefixes get a real window; southern ones get year-round. All math is stdlib dates. No fetch, no keys, no outage mode.&lt;/p&gt;

&lt;p&gt;Crops live in data/crops.csv (14 rows). Candidates are filtered by sun, difficulty, time budget (under 30 min/week keeps easy herbs/greens only), and whether the sow-by date is still inside the window. Unknown pincodes never crash; they get the fallback window.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack and shape
&lt;/h2&gt;

&lt;p&gt;FastAPI plus stdlib. No ORM, no auth, no image uploads, no weather API, no geolocation. Streaks are a JSON file. Frontend is one 74-line HTML file, system font, no framework, speech synthesis for read-aloud. Tests are five offline pytest cases with stubs forced. Docker plus render.yaml on the free tier.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would add with more time
&lt;/h2&gt;

&lt;p&gt;A second frost source with provenance per row, and a photo log for the streak instead of a counter. Neither fits a four-day window without adding a database I would have to maintain.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>BOSS vs YOU: I Built a Boss Fight for My Bored Friend — and an Open LLM Plays the Boss</title>
      <dc:creator>Ishaan</dc:creator>
      <pubDate>Sun, 04 Oct 2026 16:15:58 +0000</pubDate>
      <link>https://dev.to/ishaan-jindal/boss-vs-you-i-built-a-boss-fight-for-my-bored-friend-and-an-open-llm-plays-the-boss-1e9a</link>
      <guid>https://dev.to/ishaan-jindal/boss-vs-you-i-built-a-boss-fight-for-my-bored-friend-and-an-open-llm-plays-the-boss-1e9a</guid>
      <description>&lt;h2&gt;
  
  
  BOSS vs YOU: I Built a Boss Fight for My Bored Friend — and an Open LLM Plays the Boss
&lt;/h2&gt;

&lt;p&gt;My friend is bored by every game I show him. Too easy, too grindy, too predictable — the boss does the same three moves, so why keep playing? Fair. So for the Hacktoberfest Weekend Challenge (&lt;strong&gt;Build for a Friend&lt;/strong&gt;), I built him a boss fight where the boss is played by an open-weights LLM that studies how he plays and adapts. Same three moves? Not anymore.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Play it:&lt;/strong&gt; &lt;a href="https://boss-vs-you.onrender.com" rel="noopener noreferrer"&gt;https://boss-vs-you.onrender.com&lt;/a&gt; (free tier — give it ~50s to wake up)&lt;br&gt;
&lt;strong&gt;Code:&lt;/strong&gt; &lt;a href="https://github.com/ishaan-jindal/boss-vs-you" rel="noopener noreferrer"&gt;https://github.com/ishaan-jindal/boss-vs-you&lt;/a&gt; (MIT)&lt;br&gt;
&lt;strong&gt;Challenge:&lt;/strong&gt; &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;https://dev.to/challenges/hacktoberfest-weekend-2026-10-01&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is
&lt;/h2&gt;

&lt;p&gt;BOSS vs YOU is a real-time pixel-dungeon boss battler in the browser. You descend room by room through a cramped gothic dungeon. Each room: kill the minions, crack the boss phase, draft a level-up card, go deeper. The twist: &lt;strong&gt;one transforming boss (four forms), driven by a model brain, with a memory.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Roughly every 8 seconds the server sends the full fight state — HP, positions, your habit profile, the room — to the model, which returns tactics (pressure / bait / bombs weights), whether to transform, what to open with, and even a taunt. A rules-based stub stands behind every call: model fails, times out, or returns garbage, and the deterministic floor takes over. The game never 500s, and it plays fully offline with no keys at all.&lt;/p&gt;

&lt;p&gt;And the part built to hook him: &lt;strong&gt;it learns whoever plays.&lt;/strong&gt; The server distills the last 60 fights — turtle ratio, dash spam, potion timing, preferred range, causes of death — into a habit profile the boss prompt reads. Camp in the corner and the boss starts baiting. Dash everywhere and it starts punishing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;His honest review: &lt;em&gt;"addictive... but a little easy"&lt;/em&gt; — then, a few descents later, the dungeon thrashed him. Boredom: cured.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How it's built
&lt;/h2&gt;



&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart LR
    UI[Pixel Canvas client] --&amp;gt; API[FastAPI server]
    API --&amp;gt; Brain[brain: contract + stub]
    Brain --&amp;gt; Habits[habits: 60-fight profile]
    Brain --&amp;gt; Gemma[(Gemma 4 primary)]
    Gemma -.failover.-&amp;gt; DI[(DeepInfra Gemma)]
    Brain -.fallback.-&amp;gt; Brain&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;The stack is deliberately boring: FastAPI + uvicorn, raw httpx to the model APIs (no SDK), vanilla JS + Canvas 2D (we deleted a 1.3MB vendored Three.js mid-weekend for a 210-line pixel renderer), procedural sprites and Web Audio so there are zero asset files. The server is fully stateless — persistence is browser localStorage. Python is the tuning ground truth; the JS client mirrors four formulas, pinned by a parity test (93 tests, all green).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why open matters
&lt;/h2&gt;

&lt;p&gt;This game only works because the model is open:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Swappable by design.&lt;/strong&gt; Primary and failover are both Gemma 4 served two different ways (Google REST, DeepInfra OpenAI-compatible). Point the brain at any weights-compatible endpoint — including a locally-run Gemma — with a two-constant change. Try that with a closed API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free to run, online or off.&lt;/strong&gt; No keys, no internet? The stub brain plays a real game. The whole weekend cost $0: open weights, free-tier Render, MIT everything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inspectable opponent.&lt;/strong&gt; Anyone can read the exact prompt the boss sees and the exact counters it keeps on them. A black-box boss that adapts is marketing; an open one is a rivalry.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tracks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma:&lt;/strong&gt; Gemma 4 is the boss's brain — tactics, transforms, taunts — with thinking capped to MINIMAL after measuring full reasoning at 20-40s per tick.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render:&lt;/strong&gt; Docker deploy, health checks, secrets in the dashboard. (Shipped a real Dockerfile bug along the way: installing before &lt;code&gt;src/&lt;/code&gt; existed silently produced an empty editable install — reorder plus a non-editable build fixed it.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Built this weekend for one bored friend. If he finally stops complaining, I'll consider it a win bigger than any prize.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>weekendchallenge</category>
    </item>
  </channel>
</rss>
