@mpgd/cli 0.14.0 → 0.15.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.
- package/dist/index.js +137 -8
- package/dist/microsoft-store-starter.d.ts +28 -0
- package/dist/microsoft-store-starter.js +655 -0
- package/dist/production-target-readiness.js +3 -1
- package/package.json +7 -7
- package/templates/phaser-game/.agents/skills/release-microsoft-store/SKILL.md +60 -0
- package/templates/phaser-game/.agents/skills/release-microsoft-store/agents/openai.yaml +4 -0
- package/templates/phaser-game/.agents/skills/use-mpgd-kit/SKILL.md +45 -0
- package/templates/phaser-game/.agents/skills/use-mpgd-kit/agents/openai.yaml +4 -0
- package/templates/phaser-game/AGENTS.md +34 -0
- package/templates/phaser-game/README.md +50 -25
- package/templates/phaser-game/agent/acceptance.md +8 -0
- package/templates/phaser-game/agent/brief.md +13 -1
- package/templates/phaser-game/agent/game-manifest.json +7 -0
- package/templates/phaser-game/apps/target-ait/granite.config.ts +35 -0
- package/templates/phaser-game/apps/target-ait/index.html +15 -0
- package/templates/phaser-game/apps/target-ait/package.json +33 -0
- package/templates/phaser-game/apps/target-ait/src/main.ts +34 -0
- package/templates/phaser-game/apps/target-ait/src/styles.css +33 -0
- package/templates/phaser-game/apps/target-ait/tsconfig.json +8 -0
- package/templates/phaser-game/apps/target-ait/vite.config.ts +53 -0
- package/templates/phaser-game/docs/MPGD_KIT_WORKFLOWS.md +128 -0
- package/templates/phaser-game/gitignore +6 -0
- package/templates/phaser-game/mpgd.targets.json +9 -2
- package/templates/phaser-game/package.json +10 -10
- package/templates/phaser-game/vite.shared.ts +13 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpgd/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Gunshi CLI for mpgd-kit starter generation and target workflow orchestration.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -50,18 +50,18 @@
|
|
|
50
50
|
"@types/node": "^24.0.0",
|
|
51
51
|
"ttsc": "0.18.4",
|
|
52
52
|
"typescript": "7.0.2",
|
|
53
|
-
"@mpgd/adapter-ait": "0.4.4",
|
|
54
|
-
"@mpgd/adapter-browser": "0.5.0",
|
|
55
53
|
"@mpgd/adapter-capacitor": "0.4.4",
|
|
54
|
+
"@mpgd/adapter-browser": "0.5.0",
|
|
56
55
|
"@mpgd/adapter-devvit": "0.8.4",
|
|
57
|
-
"@mpgd/analytics": "0.3.7",
|
|
58
56
|
"@mpgd/adapter-verse8": "0.2.1",
|
|
57
|
+
"@mpgd/adapter-ait": "0.5.0",
|
|
58
|
+
"@mpgd/analytics": "0.3.7",
|
|
59
59
|
"@mpgd/bridge": "0.6.1",
|
|
60
|
-
"@mpgd/catalog": "0.5.0",
|
|
61
|
-
"@mpgd/game-services": "0.10.0",
|
|
62
60
|
"@mpgd/i18n": "0.5.3",
|
|
61
|
+
"@mpgd/game-services": "0.10.0",
|
|
62
|
+
"@mpgd/catalog": "0.5.0",
|
|
63
63
|
"@mpgd/phaser-assets": "0.4.1",
|
|
64
|
-
"@mpgd/target-config": "0.
|
|
64
|
+
"@mpgd/target-config": "0.9.0",
|
|
65
65
|
"@mpgd/platform": "0.7.0"
|
|
66
66
|
},
|
|
67
67
|
"main": "./dist/index.js",
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release-microsoft-store
|
|
3
|
+
description: Prepare, package, and verify this game's Microsoft Store PWA release. Use when configuring Store identity or listing data, building the microsoft-store target, running submission preflight, generating a PWABuilder package ZIP, inspecting MSIX/AppX bundles, collecting optional WACK evidence, or preparing Partner Center submission evidence.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Release to Microsoft Store
|
|
7
|
+
|
|
8
|
+
Read `docs/MPGD_KIT_WORKFLOWS.md`, `mpgd.microsoft-store.json`, and the
|
|
9
|
+
`microsoft-store` entry in `mpgd.targets.json`. If the target is absent, stop
|
|
10
|
+
and run `pnpm exec mpgd target init microsoft-store --game .` before editing
|
|
11
|
+
Store-specific files.
|
|
12
|
+
|
|
13
|
+
## Prepare the PWA
|
|
14
|
+
|
|
15
|
+
1. Replace every placeholder in `mpgd.microsoft-store.json` with the reserved
|
|
16
|
+
Partner Center identity, publisher, listing, age-rating, privacy, and
|
|
17
|
+
screenshot data.
|
|
18
|
+
2. Keep the web manifest ID, start URL, scope, orientation, icons, and deployed
|
|
19
|
+
URL aligned with the game-owned PWA.
|
|
20
|
+
3. Generate and verify production icons with `pnpm icons:generate` and
|
|
21
|
+
`pnpm icons:verify`.
|
|
22
|
+
4. Run `pnpm build:microsoft-store`, `pnpm smoke:microsoft-store`, and
|
|
23
|
+
`pnpm preflight:microsoft-store`. Fix warnings that reflect missing
|
|
24
|
+
submission inputs; retain the resulting preflight JSON and Markdown.
|
|
25
|
+
|
|
26
|
+
## Generate and accept packages
|
|
27
|
+
|
|
28
|
+
1. Deploy the exact bytes that passed preflight. Do not rebuild between
|
|
29
|
+
preflight, deployment, and package generation.
|
|
30
|
+
2. Set `PWA_URL` and `MANIFEST_URL` to the public production endpoints, then
|
|
31
|
+
run:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
pnpm package:microsoft-store -- \
|
|
35
|
+
--pwa-url "$PWA_URL" \
|
|
36
|
+
--manifest-url "$MANIFEST_URL" \
|
|
37
|
+
--package-version <four-part-version> \
|
|
38
|
+
--classic-version <lower-four-part-version>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
3. Keep `release-input/microsoft-store/pwabuilder-package.zip` together with
|
|
42
|
+
`release-output/microsoft-store/package-generation.json` and `.md`.
|
|
43
|
+
4. On Windows with the current SDK, inspect the generated MSIX/AppX bundles
|
|
44
|
+
using:
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
pnpm exec mpgd target accept-package microsoft-store \
|
|
48
|
+
--packages <game-relative-package-paths>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Keep `package-acceptance.json` and `.md`.
|
|
52
|
+
5. Treat WACK as optional recommended evidence. Pass `--appcert
|
|
53
|
+
<path-to-appcert.exe>` only when the active Windows environment can run it;
|
|
54
|
+
do not block otherwise valid package acceptance solely because WACK was not
|
|
55
|
+
run.
|
|
56
|
+
|
|
57
|
+
Require identity, version, signature, payload, submission-evidence, and package
|
|
58
|
+
hash checks to pass before Partner Center submission. Never grant purchases
|
|
59
|
+
from client callbacks; add Store commerce only through a dedicated adapter and
|
|
60
|
+
backend ledger verification.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: use-mpgd-kit
|
|
3
|
+
description: Route Phaser game development, platform integration, target builds, icons, localization, analytics, game services, acceptance, and release work through this generated game's mpgd-kit contracts. Use for any change that adds gameplay-facing platform behavior, configures a distribution target, prepares release evidence, or needs to discover which mpgd capability and validation flow applies.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Use mpgd-kit
|
|
7
|
+
|
|
8
|
+
Read `AGENTS.md`, `agent/game-manifest.json`, and
|
|
9
|
+
`docs/MPGD_KIT_WORKFLOWS.md` before editing. Treat the manifest as the list of
|
|
10
|
+
enabled targets and the workflow guide as the routing reference.
|
|
11
|
+
|
|
12
|
+
## Route the request
|
|
13
|
+
|
|
14
|
+
- Put deterministic state and rules in game/simulation modules.
|
|
15
|
+
- Keep Phaser scenes limited to rendering and input glue.
|
|
16
|
+
- Route identity, storage, commerce, ads, leaderboard, lifecycle, and host
|
|
17
|
+
presentation through `PlatformGateway`.
|
|
18
|
+
- Keep SDK imports in adapters or target wrappers.
|
|
19
|
+
- Route purchases, rewarded-ad grants, and verified scores through a backend
|
|
20
|
+
ledger or verifier before mutating durable state.
|
|
21
|
+
- Use `@mpgd/target-config` for target-owned runtime configuration and
|
|
22
|
+
`mpgd.targets.json` for build ownership.
|
|
23
|
+
- Use the generated icon, localization, analytics, acceptance, and evidence
|
|
24
|
+
flows instead of creating target-specific copies.
|
|
25
|
+
- For a configured target with a target skill in `agent/game-manifest.json`,
|
|
26
|
+
read that skill before changing its release flow.
|
|
27
|
+
|
|
28
|
+
## Work in order
|
|
29
|
+
|
|
30
|
+
1. Identify the owning capability and files from the manifest and workflow
|
|
31
|
+
guide.
|
|
32
|
+
2. Inspect the target entry and effective configuration; do not assume a target
|
|
33
|
+
is enabled.
|
|
34
|
+
3. Implement the smallest change that preserves `PlatformGateway` and backend
|
|
35
|
+
authority boundaries.
|
|
36
|
+
4. Update `agent/game-manifest.json`, `agent/brief.md`, and acceptance guidance
|
|
37
|
+
when the game's capabilities or handoff contract changes.
|
|
38
|
+
5. Run the focused check first, then `pnpm check`, `pnpm build`, and
|
|
39
|
+
`pnpm accept` when the change affects a handoff or target release.
|
|
40
|
+
6. Preserve generated JSON/Markdown evidence under `artifacts/acceptance` or
|
|
41
|
+
the target's `release-output` directory.
|
|
42
|
+
|
|
43
|
+
Use official target documentation or the target's configured MCP for SDK and
|
|
44
|
+
submission requirements. Do not commit personal MCP configuration, tokens,
|
|
45
|
+
credentials, signing material, or platform login state.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Generated Game Agent Instructions
|
|
2
|
+
|
|
3
|
+
This repository is a standalone Phaser game generated with `@mpgd/create-game`.
|
|
4
|
+
|
|
5
|
+
## Start here
|
|
6
|
+
|
|
7
|
+
- Read `agent/game-manifest.json` for enabled targets, capability ownership, and
|
|
8
|
+
target-specific skills.
|
|
9
|
+
- Use `.agents/skills/use-mpgd-kit/SKILL.md` for game, platform, target, build,
|
|
10
|
+
acceptance, or release work.
|
|
11
|
+
- Read `docs/MPGD_KIT_WORKFLOWS.md` only for the relevant capability or target.
|
|
12
|
+
- Keep `agent/brief.md` and `agent/acceptance.md` aligned with material changes.
|
|
13
|
+
|
|
14
|
+
## Boundaries
|
|
15
|
+
|
|
16
|
+
- Keep deterministic game state outside Phaser scenes.
|
|
17
|
+
- Keep platform SDK imports in adapters or target wrappers.
|
|
18
|
+
- Use `PlatformGateway` from game-facing code; do not call platform SDKs from
|
|
19
|
+
scenes.
|
|
20
|
+
- Keep pure game packages free of Phaser, DOM, network, and platform SDKs.
|
|
21
|
+
- Send purchases, rewarded-ad grants, and verified scores through backend
|
|
22
|
+
ledger or verifier APIs before changing durable state.
|
|
23
|
+
- Do not put side effects inside debug calls that a production strip pass may
|
|
24
|
+
remove.
|
|
25
|
+
- Do not commit secrets, signing keys, personal MCP configuration, or platform
|
|
26
|
+
authentication state.
|
|
27
|
+
|
|
28
|
+
## Tooling and checks
|
|
29
|
+
|
|
30
|
+
- Use `ttsx`, not `tsx`, for TypeScript scripts.
|
|
31
|
+
- Use `ttsc` and `@ttsc/lint`; do not add ESLint or Prettier for TypeScript.
|
|
32
|
+
- Run focused checks, then `pnpm check` and `pnpm build`.
|
|
33
|
+
- Run `pnpm accept` before a target handoff or release. Keep its evidence and
|
|
34
|
+
any target-specific release evidence with the handoff.
|
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Standalone Phaser 4 game starter generated by `@mpgd/create-game`.
|
|
4
4
|
|
|
5
|
+
For agent-assisted work, start with `AGENTS.md`, then use
|
|
6
|
+
`.agents/skills/use-mpgd-kit/SKILL.md` and
|
|
7
|
+
`docs/MPGD_KIT_WORKFLOWS.md` to route platform, content, service, target, and
|
|
8
|
+
release changes through the generated game manifest.
|
|
9
|
+
|
|
5
10
|
## Local Loop
|
|
6
11
|
|
|
7
12
|
```sh
|
|
@@ -31,17 +36,17 @@ platform-specific artifacts. Keep an `mpgd-kit` checkout nearby and pass it with
|
|
|
31
36
|
pnpm exec mpgd target build-all \
|
|
32
37
|
--targets-file ./mpgd.targets.json \
|
|
33
38
|
--kit-path ../mpgd-kit \
|
|
34
|
-
--targets
|
|
39
|
+
--targets __RECOMMENDED_MATRIX_TARGETS__ \
|
|
35
40
|
--profile staging \
|
|
36
41
|
--ait-variant wrapper
|
|
37
42
|
pnpm exec mpgd target smoke-all \
|
|
38
43
|
--targets-file ./mpgd.targets.json \
|
|
39
44
|
--kit-path ../mpgd-kit \
|
|
40
|
-
--targets
|
|
45
|
+
--targets __RECOMMENDED_MATRIX_TARGETS__
|
|
41
46
|
pnpm exec mpgd target doctor \
|
|
42
47
|
--targets-file ./mpgd.targets.json \
|
|
43
48
|
--kit-path ../mpgd-kit \
|
|
44
|
-
--targets
|
|
49
|
+
--targets __RECOMMENDED_MATRIX_TARGETS__
|
|
45
50
|
```
|
|
46
51
|
|
|
47
52
|
When developing the kit itself, the same commands work through the repository
|
|
@@ -51,7 +56,7 @@ script:
|
|
|
51
56
|
pnpm --dir ../mpgd-kit mpgd target build-all \
|
|
52
57
|
--targets-file "$PWD/mpgd.targets.json" \
|
|
53
58
|
--kit-path ../mpgd-kit \
|
|
54
|
-
--targets
|
|
59
|
+
--targets __RECOMMENDED_MATRIX_TARGETS__ \
|
|
55
60
|
--profile staging \
|
|
56
61
|
--ait-variant wrapper
|
|
57
62
|
```
|
|
@@ -60,18 +65,30 @@ pnpm --dir ../mpgd-kit mpgd target build-all \
|
|
|
60
65
|
into `.mpgd.targets.generated.json` before calling the kit's existing target
|
|
61
66
|
build and smoke scripts.
|
|
62
67
|
|
|
63
|
-
The starter
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
The starter owns its Apps in Toss wrapper under `apps/target-ait`. With
|
|
69
|
+
`authoritativeGameServices: false`, production keeps native identity, storage,
|
|
70
|
+
sharing, and Game Center while disabling IAP and ads; no game-services URL is
|
|
71
|
+
required for that fail-closed first release. To enable purchases or ads later,
|
|
72
|
+
set the authority flag to `true`, add app-owned product or ad IDs, and configure
|
|
73
|
+
`VITE_MPGD_GAME_SERVICES_URL` to a public HTTPS verifier without embedded
|
|
74
|
+
credentials.
|
|
75
|
+
|
|
76
|
+
The Capacitor entries still intentionally point at kit reference shells, so
|
|
77
|
+
their reusable validation builds use the `staging` profile. Before an Android
|
|
78
|
+
or iOS production build, copy or create the shell under this game directory and
|
|
79
|
+
update `mpgd.targets.json`. Production preflight resolves real paths, rejects
|
|
80
|
+
wrappers or shells outside the game root (including symbolic-link escapes), and
|
|
81
|
+
blocks localhost plus literal private or reserved IP addresses.
|
|
71
82
|
|
|
72
83
|
`mpgd target doctor` verifies that release manifest artifact paths stay under
|
|
73
|
-
this game directory,
|
|
74
|
-
Capacitor
|
|
84
|
+
this game directory, including non-production builds that use kit reference
|
|
85
|
+
Capacitor shells.
|
|
86
|
+
|
|
87
|
+
Optional targets can add their own config, scripts, runtime wiring, and release
|
|
88
|
+
skill. To enable Microsoft Store after creation, run
|
|
89
|
+
`pnpm exec mpgd target init microsoft-store --game . --kit-path ../mpgd-kit`.
|
|
90
|
+
The initializer is idempotent and stops before writing when it finds conflicting
|
|
91
|
+
game-owned values.
|
|
75
92
|
|
|
76
93
|
## Acceptance Handoff
|
|
77
94
|
|
|
@@ -145,7 +162,7 @@ hard-lock the device. Use `responsive` when both orientations are playable,
|
|
|
145
162
|
`prefer-landscape` or `prefer-portrait` when layout guidance should favor one
|
|
146
163
|
orientation, and `lock-landscape` or `lock-portrait` when the game should show a
|
|
147
164
|
soft rotate prompt on mismatch. The generated PWA manifest also declares
|
|
148
|
-
`"orientation": "landscape"` for installed web
|
|
165
|
+
`"orientation": "landscape"` for installed web shells; keep
|
|
149
166
|
that manifest value aligned with the runtime policy if you make a portrait-first
|
|
150
167
|
game.
|
|
151
168
|
|
|
@@ -213,8 +230,8 @@ pnpm build:ait
|
|
|
213
230
|
pnpm smoke:ait
|
|
214
231
|
```
|
|
215
232
|
|
|
216
|
-
The
|
|
217
|
-
|
|
233
|
+
The game-owned wrapper includes the Apps in Toss community devtools package for
|
|
234
|
+
SDK mocks and device debugging:
|
|
218
235
|
|
|
219
236
|
```sh
|
|
220
237
|
pnpm ait:wrapper:dev
|
|
@@ -224,7 +241,7 @@ pnpm ait:devtools:mcp
|
|
|
224
241
|
pnpm ait:devtools:mcp:mobile
|
|
225
242
|
```
|
|
226
243
|
|
|
227
|
-
`ait:wrapper:dev` runs
|
|
244
|
+
`ait:wrapper:dev` runs `apps/target-ait` with the community Vite plugin enabled.
|
|
228
245
|
It loads the last game bundle copied by `pnpm build:ait` from the wrapper's
|
|
229
246
|
`public/game` directory, so run `pnpm build:ait` again after game changes before
|
|
230
247
|
opening a wrapper devtools session. Use `ait:wrapper:dev:plain` to disable the
|
|
@@ -255,15 +272,15 @@ pnpm ait:console:deploy -- release-output/ait/YOUR_APP.ait
|
|
|
255
272
|
`ait:console:register` creates the mini-app and writes its `miniAppId` back to
|
|
256
273
|
that file. Before registration, add the real logo, thumbnail, and screenshot
|
|
257
274
|
files referenced by `aitcc.yaml` under `./assets/`. Use `pnpm build:ait` for the
|
|
258
|
-
|
|
259
|
-
so `release-output/ait/` contains the `.ait` bundle you pass after `--`.
|
|
275
|
+
game-owned wrapper smoke loop, and run `pnpm build:ait:package` before console
|
|
276
|
+
deploys so `release-output/ait/` contains the `.ait` bundle you pass after `--`.
|
|
260
277
|
|
|
261
278
|
The starter also installs `@apps-in-toss/web-framework` and awaits
|
|
262
279
|
`install()` from `@ait-co/polyfill` only when `__APP_TARGET__` is `ait`. In the
|
|
263
280
|
Apps in Toss WebView runtime, standard Web APIs such as `navigator.clipboard`,
|
|
264
281
|
`navigator.geolocation`, `navigator.share`, `navigator.vibrate`, network status,
|
|
265
282
|
and `_blank` `window.open` calls route through the Apps in Toss SDK. Plain
|
|
266
|
-
browser,
|
|
283
|
+
browser, Reddit, Android, and iOS builds do not import the AIT
|
|
267
284
|
SDK chunk and keep their native browser behavior. `pnpm dev:ait` is useful for
|
|
268
285
|
checking the AIT-gated bundle path, but SDK-backed API behavior should be
|
|
269
286
|
verified in the Apps in Toss sandbox or a game-owned devtools setup. If your
|
|
@@ -271,9 +288,16 @@ game uses permission-gated APIs such as clipboard or geolocation, declare the
|
|
|
271
288
|
matching permissions in the game-owned Apps in Toss `granite.config.ts` before
|
|
272
289
|
submission.
|
|
273
290
|
|
|
291
|
+
The generated AIT target starts with `authoritativeGameServices: false`. Native
|
|
292
|
+
anonymous identity, persistent Storage, sharing, and Game Center remain
|
|
293
|
+
available, while IAP and ads are removed from the effective game configuration.
|
|
294
|
+
Only switch the flag to `true` after adding app-owned catalog/ad ids and a public
|
|
295
|
+
HTTPS game-services backend that verifies purchase or reward evidence.
|
|
296
|
+
|
|
274
297
|
## Target Ownership Notes
|
|
275
298
|
|
|
276
299
|
- Browser preview is fully game-owned and writes to `artifacts/web-preview`.
|
|
300
|
+
<!-- mpgd:microsoft-store:start -->
|
|
277
301
|
- Microsoft Store is a game-owned PWA target that reuses the browser adapter and
|
|
278
302
|
writes to `artifacts/microsoft-store` with `manifest.webmanifest` for
|
|
279
303
|
PWABuilder packaging. Replace the starter icon and manifest metadata before
|
|
@@ -323,6 +347,7 @@ submission.
|
|
|
323
347
|
recommended optional local check; from an active administrator user session,
|
|
324
348
|
pass `--appcert <path-to-appcert.exe>` to require `OVERALL_RESULT="PASS"`
|
|
325
349
|
and bind its report hash.
|
|
350
|
+
<!-- mpgd:microsoft-store:end -->
|
|
326
351
|
- Verse8 is a game-owned iframe web target that writes to `artifacts/verse8`.
|
|
327
352
|
The adapter verifies the host-provided auth credential and distinguishes
|
|
328
353
|
Verse8-signed accounts from self-signed guest accounts. Ads are available
|
|
@@ -343,10 +368,10 @@ submission.
|
|
|
343
368
|
- Reddit Devvit is game-owned in `apps/target-devvit`. Its Redis-backed storage
|
|
344
369
|
bridge fails closed on identity, provider, serialization, and quota errors;
|
|
345
370
|
it never switches progress to browser `localStorage`.
|
|
346
|
-
- Apps in Toss
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
371
|
+
- Apps in Toss is game-owned in `apps/target-ait`. The wrapper keeps the app
|
|
372
|
+
name, console state, review metadata, and `@ait-co/devtools` development
|
|
373
|
+
integration local to the game while reusing `@mpgd/adapter-ait` for the
|
|
374
|
+
production bridge and game-bundle loader.
|
|
350
375
|
- Android and iOS currently use the kit reference Capacitor shell at
|
|
351
376
|
`${MPGD_KIT_PATH}/apps/mobile-capacitor`. That is useful for local artifact
|
|
352
377
|
checks, and final artifacts are copied back to this game's `release-output/`
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Run these checks before handing off a generated game starter:
|
|
4
4
|
|
|
5
|
+
Use `agent/game-manifest.json` and `.agents/skills/use-mpgd-kit/SKILL.md` to
|
|
6
|
+
select any target-specific acceptance workflow required by the configured
|
|
7
|
+
targets.
|
|
8
|
+
|
|
5
9
|
```sh
|
|
6
10
|
pnpm icons:generate
|
|
7
11
|
pnpm icons:verify
|
|
@@ -32,9 +36,13 @@ Play here starts gameplay inside the post, and the `game` entry opens the
|
|
|
32
36
|
separate expanded mode Phaser document. Inline gameplay must remain tap/click
|
|
33
37
|
only and must not trap feed scrolling.
|
|
34
38
|
|
|
39
|
+
<!-- mpgd:microsoft-store:start -->
|
|
35
40
|
For Microsoft Store changes, keep the first pass as a PWA/web target that uses
|
|
36
41
|
the browser adapter. Add a dedicated Store commerce adapter only when wiring
|
|
37
42
|
Digital Goods API and Payment Request through backend ledger verification.
|
|
43
|
+
Run the generated Store release skill from build and preflight through package
|
|
44
|
+
acceptance; WACK is optional recommended evidence.
|
|
45
|
+
<!-- mpgd:microsoft-store:end -->
|
|
38
46
|
|
|
39
47
|
## Verse8 Agent8 Structured Server
|
|
40
48
|
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Build a Phaser 4 game on top of the mpgd platform boundary.
|
|
4
4
|
|
|
5
|
+
Read `AGENTS.md`, `agent/game-manifest.json`, and the generated
|
|
6
|
+
`.agents/skills/use-mpgd-kit/SKILL.md` router before changing kit-facing
|
|
7
|
+
capabilities or target workflows.
|
|
8
|
+
|
|
5
9
|
Boundaries:
|
|
6
10
|
|
|
7
11
|
- Phaser scenes render and collect input only.
|
|
@@ -20,8 +24,16 @@ pnpm check
|
|
|
20
24
|
pnpm build
|
|
21
25
|
pnpm icons:generate
|
|
22
26
|
pnpm icons:verify
|
|
23
|
-
pnpm exec mpgd target build-all --targets-file ./mpgd.targets.json --kit-path ../mpgd-kit --targets
|
|
27
|
+
pnpm exec mpgd target build-all --targets-file ./mpgd.targets.json --kit-path ../mpgd-kit --targets __RECOMMENDED_MATRIX_TARGETS__ --profile staging --ait-variant wrapper
|
|
24
28
|
pnpm devvit:login
|
|
25
29
|
pnpm devvit:init
|
|
26
30
|
pnpm devvit:playtest
|
|
27
31
|
```
|
|
32
|
+
|
|
33
|
+
<!-- mpgd:microsoft-store:start -->
|
|
34
|
+
For Microsoft Store releases, use the generated
|
|
35
|
+
`.agents/skills/release-microsoft-store/SKILL.md` workflow. Build and preflight
|
|
36
|
+
the game-owned PWA before package generation, then run package acceptance on
|
|
37
|
+
Windows before Partner Center submission. WACK remains an optional recommended
|
|
38
|
+
evidence source, not a universal prerequisite.
|
|
39
|
+
<!-- mpgd:microsoft-store:end -->
|
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
"targets": ["web-preview", "microsoft-store", "verse8", "android", "ios", "ait", "reddit"],
|
|
9
9
|
"futureTargets": ["telegram", "tauri"],
|
|
10
10
|
"platformBoundary": "PlatformGateway",
|
|
11
|
+
"agentWorkflow": {
|
|
12
|
+
"guide": "docs/MPGD_KIT_WORKFLOWS.md",
|
|
13
|
+
"routerSkill": ".agents/skills/use-mpgd-kit/SKILL.md",
|
|
14
|
+
"targetSkills": {
|
|
15
|
+
"microsoft-store": ".agents/skills/release-microsoft-store/SKILL.md"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
11
18
|
"mcpRequirements": {
|
|
12
19
|
"ait": "Use apps-in-toss MCP before Apps in Toss SDK or review-flow changes.",
|
|
13
20
|
"reddit": "Use Devvit documentation/MCP before Devvit SDK or publish-flow changes. Keep Reddit deployment files in apps/target-devvit."
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { defineConfig, type AppsInTossWebConfig } from '@apps-in-toss/web-framework/config';
|
|
2
|
+
|
|
3
|
+
const config: AppsInTossWebConfig = {
|
|
4
|
+
appName: readEnvString(process.env.MPGD_AIT_APP_NAME) ?? '__GAME_NAME__',
|
|
5
|
+
brand: {
|
|
6
|
+
displayName: readEnvString(process.env.MPGD_AIT_DISPLAY_NAME) ?? '__GAME_TITLE__',
|
|
7
|
+
primaryColor: readEnvString(process.env.MPGD_AIT_PRIMARY_COLOR) ?? '#101820',
|
|
8
|
+
icon: readEnvString(process.env.MPGD_AIT_BRAND_ICON_URL) ?? 'generated/console-icon.png',
|
|
9
|
+
},
|
|
10
|
+
permissions: [],
|
|
11
|
+
web: {
|
|
12
|
+
host: 'localhost',
|
|
13
|
+
port: 5173,
|
|
14
|
+
commands: {
|
|
15
|
+
dev: 'pnpm dev',
|
|
16
|
+
build: 'pnpm build',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
webViewProps: {
|
|
20
|
+
bounces: false,
|
|
21
|
+
pullToRefreshEnabled: false,
|
|
22
|
+
overScrollMode: 'never',
|
|
23
|
+
allowsBackForwardNavigationGestures: false,
|
|
24
|
+
allowsInlineMediaPlayback: true,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const definedConfig: AppsInTossWebConfig = defineConfig(config);
|
|
29
|
+
|
|
30
|
+
export default definedConfig;
|
|
31
|
+
|
|
32
|
+
function readEnvString(input: string | undefined): string | undefined {
|
|
33
|
+
const trimmed = input?.trim();
|
|
34
|
+
return trimmed === undefined || trimmed.length === 0 ? undefined : trimmed;
|
|
35
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta
|
|
6
|
+
name="viewport"
|
|
7
|
+
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
|
|
8
|
+
/>
|
|
9
|
+
<title>__GAME_TITLE__</title>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<main id="app"></main>
|
|
13
|
+
<script type="module" src="/src/main.ts"></script>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__PACKAGE_NAME__-target-ait",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite --host 0.0.0.0",
|
|
8
|
+
"dev:plain": "MPGD_AIT_DEVTOOLS=0 VITE_MPGD_AIT_MOCK_IDENTITY=1 vite --host 0.0.0.0",
|
|
9
|
+
"dev:phone": "AIT_TUNNEL=1 AIT_TUNNEL_CDP=1 vite --host 0.0.0.0",
|
|
10
|
+
"build": "vite build",
|
|
11
|
+
"ait:build": "ait build",
|
|
12
|
+
"ait:deploy": "ait deploy --api-key \"$AIT_API_KEY\"",
|
|
13
|
+
"devtools:mcp": "pnpm exec devtools-mcp",
|
|
14
|
+
"devtools:mcp:mobile": "pnpm exec devtools-mcp --target=mobile",
|
|
15
|
+
"check": "ttsc --noEmit -p tsconfig.json",
|
|
16
|
+
"lint": "ttsc --noEmit -p tsconfig.json",
|
|
17
|
+
"format": "ttsc format",
|
|
18
|
+
"fix": "ttsc fix"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@apps-in-toss/web-framework": "^2.10.6",
|
|
22
|
+
"@mpgd/adapter-ait": "__MPGD_DEPENDENCY_VERSION_ADAPTER_AIT__"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@ait-co/devtools": "^0.1.138",
|
|
26
|
+
"@apps-in-toss/cli": "^2.10.6",
|
|
27
|
+
"@ttsc/unplugin": "0.18.4",
|
|
28
|
+
"@types/node": "^24.0.0",
|
|
29
|
+
"ttsc": "0.18.4",
|
|
30
|
+
"typescript": "7.0.2",
|
|
31
|
+
"vite": "^8.1.3"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import './styles.css';
|
|
2
|
+
|
|
3
|
+
import { installAitHostBridge, type InstallAitHostBridgeOptions } from '@mpgd/adapter-ait/host';
|
|
4
|
+
import { mountAitGameBundle } from '@mpgd/adapter-ait/wrapper';
|
|
5
|
+
|
|
6
|
+
declare const __MPGD_AIT_APP_NAME__: string;
|
|
7
|
+
declare const __MPGD_AIT_AD_GROUP_IDS__: Readonly<Record<string, string>>;
|
|
8
|
+
declare const __MPGD_AIT_AD_PLACEMENT_TYPES__: Readonly<
|
|
9
|
+
Record<string, 'rewarded' | 'interstitial'>
|
|
10
|
+
>;
|
|
11
|
+
|
|
12
|
+
installAitHostBridge({
|
|
13
|
+
appName: __MPGD_AIT_APP_NAME__,
|
|
14
|
+
adGroupIds: __MPGD_AIT_AD_GROUP_IDS__,
|
|
15
|
+
adPlacementTypes: __MPGD_AIT_AD_PLACEMENT_TYPES__,
|
|
16
|
+
...identityBridgeOptions(),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const app = document.querySelector<HTMLElement>('#app');
|
|
20
|
+
if (app !== null) {
|
|
21
|
+
void mountAitGameBundle(app).catch((error: unknown) => {
|
|
22
|
+
console.error('AIT game bundle mount failed unexpectedly.', error);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function identityBridgeOptions(): Pick<InstallAitHostBridgeOptions, 'dependencies'> {
|
|
27
|
+
return import.meta.env.VITE_MPGD_AIT_MOCK_IDENTITY === '1'
|
|
28
|
+
? {
|
|
29
|
+
dependencies: {
|
|
30
|
+
identityProvider: async () => ({ type: 'HASH', hash: 'ait-local-player' }),
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
: {};
|
|
34
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
html,
|
|
2
|
+
body,
|
|
3
|
+
#app {
|
|
4
|
+
width: 100%;
|
|
5
|
+
height: 100%;
|
|
6
|
+
margin: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
body {
|
|
10
|
+
background: #101820;
|
|
11
|
+
color: #f8fafc;
|
|
12
|
+
font-family:
|
|
13
|
+
Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.shell {
|
|
17
|
+
min-height: 100%;
|
|
18
|
+
display: grid;
|
|
19
|
+
place-content: center;
|
|
20
|
+
gap: 12px;
|
|
21
|
+
padding: 24px;
|
|
22
|
+
box-sizing: border-box;
|
|
23
|
+
text-align: center;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
h1,
|
|
27
|
+
p {
|
|
28
|
+
margin: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
code {
|
|
32
|
+
color: #fff7ad;
|
|
33
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
|
|
3
|
+
import aitDevtools from '@ait-co/devtools/unplugin';
|
|
4
|
+
import { extractAitAdBridgeConfig } from '@mpgd/adapter-ait/ad-config';
|
|
5
|
+
import ttsc from '@ttsc/unplugin/vite';
|
|
6
|
+
import { defineConfig } from 'vite';
|
|
7
|
+
|
|
8
|
+
const isTruthyEnv = (value: string | undefined): boolean =>
|
|
9
|
+
value !== undefined && value !== '' && value !== '0' && value.toLowerCase() !== 'false';
|
|
10
|
+
const aitDevtoolsTunnel = isTruthyEnv(process.env.AIT_TUNNEL)
|
|
11
|
+
? { cdp: isTruthyEnv(process.env.AIT_TUNNEL_CDP) }
|
|
12
|
+
: false;
|
|
13
|
+
const aitAppName = process.env.MPGD_AIT_APP_NAME?.trim() || '__GAME_NAME__';
|
|
14
|
+
const aitAdConfig = readAitAdConfig(process.env.MPGD_AD_PLACEMENTS_FILE);
|
|
15
|
+
|
|
16
|
+
export default defineConfig(({ command, isPreview }) => ({
|
|
17
|
+
define: {
|
|
18
|
+
__MPGD_AIT_APP_NAME__: JSON.stringify(aitAppName),
|
|
19
|
+
__MPGD_AIT_AD_GROUP_IDS__: JSON.stringify(aitAdConfig.adGroupIds),
|
|
20
|
+
__MPGD_AIT_AD_PLACEMENT_TYPES__: JSON.stringify(aitAdConfig.adPlacementTypes),
|
|
21
|
+
},
|
|
22
|
+
plugins: [
|
|
23
|
+
...(command === 'serve' && !isPreview && process.env.MPGD_AIT_DEVTOOLS !== '0'
|
|
24
|
+
? [aitDevtools.vite({ mcp: true, tunnel: aitDevtoolsTunnel })]
|
|
25
|
+
: []),
|
|
26
|
+
ttsc({ project: 'tsconfig.json', plugins: false }),
|
|
27
|
+
],
|
|
28
|
+
build: {
|
|
29
|
+
target: 'es2022',
|
|
30
|
+
outDir: 'dist',
|
|
31
|
+
emptyOutDir: true,
|
|
32
|
+
},
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
function readAitAdConfig(path: string | undefined): {
|
|
36
|
+
readonly adGroupIds: Readonly<Record<string, string>>;
|
|
37
|
+
readonly adPlacementTypes: Readonly<Record<string, 'rewarded' | 'interstitial'>>;
|
|
38
|
+
} {
|
|
39
|
+
if (path === undefined || path.trim().length === 0) {
|
|
40
|
+
return { adGroupIds: {}, adPlacementTypes: {} };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
let parsed: unknown;
|
|
44
|
+
try {
|
|
45
|
+
parsed = JSON.parse(readFileSync(path, 'utf8')) as unknown;
|
|
46
|
+
} catch (error) {
|
|
47
|
+
throw new Error(`AIT ad placements file is unreadable or invalid JSON: ${path}`, {
|
|
48
|
+
cause: error,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return extractAitAdBridgeConfig(parsed, path);
|
|
53
|
+
}
|