@doodle-engine/cli 0.0.20 → 0.0.22
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/CHANGELOG.md +56 -38
- package/dist/cli.js +297 -192
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/create.d.ts.map +1 -1
- package/dist/manifest.d.ts.map +1 -1
- package/dist/service-worker.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -206,16 +206,28 @@ function I(t) {
|
|
|
206
206
|
console.log(c.green("✓ No validation errors"));
|
|
207
207
|
return;
|
|
208
208
|
}
|
|
209
|
-
console.log(
|
|
209
|
+
console.log(
|
|
210
|
+
c.red(
|
|
211
|
+
`
|
|
210
212
|
✗ Found ${t.length} validation error${t.length === 1 ? "" : "s"}:
|
|
211
|
-
`
|
|
213
|
+
`
|
|
214
|
+
)
|
|
215
|
+
);
|
|
212
216
|
for (const o of t)
|
|
213
|
-
console.log(
|
|
217
|
+
console.log(
|
|
218
|
+
c.bold(o.file) + (o.line ? `:${o.line}` : "")
|
|
219
|
+
), console.log(" " + c.red(o.message)), o.suggestion && console.log(" " + c.dim(o.suggestion)), console.log();
|
|
214
220
|
}
|
|
215
221
|
async function q(t, o, s, r, n = Date.now().toString()) {
|
|
216
|
-
const { shell: a, game: e } = W(
|
|
222
|
+
const { shell: a, game: e } = W(
|
|
223
|
+
s,
|
|
224
|
+
r
|
|
225
|
+
);
|
|
217
226
|
async function i(g) {
|
|
218
|
-
const _ = h(
|
|
227
|
+
const _ = h(
|
|
228
|
+
o,
|
|
229
|
+
g.startsWith("/") ? g.slice(1) : g
|
|
230
|
+
);
|
|
219
231
|
try {
|
|
220
232
|
return (await B(_)).size;
|
|
221
233
|
} catch {
|
|
@@ -223,19 +235,23 @@ async function q(t, o, s, r, n = Date.now().toString()) {
|
|
|
223
235
|
}
|
|
224
236
|
}
|
|
225
237
|
const l = await Promise.all(
|
|
226
|
-
a.map(
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
238
|
+
a.map(
|
|
239
|
+
async (g) => ({
|
|
240
|
+
path: g,
|
|
241
|
+
type: R(g),
|
|
242
|
+
size: await i(g),
|
|
243
|
+
tier: 1
|
|
244
|
+
})
|
|
245
|
+
)
|
|
232
246
|
), d = await Promise.all(
|
|
233
|
-
e.map(
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
247
|
+
e.map(
|
|
248
|
+
async (g) => ({
|
|
249
|
+
path: g,
|
|
250
|
+
type: R(g),
|
|
251
|
+
size: await i(g),
|
|
252
|
+
tier: 2
|
|
253
|
+
})
|
|
254
|
+
)
|
|
239
255
|
), u = l.reduce((g, _) => g + (_.size ?? 0), 0), m = d.reduce((g, _) => g + (_.size ?? 0), 0);
|
|
240
256
|
return {
|
|
241
257
|
version: n,
|
|
@@ -248,7 +264,9 @@ async function q(t, o, s, r, n = Date.now().toString()) {
|
|
|
248
264
|
const S = "🐾", X = "✨", Z = "✏️", ee = "➕";
|
|
249
265
|
async function te() {
|
|
250
266
|
const t = process.cwd(), o = h(t, "content");
|
|
251
|
-
console.log(""), console.log(
|
|
267
|
+
console.log(""), console.log(
|
|
268
|
+
c.bold.magenta(` ${S} Doodle Engine Dev Server ${S}`)
|
|
269
|
+
), console.log("");
|
|
252
270
|
const s = {
|
|
253
271
|
name: "doodle-content-loader",
|
|
254
272
|
configureServer(n) {
|
|
@@ -257,7 +275,12 @@ async function te() {
|
|
|
257
275
|
const m = await j(o);
|
|
258
276
|
u.setHeader("Content-Type", "application/json"), u.end(JSON.stringify(m));
|
|
259
277
|
} catch (m) {
|
|
260
|
-
console.error(
|
|
278
|
+
console.error(
|
|
279
|
+
c.red(" Error loading content:"),
|
|
280
|
+
m
|
|
281
|
+
), u.statusCode = 500, u.end(
|
|
282
|
+
JSON.stringify({ error: "Failed to load content" })
|
|
283
|
+
);
|
|
261
284
|
}
|
|
262
285
|
}), n.middlewares.use("/api/manifest", async (d, u) => {
|
|
263
286
|
try {
|
|
@@ -270,7 +293,12 @@ async function te() {
|
|
|
270
293
|
);
|
|
271
294
|
u.setHeader("Content-Type", "application/json"), u.end(JSON.stringify(_));
|
|
272
295
|
} catch (m) {
|
|
273
|
-
console.error(
|
|
296
|
+
console.error(
|
|
297
|
+
c.red(" Error generating manifest:"),
|
|
298
|
+
m
|
|
299
|
+
), u.statusCode = 500, u.end(
|
|
300
|
+
JSON.stringify({ error: "Failed to generate manifest" })
|
|
301
|
+
);
|
|
274
302
|
}
|
|
275
303
|
});
|
|
276
304
|
const a = L(o, {
|
|
@@ -288,9 +316,13 @@ async function te() {
|
|
|
288
316
|
}, 50);
|
|
289
317
|
};
|
|
290
318
|
a.on("change", (d) => {
|
|
291
|
-
l(
|
|
319
|
+
l(
|
|
320
|
+
c.yellow(` ${Z} Content changed: ${d}`)
|
|
321
|
+
);
|
|
292
322
|
}), a.on("add", (d) => {
|
|
293
|
-
e && l(
|
|
323
|
+
e && l(
|
|
324
|
+
c.green(` ${ee} Content added: ${d}`)
|
|
325
|
+
);
|
|
294
326
|
});
|
|
295
327
|
}
|
|
296
328
|
}, r = await F({
|
|
@@ -301,7 +333,9 @@ async function te() {
|
|
|
301
333
|
open: !0
|
|
302
334
|
}
|
|
303
335
|
});
|
|
304
|
-
await r.listen(), r.printUrls(), console.log(""), console.log(
|
|
336
|
+
await r.listen(), r.printUrls(), console.log(""), console.log(
|
|
337
|
+
c.dim(` ${X} Watching content files for changes...`)
|
|
338
|
+
), console.log("");
|
|
305
339
|
}
|
|
306
340
|
async function j(t) {
|
|
307
341
|
const o = {
|
|
@@ -535,7 +569,10 @@ async function re() {
|
|
|
535
569
|
n,
|
|
536
570
|
Date.now().toString()
|
|
537
571
|
), l = h(a, "api");
|
|
538
|
-
await T(l, { recursive: !0 }), await w(h(l, "content"), JSON.stringify(s)), await w(h(l, "manifest"), JSON.stringify(i)), await w(
|
|
572
|
+
await T(l, { recursive: !0 }), await w(h(l, "content"), JSON.stringify(s)), await w(h(l, "manifest"), JSON.stringify(i)), await w(
|
|
573
|
+
h(a, "asset-manifest.json"),
|
|
574
|
+
JSON.stringify(i, null, 2)
|
|
575
|
+
), console.log(c.dim("Generating service worker..."));
|
|
539
576
|
const d = ae(i);
|
|
540
577
|
await w(h(a, "sw.js"), d), console.log(""), console.log(c.green("✅ Build complete! Output in dist/")), console.log(""), console.log("To preview the build:"), console.log(c.dim(" yarn preview")), console.log("");
|
|
541
578
|
} catch (a) {
|
|
@@ -597,7 +634,14 @@ async function se(t) {
|
|
|
597
634
|
const a = h(t, "game.yaml"), e = await p(a, "utf-8");
|
|
598
635
|
n = y(e);
|
|
599
636
|
} catch {
|
|
600
|
-
n = {
|
|
637
|
+
n = {
|
|
638
|
+
id: "game",
|
|
639
|
+
startLocation: "",
|
|
640
|
+
startTime: { day: 1, hour: 8 },
|
|
641
|
+
startFlags: {},
|
|
642
|
+
startVariables: {},
|
|
643
|
+
startInventory: []
|
|
644
|
+
};
|
|
601
645
|
}
|
|
602
646
|
return { registry: o, fileMap: s, config: n };
|
|
603
647
|
}
|
|
@@ -667,33 +711,33 @@ dist
|
|
|
667
711
|
*.log
|
|
668
712
|
`, de = `<!doctype html>
|
|
669
713
|
<html lang="en">
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
714
|
+
<head>
|
|
715
|
+
<meta charset="UTF-8" />
|
|
716
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
717
|
+
<title>Doodle Engine Game</title>
|
|
718
|
+
</head>
|
|
719
|
+
<body>
|
|
720
|
+
<div id="root"></div>
|
|
721
|
+
<script type="module" src="/src/main.tsx"><\/script>
|
|
722
|
+
</body>
|
|
679
723
|
</html>
|
|
680
724
|
`, ue = `{
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
725
|
+
"compilerOptions": {
|
|
726
|
+
"target": "ES2024",
|
|
727
|
+
"lib": ["ES2024", "DOM", "DOM.Iterable"],
|
|
728
|
+
"module": "ESNext",
|
|
729
|
+
"moduleResolution": "bundler",
|
|
730
|
+
"jsx": "react-jsx",
|
|
731
|
+
"strict": true,
|
|
732
|
+
"skipLibCheck": true,
|
|
733
|
+
"esModuleInterop": true,
|
|
734
|
+
"forceConsistentCasingInFileNames": true,
|
|
735
|
+
"resolveJsonModule": true,
|
|
736
|
+
"isolatedModules": true,
|
|
737
|
+
"noEmit": true,
|
|
738
|
+
"types": ["vite/client"]
|
|
739
|
+
},
|
|
740
|
+
"include": ["src"]
|
|
697
741
|
}
|
|
698
742
|
`, he = `id: bartender
|
|
699
743
|
name: "@character.bartender.name"
|
|
@@ -1364,147 +1408,190 @@ stages:
|
|
|
1364
1408
|
description: "@quest.odd_jobs.stage.talked_to_merchant"
|
|
1365
1409
|
- id: complete
|
|
1366
1410
|
description: "@quest.odd_jobs.stage.complete"
|
|
1367
|
-
`, Re = `import { useEffect, useState } from 'react'
|
|
1368
|
-
import { Engine } from '@doodle-engine/core'
|
|
1369
|
-
import type { GameState, Snapshot } from '@doodle-engine/core'
|
|
1370
|
-
import { GameProvider, useGame } from '@doodle-engine/react'
|
|
1411
|
+
`, Re = `import { useEffect, useState } from 'react';
|
|
1412
|
+
import { Engine } from '@doodle-engine/core';
|
|
1413
|
+
import type { GameState, Snapshot } from '@doodle-engine/core';
|
|
1414
|
+
import { GameProvider, useGame } from '@doodle-engine/react';
|
|
1371
1415
|
|
|
1372
1416
|
export function App() {
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1417
|
+
const [game, setGame] = useState<{
|
|
1418
|
+
engine: Engine;
|
|
1419
|
+
snapshot: Snapshot;
|
|
1420
|
+
} | null>(null);
|
|
1421
|
+
|
|
1422
|
+
useEffect(() => {
|
|
1423
|
+
fetch('/api/content')
|
|
1424
|
+
.then((res) => res.json())
|
|
1425
|
+
.then((data) => {
|
|
1426
|
+
const engine = new Engine(data.registry, createEmptyState());
|
|
1427
|
+
const snapshot = engine.newGame(data.config);
|
|
1428
|
+
setGame({ engine, snapshot });
|
|
1429
|
+
});
|
|
1430
|
+
}, []);
|
|
1431
|
+
|
|
1432
|
+
if (!game) {
|
|
1433
|
+
return (
|
|
1434
|
+
<div className="app-bootstrap">
|
|
1435
|
+
<div className="spinner" />
|
|
1436
|
+
</div>
|
|
1437
|
+
);
|
|
1438
|
+
}
|
|
1388
1439
|
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1440
|
+
return (
|
|
1441
|
+
<GameProvider
|
|
1442
|
+
engine={game.engine}
|
|
1443
|
+
initialSnapshot={game.snapshot}
|
|
1444
|
+
devTools={import.meta.env.DEV}
|
|
1445
|
+
>
|
|
1446
|
+
<GameUI />
|
|
1447
|
+
</GameProvider>
|
|
1448
|
+
);
|
|
1394
1449
|
}
|
|
1395
1450
|
|
|
1396
1451
|
function GameUI() {
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
<
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1452
|
+
const { snapshot, actions } = useGame();
|
|
1453
|
+
|
|
1454
|
+
return (
|
|
1455
|
+
<div
|
|
1456
|
+
style={{
|
|
1457
|
+
padding: '2rem',
|
|
1458
|
+
fontFamily: 'sans-serif',
|
|
1459
|
+
maxWidth: '800px',
|
|
1460
|
+
margin: '0 auto',
|
|
1461
|
+
}}
|
|
1462
|
+
>
|
|
1463
|
+
<h1>{snapshot.location.name}</h1>
|
|
1464
|
+
<p>{snapshot.location.description}</p>
|
|
1465
|
+
|
|
1466
|
+
{snapshot.dialogue && (
|
|
1467
|
+
<div
|
|
1468
|
+
style={{
|
|
1469
|
+
background: '#f0f0f0',
|
|
1470
|
+
padding: '1rem',
|
|
1471
|
+
borderRadius: '8px',
|
|
1472
|
+
margin: '1rem 0',
|
|
1473
|
+
}}
|
|
1474
|
+
>
|
|
1475
|
+
<strong>{snapshot.dialogue.speakerName}:</strong>
|
|
1476
|
+
<p>{snapshot.dialogue.text}</p>
|
|
1477
|
+
{snapshot.choices.map((choice) => (
|
|
1478
|
+
<button
|
|
1479
|
+
key={choice.id}
|
|
1480
|
+
onClick={() => actions.selectChoice(choice.id)}
|
|
1481
|
+
style={{
|
|
1482
|
+
display: 'block',
|
|
1483
|
+
margin: '0.5rem 0',
|
|
1484
|
+
padding: '0.5rem 1rem',
|
|
1485
|
+
cursor: 'pointer',
|
|
1486
|
+
}}
|
|
1487
|
+
>
|
|
1488
|
+
{choice.text}
|
|
1489
|
+
</button>
|
|
1490
|
+
))}
|
|
1491
|
+
</div>
|
|
1492
|
+
)}
|
|
1493
|
+
|
|
1494
|
+
{!snapshot.dialogue && snapshot.charactersHere.length > 0 && (
|
|
1495
|
+
<div>
|
|
1496
|
+
<h2>Characters here</h2>
|
|
1497
|
+
{snapshot.charactersHere.map((char) => (
|
|
1498
|
+
<button
|
|
1499
|
+
key={char.id}
|
|
1500
|
+
onClick={() => actions.talkTo(char.id)}
|
|
1501
|
+
style={{
|
|
1502
|
+
display: 'block',
|
|
1503
|
+
margin: '0.5rem 0',
|
|
1504
|
+
padding: '0.5rem 1rem',
|
|
1505
|
+
cursor: 'pointer',
|
|
1506
|
+
}}
|
|
1507
|
+
>
|
|
1508
|
+
Talk to {char.name}
|
|
1509
|
+
</button>
|
|
1510
|
+
))}
|
|
1511
|
+
</div>
|
|
1512
|
+
)}
|
|
1432
1513
|
</div>
|
|
1433
|
-
|
|
1434
|
-
</div>
|
|
1435
|
-
)
|
|
1514
|
+
);
|
|
1436
1515
|
}
|
|
1437
1516
|
|
|
1438
1517
|
function createEmptyState(): GameState {
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1518
|
+
return {
|
|
1519
|
+
currentLocation: '',
|
|
1520
|
+
currentTime: { day: 1, hour: 0 },
|
|
1521
|
+
flags: {},
|
|
1522
|
+
variables: {},
|
|
1523
|
+
inventory: [],
|
|
1524
|
+
questProgress: {},
|
|
1525
|
+
unlockedJournalEntries: [],
|
|
1526
|
+
playerNotes: [],
|
|
1527
|
+
dialogueState: null,
|
|
1528
|
+
characterState: {},
|
|
1529
|
+
itemLocations: {},
|
|
1530
|
+
mapEnabled: true,
|
|
1531
|
+
notifications: [],
|
|
1532
|
+
pendingSounds: [],
|
|
1533
|
+
pendingVideo: null,
|
|
1534
|
+
pendingInterlude: null,
|
|
1535
|
+
currentLocale: 'en',
|
|
1536
|
+
};
|
|
1458
1537
|
}
|
|
1459
|
-
`, Ae = `import { useEffect, useState } from 'react'
|
|
1460
|
-
import type {
|
|
1461
|
-
|
|
1538
|
+
`, Ae = `import { useEffect, useState } from 'react';
|
|
1539
|
+
import type {
|
|
1540
|
+
ContentRegistry,
|
|
1541
|
+
GameConfig,
|
|
1542
|
+
AssetManifest,
|
|
1543
|
+
} from '@doodle-engine/core';
|
|
1544
|
+
import { GameShell } from '@doodle-engine/react';
|
|
1462
1545
|
|
|
1463
1546
|
export function App() {
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1547
|
+
const [content, setContent] = useState<{
|
|
1548
|
+
registry: ContentRegistry;
|
|
1549
|
+
config: GameConfig;
|
|
1550
|
+
} | null>(null);
|
|
1551
|
+
const [manifest, setManifest] = useState<AssetManifest | null>(null);
|
|
1552
|
+
|
|
1553
|
+
useEffect(() => {
|
|
1554
|
+
Promise.all([
|
|
1555
|
+
fetch('/api/content').then((res) => res.json()),
|
|
1556
|
+
fetch('/api/manifest').then((res) => res.json()),
|
|
1557
|
+
]).then(([contentData, manifestData]) => {
|
|
1558
|
+
setContent({
|
|
1559
|
+
registry: contentData.registry,
|
|
1560
|
+
config: contentData.config,
|
|
1561
|
+
});
|
|
1562
|
+
setManifest(manifestData);
|
|
1563
|
+
});
|
|
1564
|
+
}, []);
|
|
1565
|
+
|
|
1566
|
+
// Minimal bootstrap state while fetching manifest/content
|
|
1567
|
+
if (!content || !manifest) {
|
|
1568
|
+
return (
|
|
1569
|
+
<div className="app-bootstrap">
|
|
1570
|
+
<div className="spinner" />
|
|
1571
|
+
</div>
|
|
1572
|
+
);
|
|
1573
|
+
}
|
|
1479
1574
|
|
|
1480
|
-
// Minimal bootstrap state while fetching manifest/content
|
|
1481
|
-
if (!content || !manifest) {
|
|
1482
1575
|
return (
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
manifest={manifest}
|
|
1494
|
-
title="My Doodle Game"
|
|
1495
|
-
subtitle="A text-based adventure"
|
|
1496
|
-
availableLocales={[{ code: 'en', label: 'English' }]}
|
|
1497
|
-
devTools={import.meta.env.DEV}
|
|
1498
|
-
/>
|
|
1499
|
-
)
|
|
1576
|
+
<GameShell
|
|
1577
|
+
registry={content.registry}
|
|
1578
|
+
config={content.config}
|
|
1579
|
+
manifest={manifest}
|
|
1580
|
+
title="My Doodle Game"
|
|
1581
|
+
subtitle="A text-based adventure"
|
|
1582
|
+
availableLocales={[{ code: 'en', label: 'English' }]}
|
|
1583
|
+
devTools={import.meta.env.DEV}
|
|
1584
|
+
/>
|
|
1585
|
+
);
|
|
1500
1586
|
}
|
|
1501
1587
|
`, Se = `body {
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1588
|
+
margin: 0;
|
|
1589
|
+
font-family:
|
|
1590
|
+
-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
|
1591
|
+
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
|
1592
|
+
sans-serif;
|
|
1593
|
+
-webkit-font-smoothing: antialiased;
|
|
1594
|
+
-moz-osx-font-smoothing: grayscale;
|
|
1508
1595
|
}
|
|
1509
1596
|
|
|
1510
1597
|
/* ── Theme overrides ──────────────────────────────────────────────── */
|
|
@@ -1518,24 +1605,24 @@ export function App() {
|
|
|
1518
1605
|
--doodle-accent: #6366f1;
|
|
1519
1606
|
}
|
|
1520
1607
|
*/
|
|
1521
|
-
`, je = `import { StrictMode } from 'react'
|
|
1522
|
-
import { createRoot } from 'react-dom/client'
|
|
1523
|
-
import '@doodle-engine/react/style.css'
|
|
1524
|
-
import { App } from './App'
|
|
1525
|
-
import './index.css'
|
|
1608
|
+
`, je = `import { StrictMode } from 'react';
|
|
1609
|
+
import { createRoot } from 'react-dom/client';
|
|
1610
|
+
import '@doodle-engine/react/style.css';
|
|
1611
|
+
import { App } from './App';
|
|
1612
|
+
import './index.css';
|
|
1526
1613
|
|
|
1527
1614
|
// Register service worker in production for offline asset caching
|
|
1528
1615
|
if ('serviceWorker' in navigator && import.meta.env.PROD) {
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1616
|
+
navigator.serviceWorker.register('/sw.js').catch(() => {
|
|
1617
|
+
// SW registration failure is non-fatal
|
|
1618
|
+
});
|
|
1532
1619
|
}
|
|
1533
1620
|
|
|
1534
1621
|
createRoot(document.getElementById('root')!).render(
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
)
|
|
1622
|
+
<StrictMode>
|
|
1623
|
+
<App />
|
|
1624
|
+
</StrictMode>
|
|
1625
|
+
);
|
|
1539
1626
|
`, D = "🐾", xe = "🐕", H = "🦴", Ge = "✨", $ = "📁", N = "✅", qe = "🚀", x = /* @__PURE__ */ Object.assign({
|
|
1540
1627
|
"./templates/_root/_gitignore": le,
|
|
1541
1628
|
"./templates/_root/index.html": de,
|
|
@@ -1565,7 +1652,8 @@ createRoot(document.getElementById('root')!).render(
|
|
|
1565
1652
|
});
|
|
1566
1653
|
function He(t) {
|
|
1567
1654
|
const o = t.replace("./templates/", "");
|
|
1568
|
-
if (o === "src/App.default.tsx" || o === "src/App.custom.tsx")
|
|
1655
|
+
if (o === "src/App.default.tsx" || o === "src/App.custom.tsx")
|
|
1656
|
+
return null;
|
|
1569
1657
|
if (o.startsWith("_root/")) {
|
|
1570
1658
|
const s = o.slice(6);
|
|
1571
1659
|
return s.startsWith("_") ? "." + s.slice(1) : s;
|
|
@@ -1581,8 +1669,14 @@ async function $e(t) {
|
|
|
1581
1669
|
message: "Use default renderer?",
|
|
1582
1670
|
initial: !0
|
|
1583
1671
|
});
|
|
1584
|
-
s === void 0 && (console.log(
|
|
1585
|
-
|
|
1672
|
+
s === void 0 && (console.log(
|
|
1673
|
+
c.yellow(`
|
|
1674
|
+
${H} No worries, maybe next time! Woof!`)
|
|
1675
|
+
), process.exit(0)), console.log(""), await Me(o, t, s), console.log(""), console.log(c.bold.green(` ${N} Project created successfully!`)), console.log(""), console.log(c.dim(` ${$} ${o}`)), console.log(""), console.log(c.bold(" Next steps:")), console.log(c.cyan(` cd ${t}`)), console.log(
|
|
1676
|
+
c.cyan(" npm install ") + c.dim("# or: yarn install / pnpm install")
|
|
1677
|
+
), console.log(
|
|
1678
|
+
c.cyan(" npm run dev ") + c.dim("# or: yarn dev / pnpm dev")
|
|
1679
|
+
), console.log(""), console.log(c.dim(` ${qe} Happy game making! ${D}`)), console.log("");
|
|
1586
1680
|
}
|
|
1587
1681
|
async function Me(t, o, s) {
|
|
1588
1682
|
const r = [
|
|
@@ -1632,7 +1726,10 @@ async function Me(t, o, s) {
|
|
|
1632
1726
|
vite: "^6.0.0"
|
|
1633
1727
|
}
|
|
1634
1728
|
};
|
|
1635
|
-
console.log(` ${Ge} ${c.bold("Writing project files...")}`), await w(
|
|
1729
|
+
console.log(` ${Ge} ${c.bold("Writing project files...")}`), await w(
|
|
1730
|
+
h(t, "package.json"),
|
|
1731
|
+
JSON.stringify(n, null, 2)
|
|
1732
|
+
);
|
|
1636
1733
|
for (const [e, i] of Object.entries(x)) {
|
|
1637
1734
|
const l = He(e);
|
|
1638
1735
|
if (l === null) continue;
|
|
@@ -1640,10 +1737,18 @@ async function Me(t, o, s) {
|
|
|
1640
1737
|
await T(U(d), { recursive: !0 }), await w(d, i);
|
|
1641
1738
|
}
|
|
1642
1739
|
const a = s ? "./templates/src/App.default.tsx" : "./templates/src/App.custom.tsx";
|
|
1643
|
-
await w(h(t, "src/App.tsx"), x[a]), console.log(c.green(` ${N} Source files created`)), console.log(""), console.log(` ${H} ${c.bold("Starter content written")}`), console.log(""), console.log(c.dim(" Content includes:")), console.log(c.dim(" 2 locations (tavern, market)")), console.log(c.dim(" 2 characters (bartender, merchant)")), console.log(c.dim(" 1 item (old coin)")), console.log(c.dim(" 1 map (town with 2 locations)")), console.log(c.dim(" 1 quest (odd jobs, 3 stages)")), console.log(c.dim(" 3 journal entries")), console.log(
|
|
1740
|
+
await w(h(t, "src/App.tsx"), x[a]), console.log(c.green(` ${N} Source files created`)), console.log(""), console.log(` ${H} ${c.bold("Starter content written")}`), console.log(""), console.log(c.dim(" Content includes:")), console.log(c.dim(" 2 locations (tavern, market)")), console.log(c.dim(" 2 characters (bartender, merchant)")), console.log(c.dim(" 1 item (old coin)")), console.log(c.dim(" 1 map (town with 2 locations)")), console.log(c.dim(" 1 quest (odd jobs, 3 stages)")), console.log(c.dim(" 3 journal entries")), console.log(
|
|
1741
|
+
c.dim(" 1 interlude (chapter one, auto-triggers at tavern)")
|
|
1742
|
+
), console.log(
|
|
1743
|
+
c.dim(
|
|
1744
|
+
" 5 dialogues (2 narrator intros, 2 NPC conversations, 1 skill check)"
|
|
1745
|
+
)
|
|
1746
|
+
), console.log(c.dim(" English locale with all strings"));
|
|
1644
1747
|
}
|
|
1645
1748
|
const v = new M();
|
|
1646
|
-
v.name("doodle").description(
|
|
1749
|
+
v.name("doodle").description(
|
|
1750
|
+
c.magenta("🐾 Doodle Engine") + c.dim(" — Narrative RPG development tools")
|
|
1751
|
+
).version("0.0.1");
|
|
1647
1752
|
v.command("create <project-name>").description("Scaffold a new Doodle Engine game project").action(async (t) => {
|
|
1648
1753
|
await $e(t);
|
|
1649
1754
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,wBAAsB,KAAK,
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,wBAAsB,KAAK,kBAuF1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAkBH,wBAAsB,GAAG,
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAkBH,wBAAsB,GAAG,kBA0HxB"}
|
package/dist/create.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA6CH,wBAAsB,MAAM,CAAC,WAAW,EAAE,MAAM,iBAgD/C"}
|
package/dist/manifest.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,qBAAqB,CAAC;AAErE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACvC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE,MAA8B,GACxC,OAAO,CAAC,aAAa,CAAC,CAoDxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-worker.d.ts","sourceRoot":"","sources":["../src/service-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"service-worker.d.ts","sourceRoot":"","sources":["../src/service-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CA8ErE"}
|