@silkweaver/build 1.3.1 → 1.3.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/build.js +16 -6
- package/dist/object_format.d.ts +7 -6
- package/dist/object_format.js +18 -33
- package/dist/templates.js +1 -0
- package/package.json +1 -1
- package/templates/empty/.engine/engine.mjs +17557 -0
- package/templates/empty/.engine/version.json +4 -0
- package/templates/empty/project.json +2 -2
- package/templates/physics_ball/.engine/engine.mjs +17557 -0
- package/templates/physics_ball/.engine/version.json +4 -0
- package/templates/physics_ball/objects/obj_ball.ts +24 -0
- package/templates/physics_ball/objects/obj_paddle.ts +25 -0
- package/templates/physics_ball/objects/obj_tracker.ts +7 -0
- package/templates/physics_ball/objects/obj_wall.ts +8 -0
- package/templates/physics_ball/project.json +53 -0
- package/templates/physics_ball/rooms/room_main/room.json +77 -0
- package/templates/physics_ball/sprites/spr_ball/0.png +0 -0
- package/templates/physics_ball/sprites/spr_ball/meta.json +22 -0
- package/templates/physics_ball/sprites/spr_paddle/0.png +0 -0
- package/templates/physics_ball/sprites/spr_paddle/meta.json +17 -0
- package/templates/physics_ball/sprites/spr_tracker/0.png +0 -0
- package/templates/physics_ball/sprites/spr_tracker/meta.json +22 -0
- package/templates/physics_ball/sprites/spr_wall/0.png +0 -0
- package/templates/physics_ball/sprites/spr_wall/meta.json +22 -0
- package/templates/platformer/.engine/engine.mjs +17557 -0
- package/templates/platformer/.engine/version.json +4 -0
- package/templates/platformer/objects/obj_platform.ts +0 -2
- package/templates/platformer/objects/obj_player.ts +33 -23
- package/templates/platformer/project.json +2 -2
- package/templates/topdown/.engine/engine.mjs +17557 -0
- package/templates/topdown/.engine/version.json +4 -0
- package/templates/topdown/objects/obj_player.ts +35 -37
- package/templates/topdown/project.json +2 -2
package/dist/build.js
CHANGED
|
@@ -218,10 +218,13 @@ async function generate_entry_code(project_folder, proj, asset_mode, engine_path
|
|
|
218
218
|
if ((inst.rotation ?? 0) !== 0)
|
|
219
219
|
lines.push(` ${v}.image_angle = ${inst.rotation}`);
|
|
220
220
|
lines.push(` ${v}.register_events()`);
|
|
221
|
-
|
|
222
|
-
//
|
|
221
|
+
// Queue the Create event (+ optional per-instance creation code) via the engine helper,
|
|
222
|
+
// which runs them under the active-instance context so `sw`/`inst` resolve inside.
|
|
223
223
|
if (inst.creation_code && inst.creation_code.trim()) {
|
|
224
|
-
lines.push(`
|
|
224
|
+
lines.push(` instance_queue_create(${v}, (function(this: any){\n${inst.creation_code}\n}).bind(${v}))`);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
lines.push(` instance_queue_create(${v})`);
|
|
225
228
|
}
|
|
226
229
|
return lines.join('\n');
|
|
227
230
|
}).filter(Boolean).join('\n');
|
|
@@ -277,7 +280,9 @@ async function generate_entry_code(project_folder, proj, asset_mode, engine_path
|
|
|
277
280
|
${var_name}.room_width = ${rm_data.width ?? 640}
|
|
278
281
|
${var_name}.room_height = ${rm_data.height ?? 480}
|
|
279
282
|
${var_name}.room_speed = ${rm_data.room_speed ?? 60}
|
|
280
|
-
${var_name}.room_persistent = ${rm_data.persistent ?? false}
|
|
283
|
+
${var_name}.room_persistent = ${rm_data.persistent ?? false}${room_physics[room_name]
|
|
284
|
+
? `\n${var_name}.physics_world = true\n${var_name}.physics_gravity_x = ${room_physics[room_name].gx}\n${var_name}.physics_gravity_y = ${room_physics[room_name].gy}`
|
|
285
|
+
: ''}
|
|
281
286
|
${var_name}.background_show_color = ${rm_data.bg_show_color ?? true}
|
|
282
287
|
${var_name}.background_solid_color = ${hex_to_bgr(rm_data.bg_color ?? '#000000')}${rm_data.creation_code && rm_data.creation_code.trim()
|
|
283
288
|
? `\n${var_name}.creation_code = () => {\n${rm_data.creation_code}\n}`
|
|
@@ -510,7 +515,7 @@ async function _load_sound(name: string, meta_url: string, base: string): Promis
|
|
|
510
515
|
// ── Bootstrap ───────────────────────────────────────────────────────────────
|
|
511
516
|
export default async function init(canvas: HTMLCanvasElement): Promise<void> {
|
|
512
517
|
renderer.init(canvas, ${proj.settings.windowWidth ?? 640}, ${proj.settings.windowHeight ?? 480})
|
|
513
|
-
|
|
518
|
+
renderer.set_clear_color(${JSON.stringify(proj.settings.displayColor ?? '#000000')}) // window/clear color (Game Settings)
|
|
514
519
|
game_loop.init_input(canvas)
|
|
515
520
|
|
|
516
521
|
// Load sprites
|
|
@@ -534,6 +539,9 @@ export default async function init(canvas: HTMLCanvasElement): Promise<void> {
|
|
|
534
539
|
// Set up rooms
|
|
535
540
|
${room_setups.join('\n')}
|
|
536
541
|
|
|
542
|
+
// Register rooms by name (room_goto('rm_x') / room_get('rm_x') / room_exists('rm_x'))
|
|
543
|
+
${room_names.map(n => `room_register_name('${n}', _room_${n})`).join('\n ')}
|
|
544
|
+
|
|
537
545
|
// Link room order
|
|
538
546
|
${room_var_names.map((v, i) => {
|
|
539
547
|
const prev = room_var_names[i - 1];
|
|
@@ -546,7 +554,9 @@ export default async function init(canvas: HTMLCanvasElement): Promise<void> {
|
|
|
546
554
|
|
|
547
555
|
const start = ${start_var}
|
|
548
556
|
if (!start) { console.error('[Game] No rooms defined.'); return }
|
|
549
|
-
|
|
557
|
+
// The physics world is (re)created per-room in room.build_for_entry() from the room's
|
|
558
|
+
// physics_world/gravity fields — so it's fresh on every entry AND every restart.
|
|
559
|
+
game_loop.start(start)
|
|
550
560
|
}
|
|
551
561
|
`;
|
|
552
562
|
return entry_code;
|
package/dist/object_format.d.ts
CHANGED
|
@@ -33,13 +33,14 @@ export interface object_model {
|
|
|
33
33
|
/** Extracts the object model from a class-file source. */
|
|
34
34
|
export declare function parse_object(src: string): object_model;
|
|
35
35
|
/**
|
|
36
|
-
* Collects
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
36
|
+
* Collects the object's OWN variables: declared instance fields *plus* members created/assigned at
|
|
37
|
+
* runtime via the `inst.` namespace inside any event (e.g. `inst.velocity = 0` in on_create, read in
|
|
38
|
+
* on_step). This drives `inst.` autocomplete, so a variable made in one event surfaces in all the
|
|
39
|
+
* others. Static fields (object metadata) and method/event names are excluded. The engine's built-in
|
|
40
|
+
* instance API is NOT collected here — it lives on `sw.` and is typed from the engine directly — so
|
|
41
|
+
* `this.x`/`sw.x` style writes never leak into the author's own-variable list.
|
|
41
42
|
*/
|
|
42
|
-
export declare function
|
|
43
|
+
export declare function object_vars(src: string): string[];
|
|
43
44
|
/**
|
|
44
45
|
* Sets (adds or updates) a static metadata field. `expr` is the raw initializer
|
|
45
46
|
* text (e.g. `'spr_player'`, `true`, `-5`, `obj_base`).
|
package/dist/object_format.js
CHANGED
|
@@ -46,7 +46,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
46
46
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
47
|
exports.EVENT_ORDER = exports.META_ORDER = void 0;
|
|
48
48
|
exports.parse_object = parse_object;
|
|
49
|
-
exports.
|
|
49
|
+
exports.object_vars = object_vars;
|
|
50
50
|
exports.set_static = set_static;
|
|
51
51
|
exports.remove_static = remove_static;
|
|
52
52
|
exports.set_field = set_field;
|
|
@@ -63,19 +63,6 @@ exports.META_ORDER = [
|
|
|
63
63
|
'sprite', 'parent', 'solid', 'visible', 'persistent', 'depth',
|
|
64
64
|
'physics', 'physics_shape', 'physics_density', 'physics_restitution', 'physics_friction', 'physics_sensor',
|
|
65
65
|
];
|
|
66
|
-
/**
|
|
67
|
-
* Explicit type annotations for static fields whose base-class type is narrower than what TypeScript
|
|
68
|
-
* would infer from the literal initializer. Without this, `static physics_shape = 'box'` widens to
|
|
69
|
-
* `string`, which doesn't satisfy the base's `'box' | 'circle'` and the subclass fails to compile.
|
|
70
|
-
*/
|
|
71
|
-
const META_TYPES = {
|
|
72
|
-
physics_shape: `'box' | 'circle'`,
|
|
73
|
-
};
|
|
74
|
-
/** Renders a `static <name>[: <type>] = <expr>;` declaration, adding an annotation where one is needed. */
|
|
75
|
-
function _static_decl(name, expr) {
|
|
76
|
-
const ann = META_TYPES[name];
|
|
77
|
-
return `static ${name}${ann ? `: ${ann}` : ''} = ${expr};`;
|
|
78
|
-
}
|
|
79
66
|
/** Canonical GMS-style order of `on_*` event methods (used to keep events ordered in code). */
|
|
80
67
|
exports.EVENT_ORDER = [
|
|
81
68
|
'on_create', 'on_destroy',
|
|
@@ -164,13 +151,14 @@ function _string_literal(node) {
|
|
|
164
151
|
return null;
|
|
165
152
|
}
|
|
166
153
|
/**
|
|
167
|
-
* Collects
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
154
|
+
* Collects the object's OWN variables: declared instance fields *plus* members created/assigned at
|
|
155
|
+
* runtime via the `inst.` namespace inside any event (e.g. `inst.velocity = 0` in on_create, read in
|
|
156
|
+
* on_step). This drives `inst.` autocomplete, so a variable made in one event surfaces in all the
|
|
157
|
+
* others. Static fields (object metadata) and method/event names are excluded. The engine's built-in
|
|
158
|
+
* instance API is NOT collected here — it lives on `sw.` and is typed from the engine directly — so
|
|
159
|
+
* `this.x`/`sw.x` style writes never leak into the author's own-variable list.
|
|
172
160
|
*/
|
|
173
|
-
function
|
|
161
|
+
function object_vars(src) {
|
|
174
162
|
const sf = _source(src);
|
|
175
163
|
const cls = _find_class(sf);
|
|
176
164
|
if (!cls)
|
|
@@ -183,14 +171,14 @@ function this_members(src) {
|
|
|
183
171
|
names.add(n);
|
|
184
172
|
}
|
|
185
173
|
}
|
|
186
|
-
// Any `
|
|
187
|
-
// blocks/closures — counts as an
|
|
174
|
+
// Any `inst.<name> = …` (or compound assignment) anywhere in the class body — including nested
|
|
175
|
+
// blocks/closures — counts as an author variable the user can reference elsewhere.
|
|
188
176
|
const visit = (node) => {
|
|
189
177
|
if (ts.isBinaryExpression(node)
|
|
190
178
|
&& node.operatorToken.kind >= ts.SyntaxKind.FirstAssignment
|
|
191
179
|
&& node.operatorToken.kind <= ts.SyntaxKind.LastAssignment
|
|
192
180
|
&& ts.isPropertyAccessExpression(node.left)
|
|
193
|
-
&& node.left.expression.
|
|
181
|
+
&& ts.isIdentifier(node.left.expression) && node.left.expression.text === 'inst'
|
|
194
182
|
&& ts.isIdentifier(node.left.name)) {
|
|
195
183
|
names.add(node.left.name.text);
|
|
196
184
|
}
|
|
@@ -239,19 +227,16 @@ function set_static(src, name, expr) {
|
|
|
239
227
|
if (!cls)
|
|
240
228
|
return src;
|
|
241
229
|
const existing = _find_member(cls, m => ts.isPropertyDeclaration(m) && _is_static(m) && _name_of(m) === name);
|
|
230
|
+
if (existing?.initializer) {
|
|
231
|
+
return _apply(src, { start: existing.initializer.getStart(sf), end: existing.initializer.getEnd(), text: expr });
|
|
232
|
+
}
|
|
242
233
|
if (existing) {
|
|
243
|
-
//
|
|
244
|
-
|
|
245
|
-
// to string and fails to compile). For plain fields, the cheaper initializer-only edit is fine.
|
|
246
|
-
if (META_TYPES[name])
|
|
247
|
-
return _apply(src, { start: existing.getStart(sf), end: existing.getEnd(), text: _static_decl(name, expr) });
|
|
248
|
-
if (existing.initializer)
|
|
249
|
-
return _apply(src, { start: existing.initializer.getStart(sf), end: existing.initializer.getEnd(), text: expr });
|
|
250
|
-
return _apply(src, { start: existing.getStart(sf), end: existing.getEnd(), text: _static_decl(name, expr) });
|
|
234
|
+
// declared without initializer — replace the whole member
|
|
235
|
+
return _apply(src, { start: existing.getStart(sf), end: existing.getEnd(), text: `static ${name} = ${expr};` });
|
|
251
236
|
}
|
|
252
237
|
// New static: metadata lives at the TOP, ordered by META_ORDER. Insert before the first static
|
|
253
238
|
// that sorts after it; else before the first non-static member (so statics stay grouped up top).
|
|
254
|
-
const stub = ` ${
|
|
239
|
+
const stub = ` static ${name} = ${expr};\n`;
|
|
255
240
|
const order = exports.META_ORDER.indexOf(name);
|
|
256
241
|
if (order >= 0) {
|
|
257
242
|
const after = cls.members.find(m => {
|
|
@@ -584,7 +569,7 @@ function scaffold_object(class_name, kind = 'normal') {
|
|
|
584
569
|
if (kind === 'physics') {
|
|
585
570
|
return `export class ${class_name} extends gm_object {
|
|
586
571
|
static physics = true;
|
|
587
|
-
static physics_shape
|
|
572
|
+
static physics_shape = 'box';
|
|
588
573
|
static physics_density = 0.5;
|
|
589
574
|
static physics_restitution = 0.1;
|
|
590
575
|
static physics_friction = 0.2;
|
package/dist/templates.js
CHANGED
|
@@ -51,6 +51,7 @@ const TEMPLATE_REGISTRY = [
|
|
|
51
51
|
{ id: 'empty', label: 'Empty', description: 'A blank project with a single empty room.' },
|
|
52
52
|
{ id: 'platformer', label: 'Platformer', description: 'A/D to move, Space to jump — gravity, solid platforms, parent-based collision.' },
|
|
53
53
|
{ id: 'topdown', label: 'Top-down', description: 'WASD movement with parent-based wall collision (place_meeting + a _col parent).' },
|
|
54
|
+
{ id: 'physics_ball', label: 'Physics Ball', description: 'Bounce a ball on a mouse paddle for score — matter.js physics (circle/box bodies, restitution, instance_nearest).' },
|
|
54
55
|
];
|
|
55
56
|
/** Absolute path to the bundled templates directory (sibling of dist/). */
|
|
56
57
|
function templates_dir() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silkweaver/build",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "Silkweaver toolchain — compiles a project folder into a runnable game (HTML5 / desktop executable). Usable from a CLI or the IDE.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"license": "GPL-3.0",
|