Bardic
A Python-first interactive fiction engine and authoring system. Frontend-agnostic and portable.
Install / Use
/learn @katelouie/BardicREADME
Bardic
<!-- [](https://codecov.io/gh/YOUR_USERNAME/bardic) -->Bardic is a Python-first interactive fiction engine that lets you import your own classes and use real Python in your stories.
Write your branching narrative in a clean, simple syntax (inspired by Ink), and when you need complex logic, just use Python. Bardic is designed to be the "story layer" for games that need rich data models, complex state, and custom UIs. Bardic is frontend-agnostic and works with NiceGUI, Reflex, React+FastAPI, or any other frontend layer you want to build with. It compiles stories to JSON and is portable and versatile.
Bardic in Action (with VSCode Extension)


A Quick Example
Bardic syntax is designed to be simple and stay out of your way. Here's a small story that shows off the core features:
# Import your own Python classes, just like in a .py file
from my_game.character import Player
:: Start
# Create a new Player object
~ hero = Player("Hero")
Welcome to your adventure, {hero.name}!
You have {hero.health} health.
+ [Look around] -> Forest
+ [Check your bag] -> Inventory
:: Forest
The forest is dark and spooky.
~ hero.sprint() # Call a method on your object
You feel a bit tired.
+ [Go back] -> Start
:: Inventory
# Use Python blocks for complex logic
@py:
if not hero.inventory:
bag_contents = "Your bag is empty."
else:
# Use list comprehensions, f-strings...
item_names = [item.name for item in hero.inventory]
bag_contents = f"You have: {', '.join(item_names)}"
@endpy
{bag_contents}
+ [Go back] -> Start
Why Bardic? A New Choice for Writers and Developers
You have great tools like Twine, Ink, and Ren'Py. So, why did I create Bardic?
Bardic is built for stories that get complex.
- Twine and Ink are both excellent authoring systems with large communities. If you like them, use them!
- Bardic is for when your "state" isn't just a number or a string, but a complex object. It's for when you want to write:
- "I want this character to have an inventory, which is a list of
Itemobjects." - "I need to import my
Playerclass and callplayer.take_damage(10)." - "I want to simulate a full tarot deck, with 78
Cardobjects, each with its own properties and methods."
- "I want this character to have an inventory, which is a list of
Have you ever been writing and thought, "I wish I could just import my custom class and use it"? That's what Bardic does.
It bridges the gap between simple, text-based branching logic and the full power of a programming language, letting you use both in the same file.
Quick Start
Install:
pip install bardic
# With a UI framework (pick one):
pip install bardic[nicegui] # Pure Python, single-file games
pip install bardic[web] # FastAPI + React
pip install bardic[reflex] # Python-to-React compilation
Create a project and run it:
bardic init my-game # Creates a project from template
cd my-game
pip install -r requirements.txt
bardic compile example.bard -o compiled_stories/example.json
python player.py # Opens at http://localhost:8080
Or skip the project template and just write a .bard file:
bardic play my_story.bard # Auto-compiles and plays in terminal
Installation Options
Bardic supports multiple UI frameworks. Choose the one you prefer:
| Framework | Install Command | Best For |
|-----------|----------------|----------|
| NiceGUI | pip install bardic[nicegui] | Pure Python, single-file games |
| FastAPI + React | pip install bardic[web] | Production web apps |
| Reflex | pip install bardic[reflex] | Python → React compilation |
Or install the core engine and add dependencies manually:
bardic init my-game
cd my-game
pip install -r requirements.txt
Core Features
- Write Python, Natively: Use
~for simple variable assignments or drop into full@py:blocks for complex logic. - Use Your Own Objects:
importyour custom Python classes (likePlayer,Card, orClient) and use them directly in your story. - Passage Parameters: Pass data between passages like function arguments:
:: Shop(item) -> BuyItem(item). Perfect for shops, NPC conversations, and dynamic content! - Complex State, Solved: Bardic's engine can save and load your entire game state, including all your custom Python objects, right out of the box.
- You Write the Story, Not the UI: Bardic doesn't care if you use React, NiceGUI, or a terminal. It produces structured data for any UI.
- Use the NiceGUI template for a pure-Python, single-file game.
- Use the Web template (FastAPI + React) for a production-ready, highly custom web game.
- Clean, Writer-First Syntax: Focus on your story with a minimal, line-based syntax for passages (
::), choices (+), and text. - Visualize Your Story: Automatically generate a flowchart of your entire story to find highlighted dead ends or orphaned passages with the
bardic graphcommand. - Catch Bugs Before Players Do:
bardic lintanalyzes your compiled story for broken jump targets, orphaned passages, dead ends, and attribute consistency issues. Extend it with project-specific plugins for your own game mechanics. - Instant Start-Up: Get a working game in 60 seconds with
bardic init. It comes with a browser-based frontend pre-configured and ready to run with a single command. (NiceGUI, Reflex, or React -- take your pick.) - Browser distribution.
bardic bundlepackages your game for itch.io with a full Python runtime (Pyodide). No server required. - VS Code Integration: Syntax highlighting, snippets, code folding, live preview, and graph-based navigation. Install "Bardic" from the marketplace or run
code --install-extension katelouie.bardic.
Batteries Included: Standard Library
Bardic ships with pre-built modules for common game mechanics — no need to write them from scratch.
from bardic.stdlib.inventory import Inventory
from bardic.stdlib.economy import Wallet, Shop
from bardic.stdlib.quest import QuestJournal
from bardic.stdlib.relationship import Relationship
from bardic.stdlib.dice import roll, skill_check
| Module | What it does |
|--------|-------------|
| inventory | Weight-limited item management with add/remove/filter |
| economy | Wallets, shops, buying/selling with automatic refunds |
| quest | Quest tracking with custom stages, journal entries, completion |
| relationship | NPC trust/comfort/openness with threshold events |
| dice | Dice rolls (3d6+5), skill checks, advantage/disadvantage |
Plus built-in special variables — _visits tracks how many times each passage has been entered, and _turns counts player choices.
:: Tavern
@if _visits.get("Tavern", 0) == 1:
You push open the tavern door for the first time.
@else:
The bartender nods. "The usual?"
@endif
+ {_turns >= 10} [I've been here a while...] -> Leave
CLI Reference
| Command | Description |
| ------- | ----------- |
| bardic init my-game | Create a new project from template (nicegui, web, or reflex) |
| bardic compile story.bard | Compile .bard source to .json |
| bardic play story.bard | Play a story in the terminal (accepts .bard or .json) |
| bardic graph story.json | Generate a visual flowchart (.png, .svg, or .pdf) |
| bardic lint story.bard | Analyze story for structural issues (broken jumps, dead ends, attribute bugs) |
| bardic bundle story.bard | Package for browser distribution (itch.io, static hosting) |
| bardic serve | Start the web runtime (FastAPI backend + React frontend) |
Syntax At a Glance
| Syntax | Meaning |
| ------ | ------- |
| :: Name | Passage header |
| + [Text] -> Target | Choice (persistent) |
| * [Text] -> Target | Choice (one-time, disappears after use) |
| ~ variable = value | Variable assignment |
| {variable} | Display a variable or expression |
| @if condition: ... @endif | Conditional block |
| @for item in list: ... @endfor | Loop |
| @py: ... @endpy | Python code block |
| @include file.bard | Include another file |
| @render component(data) | Send data to a UI component |
| @input name="x" label="Y" | Request player input |
Browser Distribution (itch.io)
Want to share your game on itch.io or any web hosting? Bardic can bundle your entire game into a self-contained package that runs in the browser:
# Create a browser-ready bundle
bardic bundle my-story.bard --zip
# With options
bardic bundle my-story.bard -o ./release -n "My Epic Adventure" --theme dark --zip
This creates a ZIP file containing:
- Your compiled story
- The Bardic engine (browser version)
- A complete Python runtime (Pyodide)
- Pre-installed packages: numpy, pillow, networkx, pyyaml, regex, jinja2, nltk, and more
Bundle sizes:
- Full bundle: ~17 MB (all packages included)
- Minimal bundle: ~5 MB (use
--minimalflag for stories that don't need extra packages)
No server required - everything runs in the browser via WebAssembly.
Options
|
