playcademy 0.12.1 → 0.12.3

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 CHANGED
@@ -5246,9 +5246,23 @@ async function bundleBackend(config, options = {}) {
5246
5246
  const monorepoEdgeSrc = join6(monorepoRoot, "packages/edge-play/src");
5247
5247
  const isBuiltPackage = existsSync7(embeddedEdgeSrc);
5248
5248
  const edgePlaySrc = isBuiltPackage ? embeddedEdgeSrc : monorepoEdgeSrc;
5249
- const cliPackageRoot = isBuiltPackage ? join6(distDir, "../..") : join6(monorepoRoot, "packages/cli");
5250
- const cliNodeModules = isBuiltPackage ? cliPackageRoot : monorepoRoot;
5249
+ const cliPackageRoot = isBuiltPackage ? join6(distDir, "../../..") : join6(monorepoRoot, "packages/cli");
5250
+ const cliNodeModules = isBuiltPackage ? join6(cliPackageRoot, "node_modules") : monorepoRoot;
5251
5251
  const workspaceNodeModules = join6(workspace, "node_modules");
5252
+ const constantsEntry = isBuiltPackage ? (
5253
+ // dist/edge-play/src → dist/vendor/constants/index.ts
5254
+ join6(embeddedEdgeSrc, "..", "..", "vendor", "constants", "index.ts")
5255
+ ) : join6(monorepoRoot, "packages", "constants", "src", "index.ts");
5256
+ console.log({
5257
+ isBuiltPackage,
5258
+ distDir,
5259
+ constantsEntry,
5260
+ embeddedEdgeSrc,
5261
+ edgePlaySrc,
5262
+ cliPackageRoot,
5263
+ cliNodeModules,
5264
+ workspaceNodeModules
5265
+ });
5252
5266
  const result = await esbuild.build({
5253
5267
  stdin: {
5254
5268
  contents: entryCode,
@@ -5264,12 +5278,17 @@ async function bundleBackend(config, options = {}) {
5264
5278
  sourcemap: options.sourcemap ? "inline" : false,
5265
5279
  minify: options.minify || false,
5266
5280
  logLevel: "error",
5267
- nodePaths: [workspaceNodeModules, cliNodeModules],
5268
- // Check workspace first, then CLI
5281
+ nodePaths: [workspaceNodeModules, cliNodeModules, join6(cliPackageRoot, "..")],
5282
+ // Check workspace first, then CLI package and project root
5283
+ loader: {
5284
+ ".ts": "ts"
5285
+ },
5269
5286
  define: {
5270
5287
  PLAYCADEMY_CONFIG: JSON.stringify(bundleConfig)
5271
5288
  },
5272
5289
  alias: {
5290
+ // Map workspace-only package to embedded constants for published CLI
5291
+ "@playcademy/constants": constantsEntry,
5273
5292
  /**
5274
5293
  * @game-api alias maps to the user's custom routes directory
5275
5294
  *
@@ -7541,7 +7560,7 @@ async function startDevServer(options) {
7541
7560
  platformUrl = process.env.PLAYCADEMY_BASE_URL || "http://localhost:5174"
7542
7561
  } = options;
7543
7562
  const hasSandboxTimebackCreds = !!process.env.TIMEBACK_API_CLIENT_ID;
7544
- const devConfig = config.integrations?.timeback && !hasSandboxTimebackCreds ? { ...config, integrations: { ...config.integrations, timeback: void 0 } } : config;
7563
+ const devConfig = config?.integrations?.timeback && !hasSandboxTimebackCreds ? { ...config, integrations: { ...config.integrations, timeback: void 0 } } : config;
7545
7564
  const bundle = await bundleBackend(devConfig, {
7546
7565
  sourcemap: false,
7547
7566
  minify: false
package/dist/utils.js CHANGED
@@ -1186,9 +1186,23 @@ async function bundleBackend(config, options = {}) {
1186
1186
  const monorepoEdgeSrc = join2(monorepoRoot, "packages/edge-play/src");
1187
1187
  const isBuiltPackage = existsSync2(embeddedEdgeSrc);
1188
1188
  const edgePlaySrc = isBuiltPackage ? embeddedEdgeSrc : monorepoEdgeSrc;
1189
- const cliPackageRoot = isBuiltPackage ? join2(distDir, "../..") : join2(monorepoRoot, "packages/cli");
1190
- const cliNodeModules = isBuiltPackage ? cliPackageRoot : monorepoRoot;
1189
+ const cliPackageRoot = isBuiltPackage ? join2(distDir, "../../..") : join2(monorepoRoot, "packages/cli");
1190
+ const cliNodeModules = isBuiltPackage ? join2(cliPackageRoot, "node_modules") : monorepoRoot;
1191
1191
  const workspaceNodeModules = join2(workspace, "node_modules");
1192
+ const constantsEntry = isBuiltPackage ? (
1193
+ // dist/edge-play/src → dist/vendor/constants/index.ts
1194
+ join2(embeddedEdgeSrc, "..", "..", "vendor", "constants", "index.ts")
1195
+ ) : join2(monorepoRoot, "packages", "constants", "src", "index.ts");
1196
+ console.log({
1197
+ isBuiltPackage,
1198
+ distDir,
1199
+ constantsEntry,
1200
+ embeddedEdgeSrc,
1201
+ edgePlaySrc,
1202
+ cliPackageRoot,
1203
+ cliNodeModules,
1204
+ workspaceNodeModules
1205
+ });
1192
1206
  const result = await esbuild.build({
1193
1207
  stdin: {
1194
1208
  contents: entryCode,
@@ -1204,12 +1218,17 @@ async function bundleBackend(config, options = {}) {
1204
1218
  sourcemap: options.sourcemap ? "inline" : false,
1205
1219
  minify: options.minify || false,
1206
1220
  logLevel: "error",
1207
- nodePaths: [workspaceNodeModules, cliNodeModules],
1208
- // Check workspace first, then CLI
1221
+ nodePaths: [workspaceNodeModules, cliNodeModules, join2(cliPackageRoot, "..")],
1222
+ // Check workspace first, then CLI package and project root
1223
+ loader: {
1224
+ ".ts": "ts"
1225
+ },
1209
1226
  define: {
1210
1227
  PLAYCADEMY_CONFIG: JSON.stringify(bundleConfig)
1211
1228
  },
1212
1229
  alias: {
1230
+ // Map workspace-only package to embedded constants for published CLI
1231
+ "@playcademy/constants": constantsEntry,
1213
1232
  /**
1214
1233
  * @game-api alias maps to the user's custom routes directory
1215
1234
  *
@@ -1298,7 +1317,7 @@ async function startDevServer(options) {
1298
1317
  platformUrl = process.env.PLAYCADEMY_BASE_URL || "http://localhost:5174"
1299
1318
  } = options;
1300
1319
  const hasSandboxTimebackCreds = !!process.env.TIMEBACK_API_CLIENT_ID;
1301
- const devConfig = config.integrations?.timeback && !hasSandboxTimebackCreds ? { ...config, integrations: { ...config.integrations, timeback: void 0 } } : config;
1320
+ const devConfig = config?.integrations?.timeback && !hasSandboxTimebackCreds ? { ...config, integrations: { ...config.integrations, timeback: void 0 } } : config;
1302
1321
  const bundle = await bundleBackend(devConfig, {
1303
1322
  sourcemap: false,
1304
1323
  minify: false
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Authentication Constants
3
+ *
4
+ * Constants related to authentication providers.
5
+ */
6
+
7
+ /**
8
+ * Auth Provider Constants
9
+ */
10
+ export const AUTH_PROVIDER_IDS = {
11
+ TIMEBACK: 'timeback',
12
+ TIMEBACK_LTI: 'timeback-lti',
13
+ } as const
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Domain and URL Constants
3
+ *
4
+ * Centralized domain names and base URLs for the Playcademy platform.
5
+ * These constants are shared across multiple packages to ensure consistency.
6
+ */
7
+
8
+ /**
9
+ * Playcademy domain names
10
+ */
11
+ export const PLAYCADEMY_DOMAINS = {
12
+ /** Primary domain (hub, landing pages) */
13
+ apex: 'playcademy.net',
14
+ /** Marketing/alternative domain */
15
+ apexAlt: 'playcademy.com',
16
+ /** Game backend worker domain */
17
+ games: 'playcademy.gg',
18
+ } as const
19
+
20
+ /**
21
+ * Platform hub base URLs by environment
22
+ * Used by CLI, SDK, and other packages to make API requests
23
+ */
24
+ export const PLAYCADEMY_BASE_URLS = {
25
+ production: 'https://hub.playcademy.net',
26
+ staging: 'https://hub.dev.playcademy.net',
27
+ } as const
28
+
29
+ /**
30
+ * Game backend worker domains by environment
31
+ * Workers are deployed to Cloudflare and accessible at:
32
+ * - Production: {slug}.playcademy.gg
33
+ * - Staging: {slug}-staging.playcademy.gg
34
+ */
35
+ export const GAME_WORKER_DOMAINS = {
36
+ production: 'playcademy.gg',
37
+ staging: 'staging.playcademy.gg',
38
+ } as const
39
+
40
+ /**
41
+ * Type exports
42
+ */
43
+ export type PlatformEnvironment = 'production' | 'staging'
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Environment Variable Names
3
+ *
4
+ * Centralized environment variable names used across the platform.
5
+ * These ensure consistency between deployers and runtime environments.
6
+ */
7
+
8
+ /**
9
+ * Environment variables for game backend workers
10
+ * Used by both the deployment system (@playcademy/api-core)
11
+ * and the worker runtime (@playcademy/edge-play)
12
+ */
13
+ export const WORKER_ENV_VARS = {
14
+ /** Game-specific API key for calling platform API */
15
+ PLAYCADEMY_API_KEY: 'PLAYCADEMY_API_KEY',
16
+ /** Game ID (UUID) */
17
+ GAME_ID: 'GAME_ID',
18
+ /** Platform API base URL */
19
+ PLAYCADEMY_BASE_URL: 'PLAYCADEMY_BASE_URL',
20
+ } as const
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @playcademy/constants
3
+ *
4
+ * Centralized constants shared across the Playcademy platform.
5
+ * This package contains domain names, URLs, environment variable names,
6
+ * and other constants that need to be consistent across multiple packages.
7
+ */
8
+
9
+ export * from './auth'
10
+ export * from './domains'
11
+ export * from './env-vars'
12
+ export * from './overworld'
13
+ export * from './system'
14
+ export * from './timeback'
15
+ export * from './workers'
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Overworld & Game Constants
3
+ *
4
+ * All constants related to the game world, including items, rendering,
5
+ * maps, physics, UI, and core platform games.
6
+ */
7
+
8
+ // ═══════════════════════════════════════════════════════════════════════
9
+ // VIEWPORT & LEVEL SYSTEM
10
+ // ═══════════════════════════════════════════════════════════════════════
11
+
12
+ /**
13
+ * Minimum viewport dimensions for the game
14
+ */
15
+ export const MIN_VIEWPORT_WIDTH = 960
16
+ export const MIN_VIEWPORT_HEIGHT = 640
17
+
18
+ /**
19
+ * Maximum player level
20
+ */
21
+ export const MAX_LEVEL = 100
22
+
23
+ // ═══════════════════════════════════════════════════════════════════════
24
+ // ITEMS & ECONOMY
25
+ // ═══════════════════════════════════════════════════════════════════════
26
+
27
+ /**
28
+ * Item Slugs - Canonical slugs for core platform items
29
+ */
30
+ export const ITEM_SLUGS = {
31
+ /** Primary platform currency */
32
+ PLAYCADEMY_CREDITS: 'PLAYCADEMY_CREDITS',
33
+
34
+ /** Experience points currency */
35
+ PLAYCADEMY_XP: 'PLAYCADEMY_XP',
36
+
37
+ /** Core platform badges */
38
+ FOUNDING_MEMBER_BADGE: 'FOUNDING_MEMBER_BADGE',
39
+ EARLY_ADOPTER_BADGE: 'EARLY_ADOPTER_BADGE',
40
+ FIRST_GAME_BADGE: 'FIRST_GAME_BADGE',
41
+
42
+ /** Example items */
43
+ COMMON_SWORD: 'COMMON_SWORD',
44
+ SMALL_HEALTH_POTION: 'SMALL_HEALTH_POTION',
45
+ SMALL_BACKPACK: 'SMALL_BACKPACK',
46
+
47
+ /** Placeable items */
48
+ LAVA_LAMP: 'LAVA_LAMP',
49
+ BOOMBOX: 'BOOMBOX',
50
+ CABIN_BED: 'CABIN_BED',
51
+ } as const
52
+
53
+ /**
54
+ * Currency-specific constants for easier access
55
+ */
56
+ export const CURRENCIES = {
57
+ /** Primary platform currency slug */
58
+ PRIMARY: ITEM_SLUGS.PLAYCADEMY_CREDITS,
59
+
60
+ /** Experience points slug */
61
+ XP: ITEM_SLUGS.PLAYCADEMY_XP,
62
+ } as const
63
+
64
+ /**
65
+ * Currency symbol constants
66
+ */
67
+ export const CURRENCY_SYMBOLS = {
68
+ /** Primary platform currency symbol */
69
+ PLAYCADEMY_CREDITS: 'PC',
70
+
71
+ /** Experience points symbol */
72
+ PLAYCADEMY_XP: 'XP',
73
+
74
+ /** Default currency symbol */
75
+ DEFAULT: '¤',
76
+ } as const
77
+
78
+ /**
79
+ * Badge constants for easier access
80
+ */
81
+ export const BADGES = {
82
+ FOUNDING_MEMBER: ITEM_SLUGS.FOUNDING_MEMBER_BADGE,
83
+ EARLY_ADOPTER: ITEM_SLUGS.EARLY_ADOPTER_BADGE,
84
+ FIRST_GAME: ITEM_SLUGS.FIRST_GAME_BADGE,
85
+ } as const
86
+
87
+ // ═══════════════════════════════════════════════════════════════════════
88
+ // RENDERING & VISUALS
89
+ // ═══════════════════════════════════════════════════════════════════════
90
+
91
+ /**
92
+ * Sprite System Constants
93
+ */
94
+ export const SPRITE_COMPONENTS = ['body', 'outfit', 'hairstyle', 'eyes', 'accessory'] as const
95
+ export const SPRITE_LAYER_ORDER = ['body', 'outfit', 'hairstyle', 'eyes', 'accessory'] as const
96
+
97
+ /**
98
+ * Renderer Z-layer constants – centralised depth values used by the Three.js
99
+ * front-end so magic numbers aren't scattered around the codebase.
100
+ */
101
+ export const Z_LAYERS = {
102
+ /** Depth step between successive Tiled tile-layers (background → foreground). */
103
+ TILE_LAYER_STEP: 0.01,
104
+
105
+ /** Depth step between stacked sprite components inside a single character. */
106
+ SPRITE_COMPONENT_STEP: 0.002,
107
+
108
+ /** Minimum Z for Y-sorted entities (top of screen). */
109
+ ENTITY_MIN: 0.011,
110
+
111
+ /** Maximum Z for Y-sorted entities (bottom of screen). */
112
+ ENTITY_MAX: 0.0115,
113
+
114
+ /** Fallback Z when map bounds are unavailable. */
115
+ ENTITY_FALLBACK: 0.01125,
116
+
117
+ /** Offset applied to placeable item sprites so they sit above characters. */
118
+ PLACEABLE_OFFSET: 0.012,
119
+
120
+ /** Shadow offset below entity base Z (shadows appear below characters). */
121
+ SHADOW_OFFSET: -0.001,
122
+ } as const
123
+
124
+ /**
125
+ * Shadow constants
126
+ */
127
+ export const SHADOW_CONSTANTS = {
128
+ /** Shadow radius as a fraction of tileWidth */
129
+ RADIUS_MULTIPLIER: 0.4,
130
+
131
+ /** Y offset in world units as a fraction of one tile width. */
132
+ Y_OFFSET_TILES: -0.9,
133
+
134
+ /** Shadow opacity (semi-transparent) */
135
+ OPACITY: 0.4,
136
+
137
+ /** Y-axis scale for elliptical perspective */
138
+ Y_SCALE: 0.6,
139
+
140
+ /** Minimum shadow size during jumps (30% of original) */
141
+ SCALE_MIN: 0.1,
142
+
143
+ /** Maximum jump height for scaling calculations */
144
+ MAX_JUMP_HEIGHT: 100,
145
+ } as const
146
+
147
+ /**
148
+ * Nameplate constants
149
+ */
150
+ export const NAMEPLATE_CONSTANTS = {
151
+ /** Adjust nameplate position from base height */
152
+ BASE_Y_ADJUST: -1,
153
+ /** Extra pixels to raise when a head accessory is equipped */
154
+ HEAD_ACCESSORY_EXTRA_PX: 5,
155
+ /** Available background colors for nameplates */
156
+ BACKGROUND_COLORS: [
157
+ '#2d3748', // Default gray
158
+ '#dc2626', // Red
159
+ '#ea580c', // Orange
160
+ '#ca8a04', // Amber
161
+ '#16a34a', // Green
162
+ '#0891b2', // Cyan
163
+ '#2563eb', // Blue
164
+ '#7c3aed', // Purple
165
+ '#c026d3', // Pink
166
+ '#e11d48', // Rose
167
+ '#134e4a', // Dark teal
168
+ '#831843', // Dark pink
169
+ ],
170
+ /** Default background color */
171
+ DEFAULT_BACKGROUND_COLOR: '#2d3748',
172
+ } as const
173
+
174
+ /**
175
+ * Particle system constants
176
+ */
177
+ export const LANDING_PARTICLES = {
178
+ /** Number of particles per landing */
179
+ COUNT: 6,
180
+
181
+ /** Base duration in ms */
182
+ DURATION: 500,
183
+
184
+ /** Spread radius as fraction of tileWidth */
185
+ SPREAD: 0.4,
186
+
187
+ /** Dust particle color */
188
+ COLOR: '#777',
189
+
190
+ /** Particle size in pixels in the game world */
191
+ SIZE: 3,
192
+
193
+ /** Vertical offset as a fraction of tile width (world units). */
194
+ Y_OFFSET_TILES: -0.9,
195
+ } as const
196
+
197
+ // ═══════════════════════════════════════════════════════════════════════
198
+ // MAPS
199
+ // ═══════════════════════════════════════════════════════════════════════
200
+
201
+ /**
202
+ * Map System Constants
203
+ */
204
+ export const MAP_CONSTANTS = {
205
+ /** Name of the Tiled layer containing map entry points */
206
+ ENTRY_POINT_LAYER_NAME: 'EntryPoints',
207
+
208
+ /** Name of the Tiled layer containing collision objects */
209
+ COLLISION_LAYER_NAME: 'Object Layer 1',
210
+
211
+ /** Name of the Tiled layer containing placeable objects */
212
+ PLACEABLE_AREA_LAYER_NAME: 'PlaceableArea',
213
+
214
+ /** Base path for tilesets */
215
+ TILESET_BASE_PATH: '/public/tilesets',
216
+ } as const
217
+
218
+ // ═══════════════════════════════════════════════════════════════════════
219
+ // PHYSICS & MOVEMENT
220
+ // ═══════════════════════════════════════════════════════════════════════
221
+
222
+ /**
223
+ * Player movement and physics constants
224
+ */
225
+ export const PLAYER_PHYSICS = {
226
+ /** Initial upward velocity when jumping (pixels per second) */
227
+ JUMP_FORCE: 150,
228
+
229
+ /** Downward acceleration due to gravity (pixels per second^2) */
230
+ GRAVITY: -450,
231
+ } as const
232
+
233
+ /**
234
+ * Bunny hop (jump queuing) constants – Counter-Strike style mechanics.
235
+ */
236
+ export const BUNNY_HOP = {
237
+ /** Base time window (ms) within which a queued jump is valid. */
238
+ QUEUE_WINDOW_MS: 100,
239
+
240
+ /** Downward velocity threshold (px/s) to allow jump queuing. */
241
+ FALL_SPEED_THRESHOLD: -50,
242
+
243
+ /** Vertical offset threshold (px) to allow queuing close to ground. */
244
+ CLOSE_TO_GROUND_THRESHOLD: 30,
245
+
246
+ /** Speed increase per successful hop. */
247
+ SPEED_INCREMENT: 0.15,
248
+
249
+ /** Maximum total speed multiplier. */
250
+ MAX_SPEED_MULTIPLIER: 5,
251
+
252
+ /** Multiplier applied to jump force on chained hops (slightly lower). */
253
+ HOP_JUMP_FORCE_MULTIPLIER: 0.95,
254
+ } as const
255
+
256
+ // ═══════════════════════════════════════════════════════════════════════
257
+ // UI & UX
258
+ // ═══════════════════════════════════════════════════════════════════════
259
+
260
+ /**
261
+ * Audio defaults
262
+ */
263
+ export const AUDIO_DEFAULTS = {
264
+ /** Master output volume */
265
+ MASTER_VOLUME: 0.5,
266
+
267
+ /** Background music enabled by default */
268
+ MUSIC_ENABLED: true,
269
+ /** Background music volume */
270
+ MUSIC_VOLUME: 0.5,
271
+
272
+ /** Sound effects enabled by default */
273
+ SFX_ENABLED: true,
274
+ /** Sound effects volume */
275
+ SFX_VOLUME: 0.5,
276
+ } as const
277
+
278
+ /**
279
+ * Toast Duration Constants
280
+ * Centralized toast notification display durations in milliseconds.
281
+ */
282
+ export const TOAST_DURATION = {
283
+ /** Short duration for simple confirmations */
284
+ SHORT: 3000,
285
+
286
+ /** Standard duration for most notifications */
287
+ STANDARD: 5000,
288
+
289
+ /** Long duration for important notifications */
290
+ LONG: 8000,
291
+
292
+ /** Error message duration */
293
+ ERROR: 4000,
294
+ } as const
295
+
296
+ /**
297
+ * Cache Control Headers
298
+ * Centralized cache control strategies for different asset types and API responses.
299
+ */
300
+ export const CACHE_CONTROL = {
301
+ /** Immutable assets with content-based versioning (sprites, audio, etc.) */
302
+ IMMUTABLE: 'public, max-age=31536000, immutable',
303
+
304
+ /** JSON data - cached for 1 day in browser, 1 year in CDN */
305
+ JSON_DATA: 'public, max-age=86400, s-maxage=31536000, must-revalidate',
306
+
307
+ /** Character components API - cached for 1 hour in browser, 3 hours in CDN */
308
+ API_CHARACTER_COMPONENTS: 'public, max-age=21600, s-maxage=21600, stale-while-revalidate=3600',
309
+
310
+ /** Level configs API - cached for 1 hour in browser, 12 hours in CDN */
311
+ API_LEVEL_CONFIGS: 'public, max-age=3600, s-maxage=86400, stale-while-revalidate=120',
312
+
313
+ /** Sprite templates API - cached for 1 day in browser, 1 week in CDN */
314
+ API_SPRITE_TEMPLATES: 'public, max-age=86400, s-maxage=86400, stale-while-revalidate=3600',
315
+ } as const
316
+
317
+ // ═══════════════════════════════════════════════════════════════════════
318
+ // CORE PLATFORM GAMES
319
+ // ═══════════════════════════════════════════════════════════════════════
320
+
321
+ /**
322
+ * Core Game UUIDs - Canonical UUIDs for core platform games
323
+ */
324
+ export const CORE_GAME_UUIDS = {
325
+ /** Internal playground game for development and testing */
326
+ PLAYGROUND: '00000000-0000-0000-0000-000000000001',
327
+ } as const
@@ -0,0 +1,10 @@
1
+ /**
2
+ * System-Level Platform Constants
3
+ *
4
+ * Core platform settings that affect the entire system.
5
+ */
6
+
7
+ /**
8
+ * Timezone for platform-wide operations
9
+ */
10
+ export const PLATFORM_TIMEZONE = 'America/New_York' as const
@@ -0,0 +1,32 @@
1
+ /**
2
+ * TimeBack Integration Constants
3
+ *
4
+ * Constants related to TimeBack Caliper integration.
5
+ */
6
+
7
+ /**
8
+ * TimeBack Caliper sensor URLs
9
+ * Allowed sensor URLs for Caliper event validation
10
+ */
11
+ export const TIMEBACK_CALIPER_SENSORS = [
12
+ 'https://samuraimath.com',
13
+ 'https://app.alphamath.school',
14
+ 'https://mathraiders.com',
15
+ ] as const
16
+
17
+ /**
18
+ * TimeBack integration route paths (on game backend)
19
+ * These routes are available on game backends when TimeBack is enabled
20
+ *
21
+ * NOTE:
22
+ * These paths are relative to /api/ - the full paths are /api/integrations/timeback/*
23
+ */
24
+ export const TIMEBACK_ROUTES = {
25
+ END_ACTIVITY: '/integrations/timeback/end-activity',
26
+ } as const
27
+
28
+ /**
29
+ * TimeBack OneRoster organization identifier
30
+ * This is the default organization sourcedId for Playcademy games
31
+ */
32
+ export const TIMEBACK_ORG_SOURCED_ID = 'PLAYCADEMY' as const
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Worker Naming Constants
3
+ *
4
+ * Conventions for naming Cloudflare workers to avoid collisions
5
+ * between staging and production deployments.
6
+ */
7
+
8
+ /**
9
+ * Worker naming patterns
10
+ * - Production workers: {slug} → accessible at {slug}.playcademy.gg
11
+ * - Staging workers: staging-{slug} → accessible at {slug}-staging.playcademy.gg
12
+ *
13
+ * Note: Worker names use a PREFIX (staging-) while hostnames use a SUFFIX (-staging)
14
+ * to follow subdomain naming conventions.
15
+ */
16
+ export const WORKER_NAMING = {
17
+ /** Prefix for staging worker names (e.g., "staging-bamboo") */
18
+ STAGING_PREFIX: 'staging-',
19
+ /** Suffix for staging worker hostnames (e.g., "bamboo-staging.playcademy.gg") */
20
+ STAGING_SUFFIX: '-staging',
21
+ } as const
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playcademy",
3
- "version": "0.12.1",
3
+ "version": "0.12.3",
4
4
  "type": "module",
5
5
  "module": "./dist/index.js",
6
6
  "main": "./dist/index.js",
@@ -41,7 +41,7 @@
41
41
  "dependencies": {
42
42
  "@hono/node-server": "^1.19.5",
43
43
  "@inquirer/prompts": "^7.8.6",
44
- "@playcademy/sdk": "0.1.2",
44
+ "@playcademy/sdk": "0.1.5",
45
45
  "better-sqlite3": "^12.4.1",
46
46
  "chokidar": "^4.0.3",
47
47
  "colorette": "^2.0.20",