@erik9994857/cag 1.0.3 → 2.0.2

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.
@@ -72,13 +72,11 @@ class CagCLI {
72
72
 
73
73
  this.printLine("Project: " + engine.getInfo().ID);
74
74
  this.printLine("Version: " + engine.getInfo().version);
75
- this.printLine("Dependencies: " + engine.getDependencies().join(", "));
76
- this.printLine("Code files: " + engine.getCodeFiles().length);
77
- this.printLine("Resources: " + Object.keys(engine.getResourceMap()).length);
78
75
  this.printLine("");
79
76
 
80
77
  const CagcParser = require("../parser/cagc-parser");
81
78
  const Executor = require("../runtime/executor");
79
+ const ElectronRunner = require("../runtime/electron-runner");
82
80
 
83
81
  const cagcParser = new CagcParser();
84
82
  const executor = new Executor(engine);
@@ -90,26 +88,45 @@ class CagCLI {
90
88
  const fileName = path.basename(filePath);
91
89
  const content = fs.readFileSync(filePath, "utf-8");
92
90
 
93
- this.printLine("Executing: " + fileName);
94
-
95
91
  const parsed = cagcParser.parse(content, fileName);
96
92
  const result = executor.execute(parsed);
97
93
 
98
94
  if (result.errors && result.errors.length > 0) {
99
95
  for (let j = 0; j < result.errors.length; j++) {
100
- this.printError(" " + result.errors[j]);
96
+ this.printError(result.errors[j]);
101
97
  }
102
98
  }
99
+ }
103
100
 
104
- if (result.outputs && result.outputs.length > 0) {
105
- for (let j = 0; j < result.outputs.length; j++) {
106
- this.printLine(" > " + result.outputs[j]);
101
+ const registry = executor.getRegistry();
102
+ if (registry.has("Model.API")) {
103
+ const modelAPI = registry.get("Model.API");
104
+ const loadedModels = modelAPI.getLoadedModels();
105
+ const modelNames = Object.keys(loadedModels);
106
+ if (modelNames.length > 0) {
107
+ this.printLine("Reading UV mapping...");
108
+ for (let i = 0; i < modelNames.length; i++) {
109
+ const name = modelNames[i];
110
+ const model = loadedModels[name];
111
+ if (model && model.valid && model.texture) {
112
+ this.printSuccess("Auto Mapped Custom UV for " + name);
113
+ } else if (model && model.valid) {
114
+ this.printLine(" " + name + " (no texture paired)");
115
+ } else {
116
+ this.printError("Failed to map UV for " + name);
117
+ }
107
118
  }
119
+ this.printLine("");
108
120
  }
109
121
  }
110
122
 
123
+ this.printLine("Launching game...");
111
124
  this.printLine("");
112
- this.printSuccess("Execution complete.");
125
+
126
+ const settings = ElectronRunner.extractSettings(executor);
127
+ const runner = new ElectronRunner(engine, settings);
128
+ runner.run();
129
+
113
130
  return 0;
114
131
  } catch (e) {
115
132
  this.printError(e.message);
@@ -198,7 +215,7 @@ class CagCLI {
198
215
  this.printLine("[info.cag] OK");
199
216
 
200
217
  const deps = engine.getDependencies();
201
- const validAPIs = ["Model.API", "WorldGen.API", "Pull.API"];
218
+ const validAPIs = ["Model.API", "WorldGen.API", "Pull.API", "Chunk.API", "Player.API", "Camera.API", "Render.API", "Window.API"];
202
219
  for (let i = 0; i < deps.length; i++) {
203
220
  if (validAPIs.indexOf(deps[i]) === -1) {
204
221
  this.printError("[main.cag] Unknown dependency: " + deps[i]);
package/src/index.js CHANGED
@@ -195,7 +195,7 @@ class CaG {
195
195
  } else {
196
196
  fs.writeFileSync(
197
197
  path.join(projectPath, "main.cag"),
198
- "Depency Model.API\nDepency WorldGen.API\nDepency Pull.API\n"
198
+ "Dependency Model.API\nDependency WorldGen.API\nDependency Pull.API\nDependency Chunk.API\nDependency Player.API\nDependency Camera.API\nDependency Render.API\nDependency Window.API\n"
199
199
  );
200
200
  fs.writeFileSync(
201
201
  path.join(projectPath, "info.cag"),
@@ -203,7 +203,7 @@ class CaG {
203
203
  );
204
204
  fs.writeFileSync(
205
205
  path.join(projectPath, "src", "code", "example.cagc"),
206
- "Import Model.API\n\n{function use Model.API UseModel Grass\n"
206
+ "// " + projectName + " - CaG Game\n\nImport Model.API\nImport WorldGen.API\nImport Chunk.API\nImport Player.API\nImport Camera.API\nImport Render.API\nImport Window.API\n\n{function use Window.API SetTitle " + projectName + "\n{function use Window.API SetSize 1280 720\n{function use Render.API SetSkyColor 0.53 0.81 0.92\n{function use Render.API SetFog 0.53 0.81 0.92 64 128\n{function use Render.API SetSunDirection 0.5 1.0 0.3\n{function use Render.API SetAmbientLight 0.3 0.3 0.4\n{function use Camera.API SetFOV 70\n{function use Camera.API SetMode first-person\n{function use Model.API UseModel Grass\n{function use Chunk.API SetSize 16\n{function use Chunk.API SetRenderDistance 1\n{function use WorldGen.API generate world top layer = Grass\n{function use Player.API SetSpeed 0.08\n{function use Player.API SetJumpHeight 0.18\n{function use Player.API Spawn 8 2 8\n"
207
207
  );
208
208
  }
209
209
 
@@ -48,11 +48,11 @@ class CagParser {
48
48
  continue;
49
49
  }
50
50
 
51
- if (!line.startsWith("Depency ")) {
52
- throw new Error("Invalid main.cag syntax at line " + (i + 1) + ": expected 'Depency (name)'");
51
+ if (!line.startsWith("Dependency ")) {
52
+ throw new Error("Invalid main.cag syntax at line " + (i + 1) + ": expected 'Dependency (name)'");
53
53
  }
54
54
 
55
- const depName = line.substring(8).trim();
55
+ const depName = line.substring(11).trim();
56
56
 
57
57
  if (depName === "") {
58
58
  throw new Error("Empty dependency name at line " + (i + 1));
@@ -73,10 +73,27 @@ class CagParser {
73
73
  for (let i = 0; i < lines.length; i++) {
74
74
  const line = lines[i].trim();
75
75
 
76
- if (line === "") {
76
+ if (line === "" || line.startsWith("//")) {
77
77
  continue;
78
78
  }
79
79
 
80
+ if (line.startsWith("Set ")) {
81
+ var setContent = line.substring(4).trim();
82
+ var eqIdx = setContent.indexOf("=");
83
+ if (eqIdx !== -1) {
84
+ var varName = setContent.substring(0, eqIdx).trim();
85
+ var varValue = setContent.substring(eqIdx + 1).trim();
86
+ functions.push({
87
+ type: "set",
88
+ variable: varName,
89
+ value: varValue,
90
+ raw: line,
91
+ line: i + 1
92
+ });
93
+ continue;
94
+ }
95
+ }
96
+
80
97
  if (line.startsWith("Import ")) {
81
98
  if (currentSection !== "imports") {
82
99
  throw new Error("Import statements must be at the top of the file, line " + (i + 1));
@@ -211,6 +228,41 @@ class CagParser {
211
228
  1: "retrieve",
212
229
  2: "search",
213
230
  3: "list"
231
+ },
232
+ "Chunk.API": {
233
+ 1: "SetSize",
234
+ 2: "SetRenderDistance",
235
+ 3: "Generate",
236
+ 4: "Unload",
237
+ 5: "ListLoaded"
238
+ },
239
+ "Player.API": {
240
+ 1: "Spawn",
241
+ 2: "SetSpeed",
242
+ 3: "SetJumpHeight",
243
+ 4: "SetGravity",
244
+ 5: "GetPosition"
245
+ },
246
+ "Camera.API": {
247
+ 1: "SetFOV",
248
+ 2: "SetNearFar",
249
+ 3: "SetMode",
250
+ 4: "SetSensitivity",
251
+ 5: "GetSettings"
252
+ },
253
+ "Render.API": {
254
+ 1: "SetFog",
255
+ 2: "SetSkyColor",
256
+ 3: "SetSunDirection",
257
+ 4: "SetAmbientLight",
258
+ 5: "SetRenderDistance"
259
+ },
260
+ "Window.API": {
261
+ 1: "SetTitle",
262
+ 2: "SetSize",
263
+ 3: "SetFullscreen",
264
+ 4: "SetBackground",
265
+ 5: "GetSettings"
214
266
  }
215
267
  };
216
268
 
@@ -3,7 +3,7 @@ const Tokenizer = require("./tokenizer");
3
3
  class CagcParser {
4
4
  constructor() {
5
5
  this.tokenizer = new Tokenizer();
6
- this.validAPIs = ["Model.API", "WorldGen.API", "Pull.API"];
6
+ this.validAPIs = ["Model.API", "WorldGen.API", "Pull.API", "Chunk.API", "Player.API", "Camera.API", "Render.API", "Window.API"];
7
7
  }
8
8
 
9
9
  parse(content, fileName) {
@@ -25,6 +25,13 @@ class CagcParser {
25
25
  continue;
26
26
  }
27
27
 
28
+ if (token.type === "COMMENT") {
29
+ while (i < tokens.length && tokens[i].type !== "NEWLINE") {
30
+ i++;
31
+ }
32
+ continue;
33
+ }
34
+
28
35
  if (token.type === "KEYWORD" && token.value === "Import") {
29
36
  const importResult = this.parseImport(tokens, i);
30
37
  if (importResult.error) {
@@ -205,7 +212,12 @@ class CagcParser {
205
212
  var actions = {
206
213
  "Model.API": { 1: "UseModel", 2: "RemoveModel", 3: "ListModels" },
207
214
  "WorldGen.API": { 1: "generate", 2: "destroy", 3: "modify" },
208
- "Pull.API": { 1: "retrieve", 2: "search", 3: "list" }
215
+ "Pull.API": { 1: "retrieve", 2: "search", 3: "list" },
216
+ "Chunk.API": { 1: "SetSize", 2: "SetRenderDistance", 3: "Generate", 4: "Unload", 5: "ListLoaded" },
217
+ "Player.API": { 1: "Spawn", 2: "SetSpeed", 3: "SetJumpHeight", 4: "SetGravity", 5: "GetPosition" },
218
+ "Camera.API": { 1: "SetFOV", 2: "SetNearFar", 3: "SetMode", 4: "SetSensitivity", 5: "GetSettings" },
219
+ "Render.API": { 1: "SetFog", 2: "SetSkyColor", 3: "SetSunDirection", 4: "SetAmbientLight", 5: "SetRenderDistance" },
220
+ "Window.API": { 1: "SetTitle", 2: "SetSize", 3: "SetFullscreen", 4: "SetBackground", 5: "GetSettings" }
209
221
  };
210
222
 
211
223
  if (actions[api] && actions[api][num]) {
@@ -1,9 +1,11 @@
1
1
  class Tokenizer {
2
2
  constructor() {
3
3
  this.keywords = [
4
- "Import", "Depency", "function", "use",
4
+ "Import", "Dependency", "function", "use", "Set",
5
5
  "generate", "retrieve", "search", "list",
6
- "world", "top", "layer", "model", "texture"
6
+ "world", "top", "layer", "model", "texture",
7
+ "chunk", "player", "camera", "render", "window",
8
+ "spawn", "fog", "sky", "sun", "ambient", "fov", "speed", "gravity"
7
9
  ];
8
10
  }
9
11
 
@@ -29,6 +31,16 @@ class Tokenizer {
29
31
  continue;
30
32
  }
31
33
 
34
+ if (char === "/" && i + 1 < content.length && content[i + 1] === "/") {
35
+ var commentStart = i;
36
+ while (i < content.length && content[i] !== "\n") {
37
+ i++;
38
+ col++;
39
+ }
40
+ tokens.push({ type: "COMMENT", value: content.substring(commentStart, i), line: line, col: col - (i - commentStart) });
41
+ continue;
42
+ }
43
+
32
44
  if (char === " " || char === "\t") {
33
45
  var wsStart = i;
34
46
  while (i < content.length && (content[i] === " " || content[i] === "\t")) {