<?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: Mohibullah Azhar</title>
    <description>The latest articles on DEV Community by Mohibullah Azhar (@mohibullah16).</description>
    <link>https://dev.to/mohibullah16</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4169939%2Fbb0352b9-e79d-41d4-9d5e-096e54640912.gif</url>
      <title>DEV Community: Mohibullah Azhar</title>
      <link>https://dev.to/mohibullah16</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mohibullah16"/>
    <language>en</language>
    <item>
      <title>Voices of the Wild: photograph something outside, and it talks back</title>
      <dc:creator>Mohibullah Azhar</dc:creator>
      <pubDate>Fri, 09 Oct 2026 08:51:54 +0000</pubDate>
      <link>https://dev.to/mohibullah16/voices-of-the-wild-photograph-something-outside-and-it-talks-back-2j0h</link>
      <guid>https://dev.to/mohibullah16/voices-of-the-wild-photograph-something-outside-and-it-talks-back-2j0h</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fewm9y2sra3rf5dwa2pat.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fewm9y2sra3rf5dwa2pat.gif" alt="A photo of a car goes in; Parker, the parked car, answers with +200 XP and a spoken, captioned line" width="360" height="779"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Voices of the Wild&lt;/strong&gt; is a field guide that talks back. Photograph something outdoors (a tree, a crow, a parked car, the moon) and an open model works out what it is. If it knows, that thing answers in its own voice, with captions, and joins your collection. Then the app sends you for a walk.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Well, hello down there. I'm Old Oak. Two hundred years in one spot. Touch some grass for me? I can't reach."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The screen is only on for the photo. The rest of the time you're listening and walking.&lt;/p&gt;

&lt;h3&gt;
  
  
  How the game works
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A daily trail of 5 to 7 quests&lt;/strong&gt;, the same for everyone, unlocked one at a time: &lt;em&gt;Meet a vehicle → Walk 500 steps → Touch grass → Walk 1,000 steps → …&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real steps.&lt;/strong&gt; The phone's motion sensor counts them, so the only way to finish a walk is to walk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;XP for every find and every walk,&lt;/strong&gt; a bonus for finding a different kind of thing, streaks, 12 badges, 5 ranks and an anonymous community leaderboard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A miss isn't a dead end.&lt;/strong&gt; The app tells you what it half-recognised (&lt;em&gt;"Something among the vehicles stirred… get closer"&lt;/em&gt;), and you can skip that quest for 25 XP. Walks can't be skipped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next day&lt;/strong&gt; starts tomorrow's trail early if you want to keep going.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The cast
&lt;/h3&gt;

&lt;p&gt;81 characters in 13 kinds, from trees and birds to vehicles and street objects. Each kind has a guardian who steps in when the app isn't sure. A few of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parker&lt;/strong&gt;, the parked car: &lt;em&gt;"Twenty-three hours a day, I just sit here. You walked over? Show-off."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gossip the Crow&lt;/strong&gt;: &lt;em&gt;"I remember faces, so be nice to me."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprinkles&lt;/strong&gt;, the ice cream truck: &lt;em&gt;"Walk to me. Never run into the road."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bronze Bert&lt;/strong&gt;, the statue: &lt;em&gt;"A hundred years in one pose. And my nose itches."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grumpy Gourd&lt;/strong&gt;, the pumpkin: &lt;em&gt;"It's October, so everyone wants to cut a face in me. Rude."&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Three writing rules: every goodbye points you somewhere else outside, nobody ever tells you to touch, pick, chase or climb, and the words stay easy enough for a ten-year-old.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who it's for:&lt;/strong&gt; families on an evening walk, people new to a neighbourhood, and anyone who passes the same tree every day without looking up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Live:&lt;/strong&gt; &lt;a href="https://voices-of-the-wild.netlify.app" rel="noopener noreferrer"&gt;https://voices-of-the-wild.netlify.app&lt;/a&gt; (no account, no install; best in Chrome on Android)&lt;/p&gt;

&lt;p&gt;On a laptop, tap &lt;strong&gt;"No camera? Try one"&lt;/strong&gt; to send sample photos through the real matcher, and add &lt;code&gt;?debug&lt;/code&gt; to the URL to see the match scores.&lt;/p&gt;

&lt;p&gt;The video walks through a full trail: a miss, two finds, two walks, the leaderboard, &lt;em&gt;Next day&lt;/em&gt; and a skip. The photos are Creative Commons images from Wikimedia Commons and the steps are simulated; the matching, voices, XP and timings are real.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/-b6NySIDaV4" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F56w1sh6ao8j6wtip9ntb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F56w1sh6ao8j6wtip9ntb.png" alt="Parker's card with the photo on it and the " width="780" height="1688"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd8ynzwveyppb876s6hhk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd8ynzwveyppb876s6hhk.png" alt="A miss with the near-miss hint and the Skip −25 XP button" width="780" height="1688"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Mohibullah16" rel="noopener noreferrer"&gt;
        Mohibullah16
      &lt;/a&gt; / &lt;a href="https://github.com/Mohibullah16/voices-of-the-wild" rel="noopener noreferrer"&gt;
        voices-of-the-wild
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Photograph something outdoors and it talks back. On-device EmbeddingGemma 2, step-counted quest walks, 91 voiced characters, offline-first PWA.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/Mohibullah16/voices-of-the-wild/docs/cover.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FMohibullah16%2Fvoices-of-the-wild%2FHEAD%2Fdocs%2Fcover.png" alt="Voices of the Wild: everything outside has something to say. Go find out what." width="100%"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Voices of the Wild&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;b&gt;Point your phone at something outside. An open model works out what it is, and that thing talks back.&lt;/b&gt;&lt;br&gt;
  An oak, a crow, a parked car, a puddle, the moon: 81 characters and 13 guardians, 295 captioned voice lines.&lt;br&gt;
  Then it sends you on a walk. Phones use a small &lt;b&gt;cloud listener&lt;/b&gt; running the same open model; laptops can run it &lt;b&gt;entirely on-device&lt;/b&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://voices-of-the-wild.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;b&gt;▶ Try it live: voices-of-the-wild.netlify.app&lt;/b&gt;&lt;/a&gt;&lt;br&gt;
  Best on an Android phone in Chrome. No account, no install. About 37 MB of voices downloads in the background on the first visit.
&lt;/p&gt;

&lt;p&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/9855eae66a186ec39ee6352d242048b458b4d7afe62c871cc143926936ce226e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d6f64656c2d456d62656464696e6747656d6d6125323032253230287134292d3266356433663f7374796c653d666c61742d737175617265"&gt;&lt;img alt="EmbeddingGemma 2" src="https://camo.githubusercontent.com/9855eae66a186ec39ee6352d242048b458b4d7afe62c871cc143926936ce226e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d6f64656c2d456d62656464696e6747656d6d6125323032253230287134292d3266356433663f7374796c653d666c61742d737175617265"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/efffe2a7b2d2307f9ece8a6c5a96bac13bac7ccfc868aa1da9255f5a5a5a4f32/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f72756e732d6f6e2532306465766963652532302543322542372532305765624750552d3266356433663f7374796c653d666c61742d737175617265"&gt;&lt;img alt="Runs on device" src="https://camo.githubusercontent.com/efffe2a7b2d2307f9ece8a6c5a96bac13bac7ccfc868aa1da9255f5a5a5a4f32/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f72756e732d6f6e2532306465766963652532302543322542372532305765624750552d3266356433663f7374796c653d666c61742d737175617265"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/0df53decf7b2e43592b89373e156a7a05aff21c099016883fa00628aacfdb901/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6f6e2d2d6465766963652532306d6f64652d302532306e6574776f726b25323072657175657374732d6238383932623f7374796c653d666c61742d737175617265"&gt;&lt;img alt="Offline" src="https://camo.githubusercontent.com/0df53decf7b2e43592b89373e156a7a05aff21c099016883fa00628aacfdb901/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6f6e2d2d6465766963652532306d6f64652d302532306e6574776f726b25323072657175657374732d6238383932623f7374796c653d666c61742d737175617265"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/be4a5701290513a955e2b23242487b3b775ca647550e385becebf45e1209239c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f70686f6e65732d636c6f75642532306c697374656e65722532306f6e2532304d6f64616c2d3266356433663f7374796c653d666c61742d737175617265"&gt;&lt;img alt="Cloud listener" src="https://camo.githubusercontent.com/be4a5701290513a955e2b23242487b3b775ca647550e385becebf45e1209239c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f70686f6e65732d636c6f75642532306c697374656e65722532306f6e2532304d6f64616c2d3266356433663f7374796c653d666c61742d737175617265"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/fff7ee99d68a365e0ac66a4853ee9a218b4ea0ace16baf96905b238a2c7d92af/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f766f696365732d456c6576656e4c6162732532302532422532304b6f6b6f726f2d6238383932623f7374796c653d666c61742d737175617265"&gt;&lt;img alt="Voices" src="https://camo.githubusercontent.com/fff7ee99d68a365e0ac66a4853ee9a218b4ea0ace16baf96905b238a2c7d92af/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f766f696365732d456c6576656e4c6162732532302532422532304b6f6b6f726f2d6238383932623f7374796c653d666c61742d737175617265"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/aabaabc815e49d43a1074f2d59a0beb0a365e8c34741f9cb337cf9b3bb25cff2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e63652d4d49542d3535353f7374796c653d666c61742d737175617265"&gt;&lt;img alt="MIT" src="https://camo.githubusercontent.com/aabaabc815e49d43a1074f2d59a0beb0a365e8c34741f9cb337cf9b3bb25cff2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e63652d4d49542d3535353f7374796c653d666c61742d737175617265"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/Mohibullah16/voices-of-the-wild/docs/hook.gif"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fraw.githubusercontent.com%2FMohibullah16%2Fvoices-of-the-wild%2FHEAD%2Fdocs%2Fhook.gif" alt="A car is photographed and Parker, the parked car, answers with +200 XP and a captioned line" width="260"&gt;&lt;/a&gt;
  &amp;nbsp;&amp;nbsp;
  &lt;a rel="noopener noreferrer" href="https://github.com/Mohibullah16/voices-of-the-wild/docs/quest-chain.gif"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fraw.githubusercontent.com%2FMohibullah16%2Fvoices-of-the-wild%2FHEAD%2Fdocs%2Fquest-chain.gif" alt="The quest chain: walk 500 steps counted by the phone, +75 XP, and the next quest unlocks: meet a vehicle" width="260"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Entry for the DEV Hacktoberfest Open-Source AI Challenge, Week 1: &lt;b&gt;Touch Grass&lt;/b&gt;. Demo video (1:55, sound on): &lt;a href="https://github.com/Mohibullah16/voices-of-the-wild/docs/demo.mp4" rel="noopener noreferrer"&gt;docs/demo.mp4&lt;/a&gt;&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;The idea&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Most apps want your eyes on the screen. This one wants the screen off. You only take the phone out for the photo; the rest of the time it is a voice…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Mohibullah16/voices-of-the-wild" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;app/&lt;/code&gt;: the PWA (Vite, TypeScript, lit-html, Transformers.js), with unit tests and Playwright end-to-end checks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;listener/&lt;/code&gt;: a small server running the same model, deployed on Modal.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pipeline/&lt;/code&gt;: build-time scripts for embeddings, calibration and voices.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data/roster/roster.json&lt;/code&gt;: every character, description and line.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;photo ─► EmbeddingGemma 2 ─► 768 numbers ─► compare with 717 character descriptions
                                                        │
                       character speaks  ◄─  sure?  ─►  guardian asks for a closer look
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;EmbeddingGemma 2&lt;/strong&gt; (open weights, Apache 2.0) does the recognising. At build time it embeds 717 short visual descriptions of the 81 characters: &lt;em&gt;"a dark car silhouette at night with its headlights glowing"&lt;/em&gt;, &lt;em&gt;"a close-up of a car wheel with an alloy rim"&lt;/em&gt;. At play time it embeds only your photo, and the app finds the closest description. The same q4 weights run in two places: a small CPU server on Modal for phones, or in the browser on WebGPU for laptops.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Matching&lt;/strong&gt; works in two steps: first the kind of thing, then the character within that kind. If the top character isn't clearly ahead, its guardian speaks instead. If nothing is close, &lt;em&gt;"Nobody here wants to talk."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why an embedding model and not a vision LLM?&lt;/strong&gt; Because a character should say the same thing every time you meet it, which is what makes it worth collecting. An embedding model can only pick from characters that exist, so it never invents one. Every line was written, checked against the safety rules and recorded once. And its confidence is a number I can test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tested on 244 real photos&lt;/strong&gt; (Wikimedia Commons, checked by eye), with thresholds tuned to be forgiving, because "nobody wants to talk" in front of a real tree is worse than a guardian asking for a closer look:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cross-validated&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Right character named&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;77.9%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Guardian asks for a closer look&lt;/td&gt;
&lt;td&gt;12.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wrong character named&lt;/td&gt;
&lt;td&gt;7.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Nobody here" on a real outdoor photo&lt;/td&gt;
&lt;td&gt;1.6%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Indoor photos given a character&lt;/td&gt;
&lt;td&gt;0 of 10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Voices&lt;/strong&gt; are made once, at build time. The 28 gold Elders are performed with ElevenLabs Eleven v4, using audio tags like &lt;code&gt;[caws]&lt;/code&gt; and &lt;code&gt;[hums a jingle]&lt;/code&gt;. The open-source Kokoro-82M voices everyone else. The app ships 295 captioned MP3s and never calls a voice API.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stack&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Recognition&lt;/td&gt;
&lt;td&gt;EmbeddingGemma 2 (q4 ONNX) with Transformers.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voices&lt;/td&gt;
&lt;td&gt;ElevenLabs (Elders), Kokoro-82M (everyone else), build time only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App&lt;/td&gt;
&lt;td&gt;PWA: Vite, TypeScript, lit-html, Workbox, IndexedDB, hosted on Netlify&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server&lt;/td&gt;
&lt;td&gt;Modal: the cloud listener and the anonymous rankings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quality&lt;/td&gt;
&lt;td&gt;Vitest, Playwright on a phone viewport, WCAG 2.2 AA (captions for every line)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Limitations.&lt;/strong&gt; The test photos are cleaner than a phone snap at dusk, so treat the numbers as an upper bound. Look-alikes still fool it now and then (a silver birch called a weeping willow). Phones need a connection for the cloud listener. And the characters can't hold a conversation: every line is pre-written.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;I could put the model wherever it works.&lt;/strong&gt; The same open weights run in Node at build time, in a browser tab, and on a server that costs nothing when idle. When the model didn't fit in a phone's browser, I moved it to my own server instead of changing vendors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I decide what's kept.&lt;/strong&gt; The listener turns a photo into 768 numbers and forgets it. No third party sees photos of people's streets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I could measure it.&lt;/strong&gt; Open weights give raw scores, which made the thresholds, the guardian fallback and the published accuracy numbers possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's cheap enough for a free game.&lt;/strong&gt; A child might take dozens of photos on one walk. That's fine with a server that scales to zero, and not with a per-call bill.&lt;/p&gt;

&lt;p&gt;ElevenLabs is the one closed part, and it's used only at build time to perform lines that were already written. The app never calls it.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;I built this with &lt;strong&gt;Claude Code&lt;/strong&gt;. I ran several agents in parallel: one wrote and tested character descriptions, one re-ran the photo calibration, and one built game features test-first. A Playwright script then played the app on a phone-sized screen to check each feature. A &lt;code&gt;CLAUDE.md&lt;/code&gt; file held the rules it had to follow: no photo leaves the device except to my own listener, ElevenLabs only at build time, and no line may tell anyone to touch wildlife or step into traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Use of Gemma.&lt;/strong&gt; EmbeddingGemma 2 is the whole recogniser: 717 descriptions at build time and every photo at play time, on a server and in the browser. Its raw scores make the guardian fallback possible, which keeps wrong names to 7.8%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Use of ElevenLabs.&lt;/strong&gt; The voices are the game: a character &lt;em&gt;is&lt;/em&gt; a voice you collect. The 28 gold Elders are performed with Eleven v4 audio tags, recorded once and shipped as captioned MP3s, so they play instantly and no API quota can break the game.&lt;/p&gt;




&lt;p&gt;Go outside. Find a lawn, or the big tree outside your door. Old Oak would love some news.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's one thing on your street you'd want to hear talk?&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Credits: voices by **ElevenLabs&lt;/em&gt;* and &lt;strong&gt;Kokoro-82M&lt;/strong&gt;. &lt;strong&gt;EmbeddingGemma 2&lt;/strong&gt; by Google DeepMind. &lt;strong&gt;Transformers.js&lt;/strong&gt; and &lt;strong&gt;ONNX Runtime&lt;/strong&gt;. Hosted on &lt;strong&gt;Netlify&lt;/strong&gt; and &lt;strong&gt;Modal&lt;/strong&gt;. Test and sample photos from Wikimedia Commons contributors, credited in &lt;a href="https://github.com/Mohibullah16/voices-of-the-wild/blob/main/pipeline/calibration/ATTRIBUTION.md" rel="noopener noreferrer"&gt;ATTRIBUTION.md&lt;/a&gt;. Fonts: EB Garamond and Atkinson Hyperlegible Next. Icons: Phosphor.*&lt;/p&gt;

&lt;p&gt;&lt;em&gt;AI disclosure: built with Claude Code; character lines and this post were drafted with AI help and edited by me.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>gemma</category>
      <category>elevenlabs</category>
    </item>
  </channel>
</rss>
