@mpgd/cli 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/index.js +349 -22
  2. package/package.json +14 -2
  3. package/templates/phaser-game/README.md +97 -6
  4. package/templates/phaser-game/agent/acceptance.md +7 -2
  5. package/templates/phaser-game/agent/brief.md +1 -1
  6. package/templates/phaser-game/agent/game-manifest.json +5 -1
  7. package/templates/phaser-game/apps/target-cloudflare-pages/package.json +28 -0
  8. package/templates/phaser-game/apps/target-cloudflare-pages/src/worker.ts +12 -0
  9. package/templates/phaser-game/apps/target-cloudflare-pages/tsconfig.json +8 -0
  10. package/templates/phaser-game/apps/target-cloudflare-pages/vite.config.ts +28 -0
  11. package/templates/phaser-game/apps/target-cloudflare-pages/wrangler.jsonc +28 -0
  12. package/templates/phaser-game/apps/target-devvit/README.md +1 -1
  13. package/templates/phaser-game/apps/target-devvit/package.json +1 -1
  14. package/templates/phaser-game/apps/target-devvit/src/server/index.ts +4 -4
  15. package/templates/phaser-game/index.html +2 -0
  16. package/templates/phaser-game/legal/privacy.html +78 -0
  17. package/templates/phaser-game/legal/support.html +66 -0
  18. package/templates/phaser-game/legal/terms.html +70 -0
  19. package/templates/phaser-game/mpgd.targets.json +6 -0
  20. package/templates/phaser-game/package.json +42 -12
  21. package/templates/phaser-game/pnpm-workspace.yaml +7 -0
  22. package/templates/phaser-game/public/icon.svg +12 -0
  23. package/templates/phaser-game/public/manifest.webmanifest +20 -0
  24. package/templates/phaser-game/src/assets/manifest.ts +15 -0
  25. package/templates/phaser-game/src/assets/marker.svg +12 -0
  26. package/templates/phaser-game/src/env.d.ts +1 -0
  27. package/templates/phaser-game/src/main.ts +5 -0
  28. package/templates/phaser-game/src/platform/installPlatform.ts +1 -1
  29. package/templates/phaser-game/src/platform/runtimeDetector.ts +9 -1
  30. package/templates/phaser-game/src/scenes/BootScene.ts +8 -0
  31. package/templates/phaser-game/src/scenes/PlayScene.ts +3 -2
  32. package/templates/phaser-game/vite.config.ts +2 -0
@@ -5,7 +5,7 @@ Standalone Phaser 4 game starter generated by `@mpgd/create-game`.
5
5
  ## Local Loop
6
6
 
7
7
  ```sh
8
- pnpm install --filter . --filter ./apps/target-devvit
8
+ pnpm install -w
9
9
  pnpm dev
10
10
  pnpm check
11
11
  pnpm build
@@ -15,6 +15,7 @@ The starter keeps game code behind `PlatformGateway` and demonstrates:
15
15
 
16
16
  - target-aware adapter selection through `APP_TARGET`
17
17
  - target-config/effective-config runtime snapshots
18
+ - target-portable Phaser asset manifest loading
18
19
  - local translation keys
19
20
  - optional `@mpgd/game-services` client wiring
20
21
  - best-effort analytics events
@@ -30,12 +31,16 @@ platform-specific artifacts. Keep an `mpgd-kit` checkout nearby and pass it with
30
31
  pnpm exec mpgd target build-all \
31
32
  --targets-file ./mpgd.targets.json \
32
33
  --kit-path ../mpgd-kit \
33
- --targets web,ait,reddit \
34
+ --targets web,microsoft-store,ait,reddit \
34
35
  --ait-variant wrapper
35
36
  pnpm exec mpgd target smoke-all \
36
37
  --targets-file ./mpgd.targets.json \
37
38
  --kit-path ../mpgd-kit \
38
- --targets web,ait,reddit
39
+ --targets web,microsoft-store,ait,reddit
40
+ pnpm exec mpgd target doctor \
41
+ --targets-file ./mpgd.targets.json \
42
+ --kit-path ../mpgd-kit \
43
+ --targets web,microsoft-store,ait,reddit
39
44
  ```
40
45
 
41
46
  When developing the kit itself, the same commands work through the repository
@@ -45,7 +50,7 @@ script:
45
50
  pnpm --dir ../mpgd-kit mpgd target build-all \
46
51
  --targets-file "$PWD/mpgd.targets.json" \
47
52
  --kit-path ../mpgd-kit \
48
- --targets web,ait,reddit \
53
+ --targets web,microsoft-store,ait,reddit \
49
54
  --ait-variant wrapper
50
55
  ```
51
56
 
@@ -53,6 +58,19 @@ pnpm --dir ../mpgd-kit mpgd target build-all \
53
58
  into `.mpgd.targets.generated.json` before calling the kit's existing target
54
59
  build and smoke scripts.
55
60
 
61
+ `mpgd target doctor` verifies that release manifest artifact paths stay under
62
+ this game directory, even when a build used the kit reference Apps in Toss or
63
+ Capacitor wrappers.
64
+
65
+ ## Assets
66
+
67
+ Static assets live under `src/assets` and are declared in
68
+ `src/assets/manifest.ts`. Use stable manifest keys in scenes and pass Vite-
69
+ emitted URLs into the manifest with `?url` imports, or keep static
70
+ `new URL('./file', import.meta.url)` calls directly in the manifest module. The
71
+ starter keeps Vite `base: './'` so generated asset URLs stay portable across web
72
+ preview, Apps in Toss, Devvit, Android, and iOS bundles.
73
+
56
74
  ## Reddit Devvit
57
75
 
58
76
  This starter owns its Devvit app root in `apps/target-devvit`. That directory
@@ -66,7 +84,7 @@ name.
66
84
  First-time Devvit setup:
67
85
 
68
86
  ```sh
69
- pnpm install --filter . --filter ./apps/target-devvit
87
+ pnpm install -w
70
88
  pnpm devvit:login
71
89
  pnpm devvit:whoami
72
90
  pnpm devvit:init
@@ -81,9 +99,81 @@ authorization is not available in the current terminal session. After init, use
81
99
  `pnpm devvit:playtest`, `pnpm devvit:upload`, and `pnpm devvit:publish` from
82
100
  this game root.
83
101
 
102
+ ## Apps in Toss
103
+
104
+ Use the target-aware local loop while developing game code for Apps in Toss:
105
+
106
+ ```sh
107
+ pnpm dev:ait
108
+ pnpm build:ait
109
+ pnpm smoke:ait
110
+ ```
111
+
112
+ The kit reference wrapper includes the Apps in Toss community devtools package
113
+ for SDK mock and device debugging while the wrapper is still kit-owned:
114
+
115
+ ```sh
116
+ pnpm ait:wrapper:dev
117
+ pnpm ait:wrapper:dev:plain
118
+ pnpm ait:wrapper:dev:phone
119
+ pnpm ait:devtools:mcp
120
+ pnpm ait:devtools:mcp:mobile
121
+ ```
122
+
123
+ `ait:wrapper:dev` runs the kit wrapper with the community Vite plugin enabled.
124
+ It loads the last game bundle copied by `pnpm build:ait` from the wrapper's
125
+ `public/game` directory, so run `pnpm build:ait` again after game changes before
126
+ opening a wrapper devtools session. Use `ait:wrapper:dev:plain` to disable the
127
+ devtools plugin. `ait:wrapper:dev:phone` uses the devtools tunnel and CDP relay
128
+ for phone sandbox checks, and `ait:devtools:mcp:mobile` starts the community MCP
129
+ bridge in the phone tunnel mode after the wrapper prints the tunnel URLs. Use
130
+ `ait:devtools:mcp` for the default local or relay debugging mode. The kit
131
+ intentionally leaves
132
+ `cloudflared` postinstall disabled; the first phone tunnel session downloads the
133
+ binary lazily through the community devtools package instead of during ordinary
134
+ workspace install.
135
+
136
+ The starter includes `@ait-co/console-cli`, the Apps in Toss community console
137
+ CLI, as a dev dependency for project-local console automation:
138
+
139
+ ```sh
140
+ pnpm ait:console:login
141
+ pnpm ait:console:whoami
142
+ pnpm ait:console:init
143
+ # add the real logo, thumbnail, and screenshot files referenced by aitcc.yaml
144
+ pnpm ait:console:register
145
+ pnpm ait:console:status
146
+ pnpm build:ait:package
147
+ pnpm ait:console:deploy -- release-output/ait/YOUR_APP.ait
148
+ ```
149
+
150
+ `ait:console:init` creates the game-owned `aitcc.yaml` context, and
151
+ `ait:console:register` creates the mini-app and writes its `miniAppId` back to
152
+ that file. Before registration, add the real logo, thumbnail, and screenshot
153
+ files referenced by `aitcc.yaml` under `./assets/`. Use `pnpm build:ait` for the
154
+ kit wrapper smoke loop, and run `pnpm build:ait:package` before console deploys
155
+ so `release-output/ait/` contains the `.ait` bundle you pass after `--`.
156
+
157
+ The starter also installs `@apps-in-toss/web-framework` and awaits
158
+ `install()` from `@ait-co/polyfill` only when `__APP_TARGET__` is `ait`. In the
159
+ Apps in Toss WebView runtime, standard Web APIs such as `navigator.clipboard`,
160
+ `navigator.geolocation`, `navigator.share`, `navigator.vibrate`, network status,
161
+ and `_blank` `window.open` calls route through the Apps in Toss SDK. Plain
162
+ browser, Microsoft Store, Reddit, Android, and iOS builds do not import the AIT
163
+ SDK chunk and keep their native browser behavior. `pnpm dev:ait` is useful for
164
+ checking the AIT-gated bundle path, but SDK-backed API behavior should be
165
+ verified in the Apps in Toss sandbox or a game-owned devtools setup. If your
166
+ game uses permission-gated APIs such as clipboard or geolocation, declare the
167
+ matching permissions in the game-owned Apps in Toss `granite.config.ts` before
168
+ submission.
169
+
84
170
  ## Target Ownership Notes
85
171
 
86
172
  - Browser preview is fully game-owned and writes to `artifacts/web-preview`.
173
+ - Microsoft Store is a game-owned PWA target that reuses the browser adapter and
174
+ writes to `artifacts/microsoft-store` with `manifest.webmanifest` for
175
+ PWABuilder packaging. Replace the starter icon and manifest metadata before
176
+ Store submission.
87
177
  - Reddit Devvit is game-owned in `apps/target-devvit`.
88
178
  - Apps in Toss currently uses the kit reference wrapper at
89
179
  `${MPGD_KIT_PATH}/apps/target-ait` for smoke packaging. Before a real Toss
@@ -91,7 +181,8 @@ this game root.
91
181
  review metadata are not shared with the kit demo.
92
182
  - Android and iOS currently use the kit reference Capacitor shell at
93
183
  `${MPGD_KIT_PATH}/apps/mobile-capacitor`. That is useful for local artifact
94
- checks, but production apps should own their bundle ID/package ID, signing,
184
+ checks, and final artifacts are copied back to this game's `release-output/`
185
+ directory. Production apps should own their bundle ID/package ID, signing,
95
186
  icons, and store metadata in a game-specific shell.
96
187
 
97
188
  ## Game Services
@@ -5,8 +5,9 @@ Run these checks before handing off a generated game starter:
5
5
  ```sh
6
6
  pnpm check
7
7
  pnpm build
8
- pnpm --dir ../mpgd-kit mpgd target build-all --targets-file "$PWD/mpgd.targets.json" --targets web,ait,reddit --ait-variant wrapper
9
- pnpm --dir ../mpgd-kit mpgd target smoke-all --targets-file "$PWD/mpgd.targets.json" --targets web,ait,reddit
8
+ pnpm --dir ../mpgd-kit mpgd target build-all --targets-file "$PWD/mpgd.targets.json" --targets web,microsoft-store,ait,reddit --ait-variant wrapper
9
+ pnpm --dir ../mpgd-kit mpgd target smoke-all --targets-file "$PWD/mpgd.targets.json" --targets web,microsoft-store,ait,reddit
10
+ pnpm --dir ../mpgd-kit mpgd target doctor --targets-file "$PWD/mpgd.targets.json" --targets web,microsoft-store,ait,reddit
10
11
  ```
11
12
 
12
13
  For Apps in Toss changes, use the apps-in-toss MCP before implementation and
@@ -16,3 +17,7 @@ For Reddit Devvit changes, keep Devvit SDK calls inside the target wrapper and
16
17
  continue to expose game-facing behavior through `PlatformGateway`. The Devvit
17
18
  app root is game-owned in `apps/target-devvit`; run `pnpm devvit:init` once
18
19
  after login before upload or playtest.
20
+
21
+ For Microsoft Store changes, keep the first pass as a PWA/web target that uses
22
+ the browser adapter. Add a dedicated Store commerce adapter only when wiring
23
+ Digital Goods API and Payment Request through backend ledger verification.
@@ -16,7 +16,7 @@ Useful commands:
16
16
  pnpm dev
17
17
  pnpm check
18
18
  pnpm build
19
- pnpm exec mpgd target build-all --targets-file ./mpgd.targets.json --kit-path ../mpgd-kit --targets web,ait,reddit --ait-variant wrapper
19
+ pnpm exec mpgd target build-all --targets-file ./mpgd.targets.json --kit-path ../mpgd-kit --targets web,microsoft-store,ait,reddit --ait-variant wrapper
20
20
  pnpm devvit:login
21
21
  pnpm devvit:init
22
22
  pnpm devvit:playtest
@@ -5,7 +5,7 @@
5
5
  "title": "__GAME_TITLE__",
6
6
  "engine": "phaser-4"
7
7
  },
8
- "targets": ["web-preview", "android", "ios", "ait", "reddit"],
8
+ "targets": ["web-preview", "microsoft-store", "android", "ios", "ait", "reddit"],
9
9
  "futureTargets": ["telegram", "tauri"],
10
10
  "platformBoundary": "PlatformGateway",
11
11
  "mcpRequirements": {
@@ -17,6 +17,10 @@
17
17
  "id": "simulation.loop.phase",
18
18
  "owner": "src/game/state.ts"
19
19
  },
20
+ {
21
+ "id": "assets.manifest.phaser-loader",
22
+ "owner": "src/assets/manifest.ts"
23
+ },
20
24
  {
21
25
  "id": "runtime.platform.gateway",
22
26
  "owner": "src/platform/installPlatform.ts"
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "__PACKAGE_NAME__-target-cloudflare-pages",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "check": "ttsc --noEmit -p tsconfig.json",
8
+ "lint": "ttsc --noEmit -p tsconfig.json",
9
+ "format": "ttsc format",
10
+ "fix": "ttsc fix",
11
+ "build": "vite build",
12
+ "dev": "pnpm build && wrangler pages dev dist --port 8788",
13
+ "preview": "pnpm build && wrangler pages dev dist --port 8788",
14
+ "deploy": "pnpm build && wrangler pages deploy dist --project-name __GAME_NAME__",
15
+ "types": "wrangler types --path ./src/worker-configuration.d.ts"
16
+ },
17
+ "dependencies": {
18
+ "@mpgd/bridge": "__MPGD_DEPENDENCY_VERSION_BRIDGE__"
19
+ },
20
+ "devDependencies": {
21
+ "@cloudflare/workers-types": "^5.20260707.1",
22
+ "@ttsc/unplugin": "0.16.9",
23
+ "ttsc": "0.16.9",
24
+ "typescript": "7.0.1-rc",
25
+ "vite": "^8.1.3",
26
+ "wrangler": "^4.107.0"
27
+ }
28
+ }
@@ -0,0 +1,12 @@
1
+ import {
2
+ createMpgdCloudflarePagesHostFetchHandler,
3
+ type MpgdCloudflarePagesHostEnv,
4
+ } from '@mpgd/bridge/cloudflare-pages';
5
+
6
+ const fetchHandler = createMpgdCloudflarePagesHostFetchHandler();
7
+
8
+ export default {
9
+ fetch(request, env, ctx) {
10
+ return fetchHandler(request, env, ctx);
11
+ },
12
+ } satisfies ExportedHandler<MpgdCloudflarePagesHostEnv>;
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "types": ["@cloudflare/workers-types"],
5
+ "noEmit": true
6
+ },
7
+ "include": ["src/**/*.ts", "vite.config.ts"]
8
+ }
@@ -0,0 +1,28 @@
1
+ import ttsc from '@ttsc/unplugin/vite';
2
+ import { defineConfig } from 'vite';
3
+
4
+ export default defineConfig({
5
+ publicDir: '../../artifacts/legal-site',
6
+ plugins: [
7
+ ttsc({
8
+ project: 'tsconfig.json',
9
+ plugins: false,
10
+ }),
11
+ ],
12
+ build: {
13
+ outDir: 'dist',
14
+ emptyOutDir: true,
15
+ target: 'es2022',
16
+ sourcemap: false,
17
+ lib: {
18
+ entry: 'src/worker.ts',
19
+ formats: ['es'],
20
+ fileName: () => '_worker.js',
21
+ },
22
+ rollupOptions: {
23
+ output: {
24
+ entryFileNames: '_worker.js',
25
+ },
26
+ },
27
+ },
28
+ });
@@ -0,0 +1,28 @@
1
+ {
2
+ "$schema": "../../node_modules/wrangler/config-schema.json",
3
+ "name": "__GAME_NAME__",
4
+ "compatibility_date": "2026-07-07",
5
+ "compatibility_flags": ["nodejs_compat"],
6
+ "pages_build_output_dir": "./dist",
7
+ "observability": {
8
+ "enabled": true,
9
+ "logs": {
10
+ "enabled": true,
11
+ "head_sampling_rate": 1
12
+ },
13
+ "traces": {
14
+ "enabled": true,
15
+ "head_sampling_rate": 0.01
16
+ }
17
+ },
18
+
19
+ // Bind an authoritative game-services Worker when this Pages host should
20
+ // expose /api/game-services/* locally or in production:
21
+ //
22
+ // "services": [
23
+ // {
24
+ // "binding": "GAME_SERVICES",
25
+ // "service": "mpgd-game-services"
26
+ // }
27
+ // ]
28
+ }
@@ -10,7 +10,7 @@ if you want a different Reddit app name.
10
10
  ## First Playtest
11
11
 
12
12
  ```sh
13
- pnpm install --filter . --filter ./apps/target-devvit
13
+ pnpm install -w
14
14
  pnpm devvit:login
15
15
  pnpm devvit:whoami
16
16
  pnpm devvit:init
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "@devvit/web": "0.13.6",
26
- "@mpgd/bridge": "__MPGD_DEPENDENCY_VERSION__",
26
+ "@mpgd/bridge": "__MPGD_DEPENDENCY_VERSION_BRIDGE__",
27
27
  "express": "^5.2.1",
28
28
  "helmet": "^8.1.0"
29
29
  },
@@ -480,7 +480,7 @@ async function acquireLeaderboardLock(lockKey: string, lockToken: string): Promi
480
480
 
481
481
  function leaderboardLockExpirationDate(): Date {
482
482
  // Devvit Redis SetOptions expects a Date and converts it to Redis EX seconds internally.
483
- return new Date(Date.now() + leaderboardLockTtlSeconds * 1_000);
483
+ return new Date(Date.now() + leaderboardLockTtlMs);
484
484
  }
485
485
 
486
486
  async function writeLeaderboardScoreIfLockHeld(
@@ -613,11 +613,11 @@ function expressRequestToFetchRequest(request: ExpressRequest): Request {
613
613
  };
614
614
 
615
615
  if (request.method !== 'GET' && request.method !== 'HEAD') {
616
- if (!headers.has('content-type')) {
616
+ init.body = requestBodyToBodyInit(request.body);
617
+
618
+ if (!headers.has('content-type') && !(request.body instanceof Uint8Array)) {
617
619
  headers.set('content-type', 'application/json');
618
620
  }
619
-
620
- init.body = requestBodyToBodyInit(request.body);
621
621
  }
622
622
 
623
623
  return new Request(expressRequestUrl(request), init);
@@ -3,6 +3,8 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <meta name="theme-color" content="#0f172a" />
7
+ <link rel="manifest" href="/manifest.webmanifest" />
6
8
  <title>__GAME_TITLE__</title>
7
9
  </head>
8
10
  <body>
@@ -0,0 +1,78 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>__GAME_TITLE__ Privacy Policy</title>
7
+ <style>
8
+ :root {
9
+ color-scheme: light dark;
10
+ font-family:
11
+ Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
12
+ line-height: 1.6;
13
+ }
14
+
15
+ body {
16
+ margin: 0;
17
+ background: Canvas;
18
+ color: CanvasText;
19
+ }
20
+
21
+ main {
22
+ box-sizing: border-box;
23
+ margin: 0 auto;
24
+ max-width: 760px;
25
+ padding: 48px 24px;
26
+ }
27
+
28
+ h1,
29
+ h2 {
30
+ line-height: 1.2;
31
+ }
32
+
33
+ a {
34
+ color: LinkText;
35
+ }
36
+
37
+ nav {
38
+ display: flex;
39
+ flex-wrap: wrap;
40
+ gap: 16px;
41
+ margin: 0 0 32px;
42
+ }
43
+ </style>
44
+ </head>
45
+ <body>
46
+ <main>
47
+ <nav aria-label="Legal pages">
48
+ <a href="/privacy/" aria-current="page">Privacy</a>
49
+ <a href="/support/">Support</a>
50
+ <a href="/terms/">Terms</a>
51
+ </nav>
52
+ <h1>__GAME_TITLE__ Privacy Policy</h1>
53
+ <p>Last updated: __LEGAL_LAST_UPDATED__</p>
54
+ <p>
55
+ __GAME_TITLE__ collects only the information needed to run the game,
56
+ keep player progress, operate platform features, and respond to support
57
+ requests.
58
+ </p>
59
+ <h2>Information We Process</h2>
60
+ <p>
61
+ The game may process platform player identifiers, gameplay progress,
62
+ leaderboard scores, purchase or reward validation records, coarse
63
+ device/runtime information, and support messages you choose to send.
64
+ </p>
65
+ <h2>How We Use Information</h2>
66
+ <p>
67
+ We use this information to provide gameplay features, prevent duplicate
68
+ grants, maintain leaderboards, troubleshoot issues, and satisfy platform
69
+ review or safety requirements.
70
+ </p>
71
+ <h2>Contact</h2>
72
+ <p>
73
+ Replace this template before release with the game owner's support
74
+ contact and jurisdiction-specific privacy disclosures.
75
+ </p>
76
+ </main>
77
+ </body>
78
+ </html>
@@ -0,0 +1,66 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>__GAME_TITLE__ Support</title>
7
+ <style>
8
+ :root {
9
+ color-scheme: light dark;
10
+ font-family:
11
+ Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
12
+ line-height: 1.6;
13
+ }
14
+
15
+ body {
16
+ margin: 0;
17
+ background: Canvas;
18
+ color: CanvasText;
19
+ }
20
+
21
+ main {
22
+ box-sizing: border-box;
23
+ margin: 0 auto;
24
+ max-width: 760px;
25
+ padding: 48px 24px;
26
+ }
27
+
28
+ h1,
29
+ h2 {
30
+ line-height: 1.2;
31
+ }
32
+
33
+ a {
34
+ color: LinkText;
35
+ }
36
+
37
+ nav {
38
+ display: flex;
39
+ flex-wrap: wrap;
40
+ gap: 16px;
41
+ margin: 0 0 32px;
42
+ }
43
+ </style>
44
+ </head>
45
+ <body>
46
+ <main>
47
+ <nav aria-label="Legal pages">
48
+ <a href="/privacy/">Privacy</a>
49
+ <a href="/support/" aria-current="page">Support</a>
50
+ <a href="/terms/">Terms</a>
51
+ </nav>
52
+ <h1>__GAME_TITLE__ Support</h1>
53
+ <p>
54
+ Replace this template before release with a monitored support email or
55
+ help desk URL. When contacting support, include your platform, app
56
+ version, build ID, and a short description of the issue.
57
+ </p>
58
+ <h2>Common Requests</h2>
59
+ <p>
60
+ Include relevant purchase receipts, reward/ad context, leaderboard run
61
+ IDs, or save-slot details when reporting account, purchase, reward, or
62
+ progress problems.
63
+ </p>
64
+ </main>
65
+ </body>
66
+ </html>
@@ -0,0 +1,70 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>__GAME_TITLE__ Terms</title>
7
+ <style>
8
+ :root {
9
+ color-scheme: light dark;
10
+ font-family:
11
+ Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
12
+ line-height: 1.6;
13
+ }
14
+
15
+ body {
16
+ margin: 0;
17
+ background: Canvas;
18
+ color: CanvasText;
19
+ }
20
+
21
+ main {
22
+ box-sizing: border-box;
23
+ margin: 0 auto;
24
+ max-width: 760px;
25
+ padding: 48px 24px;
26
+ }
27
+
28
+ h1,
29
+ h2 {
30
+ line-height: 1.2;
31
+ }
32
+
33
+ a {
34
+ color: LinkText;
35
+ }
36
+
37
+ nav {
38
+ display: flex;
39
+ flex-wrap: wrap;
40
+ gap: 16px;
41
+ margin: 0 0 32px;
42
+ }
43
+ </style>
44
+ </head>
45
+ <body>
46
+ <main>
47
+ <nav aria-label="Legal pages">
48
+ <a href="/privacy/">Privacy</a>
49
+ <a href="/support/">Support</a>
50
+ <a href="/terms/" aria-current="page">Terms</a>
51
+ </nav>
52
+ <h1>__GAME_TITLE__ Terms</h1>
53
+ <p>Last updated: __LEGAL_LAST_UPDATED__</p>
54
+ <p>
55
+ These starter terms are placeholders for the game owner's production
56
+ terms of service.
57
+ </p>
58
+ <h2>Gameplay</h2>
59
+ <p>
60
+ Players are expected to follow platform rules, avoid abusive behavior,
61
+ and use the game only through supported clients and stores.
62
+ </p>
63
+ <h2>Platform Features</h2>
64
+ <p>
65
+ Purchases, rewarded ads, saves, and leaderboards may depend on platform
66
+ availability and authoritative backend validation.
67
+ </p>
68
+ </main>
69
+ </body>
70
+ </html>
@@ -6,6 +6,12 @@
6
6
  "adapter": "browser",
7
7
  "output": "artifacts/web-preview"
8
8
  },
9
+ "microsoft-store": {
10
+ "kind": "web",
11
+ "gameApp": ".",
12
+ "adapter": "browser",
13
+ "output": "artifacts/microsoft-store"
14
+ },
9
15
  "android": {
10
16
  "kind": "capacitor-android",
11
17
  "gameApp": ".",