Skip to content

Repository files navigation

Metatransformer Game Stack

A toolkit of micro-tools for indie game developers, built one tool at a time.

The first tool live is the Steam Capsule Grader: upload your capsule art and get a 0–100 score against a 10-point rubric derived from professional Steam capsule design practice, with a per-criterion breakdown, what's working, and specific fixes.

There is also a companion, free, open-source Claude skill pack for game design: https://github.com/rondorkerin/gamestack

Stack

Layer Choice
Framework Next.js 16 (App Router), React 19
Styling Tailwind CSS v4 (CSS-first config, no tailwind.config.ts)
Auth Supabase Auth via @supabase/ssr
Data Supabase Postgres, accessed only with the service-role key from server code
Storage Supabase Storage, private capsules bucket + short-lived signed URLs
AI Provider-agnostic adapter layer; OpenAI vision models today
Hosting Vercel (auto-deploy from main)
Package manager pnpm workspaces

Layout

apps/web            Next.js app (the whole product surface)
packages/rubric     The 10-criterion Steam capsule rubric + Steam asset specs
packages/ai         Modular model-calling layer and provider adapters
supabase/migrations Database schema
NEXT16.md           Next.js 16 house rules — read before writing app code

Getting started

pnpm install
cp .env.example apps/web/.env.local   # then fill in the values
pnpm dev

Required environment variables are documented in .env.example. Without OPENAI_API_KEY the app runs fine — the grader simply reports that no AI provider is configured and hides the upload form, rather than failing at request time.

pnpm typecheck   # tsc across every workspace package
pnpm build       # production build
pnpm lint

Two things that will surprise you

1. This is Next.js 16. middleware.ts does not exist here — it is src/proxy.ts exporting a proxy function, always on the Node runtime. cookies(), headers(), params and searchParams are all Promises you must await. See NEXT16.md.

2. There is no row-level security, on purpose. Access control lives in application code, and every data read/write goes through the service-role client in server-only modules. Because the tables therefore have no RLS to protect them, the migration revokes all privileges from the anon and authenticated roles — otherwise the public anon key could read every table straight off PostgREST. That REVOKE block is the security boundary. Ownership checks (.eq('user_id', userId)) are the other half. If you add a table, revoke it too.

Credits

New accounts get 50 credits. A grade costs credits derived from the tokens the model actually spent — roughly 2 on the cheapest model, ~6 on the default, ~9 on the most thorough, so 50 credits is about 8 grades on the default model or 25 on the fastest. The rate lives in packages/ai/src/credits.ts; per-model pricing lives in packages/ai/src/registry.ts and should be re-checked against the provider's pricing page, since credit cost is derived from it.

Credits are only charged after a grade succeeds — a failed or rejected grade is free. debit_credits is a single atomic Postgres function that decrements the balance and writes the audit row in the same statement.

Adding an AI provider

  1. Write an adapter satisfying ProviderAdapter in packages/ai/src/providers/.
  2. Add one line to ADAPTERS in packages/ai/src/adapters.ts.
  3. Add its models to MODELS in packages/ai/src/registry.ts.

Nothing outside packages/ai imports a provider SDK, and models whose provider has no API key configured are automatically hidden from the picker.

About

Metatransformer Game Stack — a toolkit of micro-tools for indie game developers. First tool: an AI Steam capsule grader scored against a 10-point rubric.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages