Tableslayer
Tools to create animated battle maps for in person RPG games.
Install / Use
/learn @Siege-Perilous/TableslayerREADME
TableSlayer
Table Slayer provides tools for game masters to project animated battle maps on their digital tabletop.

Credits
Dave Snider designs and builds Table Slayer. The Three JS Stage component was built by Dan Greenheck. Illustrations and logo provided by Cinnamon Devil.
License & open source contributions
Table Slayer is available under a functional source license that becomes Apache 2 after two years. You are free to host and modify Table Slayer on your own as long as you don't try to build a competing business. The primary intention of the source being open is so hobbyists can get familiar with a large Svelte codebase. We welcome PRs and bug reports. If you are planning a large feature, please make an issue first. Any PRs you contribute will fall under the same usage license.
Design philosophy
This project is managed under some core philosophies. These are hard opinions that will never change.
Built for speed
User interactions in Table Slayer should be near instant. The use of loading spinner states should be minimal. Do not load the application piecemeal. You should be able to interact with the application immediately after load. First loads should be server side. Any technology decision should ask "will this make Table Slayer slower?".
Don't passively track, actively listen
Table Slayer is built completely in the dark, ignoring modern design trends of analytic-driven decision making. We don't track you. New features are considered by talking to users and listening to the community.
The less dependencies, the better
Avoid large dependencies beyond core framework choices. All design components should be hand crafted and use vanilla CSS.
Development
This repo requires certain Node and pnpm versions. These can be checked in package.json. If working in multiple Node based projects, you might want to use nvm to manage your Node version and corepack (which comes with Node and needs to be enabled) to switch your package manager. If both are installed, it should auto-switch your versions as you enter the folder.
pnpm run dev should open all the apps under their own port.
To get started, edit the .env file in each app and run pnpm run dev to load local development.
A full guide for self-hosting is coming soon. Here's a quick list for anyone who wants to get up and running.
- Copy
.env-examplein theapps/webfolder to.env - Create a new database on Turso (or use libsql directly](https://github.com/Siege-Perilous/tableslayer/issues/243#issuecomment-3613109830)). Add the required keys to
.env. - Create a Cloudflare account. Add the required API keys to
.env.- You will need to set up an R2 bucket for assets and uploads. If self-hosting, you can run
pnpm run assets:uploadto populate your bucket with any large files that are excluded from this repo (ex: illustrations and LUT files). - You will need to setup Partykit with a partykit token. For dev, Parykit will run locally. For production, Partykit is hosted with Cloudflare workers.
- You will need to set up an R2 bucket for assets and uploads. If self-hosting, you can run
pnpm installin the root of this repo.- Jump into the
apps/webfolder and runpnpm run migrateto initialize your db. - Run
pnpm run devfrom the repo root. Two runservers will open.- http://localhost:5174 for the web
- http://localhost:5173 for the ui docs
There are Fly configs in the root should you want to deploy.
Apps and packages
Table Slayer is a Turbo mono repo split into several projects.
web: a svelte-kit app for tableslayer.com.docs: a svelte-kit app that is a playground of UI components.ui: Svelte components used within the web app.config-eslint: Shared linting config across the repo.config-typescriptShared typescript config across the repo.
Linting, prettier and CI
Because TypeScript, linting and prettier are provided globally within the repo, you'll need to make sure your IDE's project starts from the root of the monorepo to receive auto-fixes. During CI, Husky should check as you make commits.
The CI scripts will make a pass on any incoming PRs and do the following:
- Check for Prettier, TypeScript and Svelte errors.
- Create a Turso DB prefixed with the PR number, then run any migrations in your PR
- Deploy a Fly preview app (setting env vars to the Turso DB and PR number)
- Run Playwright tests against the preview
- On PR merge, destroy the temporary DBs and Fly apps.
Tests
Tests are run with Playwright. Drop your tests in any of the app-folders and they will be run against the Fly preview URLs that are generated with your PR.
Styling
- Vanilla CSS
- Global variables are stored in a global CSS file that can be imported into a top level layout file.
Tech
This is a mono repo powered by Turbo and Vite. In general Table Slayer aims to use a minimal amount of dependencies. We prefer low-level dependencies, rather than component libraries. Think carefully when submitting a PR that includes a new dependency.
- Fly provides hosting
- Turbo provides the monorepo build / packaging.
- Svelte provides the frontend framework. This repo uses Svelte 5. This article provides a summary of the changes.
- Tanstack / Svelte query for client fetching.
- Tweakpane for debug controls for the Three.js scene
- Cloudflare R2 is used for a CDN.
- Cloudflare Image Transformations is used to resize images.
- Party Kit hosted on Cloudflare workers handle realtime web socket updates.
- Yjs provides conflict resolution and typing for the Party Kit Layer
- Resend is used for email management.
- Turso is used for SQLite db hosting.
- Drizzle provides the ORM
- Stripe provides billing and subscription management
Security
If you notice a security issue, please report it to dave@tableslayer.com
Related Skills
node-connect
347.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
107.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
347.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
347.0kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
