GamingTS

Configuration

GTS configuration determines how .gts files are transpiled — which runtime and provider packages to import, which symbols are available in shortcut functions, and which query bindings exist.

Configuration Sources

Configuration is resolved from three sources (in order of priority):

Defaults  <  package.json "gamingTs" field  <  Inline options (plugin/API)

1. Defaults (DEFAULT_GTS_CONFIG)

const DEFAULT_GTS_CONFIG: Required<GtsConfig> = {
  runtimeImportSource: "@gi-tcg/gts-runtime",
  providerImportSource: "@gi-tcg/core/gts",
  shortcutFunctionPreludes: ["cryo", "hydro", "pyro", "electro", "anemo", "geo", "dendro", "omni"],
  queryBindings: ["my", "opp"],
};

2. package.json (gamingTs field)

Add a gamingTs field to the nearest package.json:

{
  "name": "my-gts-project",
  "gamingTs": {
    "providerImportSource": "@example/provider",
    "runtimeImportSource": "@example/provider/runtime"
  }
}

The resolver walks up the directory tree from the source file to find the nearest package.json with a gamingTs field.

3. Inline Options

Passed directly to the transpiler API or build plugins:

import { gts } from "@gi-tcg/gts-esbuild-plugin";

const plugin = gts({
  runtimeImportSource: "@my-game/runtime",
  providerImportSource: "@my-game/provider",
});

Configuration Fields

runtimeImportSource

Type: string
Default: "@gi-tcg/gts-runtime"

The module from which runtime functions are imported. The transpiler generates:

import { createDefine, createBinding, Action, Prelude } from "<runtimeImportSource>";

providerImportSource

Type: string
Default: "@gi-tcg/core/gts"

The module prefix for the provider. The transpiler generates:

import __gts_rootVm from "<providerImportSource>/vm";
import __gts_query from "<providerImportSource>/query";  // only if query expressions exist

The provider must export:

  • ./vm — default export of the root ViewModel
  • ./query — default export of the query function (if queries are used)

shortcutFunctionPreludes

Type: string[]
Default: ["cryo", "hydro", "pyro", "electro", "anemo", "geo", "dendro", "omni"]

Names destructured from the Prelude symbol in shortcut functions. These become available as variables inside :() and :{} blocks:

// With default preludes:
:damage(hydro, 1);

// Transpiles to:
(__gts_fnArg, { cryo, hydro, pyro, electro, anemo, geo, dendro, omni } = __gts_fnArg[Prelude]) =>
  __gts_fnArg.damage(hydro, 1)

queryBindings

Type: string[]
Default: ["my", "opp"]

Names destructured in query expression callbacks:

query my.character

// Transpiles to:
__gts_query(({ my, opp }) => my.character, { star: false })

Resolution Algorithm

resolveGtsConfig(filePath, inlineConfig, options)

Async version — used by build plugins (esbuild, Rollup).

resolveGtsConfigSync(filePath, inlineConfig, options)

Sync version — used by the language plugin (Volar requires synchronous config resolution).

Algorithm

Both use a generator-based implementation for shared logic:

1. Normalize the source file path to an absolute directory
2. Walk up the directory tree:
   a. Read package.json in the current directory
   b. Parse JSON and extract the "gamingTs" field
   c. If found, use it as the package config
   d. If not found, move to the parent directory
   e. Stop at the filesystem root or the configured stopDir
3. Merge: DEFAULT_GTS_CONFIG ← packageConfig ← inlineConfig
4. Return the fully resolved config

Options

interface ResolveGtsConfigSyncOptions {
  readFileFn: (path: string, encoding: "utf8") => string;
  cwd?: string;
  stopDir?: string;
}

interface ResolveGtsConfigAsyncOptions {
  readFileFn: (path: string, encoding: "utf8") => Promise<string>;
  cwd?: string;
  stopDir?: string;
}
  • readFileFn — file reading function (allows the caller to use Node.js fs, TypeScript's sys, or Rollup's this.fs)
  • cwd — current working directory (for resolving relative paths)
  • stopDir — stop walking up the directory tree at this directory

Example: Provider Setup

A typical GTS project has this structure:

my-game/
├── package.json          # Root workspace
├── packages/
│   ├── provider/
│   │   ├── package.json  # No gamingTs field needed
│   │   ├── vm.ts         # Root ViewModel (default export)
│   │   ├── query.ts      # Query function (default export)
│   │   └── runtime.ts    # Re-exports @gi-tcg/gts-runtime
│   └── cards/
│       ├── package.json  # { "gamingTs": { "providerImportSource": "@my-game/provider" } }
│       └── barbara.gts   # Card definitions

The provider/package.json must export the correct subpaths:

{
  "name": "@my-game/provider",
  "exports": {
    "./vm": "./vm.ts",
    "./query": "./query.ts",
    "./runtime": "./runtime.ts"
  }
}

On this page