<?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: Albert Benedict Rustandi</title>
    <description>The latest articles on DEV Community by Albert Benedict Rustandi (@albertbenedict).</description>
    <link>https://dev.to/albertbenedict</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%2F4171719%2Ff3e4b116-3163-42f4-ab27-76f73fda74dd.png</url>
      <title>DEV Community: Albert Benedict Rustandi</title>
      <link>https://dev.to/albertbenedict</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/albertbenedict"/>
    <language>en</language>
    <item>
      <title>Touch Grass Quest: a scavenger hunt game powered by on-device AI</title>
      <dc:creator>Albert Benedict Rustandi</dc:creator>
      <pubDate>Mon, 12 Oct 2026 03:51:10 +0000</pubDate>
      <link>https://dev.to/albertbenedict/touch-grass-quest-a-scavenger-hunt-game-powered-by-on-device-ai-4mj7</link>
      <guid>https://dev.to/albertbenedict/touch-grass-quest-a-scavenger-hunt-game-powered-by-on-device-ai-4mj7</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;Most apps want you to keep looking at them. I wanted to make one that sends you away. So I turned touching grass into a game: quests, XP, a plant that grows, and an AI that checks your photos without anything leaving your phone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Touch Grass Quest&lt;/strong&gt; gives you five outdoor quests every day ("find a pinecone", "spot a puddle") plus one shared quest that everyone gets. You open the in-app camera, take a photo, and an on-device model decides whether you really found it. Finds earn XP that grows a plant from a seedling to a blossoming tree. Streaks multiply your XP, and every find becomes a stamp in your Grass Dex.&lt;/p&gt;

&lt;p&gt;The screen is meant to be the shortest part of the experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live camera only.&lt;/strong&gt; There's no gallery upload, so you actually have to go somewhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A cooldown between quests&lt;/strong&gt;, so you can't farm XP from the couch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An away bonus:&lt;/strong&gt; XP for the time the app spent in your pocket.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collecting, not gambling.&lt;/strong&gt; Rewards are stamps and a growing plant, with no random pulls, on purpose.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's for anyone who wants a small, playful reason to leave the house.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://albertbenedict.github.io/touch-grass/" rel="noopener noreferrer"&gt;https://albertbenedict.github.io/touch-grass/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&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%2Fvk1f2gfms7ujm10er9a9.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%2Fvk1f2gfms7ujm10er9a9.png" alt="Touch Grass Quest home screen" width="402" height="874"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A quest written on-device by Qwen2.5 0.5B, with the XP it's worth.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Taking it outside
&lt;/h3&gt;

&lt;p&gt;A pinecone passed at 90% confidence, a pile of pebbles passed as "a stone" at 93%, and a photo of my laptop screen was rejected. The away bonus showed up after I locked my phone for a few minutes. The app also reopened with airplane mode on after the first load, and that first load took only a few seconds on my Wi-Fi, by my rough count.&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%2Fls8sbzy8rekly6fnsn0p.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%2Fls8sbzy8rekly6fnsn0p.PNG" alt="Quest Success" width="800" height="2034"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Pebbles pass as "a stone" at 93%, for +24 XP (the base reward with my x1.2 streak multiplier). The next quest is already dealt, and the camera is locked for a 3-minute cooldown.&lt;/em&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%2Fu31bdbnyskaotmn3gg82.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%2Fu31bdbnyskaotmn3gg82.PNG" alt="Quest Failure" width="800" height="2119"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The quest was "find a bush". I photographed leaves up close, and the model said "leaf" at 93%, so it didn't count.&lt;/em&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%2Fn6fbsf2nouto5rwnouv4.JPEG" 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%2Fn6fbsf2nouto5rwnouv4.JPEG" alt="Grass Dex" width="800" height="1588"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Every find becomes a stamp in the Grass Dex. Unfound ones stay locked.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The check isn't perfect, though. I tried a real tree and it failed twice: once from far away, and once up close. In the failure screenshot above, a close-up of foliage was read as "leaf" instead of "bush". The model seems to want the subject at a medium distance, framed clearly. That was the most useful thing I learned from testing, and it's the first thing I'd fix.&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/albertbenedict" rel="noopener noreferrer"&gt;
        albertbenedict
      &lt;/a&gt; / &lt;a href="https://github.com/albertbenedict/touch-grass" rel="noopener noreferrer"&gt;
        touch-grass
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Touch Grass Quest
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Touch Grass Quest&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A scavenger-hunt game that sends you outside. Every day you get outdoor quests ("find a pinecone", "spot a puddle"), take a photo with the in-app camera, and an AI running &lt;strong&gt;on your phone&lt;/strong&gt; checks whether you found it. Finds earn XP that grows a plant, and every find becomes a stamp in your Grass Dex.&lt;/p&gt;
&lt;p&gt;Built for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05" rel="nofollow"&gt;Hacktoberfest Open-Source AI Challenge, Week 1: Touch Grass&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://albertbenedict.github.io/touch-grass/" rel="nofollow noopener noreferrer"&gt;https://albertbenedict.github.io/touch-grass/&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Daily quests:&lt;/strong&gt; five a day (2 easy, 2 medium, 1 hard) plus one shared quest that everyone gets on the same day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live camera only:&lt;/strong&gt; there's no gallery upload, so you have to go somewhere. (Append &lt;code&gt;?dev&lt;/code&gt; to the URL to enable file upload for desktop testing.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Photo check:&lt;/strong&gt; CLIP compares your photo against the quest target and a set of "none of the above" labels. The target must be the top guess with…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/albertbenedict/touch-grass" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


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

&lt;p&gt;The whole app is vanilla JavaScript running in the browser with &lt;a href="https://github.com/huggingface/transformers.js" rel="noopener noreferrer"&gt;transformers.js&lt;/a&gt;. There's no backend, no account, and no API key.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Photo check:&lt;/strong&gt; CLIP (&lt;code&gt;Xenova/clip-vit-base-patch32&lt;/code&gt;) does zero-shot classification. It compares your photo against the quest target plus a set of "none of the above" labels, and the target has to be the top guess with enough confidence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quest text:&lt;/strong&gt; a small open LLM writes each quest sentence. The app tries Gemma 3 270M first, then falls back to Qwen2.5 0.5B. On my setup, Qwen2.5 0.5B is the one that actually loaded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline:&lt;/strong&gt; a service worker caches the app, and transformers.js caches the model files after the first download.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progress:&lt;/strong&gt; XP, streaks, the plant, and the Grass Dex all live in &lt;code&gt;localStorage&lt;/code&gt; on your device.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Two things went wrong
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;CLIP accepted a photo of a tiger as "a leaf."&lt;/strong&gt; In my test, the app called the tiger "a leaf" at 46% confidence and gave me XP. CLIP always picks the closest label from a short list, so any photo gets forced onto something. I added generic "none of the above" labels (an animal, a person, a screenshot, and more) and a confidence threshold.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The small quest writer wrote quests about "ancient Egyptian trade routes."&lt;/strong&gt; Now its output is validated, and if it drifts, the app uses a plain template instead. Small models need guardrails.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Limitations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It runs on the honor system.&lt;/strong&gt; A determined person could still photograph a screen, and real anti-cheat would need a server, which I chose not to add for now.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The photo check is picky about framing.&lt;/strong&gt; A tree photographed from too far or too close failed in my tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A fixed shared quest can be impossible for some people.&lt;/strong&gt; Not everyone lives near a lake.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The first load downloads large model files.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Photos never leave your phone.&lt;/strong&gt; The only network traffic is downloading the app and the model files. A closed vision API would mean uploading every picture you take outdoors to someone else's server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It works with no signal.&lt;/strong&gt; The place you need this app is a trail, and a cloud API can't follow you there. After the first load, mine doesn't need the internet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It costs nothing to run.&lt;/strong&gt; It's a static site, so there's no per-photo bill and no API key to leak.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Models are swappable.&lt;/strong&gt; When Gemma didn't load for me, falling back to Qwen was just the next line in a list, and I got a working app instead of a broken one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The honest tradeoff: small open models are less capable than big closed ones, which is exactly why I needed the guardrails above. For a game where the whole point is that nothing leaves your phone, I'd make that trade again.&lt;/p&gt;

&lt;p&gt;Try it on your phone: &lt;a href="https://albertbenedict.github.io/touch-grass/" rel="noopener noreferrer"&gt;https://albertbenedict.github.io/touch-grass/&lt;/a&gt;. Allow the camera, go find a leaf, and tell me in the comments what your first stamp was.&lt;/p&gt;

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