lpc-forge 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CREDITS.csv +22985 -0
  2. package/LICENSE +674 -0
  3. package/README.md +281 -0
  4. package/assets/music/.gitkeep +0 -0
  5. package/dist/character/batch.d.ts +17 -0
  6. package/dist/character/batch.js +48 -0
  7. package/dist/character/batch.js.map +1 -0
  8. package/dist/character/composer.d.ts +3 -0
  9. package/dist/character/composer.js +164 -0
  10. package/dist/character/composer.js.map +1 -0
  11. package/dist/character/definitions.d.ts +16 -0
  12. package/dist/character/definitions.js +116 -0
  13. package/dist/character/definitions.js.map +1 -0
  14. package/dist/character/presets.d.ts +6 -0
  15. package/dist/character/presets.js +246 -0
  16. package/dist/character/presets.js.map +1 -0
  17. package/dist/character/slicer.d.ts +8 -0
  18. package/dist/character/slicer.js +66 -0
  19. package/dist/character/slicer.js.map +1 -0
  20. package/dist/character/types.d.ts +48 -0
  21. package/dist/character/types.js +32 -0
  22. package/dist/character/types.js.map +1 -0
  23. package/dist/cli.d.ts +2 -0
  24. package/dist/cli.js +938 -0
  25. package/dist/export/frames.d.ts +5 -0
  26. package/dist/export/frames.js +15 -0
  27. package/dist/export/frames.js.map +1 -0
  28. package/dist/export/godot.d.ts +17 -0
  29. package/dist/export/godot.js +464 -0
  30. package/dist/export/godot.js.map +1 -0
  31. package/dist/export/types.d.ts +11 -0
  32. package/dist/export/types.js +2 -0
  33. package/dist/export/types.js.map +1 -0
  34. package/dist/license.d.ts +49 -0
  35. package/dist/license.js +271 -0
  36. package/dist/map/cellular.d.ts +3 -0
  37. package/dist/map/cellular.js +191 -0
  38. package/dist/map/cellular.js.map +1 -0
  39. package/dist/map/dungeon.d.ts +3 -0
  40. package/dist/map/dungeon.js +238 -0
  41. package/dist/map/dungeon.js.map +1 -0
  42. package/dist/map/multifloor.d.ts +20 -0
  43. package/dist/map/multifloor.js +57 -0
  44. package/dist/map/multifloor.js.map +1 -0
  45. package/dist/map/overworld.d.ts +3 -0
  46. package/dist/map/overworld.js +205 -0
  47. package/dist/map/overworld.js.map +1 -0
  48. package/dist/map/town.d.ts +7 -0
  49. package/dist/map/town.js +181 -0
  50. package/dist/map/town.js.map +1 -0
  51. package/dist/map/types.d.ts +65 -0
  52. package/dist/map/types.js +16 -0
  53. package/dist/map/types.js.map +1 -0
  54. package/dist/map/wfc.d.ts +18 -0
  55. package/dist/map/wfc.js +192 -0
  56. package/dist/map/wfc.js.map +1 -0
  57. package/dist/tileset/atlas.d.ts +15 -0
  58. package/dist/tileset/atlas.js +55 -0
  59. package/dist/tileset/atlas.js.map +1 -0
  60. package/dist/tileset/registry.d.ts +12 -0
  61. package/dist/tileset/registry.js +71 -0
  62. package/dist/tileset/registry.js.map +1 -0
  63. package/dist/tileset/terrain.d.ts +3 -0
  64. package/dist/tileset/terrain.js +110 -0
  65. package/dist/tileset/terrain.js.map +1 -0
  66. package/dist/utils/credits.d.ts +11 -0
  67. package/dist/utils/credits.js +74 -0
  68. package/dist/utils/credits.js.map +1 -0
  69. package/dist/utils/image.d.ts +17 -0
  70. package/dist/utils/image.js +94 -0
  71. package/dist/utils/image.js.map +1 -0
  72. package/dist/utils/rng.d.ts +18 -0
  73. package/dist/utils/rng.js +48 -0
  74. package/dist/utils/rng.js.map +1 -0
  75. package/package.json +77 -0
@@ -0,0 +1,5 @@
1
+ /** Export a spritesheet as individual frame PNGs */
2
+ export declare function exportFrames(sheetBuffer: Buffer, outputDir: string, options?: {
3
+ animations?: string[];
4
+ format?: 'png' | 'webp';
5
+ }): Promise<void>;
@@ -0,0 +1,15 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { sliceCharacter } from '../character/slicer.js';
4
+ /** Export a spritesheet as individual frame PNGs */
5
+ export async function exportFrames(sheetBuffer, outputDir, options) {
6
+ await mkdir(outputDir, { recursive: true });
7
+ // Save the full spritesheet
8
+ await writeFile(join(outputDir, 'spritesheet.png'), sheetBuffer);
9
+ // Slice into individual frames
10
+ await sliceCharacter(sheetBuffer, outputDir, {
11
+ format: options?.format ?? 'png',
12
+ animations: options?.animations,
13
+ });
14
+ }
15
+ //# sourceMappingURL=frames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frames.js","sourceRoot":"","sources":["../../src/export/frames.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,oDAAoD;AACpD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,WAAmB,EACnB,SAAiB,EACjB,OAA4D;IAE5D,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5C,4BAA4B;IAC5B,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,WAAW,CAAC,CAAC;IAEjE,+BAA+B;IAC/B,MAAM,cAAc,CAAC,WAAW,EAAE,SAAS,EAAE;QAC3C,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;QAChC,UAAU,EAAE,OAAO,EAAE,UAAU;KAChC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { GeneratedMap } from '../map/types.js';
2
+ export interface CharacterExportOptions {
3
+ animationSpeed?: number;
4
+ resPath?: string;
5
+ isPlayer?: boolean;
6
+ }
7
+ /** Export a character spritesheet as Godot 4.6 resources */
8
+ export declare function exportCharacterToGodot(sheetBuffer: Buffer, outputDir: string, characterName: string, options?: CharacterExportOptions): Promise<void>;
9
+ /** Export a generated map as Godot 4.6 TileMapLayer scene */
10
+ export declare function exportMapToGodot(map: GeneratedMap, outputDir: string, mapName: string, options?: {
11
+ tileSize?: number;
12
+ }): Promise<void>;
13
+ /** Scaffold a complete Godot 4.6 project */
14
+ export declare function scaffoldGodotProject(outputDir: string, projectName: string, options?: {
15
+ characterName?: string;
16
+ mapName?: string;
17
+ }): Promise<void>;
@@ -0,0 +1,464 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { sliceCharacter } from '../character/slicer.js';
4
+ import { ANIMATIONS, DIRECTIONS, FRAME_SIZE } from '../character/types.js';
5
+ /** Export a character spritesheet as Godot 4.6 resources */
6
+ export async function exportCharacterToGodot(sheetBuffer, outputDir, characterName, options) {
7
+ const speed = options?.animationSpeed ?? 10;
8
+ const resBase = options?.resPath ?? `res://sprites/${characterName}`;
9
+ const isPlayer = options?.isPlayer ?? true;
10
+ const spritesDir = join(outputDir, 'sprites', characterName);
11
+ await mkdir(spritesDir, { recursive: true });
12
+ // Slice into individual frames
13
+ await sliceCharacter(sheetBuffer, spritesDir);
14
+ // Save the full spritesheet too
15
+ await writeFile(join(spritesDir, 'spritesheet.png'), sheetBuffer);
16
+ // Generate .tres SpriteFrames resource
17
+ const tresContent = generateSpriteFramesTres(characterName, resBase, speed);
18
+ await writeFile(join(spritesDir, `${characterName}.tres`), tresContent);
19
+ // Generate .tscn scene with hitbox/hurtbox/timers
20
+ const tscnContent = generateCharacterTscn(characterName, resBase, isPlayer);
21
+ await writeFile(join(outputDir, `${characterName}.tscn`), tscnContent);
22
+ }
23
+ function generateSpriteFramesTres(name, resBase, speed) {
24
+ const lines = [];
25
+ const extResources = [];
26
+ let extId = 1;
27
+ const extIdMap = {};
28
+ // Collect all frame paths and assign ext_resource IDs
29
+ for (const [animName, animInfo] of Object.entries(ANIMATIONS)) {
30
+ const directions = animInfo.rows === 1 ? ['down'] : [...DIRECTIONS];
31
+ for (const dir of directions) {
32
+ for (let f = 0; f < animInfo.frames; f++) {
33
+ const path = `${resBase}/${animName}/${dir}_${f}.png`;
34
+ extIdMap[path] = extId;
35
+ extResources.push(`[ext_resource type="Texture2D" path="${path}" id="${extId}"]`);
36
+ extId++;
37
+ }
38
+ }
39
+ }
40
+ lines.push(`[gd_resource type="SpriteFrames" load_steps=${extId} format=3]`);
41
+ lines.push('');
42
+ lines.push(...extResources);
43
+ lines.push('');
44
+ lines.push('[resource]');
45
+ // Build animations array
46
+ const anims = [];
47
+ for (const [animName, animInfo] of Object.entries(ANIMATIONS)) {
48
+ const directions = animInfo.rows === 1 ? ['down'] : [...DIRECTIONS];
49
+ for (const dir of directions) {
50
+ const gdAnimName = `${animName}_${dir}`;
51
+ const frames = [];
52
+ for (let f = 0; f < animInfo.frames; f++) {
53
+ const path = `${resBase}/${animName}/${dir}_${f}.png`;
54
+ const id = extIdMap[path];
55
+ frames.push(`{
56
+ "duration": 1.0,
57
+ "texture": ExtResource("${id}")
58
+ }`);
59
+ }
60
+ const loop = animName === 'walk' || animName === 'idle' || animName === 'run' || animName === 'combat_idle';
61
+ anims.push(`{
62
+ "frames": [${frames.join(', ')}],
63
+ "loop": ${loop},
64
+ "name": &"${gdAnimName}",
65
+ "speed": ${speed}.0
66
+ }`);
67
+ }
68
+ }
69
+ lines.push(`animations = [${anims.join(', ')}]`);
70
+ return lines.join('\n');
71
+ }
72
+ function generateCharacterTscn(name, resBase, isPlayer) {
73
+ const loadSteps = isPlayer ? 6 : 4;
74
+ const lines = [];
75
+ lines.push(`[gd_scene load_steps=${loadSteps} format=3]`);
76
+ lines.push('');
77
+ lines.push(`[ext_resource type="SpriteFrames" path="${resBase}/${name}.tres" id="1"]`);
78
+ if (isPlayer) {
79
+ lines.push(`[ext_resource type="Script" path="res://scripts/player.gd" id="2"]`);
80
+ }
81
+ lines.push('');
82
+ // CollisionShape2D for body
83
+ lines.push(`[sub_resource type="RectangleShape2D" id="1"]`);
84
+ lines.push(`size = Vector2(${FRAME_SIZE / 2}, ${FRAME_SIZE / 2})`);
85
+ lines.push('');
86
+ // Hitbox shape
87
+ lines.push(`[sub_resource type="RectangleShape2D" id="2"]`);
88
+ lines.push(`size = Vector2(${FRAME_SIZE / 2}, ${FRAME_SIZE / 2})`);
89
+ lines.push('');
90
+ // Hurtbox shape
91
+ lines.push(`[sub_resource type="RectangleShape2D" id="3"]`);
92
+ lines.push(`size = Vector2(24, 32)`);
93
+ lines.push('');
94
+ // Root node
95
+ lines.push(`[node name="${capitalize(name)}" type="CharacterBody2D"]`);
96
+ if (isPlayer) {
97
+ lines.push(`script = ExtResource("2")`);
98
+ }
99
+ lines.push('');
100
+ // Sprite
101
+ lines.push(`[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]`);
102
+ lines.push(`sprite_frames = ExtResource("1")`);
103
+ lines.push(`animation = &"idle_down"`);
104
+ lines.push(`autoplay = "idle_down"`);
105
+ lines.push(`offset = Vector2(0, -16)`);
106
+ lines.push('');
107
+ // Body collision
108
+ lines.push(`[node name="CollisionShape2D" type="CollisionShape2D" parent="."]`);
109
+ lines.push(`shape = SubResource("1")`);
110
+ lines.push(`position = Vector2(0, 8)`);
111
+ lines.push('');
112
+ // Hitbox Area2D
113
+ lines.push(`[node name="Hitbox" type="Area2D" parent="."]`);
114
+ lines.push(`collision_layer = 2`);
115
+ lines.push(`collision_mask = 0`);
116
+ lines.push(`monitorable = true`);
117
+ lines.push(`monitoring = false`);
118
+ lines.push('');
119
+ lines.push(`[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"]`);
120
+ lines.push(`shape = SubResource("2")`);
121
+ lines.push(`position = Vector2(16, 0)`);
122
+ lines.push(`disabled = true`);
123
+ lines.push('');
124
+ // Hurtbox Area2D
125
+ lines.push(`[node name="Hurtbox" type="Area2D" parent="."]`);
126
+ lines.push(`collision_layer = 0`);
127
+ lines.push(`collision_mask = 2`);
128
+ lines.push(`monitorable = false`);
129
+ lines.push(`monitoring = true`);
130
+ lines.push('');
131
+ lines.push(`[node name="CollisionShape2D" type="CollisionShape2D" parent="Hurtbox"]`);
132
+ lines.push(`shape = SubResource("3")`);
133
+ lines.push('');
134
+ // Timers
135
+ lines.push(`[node name="AttackTimer" type="Timer" parent="."]`);
136
+ lines.push(`wait_time = 0.4`);
137
+ lines.push(`one_shot = true`);
138
+ lines.push('');
139
+ lines.push(`[node name="HurtTimer" type="Timer" parent="."]`);
140
+ lines.push(`wait_time = 0.5`);
141
+ lines.push(`one_shot = true`);
142
+ lines.push('');
143
+ return lines.join('\n');
144
+ }
145
+ /** Export a generated map as Godot 4.6 TileMapLayer scene */
146
+ export async function exportMapToGodot(map, outputDir, mapName, options) {
147
+ const tileSize = options?.tileSize ?? 32;
148
+ await mkdir(outputDir, { recursive: true });
149
+ // Generate tileset .tres
150
+ const tilesetContent = generateTilesetTres(tileSize);
151
+ await writeFile(join(outputDir, `${mapName}_tileset.tres`), tilesetContent);
152
+ // Generate map .tscn
153
+ const tscnContent = generateMapTscn(map, mapName, tileSize);
154
+ await writeFile(join(outputDir, `${mapName}.tscn`), tscnContent);
155
+ }
156
+ function generateTilesetTres(tileSize) {
157
+ const lines = [`[gd_resource type="TileSet" format=3]`, '', `[resource]`];
158
+ lines.push(`tile_size = Vector2i(${tileSize}, ${tileSize})`);
159
+ return lines.join('\n');
160
+ }
161
+ function generateMapTscn(map, mapName, tileSize) {
162
+ const lines = [];
163
+ // Count sub resources needed: 1 for tileset ref + 1 collision shape per wall group
164
+ lines.push(`[gd_scene load_steps=2 format=3]`);
165
+ lines.push('');
166
+ lines.push(`[ext_resource type="TileSet" path="res://${mapName}_tileset.tres" id="1"]`);
167
+ lines.push('');
168
+ // Collision shape for walls
169
+ lines.push(`[sub_resource type="RectangleShape2D" id="1"]`);
170
+ lines.push(`size = Vector2(${tileSize}, ${tileSize})`);
171
+ lines.push('');
172
+ lines.push(`[node name="${capitalize(mapName)}" type="Node2D"]`);
173
+ lines.push('');
174
+ // Ground TileMapLayer
175
+ lines.push(`[node name="Ground" type="TileMapLayer" parent="."]`);
176
+ lines.push(`tile_set = ExtResource("1")`);
177
+ lines.push('');
178
+ // Wall collision StaticBody2D with individual CollisionShape2Ds
179
+ lines.push(`[node name="Walls" type="StaticBody2D" parent="."]`);
180
+ lines.push(`collision_layer = 1`);
181
+ lines.push(`collision_mask = 0`);
182
+ lines.push('');
183
+ let wallIdx = 0;
184
+ for (let y = 0; y < map.height; y++) {
185
+ for (let x = 0; x < map.width; x++) {
186
+ const t = map.tiles[y][x];
187
+ // TileType.WALL = 2, TileType.TREE = 7
188
+ if (t === 2 || t === 7) {
189
+ lines.push(`[node name="Wall${wallIdx}" type="CollisionShape2D" parent="Walls"]`);
190
+ lines.push(`position = Vector2(${x * tileSize + tileSize / 2}, ${y * tileSize + tileSize / 2})`);
191
+ lines.push(`shape = SubResource("1")`);
192
+ lines.push('');
193
+ wallIdx++;
194
+ }
195
+ }
196
+ }
197
+ // Spawn and exit markers
198
+ if (map.spawnPoint) {
199
+ lines.push(`[node name="SpawnPoint" type="Marker2D" parent="."]`);
200
+ lines.push(`position = Vector2(${map.spawnPoint.x * tileSize + tileSize / 2}, ${map.spawnPoint.y * tileSize + tileSize / 2})`);
201
+ lines.push('');
202
+ }
203
+ if (map.exitPoint) {
204
+ lines.push(`[node name="ExitPoint" type="Marker2D" parent="."]`);
205
+ lines.push(`position = Vector2(${map.exitPoint.x * tileSize + tileSize / 2}, ${map.exitPoint.y * tileSize + tileSize / 2})`);
206
+ lines.push('');
207
+ }
208
+ // POI markers
209
+ if (map.pois) {
210
+ for (let i = 0; i < map.pois.length; i++) {
211
+ const poi = map.pois[i];
212
+ const nodeName = `POI_${poi.type}_${i}`;
213
+ lines.push(`[node name="${nodeName}" type="Marker2D" parent="."]`);
214
+ lines.push(`position = Vector2(${poi.x * tileSize + tileSize / 2}, ${poi.y * tileSize + tileSize / 2})`);
215
+ const meta = { poi_type: poi.type };
216
+ if (poi.label)
217
+ meta['poi_label'] = poi.label;
218
+ lines.push(`metadata/poi_type = "${poi.type}"`);
219
+ if (poi.label)
220
+ lines.push(`metadata/poi_label = "${poi.label}"`);
221
+ lines.push('');
222
+ }
223
+ }
224
+ return lines.join('\n');
225
+ }
226
+ /** Scaffold a complete Godot 4.6 project */
227
+ export async function scaffoldGodotProject(outputDir, projectName, options) {
228
+ const charName = options?.characterName ?? 'player';
229
+ const mapName = options?.mapName ?? 'dungeon';
230
+ await mkdir(outputDir, { recursive: true });
231
+ // project.godot
232
+ const projectGodot = `; Engine configuration file.
233
+ ; It's best edited using the editor UI and not directly,
234
+ ; but it can also be edited because it's a plain text file.
235
+
236
+ config_version=5
237
+
238
+ [application]
239
+
240
+ config/name="${projectName}"
241
+ config/features=PackedStringArray("4.6")
242
+ run/main_scene="res://main.tscn"
243
+ config/icon="res://icon.svg"
244
+
245
+ [display]
246
+
247
+ window/size/viewport_width=1280
248
+ window/size/viewport_height=720
249
+ window/stretch/mode="canvas_items"
250
+
251
+ [input]
252
+
253
+ move_up={
254
+ "deadzone": 0.5,
255
+ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":87,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)]
256
+ }
257
+ move_down={
258
+ "deadzone": 0.5,
259
+ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)]
260
+ }
261
+ move_left={
262
+ "deadzone": 0.5,
263
+ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":65,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)]
264
+ }
265
+ move_right={
266
+ "deadzone": 0.5,
267
+ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":68,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)]
268
+ }
269
+ attack={
270
+ "deadzone": 0.5,
271
+ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)]
272
+ }
273
+
274
+ [rendering]
275
+
276
+ textures/canvas_textures/default_texture_filter=0
277
+ `;
278
+ await writeFile(join(outputDir, 'project.godot'), projectGodot);
279
+ // Main scene — instances map + player at spawn, adds Camera2D and HUD
280
+ const mainTscn = `[gd_scene load_steps=4 format=3]
281
+
282
+ [ext_resource type="PackedScene" path="res://${charName}.tscn" id="1"]
283
+ [ext_resource type="PackedScene" path="res://${mapName}.tscn" id="2"]
284
+ [ext_resource type="Script" path="res://scripts/hud.gd" id="3"]
285
+
286
+ [node name="Main" type="Node2D"]
287
+
288
+ [node name="Map" parent="." instance=ExtResource("2")]
289
+
290
+ [node name="Player" parent="." instance=ExtResource("1")]
291
+ position = Vector2(400, 400)
292
+
293
+ [node name="Camera2D" type="Camera2D" parent="Player"]
294
+ zoom = Vector2(2, 2)
295
+
296
+ [node name="HUD" type="CanvasLayer" parent="."]
297
+
298
+ [node name="HUDControl" type="Control" parent="HUD"]
299
+ layout_mode = 3
300
+ anchors_preset = 15
301
+ anchor_right = 1.0
302
+ anchor_bottom = 1.0
303
+ script = ExtResource("3")
304
+
305
+ [node name="HealthBar" type="ProgressBar" parent="HUD/HUDControl"]
306
+ layout_mode = 1
307
+ offset_left = 16.0
308
+ offset_top = 16.0
309
+ offset_right = 216.0
310
+ offset_bottom = 32.0
311
+ value = 100.0
312
+ show_percentage = false
313
+ `;
314
+ await writeFile(join(outputDir, 'main.tscn'), mainTscn);
315
+ // Scripts directory
316
+ const scriptsDir = join(outputDir, 'scripts');
317
+ await mkdir(scriptsDir, { recursive: true });
318
+ // State machine player script
319
+ const playerGd = `extends CharacterBody2D
320
+
321
+ signal health_changed(new_health: int, max_health: int)
322
+ signal died
323
+
324
+ enum State { IDLE, WALK, ATTACK, HURT, DEATH }
325
+
326
+ const SPEED := 200.0
327
+ const MAX_HEALTH := 100
328
+
329
+ @onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
330
+ @onready var attack_timer: Timer = $AttackTimer
331
+ @onready var hurt_timer: Timer = $HurtTimer
332
+ @onready var hitbox: Area2D = $Hitbox
333
+
334
+ var state: State = State.IDLE
335
+ var direction := "down"
336
+ var health: int = MAX_HEALTH
337
+
338
+ func _ready() -> void:
339
+ \tattack_timer.timeout.connect(_on_attack_finished)
340
+ \thurt_timer.timeout.connect(_on_hurt_finished)
341
+ \thealth_changed.emit(health, MAX_HEALTH)
342
+
343
+ func _physics_process(_delta: float) -> void:
344
+ \tmatch state:
345
+ \t\tState.IDLE:
346
+ \t\t\t_process_idle()
347
+ \t\tState.WALK:
348
+ \t\t\t_process_walk()
349
+ \t\tState.ATTACK:
350
+ \t\t\tpass
351
+ \t\tState.HURT:
352
+ \t\t\tpass
353
+ \t\tState.DEATH:
354
+ \t\t\tpass
355
+
356
+ func _process_idle() -> void:
357
+ \tvar input_dir := _get_input()
358
+ \tif input_dir != Vector2.ZERO:
359
+ \t\t_set_direction(input_dir)
360
+ \t\t_change_state(State.WALK)
361
+ \t\treturn
362
+ \tif Input.is_action_just_pressed("attack"):
363
+ \t\t_change_state(State.ATTACK)
364
+ \t\treturn
365
+ \tsprite.play("idle_" + direction)
366
+
367
+ func _process_walk() -> void:
368
+ \tvar input_dir := _get_input()
369
+ \tif input_dir == Vector2.ZERO:
370
+ \t\t_change_state(State.IDLE)
371
+ \t\treturn
372
+ \tif Input.is_action_just_pressed("attack"):
373
+ \t\t_change_state(State.ATTACK)
374
+ \t\treturn
375
+ \t_set_direction(input_dir)
376
+ \tvelocity = input_dir * SPEED
377
+ \tsprite.play("walk_" + direction)
378
+ \tmove_and_slide()
379
+
380
+ func _change_state(new_state: State) -> void:
381
+ \tstate = new_state
382
+ \tmatch new_state:
383
+ \t\tState.ATTACK:
384
+ \t\t\tvelocity = Vector2.ZERO
385
+ \t\t\tvar anim := "slash_" + direction
386
+ \t\t\tif sprite.sprite_frames.has_animation(anim):
387
+ \t\t\t\tsprite.play(anim)
388
+ \t\t\thitbox.get_child(0).disabled = false
389
+ \t\t\tattack_timer.start()
390
+ \t\tState.HURT:
391
+ \t\t\tvelocity = Vector2.ZERO
392
+ \t\t\tvar anim := "hurt"
393
+ \t\t\tif sprite.sprite_frames.has_animation("hurt_down"):
394
+ \t\t\t\tanim = "hurt_down"
395
+ \t\t\tsprite.play(anim)
396
+ \t\t\thurt_timer.start()
397
+ \t\tState.DEATH:
398
+ \t\t\tvelocity = Vector2.ZERO
399
+ \t\t\tset_physics_process(false)
400
+ \t\t\tdied.emit()
401
+ \t\t_:
402
+ \t\t\tpass
403
+
404
+ func take_damage(amount: int) -> void:
405
+ \tif state == State.DEATH or state == State.HURT:
406
+ \t\treturn
407
+ \thealth = max(0, health - amount)
408
+ \thealth_changed.emit(health, MAX_HEALTH)
409
+ \tif health <= 0:
410
+ \t\t_change_state(State.DEATH)
411
+ \telse:
412
+ \t\t_change_state(State.HURT)
413
+
414
+ func _on_attack_finished() -> void:
415
+ \thitbox.get_child(0).disabled = true
416
+ \t_change_state(State.IDLE)
417
+
418
+ func _on_hurt_finished() -> void:
419
+ \t_change_state(State.IDLE)
420
+
421
+ func _get_input() -> Vector2:
422
+ \treturn Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
423
+
424
+ func _set_direction(input_dir: Vector2) -> void:
425
+ \tif abs(input_dir.x) > abs(input_dir.y):
426
+ \t\tdirection = "right" if input_dir.x > 0 else "left"
427
+ \telse:
428
+ \t\tdirection = "down" if input_dir.y > 0 else "up"
429
+ `;
430
+ await writeFile(join(scriptsDir, 'player.gd'), playerGd);
431
+ // HUD script
432
+ const hudGd = `extends Control
433
+
434
+ @onready var health_bar: ProgressBar = $HealthBar
435
+
436
+ func _ready() -> void:
437
+ \tvar player := _find_player()
438
+ \tif player:
439
+ \t\tplayer.health_changed.connect(_on_health_changed)
440
+
441
+ func _on_health_changed(new_health: int, max_health: int) -> void:
442
+ \thealth_bar.max_value = max_health
443
+ \thealth_bar.value = new_health
444
+
445
+ func _find_player() -> CharacterBody2D:
446
+ \tvar parent := get_tree().current_scene
447
+ \tif parent:
448
+ \t\tvar player := parent.find_child("Player", true, false)
449
+ \t\tif player is CharacterBody2D:
450
+ \t\t\treturn player as CharacterBody2D
451
+ \treturn null
452
+ `;
453
+ await writeFile(join(scriptsDir, 'hud.gd'), hudGd);
454
+ // Simple SVG icon
455
+ const iconSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128">
456
+ <rect width="128" height="128" rx="16" fill="#478cbf"/>
457
+ <text x="64" y="80" text-anchor="middle" font-size="48" fill="white" font-family="sans-serif">LPC</text>
458
+ </svg>`;
459
+ await writeFile(join(outputDir, 'icon.svg'), iconSvg);
460
+ }
461
+ function capitalize(s) {
462
+ return s.charAt(0).toUpperCase() + s.slice(1);
463
+ }
464
+ //# sourceMappingURL=godot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"godot.js","sourceRoot":"","sources":["../../src/export/godot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface GodotExportOptions {
2
+ characterName: string;
3
+ outputDir: string;
4
+ resPath?: string;
5
+ animationSpeed?: number;
6
+ }
7
+ export interface TilesetExportOptions {
8
+ mapName: string;
9
+ outputDir: string;
10
+ tileSize?: number;
11
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/export/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ export interface LicenseInfo {
2
+ /** The license key from Gumroad */
3
+ key: string;
4
+ /** Email from purchase */
5
+ email: string;
6
+ /** Product identifier */
7
+ product: string;
8
+ /** ISO timestamp of activation */
9
+ activatedAt: string;
10
+ /** ISO timestamp of last successful verification */
11
+ lastVerifiedAt: string;
12
+ /** Machine fingerprint at activation time */
13
+ machineId: string;
14
+ /** HMAC signature of the license data */
15
+ signature: string;
16
+ }
17
+ /**
18
+ * Check if a valid premium license exists.
19
+ *
20
+ * Validates:
21
+ * 1. File exists and parses
22
+ * 2. HMAC signature is correct (not tampered)
23
+ * 3. Machine fingerprint matches (not copied from another machine)
24
+ * 4. Key format is valid
25
+ * 5. Activation is not absurdly far in the future
26
+ *
27
+ * Periodic re-validation:
28
+ * - If last online verification was > 30 days ago, attempts re-verify
29
+ * - If re-verify fails due to network, still valid (grace period)
30
+ * - If re-verify fails due to invalid key, invalidates
31
+ */
32
+ export declare function hasValidLicense(): Promise<boolean>;
33
+ /** Require a valid license or exit with purchase instructions */
34
+ export declare function requireLicense(commandName: string): Promise<void>;
35
+ /** Get stored license info (for display only) */
36
+ export declare function getLicenseInfo(): Promise<{
37
+ key: string;
38
+ email: string;
39
+ activatedAt: string;
40
+ lastVerifiedAt: string;
41
+ valid: boolean;
42
+ } | null>;
43
+ /** Activate a license key */
44
+ export declare function activateLicense(licenseKey: string): Promise<{
45
+ success: boolean;
46
+ message: string;
47
+ }>;
48
+ /** Deactivate the stored license */
49
+ export declare function deactivateLicense(): Promise<void>;