<?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: Teo Furlan</title>
    <description>The latest articles on DEV Community by Teo Furlan (@teo_furlan).</description>
    <link>https://dev.to/teo_furlan</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%2F3955206%2Ffc22398f-aeab-4bc8-9646-70a27e3f740b.jpeg</url>
      <title>DEV Community: Teo Furlan</title>
      <link>https://dev.to/teo_furlan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/teo_furlan"/>
    <language>en</language>
    <item>
      <title>Loci: A Walk You Have to Remember</title>
      <dc:creator>Teo Furlan</dc:creator>
      <pubDate>Mon, 12 Oct 2026 03:16:10 +0000</pubDate>
      <link>https://dev.to/teo_furlan/loci-a-walk-you-have-to-remember-14lf</link>
      <guid>https://dev.to/teo_furlan/loci-a-walk-you-have-to-remember-14lf</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;I often walk my dog, and too many walks become the same loop: I hesitate over where to go, then choose the familiar route again. I do the same when I head somewhere nearby, like the supermarket. I wanted a reason to explore on foot, and a little more purpose than scrolling through a walk.&lt;/p&gt;

&lt;p&gt;Recently I enabled my phone's warning for using it while walking. I was surprised by how often I was reading social media or chatting as I moved. That made me want to try using technology against the pull of technology: a memory game that gives me something to think about, then asks me to put the phone away.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loci&lt;/strong&gt; is an Android app that plans a walking loop through real places near you, turns them into one short mnemonic story, and then hides the map. You look at the route once, put the phone in your pocket, and walk it from memory. The screen is the shortest part of the experience: a minute to memorize, then the rest of the walk is outside.&lt;/p&gt;

&lt;h3&gt;
  
  
  Meet Loci
&lt;/h3&gt;

&lt;p&gt;Loci is also the name of the character you talk to: a small pixel-art companion on a black field. It waits on the home screen, listens while it plans, gives a hint when you ask, and celebrates when you finish a route. Instead of filling in a form, you ask it for a walk, by typing or by voice, and it answers with a route made of places around you.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ask Loci&lt;/th&gt;
&lt;th&gt;Loci listens while planning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&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%2Fw323ggnl2wcr8p5cx884.png" alt="Home screen: Loci waits and asks where to walk today, with example requests and a text and microphone input." width="720" height="1612"&gt;&lt;/td&gt;
&lt;td&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%2Fhxhvegnirmrfhl4s00zr.png" alt="Loci listens while the app finds places near you." width="720" height="1612"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every landmark is an original 32×32 pixel sprite on a night map, so the places become memory hooks rather than interchangeable pins.&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%2F1zzb52q0a8rpbb5p4q80.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%2F1zzb52q0a8rpbb5p4q80.png" alt="Memorize screen: a night map with numbered pixel-art landmarks and a story fragment in a dialogue box beside Loci." width="720" height="1612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How to play
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Ask Loci for a walk or run ("20 min walk, green areas"), then review the planned course and its story.&lt;/li&gt;
&lt;li&gt;Study the landmarks while the map is visible. The story is the cue to remember.&lt;/li&gt;
&lt;li&gt;Tap &lt;strong&gt;Hide map &amp;amp; start&lt;/strong&gt;, put the phone in your pocket and follow the story from memory. GPS keeps checking with the screen off, and a vibration marks each checkpoint. Order doesn't matter in the current mode.&lt;/li&gt;
&lt;li&gt;Ask for a hint if you need one: it replays that place's story fragment and gives a direction, for half credit. Giving up is always available and reveals the map.&lt;/li&gt;
&lt;li&gt;At the end, Loci shows what you remembered, with a badge for each place.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Walk from memory&lt;/th&gt;
&lt;th&gt;Results&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&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%2Fmojup40hu007iro8ktaw.png" alt="Pocket screen: Loci on a black field, a place counter, a Hint button and a Give up button." width="720" height="1600"&gt;&lt;/td&gt;
&lt;td&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%2Fu80eqnt8hmpttftzctow.png" alt="Results screen: Loci, the score, a badge for each checkpoint and the route map." width="720" height="1612"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The phone is never locked by the app, so calls and emergency help remain available. Planning requires connectivity; a prepared run works offline. Loci is not turn-by-turn navigation and makes no route-safety guarantee.&lt;/p&gt;

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

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

&lt;p&gt;Every screen in the video is the real release build (v1.0.0), recorded on the Android emulator. The only simulated thing is the GPS position (San Telmo, Buenos Aires), moved in small steps to walk the route. The narration is synthetic, generated locally with the open-weight Kokoro voice model.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Try it:&lt;/strong&gt; install the Android APK from the &lt;a href="https://github.com/teofurlan/loci/releases/tag/v1.0.0" rel="noopener noreferrer"&gt;v1.0.0 release&lt;/a&gt; (a sideloaded build, not a Play Store one).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://lociwalk.vercel.app" rel="noopener noreferrer"&gt;lociwalk.vercel.app&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&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/teofurlan" rel="noopener noreferrer"&gt;
        teofurlan
      &lt;/a&gt; / &lt;a href="https://github.com/teofurlan/loci" rel="noopener noreferrer"&gt;
        loci
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Loci: a memory walk. Gemma turns a random loop of real OpenStreetMap landmarks into a method-of-loci story; you look once, pocket the phone, and walk it from memory.
    &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;Loci&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Loci is an Android app that plans a walking loop through real landmarks, turns it into a mnemonic story, and asks you to walk it from memory with the phone in your pocket. It is built for the &lt;a href="https://dev.to/challenges/hf26" rel="nofollow"&gt;DEV Hacktoberfest 2026 challenge&lt;/a&gt; (&lt;code&gt;hf26&lt;/code&gt;, Gemma category).&lt;/p&gt;
&lt;p&gt;You ask Loci, a small pixel-art companion, for a route ("20 min walk, green areas") by typing or by voice. Loci finds named places near you in OpenStreetMap and links them into a short story using the method of loci: each place becomes a vivid image, and the images follow one another. You read (or listen to) the story once with the map visible, then hide the map and walk. GPS confirms each checkpoint with a vibration, and at the end Loci shows how many you remembered.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Try it&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Download the Android APK from the &lt;a href="https://github.com/teofurlan/loci/releases/latest" rel="noopener noreferrer"&gt;latest release&lt;/a&gt; (&lt;a href="https://github.com/teofurlan/loci/releases/download/v1.0.0/loci-1.0.0.apk" rel="noopener noreferrer"&gt;&lt;code&gt;loci-1.0.0.apk&lt;/code&gt;&lt;/a&gt;), open it…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/teofurlan/loci" 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;h3&gt;
  
  
  Gemma is the mechanic
&lt;/h3&gt;

&lt;p&gt;Gemma isn't a chat feature added for decoration. Without a story that connects places to memorable images, there is no memory challenge to carry away from the screen.&lt;/p&gt;

&lt;p&gt;Gemma has two jobs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Parse the request.&lt;/strong&gt; It turns free text ("30 min run, I remember places better than street names") into bounded route parameters: distance or time, pace, preferences, story style. The app validates and clamps every value.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the story.&lt;/strong&gt; It writes one short mnemonic fragment per landmark, using the method of loci: each place becomes a vivid image, and each image leads to the next. The input is only landmark IDs, names and kinds. No coordinates go to the model, and the IDs that come back are checked against the fetched set.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Gemma never gets to invent landmarks or coordinates. The places come from OpenStreetMap; the model only supplies the words. Voice input uses Android speech recognition and feeds the same text path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;The route and memory-game logic is plain TypeScript, with external services behind small adapters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Free-text request ──&amp;gt; intent parser ──&amp;gt; bounded route intent
                                           │
GPS origin ──&amp;gt; loop candidates ──&amp;gt; Overpass landmarks ──&amp;gt; snapped checkpoints
                                           │
                                           └──&amp;gt; story generator ──&amp;gt; Gemma via Vercel proxy
                                                                      │
                         Expo / React Native screens &amp;lt;── route + story┘
                         GPS fixes ──&amp;gt; hit detection ──&amp;gt; score + vibration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The domain handles distance calculations, randomized loop candidates, landmark selection, GPS hit detection, session state, hints and scoring. Application code composes those steps into route planning. Adapters connect the ports to Overpass mirrors, LLM clients, story templates and cache, and local visited-landmark history. Expo and React Native provide the Android app; MapLibre draws the map with OpenFreeMap tiles. I wrote the domain logic, the adapters and the pure view models behind the screens test-first; the suite has 586 Jest tests.&lt;/p&gt;

&lt;p&gt;In production, the app calls the open-weight Gemma 4 model through the Gemini API behind a small Vercel proxy. The proxy fixes the model, caps input and output sizes, applies best-effort per-IP rate limiting and keeps the API key server-side instead of inside the APK. If generation fails, Loci falls back to a cached or template story.&lt;/p&gt;

&lt;p&gt;The screen-off run is deliberately simple: it checks proximity to the prepared checkpoints, not whether I followed a particular street between them. Hints and giving up are always available, so the score is never the point of the walk. That balance matters to me: I want a small reason to pay attention to where I am, while still being free to keep walking or stop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lessons learned
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Leave room for model thinking.&lt;/strong&gt; Gemma's reasoning could use up a small token budget and leave an empty visible answer. More headroom fixed the case I saw.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A failed request can hide the next one.&lt;/strong&gt; A transient proxy 502 plus an over-eager, client-wide cooldown meant the story request could silently fall back to a template. Retrying transient proxy failures and limiting the cooldown to Ollama fixed it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public data services need alternatives.&lt;/strong&gt; Overpass returned 504s, so the app tries mirrors instead of depending on a single endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screen-off GPS needs Android foreground work.&lt;/strong&gt; A foreground service keeps the run's location tracking alive while the screen is off.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Loci is built from open pieces end to end, and each one does a job a closed service would have made harder:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open map data is what keeps the model honest.&lt;/strong&gt; The places come from OpenStreetMap through Overpass, with names and kinds for parks, monuments, churches, artworks and more (the app draws 18 kinds). Because the real place data is open and queryable, the model never has to "know" a neighborhood: it only writes words about places the app already fetched and verified.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An open-weight model can move.&lt;/strong&gt; The same prompts and validation run against Gemma on my laptop through Ollama during development, at no cost and with no account, and against hosted Gemma in production. Swapping is configuration, not a rewrite, and running Gemma on the phone itself is a realistic next step rather than a dependency on one vendor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No map API keys or quotas.&lt;/strong&gt; MapLibre with OpenFreeMap tiles means the map costs nothing to show and can't be switched off by a billing change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Small and inspectable.&lt;/strong&gt; The proxy is a single open function with fixed model, size caps and rate limiting, so anyone can see exactly what leaves the phone: landmark names and kinds, never your coordinates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where it worked better than a closed approach: I could develop the whole story pipeline offline against a local model, test failure paths for free, and keep the app's promise ("the model only writes the words") enforceable in code, because both the data and the model are open.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma&lt;/strong&gt;: Gemma parses every request and writes every story; the route and the game are built around what it produces.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Take Loci on a longer outdoor walk and share where it went, the distance and the score.&lt;/li&gt;
&lt;li&gt;Let Loci ask a clarifying question when a request is vague.&lt;/li&gt;
&lt;li&gt;An ordered quest mode, where remembering each place unlocks the next clue.&lt;/li&gt;
&lt;li&gt;On-device Gemma, so planning can work without a connection too.&lt;/li&gt;
&lt;/ol&gt;

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