Pluck - Real places, fictional stories
Inspiration
Most of us have hundreds of photos sitting in our gallery, but after a while they're just... pictures.
I kept thinking about how the places we visit every day already look like scenes from a story. A coffee shop, a quiet library, a rainy street, a park at sunset. They're all real, but with a little imagination they could belong to an entirely different world.
That simple idea became Pluck.
Instead of helping people journal their day, I wanted to create something that transforms ordinary places into fiction. The locations stay real, but everything that happens between them is completely made up.
What it does
Pluck is a native Android app that transforms an ordered journey of real places into one continuous fictional story.
Instead of chatting with an AI or writing prompts, you simply capture one photo at each stop during your day. Pluck preserves the order of your journey, combines it with your selected mood and optional story settings, then generates an original adventure that connects every location together.
Features include:
- CameraX photo capture and gallery import with preserved journey order
- Animated journey timeline with optional location history
- Local Gemma story generation running entirely on-device
- Optional OpenAI, Gemini, Claude, Groq, Together AI, and OpenRouter support
- Multiple storytelling moods including Cinematic, Mystery, Adventure, Warm, Whimsical, and Dark
- Story refinement actions without requiring an AI chat interface
- Reality vs Fiction reading mode connecting fictional scenes to captured places
- Offline text-to-speech narration
- Multi-day novella generation
- PDF and EPUB export
- Story sharing with automatically generated social cards
- Home screen widgets
- Completely local-first architecture with no accounts, backend, analytics, or cloud database
How I built it
Pluck is built entirely in Kotlin using Jetpack Compose, Material 3, MVVM, Hilt, Room, Coroutines, and Flow.
I built the entire project using OpenAI Codex with GPT-5.6 Terra, using Codex throughout development for architecture exploration, implementation, UI development, debugging, refactoring, and documentation while making all engineering and product decisions myself.
I used CameraX for image capture and Android's Photo Picker for gallery imports. Imported images are copied into private app storage, preserving their exact selection order so every generated story follows the intended journey.
One of the biggest architectural decisions was designing a provider abstraction layer. Every AI backend implements the same StoryProvider interface, allowing the application to switch seamlessly between Local Gemma, OpenAI, Gemini, Claude, Groq, Together AI, and OpenRouter without changing the rest of the application.
For offline generation, I integrated Google AI Edge LiteRT-LM with Local Gemma. The app downloads models securely using HTTPS, performs SHA-256 verification, stores models privately, supports pause/resume downloads, performs device capability checks, and automatically switches to fully on-device story generation after installation.
API keys are stored securely using EncryptedSharedPreferences backed by the Android Keystore, while journeys, stories, media, and exports remain local by default.
Challenges I faced
The biggest challenge wasn't generating stories.
It was making AI disappear.
Most AI applications revolve around prompts, chat windows, and endless settings. I wanted Pluck to feel different. Users shouldn't have to think about models or prompt engineering. They should simply capture places and read stories.
Supporting multiple AI providers while maintaining one consistent experience required building a flexible provider architecture that worked equally well for local and cloud inference.
Offline generation introduced another layer of complexity, including secure model downloads, SHA-256 verification, storage management, device capability checks, GPU acceleration where available, and varying Android hardware limitations.
Another challenge was preserving gallery import order while avoiding unnecessary storage permissions.
What I learned
This project taught me that the best AI experiences often hide complexity instead of exposing it.
Designing a provider abstraction layer reinforced that integrating multiple models is only part of the problem. Creating a consistent experience regardless of which model is running is far more important.
I also gained a much deeper understanding of Android media handling, local-first application architecture, on-device AI, secure credential storage, offline model deployment, and privacy-focused application design.
Working with OpenAI Codex and GPT-5.6 Terra throughout development also changed the way I build software. It became an invaluable development partner for rapidly exploring ideas, implementing features, refactoring architecture, debugging issues, and iterating much faster while allowing me to stay in control of every technical decision.
What's next
I plan to improve offline story generation, bring Local Gemma support to a wider range of Android devices through more optimized models, and make multi-day stories feel even more connected.
I'm also exploring AI-generated background music that adapts to each story, AI image generation for visualizing recurring fictional characters and scenes, richer book exports, and additional on-device AI capabilities while keeping Pluck's local-first philosophy intact.
My long-term goal is simple: build an experience that feels less like using an AI application and more like carrying a magical camera that quietly turns real places into fictional adventures.
Log in or sign up for Devpost to join the conversation.