@mpgd/cli 0.5.0 → 0.7.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 (44) hide show
  1. package/dist/game-acceptance.d.ts +65 -0
  2. package/dist/game-acceptance.js +245 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +469 -2
  5. package/dist/production-target-readiness.d.ts +8 -0
  6. package/dist/production-target-readiness.js +207 -0
  7. package/package.json +12 -12
  8. package/templates/phaser-game/README.md +71 -1
  9. package/templates/phaser-game/agent/acceptance.md +14 -6
  10. package/templates/phaser-game/agent/brief.md +3 -1
  11. package/templates/phaser-game/agent/game-manifest.json +11 -0
  12. package/templates/phaser-game/apps/target-devvit/README.md +30 -0
  13. package/templates/phaser-game/apps/target-devvit/devvit.json +7 -0
  14. package/templates/phaser-game/apps/target-devvit/package.json +8 -5
  15. package/templates/phaser-game/apps/target-devvit/src/server/index.ts +46 -1
  16. package/templates/phaser-game/apps/target-devvit/src/server/postOperationStore.ts +9 -0
  17. package/templates/phaser-game/apps/target-devvit/vite.server.config.ts +2 -1
  18. package/templates/phaser-game/game.html +13 -0
  19. package/templates/phaser-game/gitignore +2 -0
  20. package/templates/phaser-game/index.html +2 -2
  21. package/templates/phaser-game/mpgd.game.json +8 -0
  22. package/templates/phaser-game/mpgd.targets.json +6 -0
  23. package/templates/phaser-game/package.json +7 -1
  24. package/templates/phaser-game/public/manifest.webmanifest +1 -0
  25. package/templates/phaser-game/src/entry.ts +7 -0
  26. package/templates/phaser-game/src/env.d.ts +4 -0
  27. package/templates/phaser-game/src/gameEntry.ts +3 -0
  28. package/templates/phaser-game/src/main.ts +48 -3
  29. package/templates/phaser-game/src/platform/buildGatewayModule.ts +5 -0
  30. package/templates/phaser-game/src/platform/buildGateways/ait.ts +11 -0
  31. package/templates/phaser-game/src/platform/buildGateways/aitSandbox.ts +12 -0
  32. package/templates/phaser-game/src/platform/buildGateways/browser.ts +8 -0
  33. package/templates/phaser-game/src/platform/buildGateways/capacitorAndroid.ts +12 -0
  34. package/templates/phaser-game/src/platform/buildGateways/capacitorIos.ts +12 -0
  35. package/templates/phaser-game/src/platform/buildGateways/reddit.ts +11 -0
  36. package/templates/phaser-game/src/platform/buildGateways/redditSandbox.ts +15 -0
  37. package/templates/phaser-game/src/platform/devvitEntrypoint.ts +57 -0
  38. package/templates/phaser-game/src/platform/devvitInlinePreview.css +75 -0
  39. package/templates/phaser-game/src/platform/gameServices.ts +18 -61
  40. package/templates/phaser-game/src/platform/installPlatform.ts +6 -50
  41. package/templates/phaser-game/src/platform/microsoftStorePwa.ts +99 -0
  42. package/templates/phaser-game/src/runtime/gameContext.ts +3 -1
  43. package/templates/phaser-game/tools/run-game-acceptance.mjs +22 -0
  44. package/templates/phaser-game/vite.config.ts +161 -2
@@ -0,0 +1,8 @@
1
+ {
2
+ "brand": {
3
+ "appIcon": {
4
+ "source": "public/icon.svg",
5
+ "backgroundColor": "#0f172a"
6
+ }
7
+ }
8
+ }
@@ -4,12 +4,14 @@
4
4
  "kind": "web",
5
5
  "gameApp": ".",
6
6
  "adapter": "browser",
7
+ "icon": { "profile": "web-preview" },
7
8
  "output": "artifacts/web-preview"
8
9
  },
9
10
  "microsoft-store": {
10
11
  "kind": "web",
11
12
  "gameApp": ".",
12
13
  "adapter": "browser",
14
+ "icon": { "profile": "microsoft-pwa" },
13
15
  "output": "artifacts/microsoft-store"
14
16
  },
15
17
  "android": {
@@ -17,6 +19,7 @@
17
19
  "gameApp": ".",
18
20
  "shellApp": "${MPGD_KIT_PATH}/apps/mobile-capacitor",
19
21
  "adapter": "capacitor",
22
+ "icon": { "profile": "android" },
20
23
  "webDir": "${MPGD_KIT_PATH}/apps/mobile-capacitor/www",
21
24
  "artifact": "aab"
22
25
  },
@@ -25,6 +28,7 @@
25
28
  "gameApp": ".",
26
29
  "shellApp": "${MPGD_KIT_PATH}/apps/mobile-capacitor",
27
30
  "adapter": "capacitor",
31
+ "icon": { "profile": "ios" },
28
32
  "webDir": "${MPGD_KIT_PATH}/apps/mobile-capacitor/www",
29
33
  "artifact": "ipa"
30
34
  },
@@ -33,6 +37,7 @@
33
37
  "gameApp": ".",
34
38
  "wrapperApp": "${MPGD_KIT_PATH}/apps/target-ait",
35
39
  "adapter": "ait",
40
+ "icon": { "profile": "ait" },
36
41
  "webDir": "${MPGD_KIT_PATH}/apps/target-ait/public/game",
37
42
  "artifact": ".ait"
38
43
  },
@@ -41,6 +46,7 @@
41
46
  "gameApp": ".",
42
47
  "wrapperApp": "apps/target-devvit",
43
48
  "adapter": "devvit",
49
+ "icon": { "profile": "devvit" },
44
50
  "webDir": "apps/target-devvit/dist/client",
45
51
  "artifact": "devvit"
46
52
  }
@@ -8,7 +8,13 @@
8
8
  "dev": "__WORKSPACE_I18N_BUILD_PREFIX__vite --host 0.0.0.0",
9
9
  "dev:ait": "APP_TARGET=ait APP_VERSION=0.0.0-dev BUILD_ID=ait-sandbox sh -c '__WORKSPACE_I18N_BUILD_PREFIX__vite --host 0.0.0.0'",
10
10
  "build": "__WORKSPACE_I18N_BUILD_PREFIX__vite build",
11
- "build:ait": "pnpm exec mpgd target build ait production --variant wrapper --targets-file ./mpgd.targets.json --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
11
+ "accept": "node ./tools/run-game-acceptance.mjs",
12
+ "icons:generate": "pnpm exec mpgd game icons generate . --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
13
+ "icons:generate:devvit": "pnpm exec mpgd game icons generate . --targets reddit --profile development --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
14
+ "icons:generate:devvit:production": "pnpm exec mpgd game icons generate . --targets reddit --profile production --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
15
+ "icons:verify": "pnpm exec mpgd game icons verify . --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
16
+ "icons:inspect": "pnpm exec mpgd game icons inspect . --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
17
+ "build:ait": "pnpm exec mpgd target build ait staging --variant wrapper --targets-file ./mpgd.targets.json --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
12
18
  "build:ait:package": "pnpm exec mpgd target build ait production --targets-file ./mpgd.targets.json --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
13
19
  "smoke:ait": "pnpm exec mpgd target smoke ait --targets-file ./mpgd.targets.json --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
14
20
  "ait:wrapper:dev": "pnpm --dir ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}/apps/target-ait run dev",
@@ -3,6 +3,7 @@
3
3
  "name": "__GAME_TITLE__",
4
4
  "short_name": "__GAME_NAME__",
5
5
  "description": "__GAME_TITLE__ built with mpgd-kit.",
6
+ "id": "./__GAME_NAME__",
6
7
  "start_url": "./",
7
8
  "scope": "./",
8
9
  "display": "standalone",
@@ -0,0 +1,7 @@
1
+ if (__APP_TARGET__ === 'reddit') {
2
+ await import('./platform/devvitEntrypoint');
3
+ } else {
4
+ await import('./main');
5
+ }
6
+
7
+ export {};
@@ -2,8 +2,12 @@
2
2
 
3
3
  declare const __APP_TARGET__: string;
4
4
  declare const __MPGD_CONFIG_TARGET__: string;
5
+ declare const __MPGD_PLATFORM_TARGET__:
6
+ | import('@mpgd/target-config').EffectivePlatformTargetMetadata
7
+ | undefined;
5
8
  declare const __APP_VERSION__: string;
6
9
  declare const __BUILD_ID__: string;
10
+ declare const __SOURCE_GIT_SHA__: string;
7
11
  declare const __DEBUG_BUILD__: boolean;
8
12
 
9
13
  interface ImportMetaEnv {
@@ -0,0 +1,3 @@
1
+ await import('./main');
2
+
3
+ export {};
@@ -1,7 +1,8 @@
1
1
  import './styles.css';
2
2
 
3
3
  import { createAnalyticsReporter, createBufferedAnalyticsSink } from '@mpgd/analytics';
4
- import { resolveMpgdLocale, type Locale } from '@mpgd/i18n';
4
+ import { resolveTargetMpgdLocale, type Locale } from '@mpgd/i18n';
5
+ import type { IdentitySession, LaunchIntent, PlatformGateway } from '@mpgd/platform';
5
6
  import {
6
7
  resolveTargetViewportPlan,
7
8
  type TargetViewportOrientationPolicy,
@@ -13,11 +14,13 @@ import { createStarterGame } from './runtime/createGame';
13
14
  import { detectRuntime } from './platform/runtimeDetector';
14
15
  import { createStarterGameServices } from './platform/gameServices';
15
16
  import { installPlatform } from './platform/installPlatform';
17
+ import { installMicrosoftStorePwa } from './platform/microsoftStorePwa';
16
18
 
17
19
  await bootstrap();
18
20
 
19
21
  async function bootstrap(): Promise<void> {
20
22
  let locale: Locale = 'en';
23
+ let disposeMicrosoftStorePwa: (() => void) | undefined;
21
24
 
22
25
  try {
23
26
  if (__APP_TARGET__ === 'ait') {
@@ -26,6 +29,7 @@ async function bootstrap(): Promise<void> {
26
29
  }
27
30
 
28
31
  const runtimeConfig = detectRuntime();
32
+ disposeMicrosoftStorePwa = installMicrosoftStorePwa(runtimeConfig);
29
33
  const platform = await installPlatform(runtimeConfig);
30
34
  const runtime = await platform.getTargetRuntime();
31
35
  const orientationPolicy = {
@@ -41,7 +45,16 @@ async function bootstrap(): Promise<void> {
41
45
  playerId: 'local-player',
42
46
  displayName: 'Local Player',
43
47
  };
44
- locale = resolveMpgdLocale(runtime.capabilities);
48
+ const [identitySession, launchIntent] = await Promise.all([
49
+ resolveIdentitySession(platform, player.playerId),
50
+ resolveLaunchIntent(platform),
51
+ ]);
52
+ locale = resolveTargetMpgdLocale({
53
+ capabilities: runtime.capabilities,
54
+ fallbackLocale:
55
+ runtime.effectiveConfig?.localization.fallbackLocale
56
+ ?? runtime.config.localization.fallbackLocale,
57
+ });
45
58
  const analyticsSink = createBufferedAnalyticsSink();
46
59
  const analytics = createAnalyticsReporter({
47
60
  target: platform.target,
@@ -50,7 +63,7 @@ async function bootstrap(): Promise<void> {
50
63
  });
51
64
  const gameServices = createStarterGameServices({
52
65
  gateway: platform,
53
- playerId: player.playerId,
66
+ playerId: identitySession.playerId ?? player.playerId,
54
67
  });
55
68
 
56
69
  await analytics.track({
@@ -68,6 +81,8 @@ async function bootstrap(): Promise<void> {
68
81
  runtime,
69
82
  viewport,
70
83
  player,
84
+ identitySession,
85
+ launchIntent,
71
86
  locale,
72
87
  gameServices,
73
88
  analytics,
@@ -75,11 +90,41 @@ async function bootstrap(): Promise<void> {
75
90
  },
76
91
  });
77
92
  } catch (error) {
93
+ disposeMicrosoftStorePwa?.();
78
94
  renderBootstrapError(error, locale);
79
95
  console.error('[bootstrap]', error);
80
96
  }
81
97
  }
82
98
 
99
+ async function resolveIdentitySession(
100
+ platform: PlatformGateway,
101
+ fallbackPlayerId: string,
102
+ ): Promise<IdentitySession> {
103
+ try {
104
+ return (await platform.identity.getSession?.()) ?? createGuestSession(fallbackPlayerId);
105
+ } catch (error) {
106
+ console.warn('[platform] identity session unavailable; using guest fallback.', error);
107
+ return createGuestSession(fallbackPlayerId);
108
+ }
109
+ }
110
+
111
+ async function resolveLaunchIntent(platform: PlatformGateway): Promise<LaunchIntent> {
112
+ try {
113
+ return (await platform.presentation?.getLaunchIntent()) ?? { entry: 'home' };
114
+ } catch (error) {
115
+ console.warn('[platform] launch intent unavailable; using home fallback.', error);
116
+ return { entry: 'home' };
117
+ }
118
+ }
119
+
120
+ function createGuestSession(playerId: string): IdentitySession {
121
+ return {
122
+ identityLevel: 'guest',
123
+ playerId,
124
+ trustLevel: 'local',
125
+ };
126
+ }
127
+
83
128
  function renderBootstrapError(error: unknown, locale: Locale): void {
84
129
  const message = error instanceof Error ? error.message : String(error);
85
130
  const root = document.querySelector<HTMLDivElement>('#game');
@@ -0,0 +1,5 @@
1
+ declare module '#mpgd-platform-gateway' {
2
+ export function createBuildGateway(
3
+ runtime: import('./runtimeDetector').RuntimeConfig,
4
+ ): Promise<import('@mpgd/platform').PlatformGateway>;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { createAitPlatformGateway } from '@mpgd/adapter-ait';
2
+ import type { PlatformGateway } from '@mpgd/platform';
3
+
4
+ import type { RuntimeConfig } from '../runtimeDetector';
5
+
6
+ export async function createBuildGateway(runtime: RuntimeConfig): Promise<PlatformGateway> {
7
+ return createAitPlatformGateway({
8
+ appVersion: runtime.appVersion,
9
+ buildId: runtime.buildId,
10
+ });
11
+ }
@@ -0,0 +1,12 @@
1
+ import { createAitPlatformGateway, createAitSandboxBridge } from '@mpgd/adapter-ait';
2
+ import type { PlatformGateway } from '@mpgd/platform';
3
+
4
+ import type { RuntimeConfig } from '../runtimeDetector';
5
+
6
+ export async function createBuildGateway(runtime: RuntimeConfig): Promise<PlatformGateway> {
7
+ return createAitPlatformGateway({
8
+ appVersion: runtime.appVersion,
9
+ buildId: runtime.buildId,
10
+ fallbackBridge: createAitSandboxBridge(),
11
+ });
12
+ }
@@ -0,0 +1,8 @@
1
+ import { createBrowserPlatformGateway } from '@mpgd/adapter-browser';
2
+ import type { PlatformGateway } from '@mpgd/platform';
3
+
4
+ import type { RuntimeConfig } from '../runtimeDetector';
5
+
6
+ export async function createBuildGateway(_runtime: RuntimeConfig): Promise<PlatformGateway> {
7
+ return createBrowserPlatformGateway();
8
+ }
@@ -0,0 +1,12 @@
1
+ import { createCapacitorPlatformGateway } from '@mpgd/adapter-capacitor';
2
+ import type { PlatformGateway } from '@mpgd/platform';
3
+
4
+ import type { RuntimeConfig } from '../runtimeDetector';
5
+
6
+ export async function createBuildGateway(runtime: RuntimeConfig): Promise<PlatformGateway> {
7
+ return createCapacitorPlatformGateway({
8
+ target: 'android',
9
+ appVersion: runtime.appVersion,
10
+ buildId: runtime.buildId,
11
+ });
12
+ }
@@ -0,0 +1,12 @@
1
+ import { createCapacitorPlatformGateway } from '@mpgd/adapter-capacitor';
2
+ import type { PlatformGateway } from '@mpgd/platform';
3
+
4
+ import type { RuntimeConfig } from '../runtimeDetector';
5
+
6
+ export async function createBuildGateway(runtime: RuntimeConfig): Promise<PlatformGateway> {
7
+ return createCapacitorPlatformGateway({
8
+ target: 'ios',
9
+ appVersion: runtime.appVersion,
10
+ buildId: runtime.buildId,
11
+ });
12
+ }
@@ -0,0 +1,11 @@
1
+ import { createDevvitPlatformGateway } from '@mpgd/adapter-devvit';
2
+ import type { PlatformGateway } from '@mpgd/platform';
3
+
4
+ import type { RuntimeConfig } from '../runtimeDetector';
5
+
6
+ export async function createBuildGateway(runtime: RuntimeConfig): Promise<PlatformGateway> {
7
+ return createDevvitPlatformGateway({
8
+ appVersion: runtime.appVersion,
9
+ buildId: runtime.buildId,
10
+ });
11
+ }
@@ -0,0 +1,15 @@
1
+ import {
2
+ createDevvitPlatformGateway,
3
+ createDevvitSandboxBridge,
4
+ } from '@mpgd/adapter-devvit';
5
+ import type { PlatformGateway } from '@mpgd/platform';
6
+
7
+ import type { RuntimeConfig } from '../runtimeDetector';
8
+
9
+ export async function createBuildGateway(runtime: RuntimeConfig): Promise<PlatformGateway> {
10
+ return createDevvitPlatformGateway({
11
+ appVersion: runtime.appVersion,
12
+ buildId: runtime.buildId,
13
+ fallbackBridge: createDevvitSandboxBridge(),
14
+ });
15
+ }
@@ -0,0 +1,57 @@
1
+ import {
2
+ requestDevvitExpandedMode,
3
+ startDevvitWebSurface,
4
+ } from '@mpgd/adapter-devvit/web';
5
+
6
+ await startDevvitWebSurface({
7
+ async mountInlinePreview() {
8
+ await import('./devvitInlinePreview.css');
9
+ renderInlinePreview();
10
+ },
11
+ async loadExpandedGame() {
12
+ await import('../main');
13
+ },
14
+ onModeUnavailable(error) {
15
+ if (!(error instanceof ReferenceError)) {
16
+ console.warn('[devvit] web view mode unavailable; loading the game surface.', error);
17
+ }
18
+ },
19
+ });
20
+
21
+ function renderInlinePreview(): void {
22
+ const preview = document.createElement('main');
23
+ preview.className = 'devvit-preview';
24
+
25
+ const eyebrow = document.createElement('p');
26
+ eyebrow.className = 'devvit-preview__eyebrow';
27
+ eyebrow.textContent = 'Ready to play';
28
+
29
+ const title = document.createElement('h1');
30
+ title.textContent = '__GAME_TITLE__';
31
+
32
+ const description = document.createElement('p');
33
+ description.className = 'devvit-preview__description';
34
+ description.textContent = 'Open the expanded view to start the game.';
35
+
36
+ const button = document.createElement('button');
37
+ button.className = 'devvit-preview__button';
38
+ button.type = 'button';
39
+ button.textContent = 'Play';
40
+ button.addEventListener('click', async (event) => {
41
+ try {
42
+ await requestDevvitExpandedMode(event, 'game');
43
+ } catch (error) {
44
+ console.error('[devvit] expanded game surface request failed.', error);
45
+ }
46
+ });
47
+
48
+ preview.append(eyebrow, title, description, button);
49
+ const body = document.body;
50
+
51
+ if (body === null) {
52
+ throw new Error('Devvit inline preview requires a document body.');
53
+ }
54
+
55
+ body.classList.add('devvit-preview-host');
56
+ body.replaceChildren(preview);
57
+ }
@@ -0,0 +1,75 @@
1
+ body.devvit-preview-host {
2
+ min-width: 320px;
3
+ min-height: 100vh;
4
+ margin: 0;
5
+ background: #0f172a;
6
+ }
7
+
8
+ .devvit-preview,
9
+ .devvit-preview * {
10
+ box-sizing: border-box;
11
+ }
12
+
13
+ .devvit-preview {
14
+ min-height: 100vh;
15
+ display: grid;
16
+ place-content: center;
17
+ justify-items: start;
18
+ gap: 0.75rem;
19
+ padding: clamp(1.25rem, 5vw, 3rem);
20
+ background:
21
+ radial-gradient(circle at 85% 15%, rgb(56 189 248 / 0.2), transparent 38%),
22
+ linear-gradient(145deg, #0f172a, #172554);
23
+ color: #f8fafc;
24
+ font-family: Inter, ui-sans-serif, system-ui, sans-serif;
25
+ }
26
+
27
+ .devvit-preview__eyebrow,
28
+ .devvit-preview__description,
29
+ .devvit-preview h1 {
30
+ margin: 0;
31
+ }
32
+
33
+ .devvit-preview__eyebrow {
34
+ color: #7dd3fc;
35
+ font-size: 0.75rem;
36
+ font-weight: 700;
37
+ letter-spacing: 0.12em;
38
+ text-transform: uppercase;
39
+ }
40
+
41
+ .devvit-preview h1 {
42
+ max-width: 18ch;
43
+ font-size: clamp(2rem, 9vw, 4.5rem);
44
+ line-height: 0.95;
45
+ }
46
+
47
+ .devvit-preview__description {
48
+ max-width: 36rem;
49
+ color: #cbd5e1;
50
+ line-height: 1.5;
51
+ }
52
+
53
+ .devvit-preview__button {
54
+ min-height: 2.75rem;
55
+ margin-top: 0.5rem;
56
+ padding: 0.65rem 1.25rem;
57
+ border: 0;
58
+ border-radius: 999px;
59
+ color: #082f49;
60
+ background: #7dd3fc;
61
+ font: inherit;
62
+ font-weight: 800;
63
+ cursor: pointer;
64
+ }
65
+
66
+ .devvit-preview__button:focus-visible {
67
+ outline: 3px solid #f8fafc;
68
+ outline-offset: 3px;
69
+ }
70
+
71
+ @media (hover: hover) {
72
+ .devvit-preview__button:hover {
73
+ filter: brightness(1.1);
74
+ }
75
+ }
@@ -1,70 +1,27 @@
1
1
  import {
2
- createGameServicesClient,
3
- createGameServicesFetchBackendTransport,
4
- createGameServicesHttpBackendApi,
5
- createGameServicesOrpcBackendApi,
6
- createGameServicesOrpcClient,
7
- type GameServicesClient,
8
- type GameServicesStoreTarget,
2
+ createGameServicesRuntime,
3
+ resolveGameServicesAuthorityMode,
4
+ resolveGameServicesTransport,
5
+ type GameServicesRuntime,
6
+ type GameServicesRuntimeMode,
9
7
  } from '@mpgd/game-services';
10
- import type { PlatformGateway, PlatformTarget } from '@mpgd/platform';
8
+ import type { PlatformGateway } from '@mpgd/platform';
11
9
 
12
- export type StarterBackendMode = 'disabled' | 'http' | 'orpc';
13
-
14
- export interface StarterGameServices {
15
- readonly mode: StarterBackendMode;
16
- readonly baseUrl?: string;
17
- readonly target?: GameServicesStoreTarget;
18
- readonly client?: GameServicesClient;
19
- }
10
+ export type StarterBackendMode = GameServicesRuntimeMode;
11
+ export type StarterGameServices = GameServicesRuntime;
20
12
 
21
13
  export function createStarterGameServices(input: {
22
14
  readonly gateway: PlatformGateway;
23
15
  readonly playerId: string;
24
16
  }): StarterGameServices {
25
- const baseUrl = import.meta.env.VITE_MPGD_GAME_SERVICES_URL;
26
- const requestedMode = import.meta.env.VITE_MPGD_GAME_SERVICES_TRANSPORT;
27
- const storeTarget = readStoreTarget(
28
- import.meta.env.VITE_MPGD_GAME_SERVICES_TARGET ?? input.gateway.target,
29
- );
30
-
31
- if (baseUrl === undefined || baseUrl.length === 0 || storeTarget === null) {
32
- return {
33
- mode: 'disabled',
34
- };
35
- }
36
-
37
- const mode = requestedMode === 'orpc' ? 'orpc' : 'http';
38
- const backend =
39
- mode === 'orpc'
40
- ? createGameServicesOrpcBackendApi(
41
- createGameServicesOrpcClient({
42
- url: baseUrl,
43
- }),
44
- )
45
- : createGameServicesHttpBackendApi({
46
- transport: createGameServicesFetchBackendTransport({
47
- baseUrl,
48
- }),
49
- });
50
-
51
- return {
52
- mode,
53
- baseUrl,
54
- target: storeTarget,
55
- client: createGameServicesClient({
56
- gateway: input.gateway,
57
- backend,
58
- playerId: input.playerId,
59
- target: storeTarget,
60
- }),
61
- };
62
- }
63
-
64
- function readStoreTarget(target: PlatformTarget | string): GameServicesStoreTarget | null {
65
- if (target === 'android' || target === 'ios' || target === 'ait') {
66
- return target;
67
- }
68
-
69
- return null;
17
+ return createGameServicesRuntime({
18
+ gateway: input.gateway,
19
+ playerId: input.playerId,
20
+ authorityMode: resolveGameServicesAuthorityMode(import.meta.env.MODE),
21
+ target: import.meta.env.VITE_MPGD_GAME_SERVICES_TARGET ?? input.gateway.target,
22
+ ...(import.meta.env.VITE_MPGD_GAME_SERVICES_URL === undefined
23
+ ? {}
24
+ : { baseUrl: import.meta.env.VITE_MPGD_GAME_SERVICES_URL }),
25
+ transport: resolveGameServicesTransport(import.meta.env.VITE_MPGD_GAME_SERVICES_TRANSPORT),
26
+ });
70
27
  }
@@ -1,7 +1,8 @@
1
+ import { createBuildGateway } from '#mpgd-platform-gateway';
2
+
1
3
  import type { AdPlacements, ProductCatalog } from '@mpgd/catalog';
2
4
  import productCatalogJson from '@mpgd/catalog/catalog.json';
3
5
  import adPlacementsJson from '@mpgd/catalog/placements.json';
4
- import type { PlatformGateway } from '@mpgd/platform';
5
6
  import {
6
7
  createEffectiveTargetConfig,
7
8
  getTargetConfig,
@@ -14,7 +15,6 @@ import targetConfigMatrixJson from '@mpgd/target-config/targets.json';
14
15
 
15
16
  import type { RuntimeConfig } from './runtimeDetector';
16
17
 
17
- const devvitSandboxBuildId = 'devvit-sandbox';
18
18
  const targetConfigMatrix = targetConfigMatrixJson as TargetConfigMatrix;
19
19
  const productCatalog = productCatalogJson as ProductCatalog;
20
20
  const adPlacements = adPlacementsJson as AdPlacements;
@@ -27,50 +27,7 @@ const adPlacementTypes = new Map<string, 'rewarded' | 'interstitial'>(
27
27
  );
28
28
 
29
29
  export async function installPlatform(runtime: RuntimeConfig): Promise<TargetConfiguredGateway> {
30
- let gateway: PlatformGateway;
31
-
32
- switch (runtime.target) {
33
- case 'android':
34
- case 'ios': {
35
- const { createCapacitorPlatformGateway } = await import('@mpgd/adapter-capacitor');
36
- gateway = createCapacitorPlatformGateway({
37
- target: runtime.target,
38
- appVersion: runtime.appVersion,
39
- buildId: runtime.buildId,
40
- });
41
- break;
42
- }
43
-
44
- case 'ait': {
45
- const { createAitPlatformGateway, createAitSandboxBridge } = await import(
46
- '@mpgd/adapter-ait'
47
- );
48
- gateway = createAitPlatformGateway({
49
- appVersion: runtime.appVersion,
50
- buildId: runtime.buildId,
51
- ...(runtime.debug ? { fallbackBridge: createAitSandboxBridge() } : {}),
52
- });
53
- break;
54
- }
55
-
56
- case 'reddit': {
57
- const { createDevvitPlatformGateway, createDevvitSandboxBridge } = await import(
58
- '@mpgd/adapter-devvit'
59
- );
60
- gateway = createDevvitPlatformGateway({
61
- appVersion: runtime.appVersion,
62
- buildId: runtime.buildId,
63
- ...(shouldUseDevvitSandbox(runtime) ? { fallbackBridge: createDevvitSandboxBridge() } : {}),
64
- });
65
- break;
66
- }
67
-
68
- default: {
69
- const { createBrowserPlatformGateway } = await import('@mpgd/adapter-browser');
70
- gateway = createBrowserPlatformGateway();
71
- }
72
- }
73
-
30
+ const gateway = await createBuildGateway(runtime);
74
31
  const configTarget = runtime.configTarget || targetConfigKeyForPlatform(runtime.target);
75
32
  const targetConfig = getTargetConfig(targetConfigMatrix, configTarget);
76
33
  const effectiveConfig = createEffectiveTargetConfig({
@@ -79,6 +36,9 @@ export async function installPlatform(runtime: RuntimeConfig): Promise<TargetCon
79
36
  config: targetConfig,
80
37
  catalog: productCatalog,
81
38
  adPlacements,
39
+ ...(__MPGD_PLATFORM_TARGET__ === undefined
40
+ ? {}
41
+ : { platformTarget: __MPGD_PLATFORM_TARGET__ }),
82
42
  });
83
43
 
84
44
  return withTargetAvailability(gateway, targetConfig, {
@@ -90,7 +50,3 @@ export async function installPlatform(runtime: RuntimeConfig): Promise<TargetCon
90
50
  },
91
51
  });
92
52
  }
93
-
94
- function shouldUseDevvitSandbox(runtime: RuntimeConfig): boolean {
95
- return runtime.debug && runtime.buildId === devvitSandboxBuildId;
96
- }