Inspiration

Most interactive stories ask players to step into a character that has already been written. I wanted to explore a different idea: what if a story began with who the player is, how they feel today, and the first sentence they personally want to write?

That question became You Can Be Anything, a replayable five-act narrative experience where a lightweight personality profile and a sequence of meaningful choices shape both the journey and its final image.

What it does

The player enters a protagonist name, MBTI, preferred style, current mood, and an original opening sentence. They then select one of four genres: Mystery, Cyberpunk, Science Fiction, or Romance Fantasy.

The story progresses through five acts—Origin, Growth, Crisis, Climax, and Resolution. Each act presents three choices generated from the player's profile, genre, opening sentence, and previous decisions. After the final choice, the game assembles the selected scenes into a complete story.

Every completed playthrough is automatically archived with its profile, opening sentence, five selected decisions, finale, illustration prompt, and soundtrack plan. The player can also explicitly approve one low-cost protagonist illustration. If an identical ending has already been illustrated, the game reuses its cached image without making another image request.

The game includes a complete offline path. If the AI service is unavailable, a procedural narrative engine immediately takes over, so the story can still reach its ending without credentials or an internet connection.

How we built it

I built the game with Ren'Py 8.5.3, Ren'Py Screen Language, and embedded Python.

The narrative architecture separates a reusable five-act structure from genre-specific settings, actions, twists, emotional beats, colors, and imagery. A StorySession object tracks the player profile, current act, generated choices, selected scenes, soundtrack state, finale data, illustration state, and playthrough archive.

For live AI choices, the Ren'Py client sends structured story context to a local Python proxy. The proxy keeps the credential outside the game and repository, calls GPT-5.6 Luna through Sogang University's OpenAI-compatible API Gateway, validates the returned JSON, and sends exactly three choices back to Ren'Py.

For finale art, the proxy uses GPT Image 1 Mini with one image and low quality enforced by code. Image generation is never automatic: the player sees a maximum-cost confirmation first. Requests are addressed by a SHA-256 hash, identical endings reuse a local cache, simultaneous duplicates are rejected, failures are not cached, and failed requests are not automatically retried.

The downloadable game remains fully playable without the proxy through its offline procedural fallback.

Challenges we ran into

One challenge was making AI generation optional rather than allowing the entire game to depend on a network request. I solved this by preserving a procedural generator behind the same choice interface. The player can complete the same five-act cycle whether the model is online or offline.

Another challenge was protecting a university API credential in a downloadable desktop game. Embedding the key in Ren'Py would expose it, so I separated model access into a localhost proxy that reads an external credential or environment variable. The key is never returned to the game or committed to the repository.

Image generation introduced a different problem: a double-click, retry, or repeated ending could create unnecessary cost. The final design requires explicit approval, allows only one low-quality image per request, blocks an identical in-flight request, reuses completed images by content hash, and never retries a failed image automatically.

I also had to distinguish real Ren'Py errors from editor diagnostics. A standard Python language server marks valid Screen Language statements as errors because .rpy is not ordinary Python. Ren'Py 8.5.3 Lint became the authoritative parser check, followed by a complete manual playthrough.

Accomplishments that we're proud of

  • A complete profile-to-finale five-act gameplay loop
  • Live GPT-5.6 Luna choices with strict response validation
  • A credential-free offline fallback for judges and players
  • Optional GPT Image 1 Mini finale artwork with visible cost consent
  • Hash-based image caching and duplicate-request protection
  • Automatic archives containing the complete story, structured decision history, and illustration
  • English gameplay and standard Ren'Py interface
  • API-free mock tests and a successful Ren'Py 8.5.3 Lint run

What we learned

I learned that adding a model call is only one part of building a reliable AI product. The surrounding system—state, validation, fallback behavior, credential boundaries, cost controls, caching, persistence, and an understandable user experience—is just as important as the generated text.

I also learned how Ren'Py combines its own script and screen languages with Python, and how to move blocking model work away from the interaction thread while returning safe state updates to the UI.

What's next for You Can Be Anything

Next, I would add adaptive BGM generation. The game would turn each playthrough's genre, mood, act, and accumulated story facts into a soundtrack that evolves from Origin through Epilogue. I would apply the same safeguards used for illustration generation: explicit player consent, visible cost limits, content-hash caching, duplicate prevention, and clear licensing and attribution records. Each completed soundtrack would be saved inside the same session archive as its story and illustration.

Built With

  • codex
  • gpt-5.6
  • gpt-5.6-luna
  • gpt-image-1-mini
  • openai
  • python
  • ren'py
Share this project:

Updates