game-data-gen 1.2.1 → 2.1.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.
package/README.md CHANGED
@@ -34,7 +34,7 @@ npx game-data-gen <input-file-path> <optional-output-file-path>
34
34
  ## Format
35
35
 
36
36
  ```
37
- name type? length?
37
+ name type? length? struct?
38
38
  fieldName fieldType fieldArrayType? fieldArrayLength?
39
39
  ```
40
40
 
@@ -42,13 +42,14 @@ fieldName fieldType fieldArrayType? fieldArrayLength?
42
42
 
43
43
  The name of the data structure.
44
44
 
45
- `type` (optional)
45
+ `type`
46
46
 
47
47
  Supported data structure types:
48
48
 
49
+ - group
50
+ - struct
49
51
  - soa (Structure of Arrays)
50
-
51
- If no type is given, it will act as a group which gets a zero function for the whole group.
52
+ - aos (Array of Structures)
52
53
 
53
54
  `length` (optional)
54
55
 
@@ -56,6 +57,10 @@ The length of the arrays within the Structure of Arrays data structure.
56
57
 
57
58
  If no length is given to the type and no length is given to a field it is considered a dynamic array and zeroing will set the array's length back to zero (emptying it).
58
59
 
60
+ `struct` (optional, required if type=aos)
61
+
62
+ The struct to use for this Array of Structures.
63
+
59
64
  `fieldName`
60
65
 
61
66
  The name of one of the fields within the data structure.
@@ -64,30 +69,27 @@ The name of one of the fields within the data structure.
64
69
 
65
70
  Supported field types:
66
71
 
72
+ - string
73
+ - number
74
+ - boolean
67
75
  - array
76
+ - a struct (see entity struct in example below)
68
77
 
69
- `fieldArrayType` (optional, required if fieldType=array)
78
+ `fieldArrayType` (required if fieldType=array)
70
79
 
71
80
  Supported array field types:
72
81
 
73
82
  - string
74
83
  - boolean
75
84
  - number
76
- - int8
77
- - int16
78
- - int32
79
- - uint8
80
- - uint16
81
- - uint32
82
- - float32
83
- - float64
84
85
 
85
86
  `fieldArrayLength` (optional)
86
87
 
87
- The length of the array field.
88
+ The length of the array field, leave empty to use a dynamically sized array instead of a fixed size array.
88
89
 
89
90
  In case of a Structure of Arrays data structure (type=soa), setting the length on the type instead is recommended so that all arrays have the same length.
90
91
 
92
+
91
93
  ## Example
92
94
 
93
95
  Create a plain text file somewhere in your source code (without a file extension).
@@ -95,13 +97,24 @@ Create a plain text file somewhere in your source code (without a file extension
95
97
  For example `src/data/game`:
96
98
 
97
99
  ```
98
- Game
100
+ game group
99
101
  activeEntities array number
100
102
 
101
- Entity soa 2048
102
- posX array float32
103
- posY array float32
104
- isActive array uint8
103
+ vector struct
104
+ x number
105
+ y number
106
+
107
+ entity struct
108
+ position vector
109
+ velocity vector
110
+ health number
111
+ isActive boolean
112
+
113
+ entities aos 2048 entity
114
+
115
+ particle soa 1024
116
+ posX array number
117
+ posY array number
105
118
  ```
106
119
 
107
120
  Run the package with (consider making this a script in your package.json):
@@ -110,67 +123,134 @@ Run the package with (consider making this a script in your package.json):
110
123
  npx game-data-gen src/data/game
111
124
  ```
112
125
 
113
- This will create or update the `src/data/game.ts` file:
126
+ This will create or update the `src/data/game.ts` file (see below). The data and functions can then be imported from this file into your code.
114
127
 
115
128
  ```typescript
116
129
  /*
117
130
  * --------------------------------------------------
118
- * Game (group)
131
+ * game (group)
119
132
  * --------------------------------------------------
120
133
  */
121
134
 
122
- export const activeEntities = new Array<number>();
135
+ export const activeEntities = new Array<number>()
123
136
 
124
- /** Zero the activeEntities field within the Game group. */
137
+ /** Zero the activeEntities field within the game group. */
125
138
  export function zeroActiveEntities() {
126
- activeEntities.length = 0;
139
+ activeEntities.length = 0
127
140
  }
128
141
 
129
- /** Zero all fields within the Game group. */
142
+ /** Zero all fields within the game group. */
130
143
  export function zeroGameData() {
131
- activeEntities.length = 0;
144
+ activeEntities.length = 0
132
145
  }
133
146
 
134
147
  /*
135
148
  * --------------------------------------------------
136
- * Entity (Structure of Arrays)
149
+ * vector (struct)
137
150
  * --------------------------------------------------
138
151
  */
139
152
 
140
- export const MAX_ENTITY_COUNT = 2048;
153
+ export type Vector = {
154
+ x: number
155
+ y: number
156
+ }
141
157
 
142
- export const posX = new Float32Array(2048);
143
- export const posY = new Float32Array(2048);
144
- export const isActive = new Uint8Array(2048);
158
+ /** Create a new Vector object. */
159
+ export function createVector(): Vector {
160
+ const obj = Object.create(null)
161
+ obj.x = 0
162
+ obj.y = 0
163
+ return obj
164
+ }
145
165
 
146
- /** Zero an index within the Entity Structure of Arrays. */
147
- export function zeroEntity(idx: number) {
148
- posX[idx] = 0;
149
- posY[idx] = 0;
150
- isActive[idx] = 0;
166
+ /** Zero the given Vector object. */
167
+ export function zeroVector(obj: Vector) {
168
+ obj.x = 0
169
+ obj.y = 0
151
170
  }
152
171
 
153
- /** Zero the posX field within the Entity Structure of Arrays. */
154
- export function zeroPosX() {
155
- posX.fill(0);
172
+ /*
173
+ * --------------------------------------------------
174
+ * entity (struct)
175
+ * --------------------------------------------------
176
+ */
177
+
178
+ export type Entity = {
179
+ position: Vector
180
+ velocity: Vector
181
+ health: number
182
+ isActive: boolean
156
183
  }
157
184
 
158
- /** Zero the posY field within the Entity Structure of Arrays. */
159
- export function zeroPosY() {
160
- posY.fill(0);
185
+ /** Create a new Entity object. */
186
+ export function createEntity(): Entity {
187
+ const obj = Object.create(null)
188
+ obj.position = createVector()
189
+ obj.velocity = createVector()
190
+ obj.health = 0
191
+ obj.isActive = false
192
+ return obj
161
193
  }
162
194
 
163
- /** Zero the isActive field within the Entity Structure of Arrays. */
164
- export function zeroIsActive() {
165
- isActive.fill(0);
195
+ /** Zero the given Entity object. */
196
+ export function zeroEntity(obj: Entity) {
197
+ zeroVector(obj.position)
198
+ zeroVector(obj.velocity)
199
+ obj.health = 0
200
+ obj.isActive = false
166
201
  }
167
202
 
168
- /** Zero all fields within the Entity Structure of Arrays. */
169
- export function zeroEntityData() {
170
- posX.fill(0);
171
- posY.fill(0);
172
- isActive.fill(0);
203
+ /*
204
+ * --------------------------------------------------
205
+ * entities (array of structures)
206
+ * --------------------------------------------------
207
+ */
208
+
209
+ export const MAX_ENTITIES_COUNT = 2048
210
+
211
+ /** An array of Entity objects (structures). */
212
+ export const entities = new Array<Entity>(2048)
213
+ for (let i=0; i<2048; i++) {
214
+ entities[i] = createEntity()
173
215
  }
174
- ```
175
216
 
176
- Then import the data and its functions from `src/data/game.ts` in your code.
217
+ /** Zero all objects within the entities array of structures. */
218
+ export function zeroEntities() {
219
+ for (let i=0; i<2048; i++) {
220
+ zeroEntity(entities[i])
221
+ }
222
+ }
223
+
224
+ /*
225
+ * --------------------------------------------------
226
+ * particle (structure of arrays)
227
+ * --------------------------------------------------
228
+ */
229
+
230
+ export const MAX_PARTICLE_COUNT = 1024
231
+
232
+ export const posX = new Array<number>(1024).fill(0)
233
+ export const posY = new Array<number>(1024).fill(0)
234
+
235
+ /** Zero an index within the particle structure of arrays. */
236
+ export function zeroParticle(idx: number) {
237
+ posX[idx] = 0
238
+ posY[idx] = 0
239
+ }
240
+
241
+ /** Zero the posX field within the particle structure of arrays. */
242
+ export function zeroPosX() {
243
+ posX.fill(0)
244
+ }
245
+
246
+ /** Zero the posY field within the particle structure of arrays. */
247
+ export function zeroPosY() {
248
+ posY.fill(0)
249
+ }
250
+
251
+ /** Zero all fields within the particle structure of arrays. */
252
+ export function zeroParticleData() {
253
+ posX.fill(0)
254
+ posY.fill(0)
255
+ }
256
+ ```
package/dist/consts.js ADDED
@@ -0,0 +1,21 @@
1
+ export var Type;
2
+ (function (Type) {
3
+ Type["SOA"] = "soa";
4
+ Type["AOS"] = "aos";
5
+ Type["STRUCT"] = "struct";
6
+ Type["GROUP"] = "group";
7
+ })(Type || (Type = {}));
8
+ export var FieldType;
9
+ (function (FieldType) {
10
+ FieldType["STRING"] = "string";
11
+ FieldType["NUMBER"] = "number";
12
+ FieldType["BOOLEAN"] = "boolean";
13
+ FieldType["ARRAY"] = "array";
14
+ FieldType["SET"] = "set";
15
+ })(FieldType || (FieldType = {}));
16
+ export var ArrayType;
17
+ (function (ArrayType) {
18
+ ArrayType["STRING"] = "string";
19
+ ArrayType["NUMBER"] = "number";
20
+ ArrayType["BOOLEAN"] = "boolean";
21
+ })(ArrayType || (ArrayType = {}));
@@ -0,0 +1,32 @@
1
+ import { addFieldMaxLengthConstant } from "./fields.js";
2
+ import { capitalize, getName } from "./utils.js";
3
+ export function addArrayOfStructures(header, output) {
4
+ const [name, , length, struct] = header.split(" ");
5
+ addFieldMaxLengthConstant(name, length, output);
6
+ addArrayOfStructuresDefinition(name, struct, length, output);
7
+ addArrayOfStructuresZeroFunction(name, struct, length, output);
8
+ addArrayOfStructuresZeroAtIndexFunction(name, struct, output);
9
+ }
10
+ function addArrayOfStructuresDefinition(name, struct, length, output) {
11
+ output.push(`/** An array of ${capitalize(struct)} objects (structures). */`);
12
+ output.push(`export const ${name} = new Array<${getName(struct)}>(${length})`);
13
+ output.push(`for (let i=0; i<${length}; i++) {`);
14
+ output.push(` ${name}[i] = create${capitalize(struct)}()`);
15
+ output.push("}");
16
+ }
17
+ function addArrayOfStructuresZeroFunction(name, struct, length, output) {
18
+ output.push("");
19
+ output.push(`/** Zero all objects within the ${name} array of structures. */`);
20
+ output.push(`export function zero${capitalize(name)}() {`);
21
+ output.push(` for (let i=0; i<${length}; i++) {`);
22
+ output.push(` zero${capitalize(struct)}(${name}[i])`);
23
+ output.push(" }");
24
+ output.push("}");
25
+ }
26
+ function addArrayOfStructuresZeroAtIndexFunction(name, struct, output) {
27
+ output.push("");
28
+ output.push(`/** Zero an object at a specific index within the ${name} array of structures. */`);
29
+ output.push(`export function zero${capitalize(struct)}At(index: number) {`);
30
+ output.push(` zero${capitalize(struct)}(${name}[index])`);
31
+ output.push("}");
32
+ }
@@ -0,0 +1,102 @@
1
+ import { ArrayType, FieldType } from "../consts.js";
2
+ import { capitalize, getName } from "./utils.js";
3
+ export function addFieldDefinition(field, baseLength, output) {
4
+ const [fieldName, fieldType, fieldArrayType, fieldLength] = field.split(" ");
5
+ const fieldArrayLength = baseLength || fieldLength || "";
6
+ switch (fieldType) {
7
+ case FieldType.STRING:
8
+ output.push(`export let ${fieldName} = ""`);
9
+ break;
10
+ case FieldType.NUMBER:
11
+ output.push(`export let ${fieldName} = 0`);
12
+ break;
13
+ case FieldType.BOOLEAN:
14
+ output.push(`export let ${fieldName} = false`);
15
+ break;
16
+ case FieldType.ARRAY:
17
+ {
18
+ switch (fieldArrayType) {
19
+ case ArrayType.STRING:
20
+ output.push(`export let ${fieldName} = new Array<string>(${fieldArrayLength})${fieldArrayLength ? '.fill("")' : ""}`);
21
+ break;
22
+ case ArrayType.NUMBER:
23
+ output.push(`export let ${fieldName} = new Array<number>(${fieldArrayLength})${fieldArrayLength ? ".fill(0)" : ""}`);
24
+ break;
25
+ case ArrayType.BOOLEAN:
26
+ output.push(`export let ${fieldName} = new Array<boolean>(${fieldArrayLength})${fieldArrayLength ? ".fill(false)" : ""}`);
27
+ break;
28
+ }
29
+ }
30
+ break;
31
+ case FieldType.SET:
32
+ output.push(`export let ${fieldName} = new Set<${getName(fieldArrayType)}>()`);
33
+ break;
34
+ default:
35
+ output.push(`export let ${fieldName} = create${capitalize(fieldType)}()`);
36
+ }
37
+ }
38
+ export function addFieldSetFunction(name, type, field, output) {
39
+ const [fieldName, fieldType, fieldArrayType] = field.split(" ");
40
+ output.push("");
41
+ output.push(`/** Set the value of the ${fieldName} field within the ${name} ${getName(type)}. */`);
42
+ output.push(`export function set${capitalize(fieldName)}(value: ${getName(fieldType, fieldArrayType)}) {`);
43
+ output.push(` ${fieldName} = value`);
44
+ output.push("}");
45
+ }
46
+ export function addFieldZeroFunction(name, type, field, baseLength, output) {
47
+ const [fieldName, fieldType, fieldArrayType, fieldLength] = field.split(" ");
48
+ const length = baseLength || fieldLength || "";
49
+ output.push("");
50
+ output.push(`/** Zero the ${fieldName} field within the ${name} ${getName(type)}. */`);
51
+ output.push(`export function zero${capitalize(fieldName)}() {`);
52
+ zeroField(fieldName, fieldType, fieldArrayType, length, output);
53
+ output.push("}");
54
+ }
55
+ export function addZeroFunction(name, type, fields, baseLength, output) {
56
+ output.push("");
57
+ output.push(`/** Zero all fields within the ${name} ${getName(type)}. */`);
58
+ output.push(`export function zero${capitalize(name)}Data() {`);
59
+ for (const field of fields) {
60
+ const [fieldName, fieldType, fieldArrayType, fieldLength] = field.split(" ");
61
+ const length = baseLength || fieldLength || "";
62
+ zeroField(fieldName, fieldType, fieldArrayType, length, output);
63
+ }
64
+ output.push("}");
65
+ }
66
+ function zeroField(name, type, arrayType, length, output) {
67
+ switch (type) {
68
+ case FieldType.STRING:
69
+ output.push(` ${name} = ""`);
70
+ break;
71
+ case FieldType.NUMBER:
72
+ output.push(` ${name} = 0`);
73
+ break;
74
+ case FieldType.BOOLEAN:
75
+ output.push(` ${name} = false`);
76
+ break;
77
+ case FieldType.ARRAY:
78
+ {
79
+ switch (arrayType) {
80
+ case ArrayType.STRING:
81
+ output.push(` ${name}.${length ? 'fill("")' : "length = 0"}`);
82
+ break;
83
+ case ArrayType.NUMBER:
84
+ output.push(` ${name}.${length ? "fill(0)" : "length = 0"}`);
85
+ break;
86
+ case ArrayType.BOOLEAN:
87
+ output.push(` ${name}.${length ? "fill(false)" : "length = 0"}`);
88
+ break;
89
+ }
90
+ }
91
+ break;
92
+ case FieldType.SET:
93
+ output.push(` ${name}.clear()`);
94
+ break;
95
+ default:
96
+ output.push(` zero${capitalize(type)}(${name})`);
97
+ }
98
+ }
99
+ export function addFieldMaxLengthConstant(name, length, output) {
100
+ output.push(`export const MAX_${name.toUpperCase()}_COUNT = ${length}`);
101
+ output.push("");
102
+ }
@@ -0,0 +1,14 @@
1
+ import { addFieldDefinition, addFieldSetFunction, addFieldZeroFunction, addZeroFunction } from "./fields.js";
2
+ export function addGroup(header, fields, output) {
3
+ const [name, type, baseLength] = header.split(" ");
4
+ for (const field of fields) {
5
+ addFieldDefinition(field, baseLength, output);
6
+ }
7
+ for (const field of fields) {
8
+ addFieldSetFunction(name, type, field, output);
9
+ }
10
+ for (const field of fields) {
11
+ addFieldZeroFunction(name, type, field, baseLength, output);
12
+ }
13
+ addZeroFunction(name, type, fields, baseLength, output);
14
+ }
@@ -0,0 +1,38 @@
1
+ import { ArrayType } from "../consts.js";
2
+ import { addFieldDefinition, addFieldMaxLengthConstant, addFieldSetFunction, addFieldZeroFunction, addZeroFunction } from "./fields.js";
3
+ import { capitalize, getName } from "./utils.js";
4
+ export function addStructureOfArrays(header, fields, output) {
5
+ const [name, type, baseLength] = header.split(" ");
6
+ addFieldMaxLengthConstant(name, baseLength, output);
7
+ for (const field of fields) {
8
+ addFieldDefinition(field, baseLength, output);
9
+ }
10
+ for (const field of fields) {
11
+ addFieldSetFunction(name, type, field, output);
12
+ }
13
+ addFieldZeroAtIndexFunction(name, type, fields, output);
14
+ for (const field of fields) {
15
+ addFieldZeroFunction(name, type, field, baseLength, output);
16
+ }
17
+ addZeroFunction(name, type, fields, baseLength, output);
18
+ }
19
+ function addFieldZeroAtIndexFunction(name, type, fields, output) {
20
+ output.push("");
21
+ output.push(`/** Zero an index within the ${name} ${getName(type)}. */`);
22
+ output.push(`export function zero${capitalize(name)}(idx: number) {`);
23
+ for (const field of fields) {
24
+ const [fieldName, _, fieldArrayType] = field.split(" ");
25
+ switch (fieldArrayType) {
26
+ case ArrayType.STRING:
27
+ output.push(` ${fieldName}[idx] = ""`);
28
+ break;
29
+ case ArrayType.NUMBER:
30
+ output.push(` ${fieldName}[idx] = 0`);
31
+ break;
32
+ case ArrayType.BOOLEAN:
33
+ output.push(` ${fieldName}[idx] = false`);
34
+ break;
35
+ }
36
+ }
37
+ output.push("}");
38
+ }
@@ -0,0 +1,99 @@
1
+ import { ArrayType, FieldType } from "../consts.js";
2
+ import { capitalize, getName } from "./utils.js";
3
+ export function addStruct(header, fields, output) {
4
+ const [name] = header.split(" ");
5
+ addStructTypeDefinition(name, fields, output);
6
+ addStructCreateFunction(name, fields, output);
7
+ addStructZeroFunction(name, fields, output);
8
+ }
9
+ function addStructTypeDefinition(name, fields, output) {
10
+ output.push(`export type ${capitalize(name)} = {`);
11
+ for (const field of fields) {
12
+ const [fieldName, fieldType, fieldArrayType] = field.split(" ");
13
+ output.push(` ${fieldName}: ${getName(fieldType, fieldArrayType)}`);
14
+ }
15
+ output.push("}");
16
+ }
17
+ function addStructCreateFunction(name, fields, output) {
18
+ output.push("");
19
+ output.push(`/** Create a new ${capitalize(name)} object. */`);
20
+ output.push(`export function create${capitalize(name)}(): ${capitalize(name)} {`);
21
+ output.push(` const obj = Object.create(null)`);
22
+ for (const field of fields) {
23
+ const [fieldName, fieldType, fieldArrayType, fieldArrayLength = ""] = field.split(" ");
24
+ switch (fieldType) {
25
+ case FieldType.STRING:
26
+ output.push(` obj.${fieldName} = ""`);
27
+ break;
28
+ case FieldType.NUMBER:
29
+ output.push(` obj.${fieldName} = 0`);
30
+ break;
31
+ case FieldType.BOOLEAN:
32
+ output.push(` obj.${fieldName} = false`);
33
+ break;
34
+ case FieldType.ARRAY:
35
+ {
36
+ switch (fieldArrayType) {
37
+ case ArrayType.STRING:
38
+ output.push(` obj.${fieldName} = new Array<string>(${fieldArrayLength})${fieldArrayLength ? '.fill("")' : ""}`);
39
+ break;
40
+ case ArrayType.NUMBER:
41
+ output.push(` obj.${fieldName} = new Array<number>(${fieldArrayLength})${fieldArrayLength ? ".fill(0)" : ""}`);
42
+ break;
43
+ case ArrayType.BOOLEAN:
44
+ output.push(` obj.${fieldName} = new Array<boolean>(${fieldArrayLength})${fieldArrayLength ? ".fill(false)" : ""}`);
45
+ break;
46
+ }
47
+ }
48
+ break;
49
+ case FieldType.SET:
50
+ output.push(` obj.${fieldName} = new Set<${getName(fieldArrayType)}>()`);
51
+ break;
52
+ default: {
53
+ output.push(` obj.${fieldName} = create${capitalize(fieldType)}()`);
54
+ }
55
+ }
56
+ }
57
+ output.push(" return obj");
58
+ output.push("}");
59
+ }
60
+ function addStructZeroFunction(name, fields, output) {
61
+ output.push("");
62
+ output.push(`/** Zero the given ${capitalize(name)} object. */`);
63
+ output.push(`export function zero${capitalize(name)}(obj: ${capitalize(name)}) {`);
64
+ for (const field of fields) {
65
+ const [fieldName, fieldType, fieldArrayType, fieldArrayLength] = field.split(" ");
66
+ switch (fieldType) {
67
+ case FieldType.STRING:
68
+ output.push(` obj.${fieldName} = ""`);
69
+ break;
70
+ case FieldType.NUMBER:
71
+ output.push(` obj.${fieldName} = 0`);
72
+ break;
73
+ case FieldType.BOOLEAN:
74
+ output.push(` obj.${fieldName} = false`);
75
+ break;
76
+ case FieldType.ARRAY:
77
+ {
78
+ switch (fieldArrayType) {
79
+ case ArrayType.STRING:
80
+ output.push(` obj.${fieldName}.${fieldArrayLength ? 'fill("")' : "length = 0"}`);
81
+ break;
82
+ case ArrayType.NUMBER:
83
+ output.push(` obj.${fieldName}.${fieldArrayLength ? "fill(0)" : "length = 0"}`);
84
+ break;
85
+ case ArrayType.BOOLEAN:
86
+ output.push(` obj.${fieldName}.${fieldArrayLength ? "fill(false)" : "length = 0"}`);
87
+ break;
88
+ }
89
+ }
90
+ break;
91
+ case FieldType.SET:
92
+ output.push(` obj.${fieldName}.clear()`);
93
+ break;
94
+ default:
95
+ output.push(` zero${capitalize(fieldType)}(obj.${fieldName})`);
96
+ }
97
+ }
98
+ output.push("}");
99
+ }
@@ -0,0 +1,34 @@
1
+ import { FieldType, Type } from "../consts.js";
2
+ /**
3
+ * Get the name based on the type of the data structure.
4
+ */
5
+ export function getName(type, arrayType = "") {
6
+ switch (type) {
7
+ case Type.SOA:
8
+ return "structure of arrays";
9
+ case Type.AOS:
10
+ return "array of structures";
11
+ case Type.STRUCT:
12
+ return "struct";
13
+ case Type.GROUP:
14
+ return "group";
15
+ case FieldType.STRING:
16
+ return "string";
17
+ case FieldType.NUMBER:
18
+ return "number";
19
+ case FieldType.BOOLEAN:
20
+ return "boolean";
21
+ case FieldType.ARRAY:
22
+ return `Array<${getName(arrayType)}>`;
23
+ case FieldType.SET:
24
+ return `Set<${getName(arrayType)}>`;
25
+ default:
26
+ return capitalize(type);
27
+ }
28
+ }
29
+ /**
30
+ * Capitalize the first letter of a string.
31
+ */
32
+ export function capitalize(str) {
33
+ return `${str.substring(0, 1).toUpperCase()}${str.substring(1)}`;
34
+ }
package/dist/main.js CHANGED
@@ -1,175 +1,45 @@
1
1
  #!/usr/bin/env node
2
-
3
- // src/main.ts
4
- import fs from "fs";
5
- var inputFile = process.argv[2];
6
- var outputFile = process.argv[3] || `${inputFile}.ts`;
7
- var input = fs.readFileSync(inputFile, "utf-8");
8
- var output = [];
2
+ import fs from "node:fs";
3
+ import { Type } from "./consts.js";
4
+ import { addArrayOfStructures } from "./lib/aos.js";
5
+ import { addGroup } from "./lib/group.js";
6
+ import { addStructureOfArrays } from "./lib/soa.js";
7
+ import { addStruct } from "./lib/struct.js";
8
+ import { getName } from "./lib/utils.js";
9
+ const inputFile = process.argv[2];
10
+ const outputFile = process.argv[3] || `${inputFile}.ts`;
11
+ const input = fs.readFileSync(inputFile, "utf-8");
12
+ const output = [];
9
13
  output.push("/*");
10
- output.push(` * Generated with game-data-gen on ${(/* @__PURE__ */ new Date()).toLocaleString()}. DO NOT MODIFY THIS FILE!`);
14
+ output.push(` * Generated with game-data-gen on ${new Date().toLocaleString()}. DO NOT MODIFY THIS FILE!`);
11
15
  output.push(" */");
12
- var blocks = input.trim().split("\n\n");
16
+ const blocks = input.trim().split("\n\n");
13
17
  for (const block of blocks) {
14
- const fields = block.split("\n");
15
- const header = fields.shift();
16
- if (!header) continue;
17
- const [name, type, baseLength] = header.split(" ");
18
- output.push("");
19
- output.push("/*");
20
- output.push(` * ${"-".repeat(50)}`);
21
- output.push(` * ${name} (${getTypeName(type)})`);
22
- output.push(` * ${"-".repeat(50)}`);
23
- output.push(" */");
24
- output.push("");
25
- if (type === "soa" /* SOA */) {
26
- output.push(`export const MAX_${name.toUpperCase()}_COUNT = ${baseLength}`);
18
+ const fields = block.split("\n");
19
+ const header = fields.shift();
20
+ if (!header)
21
+ continue;
22
+ const [name, type] = header.split(" ");
27
23
  output.push("");
28
- }
29
- for (const field of fields) {
30
- const [fieldName, fieldType, fieldArrayType, fieldLength] = field.split(" ");
31
- const length = baseLength || fieldLength || "";
32
- switch (fieldType) {
33
- case "string" /* STRING */:
34
- output.push(`export let ${fieldName} = ""`);
35
- break;
36
- case "boolean" /* BOOLEAN */:
37
- output.push(`export let ${fieldName} = false`);
38
- break;
39
- case "number" /* NUMBER */:
40
- output.push(`export let ${fieldName} = 0`);
41
- break;
42
- case "array" /* ARRAY */:
43
- {
44
- switch (fieldArrayType) {
45
- case "int8" /* INT8 */:
46
- output.push(`export const ${fieldName} = new Int8Array(${length})`);
47
- break;
48
- case "int16" /* INT16 */:
49
- output.push(`export const ${fieldName} = new Int16Array(${length})`);
50
- break;
51
- case "int32" /* INT32 */:
52
- output.push(`export const ${fieldName} = new Int32Array(${length})`);
53
- break;
54
- case "uint8" /* UINT8 */:
55
- output.push(`export const ${fieldName} = new Uint8Array(${length})`);
56
- break;
57
- case "uint16" /* UINT16 */:
58
- output.push(`export const ${fieldName} = new Uint16Array(${length})`);
59
- break;
60
- case "uint32" /* UINT32 */:
61
- output.push(`export const ${fieldName} = new Uint32Array(${length})`);
62
- break;
63
- case "float32" /* FLOAT32 */:
64
- output.push(`export const ${fieldName} = new Float32Array(${length})`);
65
- break;
66
- case "float64" /* FLOAT64 */:
67
- output.push(`export const ${fieldName} = new Float64Array(${length})`);
68
- break;
69
- case "string" /* STRING */:
70
- output.push(`export const ${fieldName} = new Array<string>(${length})${length ? '.fill("")' : ""}`);
71
- break;
72
- case "boolean" /* BOOLEAN */:
73
- output.push(`export const ${fieldName} = new Array<boolean>(${length})${length ? ".fill(false)" : ""}`);
74
- break;
75
- case "number" /* NUMBER */:
76
- output.push(`export const ${fieldName} = new Array<number>(${length})${length ? ".fill(0)" : ""}`);
77
- break;
78
- default:
79
- output.push(`export const ${fieldName} = new Array<${fieldArrayType}>(${length})`);
80
- }
81
- }
82
- break;
83
- }
84
- }
85
- for (const field of fields) {
86
- const [fieldName, fieldType] = field.split(" ");
87
- switch (fieldType) {
88
- case "string" /* STRING */:
89
- case "boolean" /* BOOLEAN */:
90
- case "number" /* NUMBER */:
91
- output.push("");
92
- output.push(`/** Set the value of the ${fieldName} field within the ${name} ${getTypeName(type)}. */`);
93
- output.push(`export function set${capitalize(fieldName)}(value: ${fieldType}) {`);
94
- output.push(` ${fieldName} = value`);
95
- output.push("}");
96
- break;
97
- }
98
- }
99
- if (type === "soa" /* SOA */) {
24
+ output.push("/*");
25
+ output.push(` * ${"-".repeat(50)}`);
26
+ output.push(` * ${name} (${getName(type)})`);
27
+ output.push(` * ${"-".repeat(50)}`);
28
+ output.push(" */");
100
29
  output.push("");
101
- output.push(`/** Zero an index within the ${name} ${getTypeName(type)}. */`);
102
- output.push(`export function zero${capitalize(name)}(idx: number) {`);
103
- for (const field of fields) {
104
- const [fieldName, _, fieldArrayType] = field.split(" ");
105
- switch (fieldArrayType) {
106
- case "string" /* STRING */:
107
- output.push(` ${fieldName}[idx] = ""`);
108
- break;
109
- case "boolean" /* BOOLEAN */:
110
- output.push(` ${fieldName}[idx] = false`);
111
- break;
112
- default:
113
- output.push(` ${fieldName}[idx] = 0`);
114
- }
115
- }
116
- output.push("}");
117
- }
118
- for (const field of fields) {
119
- const [fieldName, fieldType, fieldArrayType, fieldLength] = field.split(" ");
120
- const length = baseLength || fieldLength || "";
121
- output.push("");
122
- output.push(`/** Zero the ${fieldName} field within the ${name} ${getTypeName(type)}. */`);
123
- output.push(`export function zero${capitalize(fieldName)}() {`);
124
- zeroField(fieldName, fieldType, fieldArrayType, length);
125
- output.push("}");
126
- }
127
- output.push("");
128
- output.push(`/** Zero all fields within the ${name} ${getTypeName(type)}. */`);
129
- output.push(`export function zero${capitalize(name)}Data() {`);
130
- for (const field of fields) {
131
- const [fieldName, fieldType, fieldArrayType, fieldLength] = field.split(" ");
132
- const length = baseLength || fieldLength || "";
133
- zeroField(fieldName, fieldType, fieldArrayType, length);
134
- }
135
- output.push("}");
136
- }
137
- function zeroField(name, type, arrayType, length) {
138
- switch (type) {
139
- case "string" /* STRING */:
140
- output.push(` ${name} = ""`);
141
- break;
142
- case "boolean" /* BOOLEAN */:
143
- output.push(` ${name} = false`);
144
- break;
145
- case "number" /* NUMBER */:
146
- output.push(` ${name} = 0`);
147
- break;
148
- case "array" /* ARRAY */:
149
- {
150
- switch (arrayType) {
151
- case "string" /* STRING */:
152
- output.push(` ${name}.${length ? 'fill("")' : "length = 0"}`);
30
+ switch (type) {
31
+ case Type.STRUCT:
32
+ addStruct(header, fields, output);
153
33
  break;
154
- case "boolean" /* BOOLEAN */:
155
- output.push(` ${name}.${length ? "fill(false)" : "length = 0"}`);
34
+ case Type.GROUP:
35
+ addGroup(header, fields, output);
156
36
  break;
157
- default:
158
- output.push(` ${name}.${length ? "fill(0)" : "length = 0"}`);
159
- }
160
- }
161
- break;
162
- }
163
- }
164
- function getTypeName(type) {
165
- switch (type) {
166
- case "soa" /* SOA */:
167
- return "Structure of Arrays";
168
- default:
169
- return "group";
170
- }
171
- }
172
- function capitalize(str) {
173
- return `${str.substring(0, 1).toUpperCase()}${str.substring(1)}`;
37
+ case Type.SOA:
38
+ addStructureOfArrays(header, fields, output);
39
+ break;
40
+ case Type.AOS:
41
+ addArrayOfStructures(header, output);
42
+ break;
43
+ }
174
44
  }
175
45
  fs.writeFileSync(outputFile, output.join("\n"));
package/package.json CHANGED
@@ -1,24 +1,24 @@
1
1
  {
2
2
  "name": "game-data-gen",
3
- "version": "1.2.1",
3
+ "version": "2.1.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
7
7
  ],
8
- "bin": "dist/main.js",
8
+ "bin": {
9
+ "game-data-gen": "dist/main.js"
10
+ },
9
11
  "scripts": {
10
- "start": "tsx watch src/main.ts tests/data",
11
- "build": "tsc && esbuild src/main.ts --bundle --platform=node --format=esm --target=es6 --outdir=dist --banner:js='#!/usr/bin/env node'",
12
- "test": "npm run build && npx game-data-gen tests/data"
12
+ "start": "tsc && node dist/main.js tests/data",
13
+ "build": "biome check && tsc"
13
14
  },
14
15
  "repository": {
15
16
  "type": "git",
16
- "url": "https://github.com/patrickswijgman/game-data-gen"
17
+ "url": "git+https://github.com/patrickswijgman/game-data-gen.git"
17
18
  },
18
19
  "devDependencies": {
19
- "@types/node": "^22.15.18",
20
- "esbuild": "^0.25.4",
21
- "tsx": "^4.19.4",
22
- "typescript": "~5.8.3"
20
+ "@biomejs/biome": "^2.4.11",
21
+ "@types/node": "^24.12.2",
22
+ "typescript": "^6.0.2"
23
23
  }
24
24
  }