¯\_(ツ)_/¯
I adore MinUI by Shaun Inman. No fuss, a focused feature set, and unapologetically opinionated.
Without his masterpiece this derivative would not exist.
For that I thank him, and apologize for the bastardization that follows.
Since purchasing a Retroid Pocket Classic I've been yearning for MinUI's simplicity.
This is my attempt to bring that experience to Android.
- Play Some Damn Games!
- Minimal Configuration
- Easy to add new games
- Basic features baked in
- Judicious addition of additional features
- Opinionated and Unambiguous Directory Structure
- MinUI-inspired UI
- Basic creature comforts right in the UI
- Rename
- Delete
- Collections
- Favorites
- Platform Reordering
- Collection Reordering
- Search in Collection / Platform
- Box Art
- Background Wallpaper (non-dynamic)
- Accent Colors
- Associating each platform with a particular emulator
Cannoli comes with a built-in libretro core runner that is a shameless rip-off of minarch from MinUI.
Here's the plan, if you are a grizzled vet use Cannoli as a launcher.
If you are a beginner, use the built-in core runner. When you are ready for more features and complexity use the external emulators.
You don't have to choose one path over the other.
Want the simplicity of the built-in core runner but want to play games that don't have a libretro core or function better with an external emulator? That's supported.
The best news is the opinionated directory structure is compatible with both approaches, no file wrangling required.
- Launching RetroArch
- Launching Standalone Emulators
- Launching Android Apps and Games
- Art Scraper
- Game Time Tracker
- LED Control
- Menu Music (yuck, but I respect that you might like it)
- Themes
- Video Previews (yuck x2, but I don't respect that you might like them)
- GLSL / Slang Shaders
- Netplay
- RetroAchievements
For all of these just use RetroArch. You can choose to use RetroArch by platform or by individual game.
If that is the case don't switch. Sorry for being dismissive!
It has become a meme in this hobby to spend all this time curating to never play anything.
(Yes I understand the irony of building a custom launcher rather than playing games. I'm a hypocrite.)
I've been working AI into my development workflow as of late both professionally and for fun.
There is a stigma against vibe-coded projects and rightfully so.
My personal opinion is that it is only a problem for mission-critical stuff and when it is not disclosed.
My promise to you is I will disclose how AI was used in each project.
My current tool of choice is Claude Code.
Here is what I used Claude Code for. Everything produced was reviewed.
My biggest sin is the internal libretro core runner. I designed the specs, Claude designed it, I reviewed it.
The libretro cores are doing so much of the heavy lifting that I am not too worried about this.
Now for the lesser sins!
- Help with the boring UI stuff (layout, scaling, etc.).
- Kotlin syntax help (my first time using it)
- Copy-editor for documentation
- Nano Banana made the Cannoli pixel art logo. I think it is cute.
Here is what I built:
- Project scope, architecture, and design decisions that weren't a rip-off of MinUI
- Data models (Platform, Game, Collection, LaunchTarget)
- File management (scanner, platform resolver, INI parser, atomic rename)
- Launcher integrations (RetroArch, standalone emulators, APK launching)
- Settings system (SharedPreferences repository, enums, reactive state)
- Input handling (controller routing, layout swap logic)
- Navigation structure and guard logic
- Custom ordering and persistence (platforms, collections)
- API for the Nonna's Kitchen
Documentation is written completely by me and will never be outsourced to the clankers.
Claude did help with grammar and as a sounding board to point out when I wasn't making any sense.
You can decide if these two statements are opposed or not.
I consider Claude just another tool and have been upfront about its usage out of respect to you.
You can decide how that impacts your desire to use this project.
Don't like AI? I don't care. I build this for fun, and you didn't pay shit for it. Take it for what it is.
| Name | What | License |
|---|---|---|
| M+ Fonts Project | M PLUS 1 Code | OFL |
| Nerd Fonts | NerdSymbols | OFL |
| ZXing | QR Code Library | Apache 2.0 |
| Atari800 | Core | GPLv2 |
| Beetle NeoPop | Core | GPLv2 |
| Beetle PCE FAST | Core | GPLv2 |
| Beetle PC-FX | Core | GPLv2 |
| Beetle VB | Core | GPLv2 |
| Beetle Wonderswan | Core | GPLv2 |
| blueMSX | Core | GPLv2 |
| DOSBox-Pure | Core | GPLv2 |
| FCEUmm | Core | GPLv2 |
| FreeIntv | Core | GPLv3 |
| Gambatte | Core | GPLv2 |
| Genesis Plus GX | Core | Non-commercial |
| Handy | Core | Zlib |
| mGBA | Core | MPLv2.0 |
| Mupen64Plus-Next | Core | GPLv2 |
| Nestopia | Core | GPLv2 |
| PCSX ReARMed | Core | GPLv2 |
| PicoDrive | Core | MAME |
| PokeMini | Core | GPLv3 |
| ProSystem | Core | GPLv2 |
| Snes9x | Core | Non-commercial |
| Stella | Core | GPLv2 |
| SwanStation | Core | GPLv3 |
| vecx | Core | GPLv3 |
| Virtual Jaguar | Core | GPLv3 |
| lcd3x by Gigaherz | Shader | Public domain |
| zfast_crt_geo by Greg Hogan | Shader | GPLv2 |
I've spent a lot of time building Cannoli.
If you enjoy using it and feel inclined to pay it forward, go do something nice for someone! ❤️
