Inspiration
Thinking about our friendships, a few of us realized we’d gone months without actually interacting with people we care about, some just ten minutes away, others scattered across the country. No one was to blame, we were just busy with our own lives. Many of us are buried in classes, jobs, shifts which cause every “game night friday” or “poker” in the group chat to quietly die after a couple replies. This made us realize we needed to put a fun new twist on social connection by building something that fits naturally into people’s everyday lives.
What it does
Luma is our lively, interactive 3D town that turns your friend group into characters modeling their real lives. Each character represents someone important in your life. How they move around the town reflects how their week is really going, off to class, a 9-5, the gym after a long day, or back home. Instead of seeing posts or catching one sentence updates, you get to watch your friends’ lives happen in a community you all share. Unlocking the ability to find new opportunities to connect that would have otherwise been overlooked.
How we built it
The town is built with Three.js with low-poly city models and little animated characters. The backend uses FastAPI hosted on Fly.io, and Supabase as the postgres database. Supabase allows us to handle auth and real-time updates, meaning you can see your friend's character walk to the library on your screen in real-time. We use AI in 3 main areas. The first area is generating fully customized, expandable towns for your friends to live, interact, and connect. The second area we utilize AI is to suggest meetup times/places, share customized insights based on your friends activity and posts in the town, and spark discussion between friends. We additionally use AI when connecting a user’s Google Calendar. As many of the events in the google calendar don’t match the specific notation of the town’s places, we utilized an AI to make an inference on the event based on a preliminary search. This allowed for many of the events that won’t match any of the descriptions of locations to be placed into the town.
Challenges we ran into
The town map generation was the hardest part to get right. Our first idea was to let the AI draw each town tile by tile, but the results kept breaking: shops faced nothing, parks were cut off from the roads, and sometimes two places landed on the same building. So we had the AI pick the design and wrote our own layout code to build the actual grid. Rendering it was the next problem. Once a town got to 31 by 31 tiles with 24 characters walking around, the frame rate tanked, and the cause was the feature that makes buildings see-through when a character walks behind them. We were casting rays from the camera to every character on every frame and testing them against every building mesh in the city. We cut that to ten checks a second, only for characters actually on screen, and had each ray test a cached bounding box before the exact mesh, so most buildings get ruled out instantly. We also stopped small props like lamps and benches from casting shadows, and froze the positions of all the scenery that never moves, so the GPU wasn't recalculating a whole city every frame.
Accomplishments that we're proud of
We're most proud that Luma actually feels alive. The town follows the real clock: streetlights flicker on at dusk, windows light up across downtown at night, and rain or snow rolls in on its own. Characters stop to chat with speech bubbles when they cross paths, and a trail shows where each one is headed. Houses change with the people who live in them, so a friend's good news can throw party lights over their roof. None of us expected how much those little details would matter. The first time one of us opened the app late at night and saw a friend's character walking home under the streetlights, it stopped feeling like a project we were building and started feeling like a place we wanted to visit.
What we learned
We learned the difficulty of making a shared world feel natural when multiple people are interacting at the same time. Additionally, we learned to test and reinforce the boring stuff early when our backend went down mid-hackathon after a free trial ran out. Honestly though, the biggest thing we learned is that it's easy to build something that keeps people staring at their phone, but a lot harder to build something that gets them to put it down and go see their friends.
What's next for Luma
The first thing we want to build is better friend matching and growth for new connections. Right now, Luma can recognize when two people share an interest, but we want it to catch the less obvious connections too, like two friends who are both free Thursday night or someone from your climbing group who would get along with someone from work. We also want a real mobile app with notifications, because a plan suggestion only helps if you see it before Thursday night is over. After that, we’d like to add more external connections, including Apple/Outlook calendars or more social network platforms and give people more control over exactly what their town can see. Long term, we want Luma to be the thing that turns “we should hang out” into an actual plan that people follow through on.
Built With
- cursor
- fastapi
- fly.io
- gemini
- google-calendar
- grok
- javascript
- postgresql
- python
- supabase
- three.js
- vercel
Log in or sign up for Devpost to join the conversation.