Latin "ludus" (game) + dex (index)
I made a Dash AG Grid enemy database for Xenosaga a few years ago and found it really fun to build and actually super useful, so I decided to expand that concept into a more general project that can host tools for multiple games.
With the exception of most of the Xenosaga Enemy Database, which was built years ago, the rest of the code in this repository was generated with the help of AI. I used Codex.
I do my best to review and test all AI-generated code, but there may be bugs. If you find any, please open an issue or submit a PR.
Current pages in this repository:
Xenosaga: enemy database with sortable, filterable AG Grid tables for Episodes I, II, and III, plus a row-click modal for full enemy details. Docs: Xenosaga READMEClair Obscur: Expedition 33: skill damage data browser, skill damage calculator, and zone level reference table. Docs: Expedition 33 calculator README
Dashfor routing, layout, and callbacksdash-ag-gridfor interactive data tablesdash-bootstrap-componentsanddash-mantine-componentsfor UIpandasfor data loading and shapinggunicornfor production servinguvfor dependency management
.
├── app.py # Dash app entrypoint and home page
├── games/ # Dash pages, grouped by game
│ ├── expedition33/
│ └── xenosaga/
├── assets/ # CSS, JS, CSVs, SQLite DB, static helpers
├── helpers/ # Shared utility code
├── pyproject.toml # Project metadata and dependencies
└── Dockerfile # Container build for deployment
app.py enables Dash Pages with pages_folder="games", so any module under games/ that calls register_page(...) becomes part of the site automatically.
uv sync
uv run python app.pyThe development server starts on Dash's default local port.
uv sync
uv run gunicorn -b 0.0.0.0:8080 --workers=4 --preload app:serverBuild the image:
docker build -t ludex .Run the container:
docker run --rm -p 8080:8080 ludexThen open http://localhost:8080.
- Create a module under
games/<game_name>/. - Define a
layout. - Register the page with Dash using
register_page(...)and a game-scoped path such as/<game_name>/<page_name>. - Restart the app.
Once registered, the home tree in app.py will automatically group the page under that game.
- The top-level app is intentionally generic so multiple games can live in one project.
- Game URLs are namespaced by game, for example
/exp33/skilldamage. - Game-specific documentation lives in Expedition 33 calculator README and Xenosaga README.