https://github.com/bocaletto-luca/textquestengine
https://github.com/bocaletto-luca/textquestengine
bocaletto-luca engine engine-development engine-videogames python terminal-engine videogames-engine
Last synced: 10 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/bocaletto-luca/textquestengine
- Owner: bocaletto-luca
- License: gpl-3.0
- Created: 2025-07-19T01:33:55.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2025-07-19T01:48:42.000Z (11 months ago)
- Last Synced: 2025-07-19T06:13:21.545Z (11 months ago)
- Topics: bocaletto-luca, engine, engine-development, engine-videogames, python, terminal-engine, videogames-engine
- Language: HTML
- Homepage: https://bocaletto-luca.github.io/
- Size: 39.1 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# TextQuestEngine
**Author**: Luca Bocaletto (bocaletto-luca)
**Repository**: https://github.com/bocaletto-luca/TextQuestEngine
**License**: GNU GPL v3.0
A Python engine for creating modular, extensible, and standalone text adventures. This repository includes:
- Core engine: parser, dispatcher, loader, plugin system
- A complete demo: “The Lost Cave”
- CLI tools to scaffold, run, test, lint, build and package your adventure
---
## Table of Contents
- [Features](#features)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Usage](#usage)
- [CLI Commands](#cli-commands)
- [Demo Walkthrough](#demo-walkthrough)
- [Project Structure](#project-structure)
- [Demo “The Lost Cave”](#demo-the-lost-cave)
- [world.yaml](#worldyaml)
- [items.json](#itemsjson)
- [Plugin: light_plugin.py](#plugin-light_pluginpy)
- [Packaging](#packaging)
- [Contributing](#contributing)
- [License](#license)
---
## Features
- Multilingual parser (Italian/English) with synonyms
- Event-driven dispatcher & plugin hooks (`pre_action`, `command_`, `post_action`)
- World loader from YAML + JSON (`world.yaml` + `items.json`)
- Built-in support for rooms, items, NPCs, missions, game time
- Intuitive CLI: `init`, `run`, `test`, `lint`, `build`, `package`
- Standalone packaging via PyInstaller
---
## Prerequisites
- Python 3.8+
- pip
- (optional) PyInstaller for standalone packaging
---
## Installation
```bash
git clone https://github.com/bocaletto-luca/TextQuestEngine.git
cd TextQuestEngine
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
pip install pyinstaller # only if you intend to use `tqe package`
```
---
## Usage
### CLI Commands
After installation, the `tqe` command (alias for `python3 -m engine.utils.cli`) provides:
```bash
tqe init # Scaffold a new adventure project
tqe run --world # Launch the interactive game
tqe test # Run unit & integration tests (pytest)
tqe lint # Check code style & quality
tqe build # Build sdist & wheel packages
tqe package # Create a standalone executable (PyInstaller)
```
### Demo Walkthrough
The demo “The Lost Cave” is in `demo_adventure/`. To try it:
```bash
cd demo_adventure
tqe run
```
Sample commands:
```txt
> look
> take torch
> move inside
> use torch
> look
> take gem
> missions
```
---
## Project Structure
```
TextQuestEngine/
├── engine/ # Core engine code
│ ├── core/
│ │ ├── dispatcher.py
│ │ ├── game.py
│ │ ├── parser.py
│ │ └── cli_commands.py
│ ├── data/
│ │ ├── loader.py
│ │ └── models.py
│ ├── plugins/
│ │ └── base.py
│ └── utils/
│ └── cli.py
├── demo_adventure/ # “The Lost Cave” demo
│ ├── config/
│ │ ├── world.yaml
│ │ └── items.json
│ ├── plugins/
│ │ └── light_plugin.py
│ └── assets/
│ └── map.txt
├── src/ # PyInstaller entrypoint
│ └── main.py
├── setup.py
└── README.md
```
---
## Demo “The Lost Cave”
### world.yaml
```yaml
# demo_adventure/config/world.yaml
config:
start_room: house
start_time: 0
intro_text: >
You are an explorer seeking epic adventures… and epically bad jokes.
If you can keep a grin while risking life and limb, you’re in the right place!
initial_missions:
- mission_gem
- mission_beer
rooms:
house:
name: Abandoned House
desc: >
A dusty little house filled with creaky furniture and mysterious
oddities. A torch glints on the table like a miniature sun.
connections:
outside: forest
items:
- torch
forest:
name: Messy Forest
desc: >
Trees look like they’ve given each other bad haircuts. A winding path
leads deeper, where a mysterious cave yawns in darkness.
connections:
back: house
inside: cave
items: []
cave:
name: Dark (and Witty) Cave
desc: >
It’s so dark even your brightest ideas struggle to stand out.
Maybe you need something to light the way… or at least a comedian.
connections:
exit: forest
items: []
tavern:
name: Tavern of the Dozy Gnome
desc: >
A humble tavern where every patron snores into their pint.
The bar is lined with bottles—most as empty as your wallet.
connections:
outside: house
items:
- beer
npcs:
lazy_gnome:
name: Lazy Gnome
location: tavern
dialogues:
- text: "Oh, traveler! If you have a beer, we can call it ‘friendship’."
options:
- reply: "Here’s a beer"
text: "Ah, finally! *sneeze*"
next: end
- reply: "I have a gem"
text: "A gem? I prefer frothy mugs, but sure…"
next: end
- text: "end"
options: []
missions:
mission_gem:
title: "The Shiny Gem"
description: >
Legend speaks of a precious gem hidden in the dark depths of the cave.
Find it and bring it back… and maybe entertain a gnome!
requirements:
have_item: ["gem"]
steps:
- "Enter the cave"
- "Light the torch"
- "Take the gem"
- "Return to the Lazy Gnome"
rewards:
xp: 50
message: "You lit up the cave… and one gnome’s spirits!"
mission_beer:
title: "Bring the Beer"
description: >
The Lazy Gnome is parched. Fetch a cold beer and present it with flair.
requirements:
have_item: ["beer"]
steps:
- "Find a beer"
- "Go to the tavern"
- "Give the beer to the Lazy Gnome"
rewards:
xp: 20
message: "The gnome now sleeps soundly. Mission accomplished!"
```
### items.json
```json
{
"torch": {
"names": ["torch", "lantern"],
"description": "A battery-powered torch that shines brightly—perfect for caves.",
"weight": 1.0,
"usable_on": ["cave"]
},
"gem": {
"names": ["gem", "precious stone"],
"description": "A sparkling gem embedded in the cave wall—brighter than your wits.",
"weight": 0.2,
"usable_on": []
},
"beer": {
"names": ["beer", "pint", "bottle"],
"description": "A frothy pint of beer: liquid consolation for any gnome.",
"weight": 0.5,
"usable_on": ["lazy_gnome"]
}
}
```
### Plugin: `light_plugin.py`
```python
# demo_adventure/plugins/light_plugin.py
from engine.plugins.base import PluginBase
from types import SimpleNamespace
class LightPlugin(PluginBase):
"""
Handles darkness in the cave and torch usage:
- Blocks vision until the torch is lit
- Spawns the gem once lit
"""
def on_pre_action(self, action: SimpleNamespace, state, world):
if action.command == "look" and state["current_room"] == "cave":
if not state.get("torch_lit", False):
return "It’s too dark to see. Maybe a torch would help!"
return None
def on_command_use(self, action: SimpleNamespace, state, world):
if action.target == "torch":
state["torch_lit"] = True
cave = world.rooms["cave"]
if "gem" not in cave.items:
cave.items.append("gem")
return "You light the torch! Warm glow reveals a shiny gem."
return None
```
---
## Packaging
To build a standalone executable:
```bash
pip install pyinstaller
tqe package
```
The binary (plus `config/` and `assets/`) will appear in `dist/`. Rename it to `tqe` and distribute!
---
## Contributing
1. Fork the repository
2. Create a feature branch (`feature/your-feature`)
3. Make changes, run `tqe test` & `tqe lint`
4. Submit a Pull Request
---
## License
This project is licensed under **GNU GPL v3.0**.
See [LICENSE](LICENSE) for details.