@bitmagic/cli 0.1.65-dev.24 → 0.1.65-dev.4
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/README.md +18 -106
- package/dist/assets/materials.d.ts +0 -9
- package/dist/assets/materials.js +2 -10
- package/dist/assets/materials.js.map +1 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/forge.js +23 -39
- package/dist/commands/forge.js.map +1 -1
- package/dist/commands/generate.d.ts +13 -31
- package/dist/commands/generate.js +56 -48
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/trailer.js +1 -1
- package/dist/commands/trailer.js.map +1 -1
- package/dist/editor/animation-preview-page.js +1 -88
- package/dist/editor/animation-preview-page.js.map +1 -1
- package/dist/editor/asset-detail-panel.d.ts +2 -2
- package/dist/editor/asset-detail-panel.js +0 -21
- package/dist/editor/asset-detail-panel.js.map +1 -1
- package/dist/editor/asset-viewer.js +8 -31
- package/dist/editor/asset-viewer.js.map +1 -1
- package/dist/editor/shell-page.js +1 -63
- package/dist/editor/shell-page.js.map +1 -1
- package/dist/mobile/asset-hosts.d.ts +9 -7
- package/dist/mobile/asset-hosts.js +16 -7
- package/dist/mobile/asset-hosts.js.map +1 -1
- package/dist/scaffold/blender-level-skill-files.js +2 -3
- package/dist/scaffold/blender-level-skill-files.js.map +1 -1
- package/dist/scaffold/claude-settings.js +0 -4
- package/dist/scaffold/claude-settings.js.map +1 -1
- package/dist/scaffold/project-files.js +12 -18
- package/dist/scaffold/project-files.js.map +1 -1
- package/dist/scaffold/project.js +1 -4
- package/dist/scaffold/project.js.map +1 -1
- package/dist/scaffold/skill-files.d.ts +5 -32
- package/dist/scaffold/skill-files.js +63 -102
- package/dist/scaffold/skill-files.js.map +1 -1
- package/dist/telemetry/creator-prompt.d.ts +2 -18
- package/dist/telemetry/creator-prompt.js +3 -24
- package/dist/telemetry/creator-prompt.js.map +1 -1
- package/dist/telemetry/report.js +16 -31
- package/dist/telemetry/report.js.map +1 -1
- package/package.json +4 -4
- package/assets/skills/trailer-craft.md +0 -180
- package/dist/commands/character.d.ts +0 -18
- package/dist/commands/character.js +0 -268
- package/dist/commands/character.js.map +0 -1
- package/dist/forge/prune-store.d.ts +0 -46
- package/dist/forge/prune-store.js +0 -86
- package/dist/forge/prune-store.js.map +0 -1
- package/dist/forge/remote-store.d.ts +0 -36
- package/dist/forge/remote-store.js +0 -113
- package/dist/forge/remote-store.js.map +0 -1
- package/dist/generate/character-body.d.ts +0 -79
- package/dist/generate/character-body.js +0 -100
- package/dist/generate/character-body.js.map +0 -1
- package/dist/project/character-search.d.ts +0 -30
- package/dist/project/character-search.js +0 -82
- package/dist/project/character-search.js.map +0 -1
- package/dist/scaffold/asset-pipeline-skill-files.d.ts +0 -42
- package/dist/scaffold/asset-pipeline-skill-files.js +0 -207
- package/dist/scaffold/asset-pipeline-skill-files.js.map +0 -1
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
export interface CharacterArgs {
|
|
2
|
-
name: string;
|
|
3
|
-
prompt: string;
|
|
4
|
-
applyToPlayer?: boolean;
|
|
5
|
-
headScale?: string;
|
|
6
|
-
/** `--fresh`: forge a new one, never substitute a stored body. */
|
|
7
|
-
fresh?: boolean;
|
|
8
|
-
/**
|
|
9
|
-
* citty's negative boolean: `--no-library` arrives as `false`; the flag has no positive form.
|
|
10
|
-
* The deprecated spelling of `--fresh`, kept working because every scaffolded AGENTS.md
|
|
11
|
-
* written before the rename teaches it.
|
|
12
|
-
*/
|
|
13
|
-
library?: boolean;
|
|
14
|
-
/** `--library-only`: take the closest stored body, never forge, never charge. */
|
|
15
|
-
libraryOnly?: boolean;
|
|
16
|
-
/** A row a prior search returned, which `bitmagic character add --id` adds verbatim. */
|
|
17
|
-
libraryPick?: {
|
|
18
|
-
sid: string;
|
|
19
|
-
assetUrl: string;
|
|
20
|
-
description?: string;
|
|
21
|
-
similarity: number;
|
|
22
|
-
};
|
|
23
|
-
/** Absent = the generator's default (true); the command fills it from the project's art style. */
|
|
24
|
-
voxelize?: boolean;
|
|
25
|
-
/** Asset Forger image-to-mesh model; absent = the Forger default. */
|
|
26
|
-
meshModel?: string;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* The character default a project's art style implies: a low-poly game keeps the textured rig.
|
|
30
|
-
* Read from the cwd's project like every other generate command; outside a project the answer
|
|
31
|
-
* is "declares nothing", so the generator's own default (voxelize) stands and `loadProjectContext`
|
|
32
|
-
* reports the missing project on the very next line.
|
|
33
|
-
*/
|
|
34
|
-
export declare function defaultVoxelizeForProject(): boolean | undefined;
|
|
35
|
-
export declare function buildCharacterBody(args: CharacterArgs): Record<string, unknown>;
|
|
36
|
-
export declare const NAME_ARG: {
|
|
37
|
-
readonly type: "string";
|
|
38
|
-
readonly required: true;
|
|
39
|
-
readonly description: "Unique name for the character.";
|
|
40
|
-
};
|
|
41
|
-
export declare const PROMPT_ARG: {
|
|
42
|
-
readonly type: "string";
|
|
43
|
-
readonly required: true;
|
|
44
|
-
readonly description: "Description of the character.";
|
|
45
|
-
};
|
|
46
|
-
export declare const APPLY_TO_PLAYER_ARG: {
|
|
47
|
-
readonly type: "boolean";
|
|
48
|
-
readonly description: "Set this character as the PLAYER. Omit to use the generator default (true).";
|
|
49
|
-
};
|
|
50
|
-
export declare const HEAD_SCALE_ARG: {
|
|
51
|
-
readonly type: "string";
|
|
52
|
-
readonly description: "Head size as a percentage of normal, 50-300. Omit to use the generator default.";
|
|
53
|
-
};
|
|
54
|
-
export declare const FRESH_ARG: {
|
|
55
|
-
readonly type: "boolean";
|
|
56
|
-
readonly description: string;
|
|
57
|
-
};
|
|
58
|
-
export declare const VOXELIZE_ARG: {
|
|
59
|
-
readonly type: "boolean";
|
|
60
|
-
readonly description: "Voxelize the rigged body. Omit to follow game.json artStyle: voxel games voxelize, low-poly games keep the textured rig.";
|
|
61
|
-
readonly negativeDescription: "Keep the textured low-poly rig instead of voxelizing it.";
|
|
62
|
-
};
|
|
63
|
-
export declare const MESH_MODEL_ARG: {
|
|
64
|
-
readonly type: "string";
|
|
65
|
-
readonly description: "Image-to-mesh model. Low-poly characters already default to 'runware-rodin-gen-2', which bills 60 sparks and takes ~3 min; pass 'unified-trellis' to put one back on the cheap lane at 15 sparks. Voxel characters ignore the default and use the Forger's.";
|
|
66
|
-
};
|
|
67
|
-
/**
|
|
68
|
-
* The deprecated spelling of `--fresh`.
|
|
69
|
-
*
|
|
70
|
-
* Kept declared because citty derives `--no-library` from an argument NAMED
|
|
71
|
-
* `library`, so there is no way to accept the old flag without it — and no way
|
|
72
|
-
* to hide it either: citty's `ArgDef` has no `hidden` field (only `CommandMeta`
|
|
73
|
-
* does). So it stays visible and says what it is.
|
|
74
|
-
*/
|
|
75
|
-
export declare const LIBRARY_ARG: {
|
|
76
|
-
readonly type: "boolean";
|
|
77
|
-
readonly description: "Deprecated and unnecessary — the library is consulted by default. Use --fresh to skip it.";
|
|
78
|
-
readonly negativeDescription: "Deprecated spelling of --fresh. Always makes a new character.";
|
|
79
|
-
};
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The character request: its flags, and the body they map onto.
|
|
3
|
-
*
|
|
4
|
-
* Lives here rather than in either command because TWO commands present it —
|
|
5
|
-
* `bitmagic character generate` and the deprecated `bitmagic generate character`
|
|
6
|
-
* it replaced — and a deprecated alias whose flags have drifted from the command
|
|
7
|
-
* it aliases is worse than no alias at all. One definition, imported by both.
|
|
8
|
-
*
|
|
9
|
-
* Field names are exactly what `characterParamsSchema`
|
|
10
|
-
* (shared/asset-core/src/generators/character.ts) expects, and a flag the
|
|
11
|
-
* creator did not pass is OMITTED rather than sent as `undefined` or as a
|
|
12
|
-
* restated default — the generator owns its defaults.
|
|
13
|
-
*/
|
|
14
|
-
import { findProjectRootOrNull } from '../project/context.js';
|
|
15
|
-
import { readArtStyleDeclaration } from '../project/art-style.js';
|
|
16
|
-
import { parseNumberFlag } from '../commands/number-flag.js';
|
|
17
|
-
/** Drops the keys an absent flag left `undefined`; `false` and `0` are deliberate values. */
|
|
18
|
-
function withoutAbsentFlags(fields) {
|
|
19
|
-
return Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== undefined));
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* The character default a project's art style implies: a low-poly game keeps the textured rig.
|
|
23
|
-
* Read from the cwd's project like every other generate command; outside a project the answer
|
|
24
|
-
* is "declares nothing", so the generator's own default (voxelize) stands and `loadProjectContext`
|
|
25
|
-
* reports the missing project on the very next line.
|
|
26
|
-
*/
|
|
27
|
-
export function defaultVoxelizeForProject() {
|
|
28
|
-
const root = findProjectRootOrNull();
|
|
29
|
-
if (root === null)
|
|
30
|
-
return undefined;
|
|
31
|
-
return readArtStyleDeclaration(root).artStyle === 'low-poly' ? false : undefined;
|
|
32
|
-
}
|
|
33
|
-
export function buildCharacterBody(args) {
|
|
34
|
-
return withoutAbsentFlags({
|
|
35
|
-
name: args.name,
|
|
36
|
-
prompt: args.prompt,
|
|
37
|
-
applyToPlayer: args.applyToPlayer,
|
|
38
|
-
headScale: parseNumberFlag('head-scale', args.headScale, { min: 50, max: 300 }),
|
|
39
|
-
// `--fresh` and the deprecated `--no-library` are the same request. Neither
|
|
40
|
-
// passed leaves the field absent, so the generator's default (search first)
|
|
41
|
-
// stands rather than being restated here.
|
|
42
|
-
useLibrary: args.fresh === true ? false : args.library,
|
|
43
|
-
libraryOnly: args.libraryOnly,
|
|
44
|
-
libraryPick: args.libraryPick,
|
|
45
|
-
voxelize: args.voxelize,
|
|
46
|
-
meshModel: args.meshModel,
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
// ============================================================================
|
|
50
|
-
// Flag definitions, shared by `character generate` and the deprecated alias
|
|
51
|
-
// ============================================================================
|
|
52
|
-
export const NAME_ARG = {
|
|
53
|
-
type: 'string',
|
|
54
|
-
required: true,
|
|
55
|
-
description: 'Unique name for the character.',
|
|
56
|
-
};
|
|
57
|
-
export const PROMPT_ARG = {
|
|
58
|
-
type: 'string',
|
|
59
|
-
required: true,
|
|
60
|
-
description: 'Description of the character.',
|
|
61
|
-
};
|
|
62
|
-
export const APPLY_TO_PLAYER_ARG = {
|
|
63
|
-
type: 'boolean',
|
|
64
|
-
description: 'Set this character as the PLAYER. Omit to use the generator default (true).',
|
|
65
|
-
};
|
|
66
|
-
export const HEAD_SCALE_ARG = {
|
|
67
|
-
type: 'string',
|
|
68
|
-
description: 'Head size as a percentage of normal, 50-300. Omit to use the generator default.',
|
|
69
|
-
};
|
|
70
|
-
export const FRESH_ARG = {
|
|
71
|
-
type: 'boolean',
|
|
72
|
-
description: 'Forge a new character even when the library has a close match. '
|
|
73
|
-
+ 'Use it when you want this exact brief made rather than the nearest ready-made body.',
|
|
74
|
-
};
|
|
75
|
-
export const VOXELIZE_ARG = {
|
|
76
|
-
type: 'boolean',
|
|
77
|
-
description: 'Voxelize the rigged body. Omit to follow game.json artStyle: voxel games voxelize, low-poly games keep the textured rig.',
|
|
78
|
-
negativeDescription: 'Keep the textured low-poly rig instead of voxelizing it.',
|
|
79
|
-
};
|
|
80
|
-
export const MESH_MODEL_ARG = {
|
|
81
|
-
type: 'string',
|
|
82
|
-
description: "Image-to-mesh model. Low-poly characters already default to 'runware-rodin-gen-2', which bills 60 sparks and takes ~3 min; pass 'unified-trellis' to put one back on the cheap lane at 15 sparks. Voxel characters ignore the default and use the Forger's.",
|
|
83
|
-
};
|
|
84
|
-
/**
|
|
85
|
-
* The deprecated spelling of `--fresh`.
|
|
86
|
-
*
|
|
87
|
-
* Kept declared because citty derives `--no-library` from an argument NAMED
|
|
88
|
-
* `library`, so there is no way to accept the old flag without it — and no way
|
|
89
|
-
* to hide it either: citty's `ArgDef` has no `hidden` field (only `CommandMeta`
|
|
90
|
-
* does). So it stays visible and says what it is.
|
|
91
|
-
*/
|
|
92
|
-
export const LIBRARY_ARG = {
|
|
93
|
-
type: 'boolean',
|
|
94
|
-
// Both forms get a description, because citty renders a positive row for any
|
|
95
|
-
// boolean arg whether or not the flag is meant to be used. Left undescribed it
|
|
96
|
-
// was a blank line in `--help` sitting next to `--fresh`.
|
|
97
|
-
description: 'Deprecated and unnecessary — the library is consulted by default. Use --fresh to skip it.',
|
|
98
|
-
negativeDescription: 'Deprecated spelling of --fresh. Always makes a new character.',
|
|
99
|
-
};
|
|
100
|
-
//# sourceMappingURL=character-body.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"character-body.js","sourceRoot":"","sources":["../../src/generate/character-body.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,6FAA6F;AAC7F,SAAS,kBAAkB,CAAC,MAA+B;IACzD,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC;AAC/F,CAAC;AAyBD;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB;IACvC,MAAM,IAAI,GAAG,qBAAqB,EAAE,CAAC;IACrC,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IACpC,OAAO,uBAAuB,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAmB;IACpD,OAAO,kBAAkB,CAAC;QACxB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,SAAS,EAAE,eAAe,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;QAC/E,4EAA4E;QAC5E,4EAA4E;QAC5E,0CAA0C;QAC1C,UAAU,EAAE,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO;QACtD,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,SAAS,EAAE,IAAI,CAAC,SAAS;KAC1B,CAAC,CAAC;AACL,CAAC;AAED,+EAA+E;AAC/E,4EAA4E;AAC5E,+EAA+E;AAE/E,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,IAAI;IACd,WAAW,EAAE,gCAAgC;CACrC,CAAC;AAEX,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,IAAI;IACd,WAAW,EAAE,+BAA+B;CACpC,CAAC;AAEX,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,6EAA6E;CAClF,CAAC;AAEX,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,iFAAiF;CACtF,CAAC;AAEX,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,iEAAiE;UAC1E,qFAAqF;CACjF,CAAC;AAEX,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,0HAA0H;IACvI,mBAAmB,EAAE,0DAA0D;CACvE,CAAC;AAEX,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,6PAA6P;CAClQ,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,SAAS;IACf,6EAA6E;IAC7E,+EAA+E;IAC/E,0DAA0D;IAC1D,WAAW,EAAE,2FAA2F;IACxG,mBAAmB,EAAE,+DAA+D;CAC5E,CAAC"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export declare function characterSearchPath(root: string): string;
|
|
2
|
-
/** One row as the search displayed it. The shape `libraryPick` needs, plus the caption. */
|
|
3
|
-
export interface CharacterCandidate {
|
|
4
|
-
sid: string;
|
|
5
|
-
assetUrl: string;
|
|
6
|
-
description: string;
|
|
7
|
-
subject: string | null;
|
|
8
|
-
similarity: number;
|
|
9
|
-
}
|
|
10
|
-
export interface CharacterSearchRecord {
|
|
11
|
-
/** The prompt that produced this list — `add --id` reuses it as the asset's brief. */
|
|
12
|
-
prompt: string;
|
|
13
|
-
/** Which shelf was searched. `add` sends the matching `voxelize` so the media cannot cross. */
|
|
14
|
-
representation: 'voxel' | 'lowpoly';
|
|
15
|
-
/** The floor automatic substitution would have applied, for the "auto" column. */
|
|
16
|
-
threshold: number;
|
|
17
|
-
searchedAt: string;
|
|
18
|
-
candidates: CharacterCandidate[];
|
|
19
|
-
}
|
|
20
|
-
/** The last search, or null when there is none to trust. */
|
|
21
|
-
export declare function readCharacterSearch(root: string): CharacterSearchRecord | null;
|
|
22
|
-
export declare function writeCharacterSearch(root: string, record: CharacterSearchRecord): void;
|
|
23
|
-
/**
|
|
24
|
-
* The cached row with this id, or null.
|
|
25
|
-
*
|
|
26
|
-
* Case-insensitive on the id because a creator reads it off a table and retypes
|
|
27
|
-
* it, and the corpus uses one case throughout — so a capital letter is a typo
|
|
28
|
-
* with an obvious intent, not a different character.
|
|
29
|
-
*/
|
|
30
|
-
export declare function findCachedCandidate(record: CharacterSearchRecord, sid: string): CharacterCandidate | null;
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The candidates the last `bitmagic character search` returned, so
|
|
3
|
-
* `bitmagic character add --id <sid>` can name one of them.
|
|
4
|
-
*
|
|
5
|
-
* The search already fetched every row it displayed — sid, URL, caption and
|
|
6
|
-
* score. Keeping them means `add --id` needs nothing but the id: no second
|
|
7
|
-
* query, no re-ranking, and no asking the creator to retype the prompt that
|
|
8
|
-
* produced the list they are looking at. It also means `add` cannot drift from
|
|
9
|
-
* what was on screen, which a re-search could (the catalogue grows).
|
|
10
|
-
*
|
|
11
|
-
* Lives under `.bitmagic/` like `reference.json` and `cover.json`: generated,
|
|
12
|
-
* machine-written state. NOT in `bitmagic.json`, deliberately — that file is
|
|
13
|
-
* inside the publish fingerprint (shared/asset-core's publish-source.ts), so
|
|
14
|
-
* recording a search there would invalidate a passing `bitmagic verify` every
|
|
15
|
-
* time somebody browsed the shelf.
|
|
16
|
-
*
|
|
17
|
-
* Readers are lenient, like `readCoverRecord` and the reference records: a
|
|
18
|
-
* corrupt or absent file reads as "no search yet", because the worst case is one
|
|
19
|
-
* re-run of a free command, and a hard error would wedge the very command that
|
|
20
|
-
* would have replaced the bad file.
|
|
21
|
-
*
|
|
22
|
-
* There is deliberately no expiry. The catalogue only changes when someone
|
|
23
|
-
* promotes to it, and a stale row fails loudly and harmlessly (the URL 404s) —
|
|
24
|
-
* where a timeout would expire a list the creator is still reading. `add` prints
|
|
25
|
-
* the search's own timestamp instead, so age is visible rather than enforced.
|
|
26
|
-
*/
|
|
27
|
-
import * as path from 'path';
|
|
28
|
-
import { readJsonFile, writeJsonAtomic } from '../atomic-json.js';
|
|
29
|
-
const SEARCH_FILE = path.join('.bitmagic', 'character-search.json');
|
|
30
|
-
export function characterSearchPath(root) {
|
|
31
|
-
return path.join(root, SEARCH_FILE);
|
|
32
|
-
}
|
|
33
|
-
function isCandidate(value) {
|
|
34
|
-
if (typeof value !== 'object' || value === null)
|
|
35
|
-
return false;
|
|
36
|
-
const row = value;
|
|
37
|
-
return typeof row.sid === 'string' && row.sid !== ''
|
|
38
|
-
&& typeof row.assetUrl === 'string' && row.assetUrl !== ''
|
|
39
|
-
&& typeof row.similarity === 'number';
|
|
40
|
-
}
|
|
41
|
-
/** The last search, or null when there is none to trust. */
|
|
42
|
-
export function readCharacterSearch(root) {
|
|
43
|
-
const raw = readJsonFile(characterSearchPath(root));
|
|
44
|
-
if (typeof raw !== 'object' || raw === null)
|
|
45
|
-
return null;
|
|
46
|
-
const record = raw;
|
|
47
|
-
if (typeof record.prompt !== 'string')
|
|
48
|
-
return null;
|
|
49
|
-
if (record.representation !== 'voxel' && record.representation !== 'lowpoly')
|
|
50
|
-
return null;
|
|
51
|
-
if (!Array.isArray(record.candidates))
|
|
52
|
-
return null;
|
|
53
|
-
const candidates = record.candidates.filter(isCandidate).map((row) => ({
|
|
54
|
-
sid: row.sid,
|
|
55
|
-
assetUrl: row.assetUrl,
|
|
56
|
-
description: typeof row.description === 'string' ? row.description : '',
|
|
57
|
-
subject: typeof row.subject === 'string' ? row.subject : null,
|
|
58
|
-
similarity: row.similarity,
|
|
59
|
-
}));
|
|
60
|
-
return {
|
|
61
|
-
prompt: record.prompt,
|
|
62
|
-
representation: record.representation,
|
|
63
|
-
threshold: typeof record.threshold === 'number' ? record.threshold : 0,
|
|
64
|
-
searchedAt: typeof record.searchedAt === 'string' ? record.searchedAt : '',
|
|
65
|
-
candidates,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
export function writeCharacterSearch(root, record) {
|
|
69
|
-
writeJsonAtomic(characterSearchPath(root), record);
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* The cached row with this id, or null.
|
|
73
|
-
*
|
|
74
|
-
* Case-insensitive on the id because a creator reads it off a table and retypes
|
|
75
|
-
* it, and the corpus uses one case throughout — so a capital letter is a typo
|
|
76
|
-
* with an obvious intent, not a different character.
|
|
77
|
-
*/
|
|
78
|
-
export function findCachedCandidate(record, sid) {
|
|
79
|
-
const wanted = sid.trim().toLowerCase();
|
|
80
|
-
return record.candidates.find((row) => row.sid.toLowerCase() === wanted) ?? null;
|
|
81
|
-
}
|
|
82
|
-
//# sourceMappingURL=character-search.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"character-search.js","sourceRoot":"","sources":["../../src/project/character-search.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `<skills dir>/choosing-asset-pipelines/SKILL.md` — WHICH lane makes a given thing, before any
|
|
3
|
-
* command runs.
|
|
4
|
-
*
|
|
5
|
-
* Exists because the GDK grew several ways to make the same thing — a level from the baseline
|
|
6
|
-
* terrain, `bitmagic forge` (five modes), a Blender script or a Unity port; a character from the
|
|
7
|
-
* free block default, a free library hit, a voxel forge or a low-poly forge at four times the
|
|
8
|
-
* price — and the routing knowledge sat in five places: the per-command reference in
|
|
9
|
-
* `generating-assets`, the "one forge" rule in `planning-a-game`, the Blender skill's §0 gate, the
|
|
10
|
-
* hosted Creator agent's GLB-vs-voxel rules (which never reach a CLI project at all), and code
|
|
11
|
-
* comments. An agent took the first lane it remembered, and a creator had to know Bitmagic's
|
|
12
|
-
* internals to steer it. This file is the table by NEED: conditions (art style, model class,
|
|
13
|
-
* local tooling, prototype vs polished), rough cost, rough time, recommended order — and the rule
|
|
14
|
-
* for when the agent decides alone versus asks the creator with a recommendation.
|
|
15
|
-
*
|
|
16
|
-
* It is a shipped skill so that `bitmagic upgrade` re-renders it in every project with every CLI
|
|
17
|
-
* release — that is the whole update mechanism; nothing here is hand-maintained in a creator's
|
|
18
|
-
* project. Same file-layout contract as `skill-files.ts`: a pure function returning the markdown
|
|
19
|
-
* as a template literal, every backtick inside escaped as \` and every `${` escaped, except the
|
|
20
|
-
* `${PRIMARY_SKILLS_DIR}` interpolations, which are the point (sibling skills are cited by the
|
|
21
|
-
* fixed path every agent's project has, never by a vendor path). Imports only `agent-targets.js`
|
|
22
|
-
* so `project.ts` can import this without a cycle.
|
|
23
|
-
*
|
|
24
|
-
* What keeps it honest, and what does not:
|
|
25
|
-
* - `__tests__/asset-pipeline-skill-files.test.ts` fails when a `bitmagic generate` subcommand or
|
|
26
|
-
* a `bitmagic character` verb exists with no row here (deprecated aliases excepted), when a row
|
|
27
|
-
* names a subcommand or a skill directory that does not exist, or when one of the need sections
|
|
28
|
-
* or the two defaults (audio opt-in, block characters) disappears. So a new generator cannot
|
|
29
|
-
* ship without a row — but a RENAMED flag can: the day this shipped, `--no-library` had just
|
|
30
|
-
* become `--fresh` and `--library-only` had become `character search` + `add`, and every test
|
|
31
|
-
* passed. That is why the sheet names COMMANDS ONLY and tells the agent to read `--help` —
|
|
32
|
-
* a flag written here is a flag that will be wrong.
|
|
33
|
-
* - Prices and timings are NOT test-checked. Sparks come from `api-server/src/llm/llm_cost.json`
|
|
34
|
-
* (`toolCosts`, 1 spark = $0.01): glb/model/prop 3, voxel character 15, low-poly character 60,
|
|
35
|
-
* library-only 0, skybox and background 5, image 3, cover and reference 6, block-type 3, sound
|
|
36
|
-
* 12, music 0.25/s, video 1.35/s, authored animation 1, video-to-motion 15; forge and vehicle
|
|
37
|
-
* are usage-priced, presets free. Timings are observed. The CLI cannot import that file, so a
|
|
38
|
-
* price, flag or backend change is invisible to the test — which is why the release checklist
|
|
39
|
-
* (`.claude/skills/generate-release-checklist`) asks for this file to be re-read whenever a
|
|
40
|
-
* generator or `toolCosts` changes. Every figure is written as approximate for the same reason.
|
|
41
|
-
*/
|
|
42
|
-
export declare function renderAssetPipelinesSkill(): string;
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `<skills dir>/choosing-asset-pipelines/SKILL.md` — WHICH lane makes a given thing, before any
|
|
3
|
-
* command runs.
|
|
4
|
-
*
|
|
5
|
-
* Exists because the GDK grew several ways to make the same thing — a level from the baseline
|
|
6
|
-
* terrain, `bitmagic forge` (five modes), a Blender script or a Unity port; a character from the
|
|
7
|
-
* free block default, a free library hit, a voxel forge or a low-poly forge at four times the
|
|
8
|
-
* price — and the routing knowledge sat in five places: the per-command reference in
|
|
9
|
-
* `generating-assets`, the "one forge" rule in `planning-a-game`, the Blender skill's §0 gate, the
|
|
10
|
-
* hosted Creator agent's GLB-vs-voxel rules (which never reach a CLI project at all), and code
|
|
11
|
-
* comments. An agent took the first lane it remembered, and a creator had to know Bitmagic's
|
|
12
|
-
* internals to steer it. This file is the table by NEED: conditions (art style, model class,
|
|
13
|
-
* local tooling, prototype vs polished), rough cost, rough time, recommended order — and the rule
|
|
14
|
-
* for when the agent decides alone versus asks the creator with a recommendation.
|
|
15
|
-
*
|
|
16
|
-
* It is a shipped skill so that `bitmagic upgrade` re-renders it in every project with every CLI
|
|
17
|
-
* release — that is the whole update mechanism; nothing here is hand-maintained in a creator's
|
|
18
|
-
* project. Same file-layout contract as `skill-files.ts`: a pure function returning the markdown
|
|
19
|
-
* as a template literal, every backtick inside escaped as \` and every `${` escaped, except the
|
|
20
|
-
* `${PRIMARY_SKILLS_DIR}` interpolations, which are the point (sibling skills are cited by the
|
|
21
|
-
* fixed path every agent's project has, never by a vendor path). Imports only `agent-targets.js`
|
|
22
|
-
* so `project.ts` can import this without a cycle.
|
|
23
|
-
*
|
|
24
|
-
* What keeps it honest, and what does not:
|
|
25
|
-
* - `__tests__/asset-pipeline-skill-files.test.ts` fails when a `bitmagic generate` subcommand or
|
|
26
|
-
* a `bitmagic character` verb exists with no row here (deprecated aliases excepted), when a row
|
|
27
|
-
* names a subcommand or a skill directory that does not exist, or when one of the need sections
|
|
28
|
-
* or the two defaults (audio opt-in, block characters) disappears. So a new generator cannot
|
|
29
|
-
* ship without a row — but a RENAMED flag can: the day this shipped, `--no-library` had just
|
|
30
|
-
* become `--fresh` and `--library-only` had become `character search` + `add`, and every test
|
|
31
|
-
* passed. That is why the sheet names COMMANDS ONLY and tells the agent to read `--help` —
|
|
32
|
-
* a flag written here is a flag that will be wrong.
|
|
33
|
-
* - Prices and timings are NOT test-checked. Sparks come from `api-server/src/llm/llm_cost.json`
|
|
34
|
-
* (`toolCosts`, 1 spark = $0.01): glb/model/prop 3, voxel character 15, low-poly character 60,
|
|
35
|
-
* library-only 0, skybox and background 5, image 3, cover and reference 6, block-type 3, sound
|
|
36
|
-
* 12, music 0.25/s, video 1.35/s, authored animation 1, video-to-motion 15; forge and vehicle
|
|
37
|
-
* are usage-priced, presets free. Timings are observed. The CLI cannot import that file, so a
|
|
38
|
-
* price, flag or backend change is invisible to the test — which is why the release checklist
|
|
39
|
-
* (`.claude/skills/generate-release-checklist`) asks for this file to be re-read whenever a
|
|
40
|
-
* generator or `toolCosts` changes. Every figure is written as approximate for the same reason.
|
|
41
|
-
*/
|
|
42
|
-
import { PRIMARY_SKILLS_DIR } from './agent-targets.js';
|
|
43
|
-
export function renderAssetPipelinesSkill() {
|
|
44
|
-
return `---
|
|
45
|
-
name: choosing-asset-pipelines
|
|
46
|
-
description: Pick the lane that makes a given thing for this Bitmagic game — a whole level, a character, a building, a small prop, a vehicle, a weapon, the sky, block textures, an image or cover, an animation, audio, a cutscene — choosing between the free built-in, bitmagic generate, bitmagic forge, a Blender build, a Unity port and the creator's own files, with approximate sparks and wall-clock minutes per option and the rule for when to ask the creator first. Use before any generation, forge or Blender build, and whenever two routes could make the same thing.
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
# Choosing an asset pipeline
|
|
50
|
-
|
|
51
|
-
Most things this game needs can be made three or four ways, and the ways differ by a hundred
|
|
52
|
-
sparks and by twenty minutes. This file is the routing table: find the need, take the first row
|
|
53
|
-
whose conditions hold, say which you took. It names commands without their flags on purpose —
|
|
54
|
-
**run \`<command> --help\` before using one.** Flags move between releases; the help does not lie.
|
|
55
|
-
Flags and refusals in prose are in \`${PRIMARY_SKILLS_DIR}/generating-assets/SKILL.md\`; this file only decides.
|
|
56
|
-
|
|
57
|
-
Costs are **approximate** — sparks are rounded and times are typical, not promised. \`bitmagic
|
|
58
|
-
usage\` is the truth about what was actually spent.
|
|
59
|
-
|
|
60
|
-
## Know these four things first
|
|
61
|
-
|
|
62
|
-
1. **Art style** — \`artStyle\` in \`src/work/game.json\`: \`voxel\` (default) or \`low-poly\`. A declared
|
|
63
|
-
switch, not a per-asset flag: in a low-poly game models, props, added files and characters keep
|
|
64
|
-
their meshes instead of voxelizing (and a character costs four times more), the Blender level
|
|
65
|
-
route opens, and built-in weapons should use their \`_lowpoly\` twins. Set it before the first cover.
|
|
66
|
-
2. **Your model class** — frontier (Claude Fable / Opus 5, GPT-6 class) or not. Only the Blender
|
|
67
|
-
route depends on it; its §0 says "if you are not sure you are one, you are not".
|
|
68
|
-
3. **Local tooling** — Google Chrome (the forge, generated models, props and vehicles, added \`.glb\`
|
|
69
|
-
files in a voxel game, \`verify\`); Blender 4.2+ (Blender levels); \`ffmpeg\` (\`trailer\`, video
|
|
70
|
-
contact sheets); a Unity project to port. Probe once with the checks each skill gives.
|
|
71
|
-
4. **Purpose** — **prototype** (slice 1, prove the loop, the creator will iterate) or **polished**
|
|
72
|
-
("final", "ship it", "make it look great", publishing). Take it from their words. Unsaid:
|
|
73
|
-
assume prototype for slice 1 and note the upgrade as a backlog item.
|
|
74
|
-
|
|
75
|
-
## Decide, say so, ask only when it is expensive
|
|
76
|
-
|
|
77
|
-
Default: you decide, and state the assumption in one line before running anything:
|
|
78
|
-
|
|
79
|
-
> Assuming *prototype*: using \`<route>\` (~N sparks, ~T). Say "polished" and I will use \`<alt>\`.
|
|
80
|
-
|
|
81
|
-
Ask first only when BOTH hold: the recommended option is expensive — tens of sparks or many
|
|
82
|
-
minutes (a forge, a low-poly character, a video-to-motion animation, a long music track, a Blender
|
|
83
|
-
build) — AND the creator has not said prototype or polished. Recommended option first, answerable
|
|
84
|
-
in a word:
|
|
85
|
-
|
|
86
|
-
> \`<need>\`: I recommend \`<A>\` (~N sparks, ~T) because \`<why>\`; the alternative is \`<B>\` (~N, ~T).
|
|
87
|
-
> Which — or just say prototype / polished and I will pick?
|
|
88
|
-
|
|
89
|
-
Never ask about a free or seconds-long option, never ask twice for the same need, never run two
|
|
90
|
-
paid options to compare. If the allowance is nearly gone
|
|
91
|
-
(\`${PRIMARY_SKILLS_DIR}/checking-usage/SKILL.md\`), say so before an expensive one.
|
|
92
|
-
|
|
93
|
-
## By need
|
|
94
|
-
|
|
95
|
-
Rows are in recommended order: take the first whose conditions hold.
|
|
96
|
-
|
|
97
|
-
### A whole level
|
|
98
|
-
|
|
99
|
-
| Route | Conditions | ~Cost | Notes |
|
|
100
|
-
|---|---|---|---|
|
|
101
|
-
| The baseline's procedural voxel terrain (already there) | prototype, or the terrain is not the mechanic | free, instant | Slice 1's world unless the game cannot be played without its shape (planning skill) |
|
|
102
|
-
| \`bitmagic forge\` — natural terrain by default, or one of its modes: city, dungeon, platformer, freeform, vessel | Chrome; terrain IS the mechanic (skiing, a circuit, open-world driving, an enclosed dungeon) or polished | usage-priced, tens of sparks; many minutes (the bake alone can take twenty) | One forge per game; it can edit a forged level in place and resume a failed job — see its help. AGENTS.md "Forging a whole level" |
|
|
103
|
-
| \`${PRIMARY_SKILLS_DIR}/building-levels-in-blender/SKILL.md\` | frontier model AND Blender 4.2+ AND \`artStyle: "low-poly"\`; a DESIGNED place (interior, station, set), not natural terrain | free in sparks; an hour or more of your time | Its §0 is the gate; audited with ray casts, loaded by \`MeshLevel\` |
|
|
104
|
-
| \`${PRIMARY_SKILLS_DIR}/converting-unity-levels/SKILL.md\` | the creator has a Unity scene to bring over | free in sparks; minutes to hours | Reuses their prefabs, FBX, colliders; not a way to make a level from nothing |
|
|
105
|
-
|
|
106
|
-
### A character (player or NPC)
|
|
107
|
-
|
|
108
|
-
| Route | Conditions | ~Cost | Notes |
|
|
109
|
-
|---|---|---|---|
|
|
110
|
-
| A block character built in code (the default) | any; recolours, outfits, a blocky knight/robot/wizard | free, seconds | \`character-system.md\`, \`npc-appearance.md\`. Highres and block **never coexist** — going highres means the whole cast goes |
|
|
111
|
-
| \`bitmagic character search\` then \`bitmagic character add\` | prototype; any plausible ready-made body will do | free, instant | \`search\` lists the closest library bodies and changes nothing; \`add\` takes one and never forges. Judge the match yourself — a score says "plausible", not "right" |
|
|
112
|
-
| \`bitmagic character generate\` | the look is genuinely custom; the whole cast will be highres | free and seconds on a library match; else ~15 sparks, ~1.5–4 min (voxel) or ~60 sparks, ~3 min (low-poly) | Library-first by default; a custom head scale or mesh model always forges. It can set the player directly |
|
|
113
|
-
| \`bitmagic character generate\`, forced fresh | polished; exactly this one, no library substitute | ~15 (voxel) / ~60 (low-poly) sparks; minutes | The costly row: ask first if purpose is unknown |
|
|
114
|
-
|
|
115
|
-
### A building or landmark
|
|
116
|
-
|
|
117
|
-
| Route | Conditions | ~Cost | Notes |
|
|
118
|
-
|---|---|---|---|
|
|
119
|
-
| A structure a forge already placed, or a \`building\` hotspot | the level was forged | free | \`environment-objects.md\` |
|
|
120
|
-
| \`bitmagic generate model\` | a new named structure the code places | ~3 sparks; ~10 s voxel, minutes for a mesh | Chrome in a voxel game; give it a height — above 6 m stays hollow |
|
|
121
|
-
| \`bitmagic generate prop\` | a placeholder or forge asset is already placed and looks bad | ~3 sparks; ~10 s | REPLACES that asset; every placed instance upgrades. Never for a new object |
|
|
122
|
-
| \`bitmagic assets add\` | the creator has the model | free; seconds to a minute | Chrome to voxelize in a voxel game; can keep the mesh instead |
|
|
123
|
-
|
|
124
|
-
### A small prop (a crate, a lantern, a pickup)
|
|
125
|
-
|
|
126
|
-
| Route | Conditions | ~Cost | Notes |
|
|
127
|
-
|---|---|---|---|
|
|
128
|
-
| An asset already in \`assets[]\` (\`bitmagic assets list\`) | one fits | free | The same object twice is the commonest waste |
|
|
129
|
-
| \`bitmagic generate model\` | a new object the code spawns or places | ~3 sparks; ~10 s voxel | Cheap enough not to ask. \`environmentObjects[]\` or \`engine.spawnAsset()\` — \`environment-objects.md\` |
|
|
130
|
-
| \`bitmagic assets add\` | the creator has a \`.glb\`/\`.vxl\` | free | Same voxelize rule as above |
|
|
131
|
-
| Plain three.js geometry in code | a marker, trigger or debug prop nobody looks at | free, no browser | Do not hand-build what a 3-spark model makes better |
|
|
132
|
-
|
|
133
|
-
### A vehicle
|
|
134
|
-
|
|
135
|
-
| Route | Conditions | ~Cost | Notes |
|
|
136
|
-
|---|---|---|---|
|
|
137
|
-
| \`bitmagic generate vehicle\` from a preset (its help lists them) | no bespoke look needed; prototype | free; ~a minute (Chrome) | Physics, lights, AI built in either way; spawn via \`engine.getVehicleSpawner().spawnAndEnterFromAsset(...)\` |
|
|
138
|
-
| \`bitmagic generate vehicle\` from a description | the look is the point | usage-priced, several sparks; several minutes | NEW asset each run; ask first when purpose is unknown |
|
|
139
|
-
|
|
140
|
-
### A weapon
|
|
141
|
-
|
|
142
|
-
| Route | Conditions | ~Cost | Notes |
|
|
143
|
-
|---|---|---|---|
|
|
144
|
-
| A built-in id (\`sword\`, \`assault_rifle\`, \`bow\`…) or its \`_lowpoly\` twin via \`weaponStyleId(base, 'lowpoly')\` | any; match the twin to \`artStyle\` | free, instant | Wired into damage, animations, pickups, NPC use. \`weapon-visuals.md\`, \`combat-system.md\` |
|
|
145
|
-
| \`bitmagic generate model\` | a genuinely custom look | ~3 sparks; ~10 s | A mesh only — still wire it to a built-in's combat behaviour |
|
|
146
|
-
|
|
147
|
-
### The sky
|
|
148
|
-
|
|
149
|
-
| Route | Conditions | ~Cost | Notes |
|
|
150
|
-
|---|---|---|---|
|
|
151
|
-
| The engine's default sky | prototype; no strong setting | free | |
|
|
152
|
-
| \`bitmagic generate skybox\` | a free-look or third-person camera | ~5 sparks; ~a minute | Usually earns its place in slice 1 |
|
|
153
|
-
| \`bitmagic generate background\` | a fixed sidescroller or top-down camera | ~5 sparks; ~a minute | SAME field as skybox; the second run silently replaces the first |
|
|
154
|
-
|
|
155
|
-
### Block textures
|
|
156
|
-
|
|
157
|
-
| Route | Conditions | ~Cost | Notes |
|
|
158
|
-
|---|---|---|---|
|
|
159
|
-
| A built-in block name (\`stone\`, \`grass\`, \`sand\`, \`marble\`…) | one fits | free | \`custom-block-types.md\` |
|
|
160
|
-
| A plain-colour \`customBlockTypes[]\` entry by hand | prototype; a colour is enough | free | snake_case, never a built-in's name |
|
|
161
|
-
| \`bitmagic generate block-type\` | the surface needs a real texture (a second one for the sides is optional) | ~3 sparks (~6 with sides); seconds to a minute | The same name replaces the entry |
|
|
162
|
-
|
|
163
|
-
### Images, cover, reference
|
|
164
|
-
|
|
165
|
-
| Route | Conditions | ~Cost | Notes |
|
|
166
|
-
|---|---|---|---|
|
|
167
|
-
| \`bitmagic assets add\` | the creator has the picture | free | |
|
|
168
|
-
| \`bitmagic generate image\` | a portrait, icon, poster, HUD art | ~3 sparks; ~30 s | |
|
|
169
|
-
| \`bitmagic cover\` | always, early — after \`artStyle\` is set, before \`verify\` | ~6 sparks; minutes | Prompt comes from \`GAME-DESIGN.md\`; an unchanged design regenerates nothing |
|
|
170
|
-
| \`bitmagic reference make\`, then the HUMAN accepts | the idea names a place or a look | ~6 sparks per candidate; ~a minute | Steers every later skybox, block, cover and forge |
|
|
171
|
-
|
|
172
|
-
### Animation
|
|
173
|
-
|
|
174
|
-
| Route | Conditions | ~Cost | Notes |
|
|
175
|
-
|---|---|---|---|
|
|
176
|
-
| A built-in clip (\`mGenIdle01\`, \`mGenWalk01\`, \`mKicking01\`, \`mPunching01\`…) | one fits | free, instant | \`animation-assets.md\`; locomotion auto-plays |
|
|
177
|
-
| \`bitmagic generate animation\` from an authored spec (gait, melee, one-shot) | a gait variant, a melee move, a key-pose one-shot | ~1 spark; ~1 s | Solved locally; the cheapest generator |
|
|
178
|
-
| \`bitmagic generate animation\` from a video | a motion only footage captures | ~15 sparks (plus video seconds if it generates the clip); minutes | Ask first when purpose is unknown |
|
|
179
|
-
|
|
180
|
-
### Audio
|
|
181
|
-
|
|
182
|
-
| Route | Conditions | ~Cost | Notes |
|
|
183
|
-
|---|---|---|---|
|
|
184
|
-
| None | the creator has not asked for sound | free | Audio is added only on request — never by default |
|
|
185
|
-
| Web Audio synthesis in code | ordinary SFX: a beep, a hit, a pickup | free | \`audio-system.md\` |
|
|
186
|
-
| \`bitmagic assets add\` | the creator has the track | free | |
|
|
187
|
-
| \`bitmagic generate sound\` | they asked for a premium or generated effect | ~12 sparks; ~30 s | One prompt, one effect |
|
|
188
|
-
| \`bitmagic generate music\` | they asked for original music | ~0.25 sparks/s (30 s ≈ 8, 120 s ≈ 30); ~a minute | Ask first for a long track when purpose is unknown; it can write a file instead of a world asset, for a trailer bed |
|
|
189
|
-
|
|
190
|
-
### A cutscene or video
|
|
191
|
-
|
|
192
|
-
| Route | Conditions | ~Cost | Notes |
|
|
193
|
-
|---|---|---|---|
|
|
194
|
-
| \`bitmagic generate video\` from a prompt | a story beat played by \`engine.playVideo()\` | ~1.35 sparks/s (5 s ≈ 7); ~40 s | Read the frame sheet before wiring; needs a user gesture to play. \`video-cutscenes.md\` |
|
|
195
|
-
| \`bitmagic generate video\` from a still | animate a picture you have (cover, reference) | same sparks; ~3 min | Comes back in the image's shape, not 16:9 |
|
|
196
|
-
| \`bitmagic trailer\` (\`${PRIMARY_SKILLS_DIR}/making-a-trailer/SKILL.md\`) | a trailer or highlight reel of real gameplay | free apart from an optional music bed; \`ffmpeg\` | Cut from a recording, not generated |
|
|
197
|
-
|
|
198
|
-
## After you have chosen
|
|
199
|
-
|
|
200
|
-
- \`<command> --help\` first, then pass the creator's request verbatim the way AGENTS.md says.
|
|
201
|
-
- Each generation writes \`src/work/world.json\`; re-read it if you hold a copy.
|
|
202
|
-
- One generation per decision. Decide the prompt, run it once, use what comes back.
|
|
203
|
-
- Flags in prose, reference-image rules, refusals: \`${PRIMARY_SKILLS_DIR}/generating-assets/SKILL.md\`.
|
|
204
|
-
What it cost: \`bitmagic usage\`.
|
|
205
|
-
`;
|
|
206
|
-
}
|
|
207
|
-
//# sourceMappingURL=asset-pipeline-skill-files.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"asset-pipeline-skill-files.js","sourceRoot":"","sources":["../../src/scaffold/asset-pipeline-skill-files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,UAAU,yBAAyB;IACvC,OAAO;;;;;;;;;;;uCAW8B,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoCpD,kBAAkB;;;;;;;;;;;;MAYjB,kBAAkB;MAClB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BA4FI,kBAAkB;;;;;;;uDAOS,kBAAkB;;CAExE,CAAC;AACF,CAAC"}
|