omegga 1.8.1 → 1.9.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/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@
4
4
 
5
5
  - Future features go here
6
6
 
7
+ ## 1.9.0 - 2026-07-05
8
+
9
+ Wire graph log events and a brs-js 3.0.0 upgrade for native brdb/brz reading.
10
+
11
+ - Plugins: Add `wirelog` event, emitted for each `[Wire Graph]` console log with the raw text
12
+ - Plugins: Add `wirecmd:command` event, emitted when a `[Wire Graph]` log starts with a command word (lowercased) followed by space-separated args
13
+ - Update brs-js to 3.2.1 and expose brdb/brz features on `OMEGGA_UTIL.brdb`
14
+ - World revisions are now read directly from the `.brdb` file instead of the game console, so `getWorldRevisions` no longer requires the server to be running
15
+ - Plugins: Add `OMEGGA_UTIL.Sqlite` for opening sqlite files (or brdb files)
16
+ - Plugins: `loadSaveData`/`loadSaveDataOnPlayer`/`getSaveData` are back using `brs-js` 3
17
+ - Fix `clearRegion`, `clearAllBricks`, `loadSaveData`, `getSaveData`, in safe plugins
18
+
7
19
  ## 1.8.1 - 2026-07-03
8
20
 
9
21
  Prefab support for EA3, replacing the removed `.brs` bricks commands.
package/README.md CHANGED
@@ -891,7 +891,9 @@ Register custom `/commands` by returning `{registeredCommands: ['foo', 'bar']}`
891
891
  | `event:NAME` | [>player from click<, ...args] | Runs when an interact component has `event:NAME: arg1,arg2,arg\,3, | |
892
892
  | `mapchange` | \[{map}\] | Runs when the map changes | |
893
893
  | `autorestart` | [autorestart config] | Runs server has an autorestart scheduled | |
894
- | `minigamejoin` | {player: {name, id}; minigameName: string} | Runs when a player joins a minigame. Note that minigameName is not unique between minigames. minigameName will be null if player leaves all minigames. This will run before `join` | |
894
+ | `minigamejoin` | {player: {name, id}; minigameName: string} | **Deprecated as of EA3.** Runs when a player joins a minigame. Note that minigameName is not unique between minigames. minigameName will be null if player leaves all minigames. This will run before `join` | |
895
+ | `wirelog` | [raw string] | Runs when a `[Wire Graph]` log line is emitted. `raw` is the text after the `[Wire Graph] ` prefix | |
896
+ | `wirecmd:command` | [...args] | Runs when a `[Wire Graph]` log starts with `command args`. `command` is lowercased; args are the remaining space-separated words | |
895
897
 
896
898
  ### Folder Structure
897
899
 
@@ -11,6 +11,7 @@ const init = require("./init.js");
11
11
  const mapChange = require("./mapChange.js");
12
12
  const interact = require("./interact.js");
13
13
  const minigameJoin = require("./minigameJoin.js");
14
+ const wire = require("./wire.js");
14
15
  const MATCHERS = [
15
16
  join.default,
16
17
  leave.default,
@@ -22,7 +23,8 @@ const MATCHERS = [
22
23
  init.default,
23
24
  mapChange.default,
24
25
  interact.default,
25
- minigameJoin.default
26
+ minigameJoin.default,
27
+ wire.default
26
28
  ];
27
29
  exports.default = MATCHERS;
28
30
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/omegga/matchers/index.ts"],"sourcesContent":["import { MatchGenerator } from './types';\n\nimport join from './join';\n// 'join' event => { name, id, state, controller }\n\nimport leave from './leave';\n// 'leave' event => { name, id, state, controller }\n\nimport chat from './chat';\n// 'chat' event => name, message; 'chatcmd:command' event => name, [...args]\n// 'kick' event => name, kicker, reason\n\nimport command from './command';\n// 'cmd:command' event => name, args (string)\n\nimport auth from './auth';\n// assigns host, 'host' event, 'start' event, 'unauthorized' event\n\nimport exit from './exit';\n// 'exit' event\n\nimport version from './version';\n// 'version' event, check game version\n\nimport init from './init';\n// watch loginit for any funny business\n\nimport mapChange from './mapChange';\n// 'mapchange' event\n\n// interaction event\nimport interact from './interact';\n\n// minigame join event\nimport minigameJoin from './minigameJoin';\n\nexport default [\n join,\n leave,\n chat,\n command,\n auth,\n exit,\n version,\n init,\n mapChange,\n interact,\n minigameJoin,\n] as MatchGenerator<any>[];\n"],"names":["join","leave","chat","command","auth","exit","version","init","mapChange","interact","minigameJoin"],"mappings":";;;;;;;;;;;;;AAoCA,MAAA,WAAe;AAAA,EACbA,KAAAA;AAAAA,EACAC,MAAAA;AAAAA,EACAC,KAAAA;AAAAA,EACAC,QAAAA;AAAAA,EACAC,KAAAA;AAAAA,EACAC,KAAAA;AAAAA,EACAC,QAAAA;AAAAA,EACAC,KAAAA;AAAAA,EACAC,UAAAA;AAAAA,EACAC,SAAAA;AAAAA,EACAC,aAAAA;AACF;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/omegga/matchers/index.ts"],"sourcesContent":["import { MatchGenerator } from './types';\n\nimport join from './join';\n// 'join' event => { name, id, state, controller }\n\nimport leave from './leave';\n// 'leave' event => { name, id, state, controller }\n\nimport chat from './chat';\n// 'chat' event => name, message; 'chatcmd:command' event => name, [...args]\n// 'kick' event => name, kicker, reason\n\nimport command from './command';\n// 'cmd:command' event => name, args (string)\n\nimport auth from './auth';\n// assigns host, 'host' event, 'start' event, 'unauthorized' event\n\nimport exit from './exit';\n// 'exit' event\n\nimport version from './version';\n// 'version' event, check game version\n\nimport init from './init';\n// watch loginit for any funny business\n\nimport mapChange from './mapChange';\n// 'mapchange' event\n\n// interaction event\nimport interact from './interact';\n\n// minigame join event\nimport minigameJoin from './minigameJoin';\n\nimport wire from './wire';\n// 'wirelog' event => raw; 'wirecmd:command' event => [...args]\n\nexport default [\n join,\n leave,\n chat,\n command,\n auth,\n exit,\n version,\n init,\n mapChange,\n interact,\n minigameJoin,\n wire,\n] as MatchGenerator<any>[];\n"],"names":["join","leave","chat","command","auth","exit","version","init","mapChange","interact","minigameJoin","wire"],"mappings":";;;;;;;;;;;;;;AAuCA,MAAA,WAAe;AAAA,EACbA,KAAAA;AAAAA,EACAC,MAAAA;AAAAA,EACAC,KAAAA;AAAAA,EACAC,QAAAA;AAAAA,EACAC,KAAAA;AAAAA,EACAC,KAAAA;AAAAA,EACAC,QAAAA;AAAAA,EACAC,KAAAA;AAAAA,EACAC,UAAAA;AAAAA,EACAC,SAAAA;AAAAA,EACAC,aAAAA;AAAAA,EACAC,KAAAA;AACF;;"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const wire = (omegga) => {
4
+ const wireRegExp = /^\[Wire Graph\] (?<raw>.*)$/;
5
+ return {
6
+ // listen for wire graph messages
7
+ pattern(_line, logMatch) {
8
+ if (!logMatch) return;
9
+ const { generator, data } = logMatch.groups;
10
+ if (generator !== "LogBrickadia") return;
11
+ const match = data.match(wireRegExp);
12
+ if (!match) return;
13
+ return { raw: match.groups.raw };
14
+ },
15
+ // when there's a match, emit the wire log event
16
+ callback({ raw }) {
17
+ omegga.emit("wirelog", raw);
18
+ const [cmd, ...args] = raw.split(" ");
19
+ if (cmd.length > 0) {
20
+ omegga.emit("wirecmd:" + cmd.toLowerCase(), ...args);
21
+ omegga.emit("wirecmd", cmd.toLowerCase(), ...args);
22
+ }
23
+ }
24
+ };
25
+ };
26
+ exports.default = wire;
27
+ //# sourceMappingURL=wire.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire.js","sources":["../../../src/omegga/matchers/wire.ts"],"sourcesContent":["import { MatchGenerator } from './types';\n\nconst wire: MatchGenerator<{ raw: string }> = omegga => {\n // pattern to match wire graph log messages\n // e.g. `LogBrickadia: [Wire Graph] test`\n const wireRegExp = /^\\[Wire Graph\\] (?<raw>.*)$/;\n\n return {\n // listen for wire graph messages\n pattern(_line, logMatch) {\n // line is not generic console log\n if (!logMatch) return;\n\n const { generator, data } = logMatch.groups;\n // check if log is a brickadia log\n if (generator !== 'LogBrickadia') return;\n\n // match the wire graph log pattern\n const match = data.match(wireRegExp);\n if (!match) return;\n\n return { raw: match.groups.raw };\n },\n // when there's a match, emit the wire log event\n callback({ raw }) {\n omegga.emit('wirelog', raw);\n\n // wire command parsing, emit `wirecmd:test` when `test ...` is logged\n const [cmd, ...args] = raw.split(' ');\n if (cmd.length > 0) {\n omegga.emit('wirecmd:' + cmd.toLowerCase(), ...args);\n omegga.emit('wirecmd', cmd.toLowerCase(), ...args);\n }\n },\n };\n};\n\nexport default wire;\n"],"names":[],"mappings":";;AAEA,MAAM,OAAwC,CAAA,WAAU;AAGtD,QAAM,aAAa;AAEnB,SAAO;AAAA;AAAA,IAEL,QAAQ,OAAO,UAAU;AAEvB,UAAI,CAAC,SAAU;AAEf,YAAM,EAAE,WAAW,KAAA,IAAS,SAAS;AAErC,UAAI,cAAc,eAAgB;AAGlC,YAAM,QAAQ,KAAK,MAAM,UAAU;AACnC,UAAI,CAAC,MAAO;AAEZ,aAAO,EAAE,KAAK,MAAM,OAAO,IAAA;AAAA,IAC7B;AAAA;AAAA,IAEA,SAAS,EAAE,OAAO;AAChB,aAAO,KAAK,WAAW,GAAG;AAG1B,YAAM,CAAC,KAAK,GAAG,IAAI,IAAI,IAAI,MAAM,GAAG;AACpC,UAAI,IAAI,SAAS,GAAG;AAClB,eAAO,KAAK,aAAa,IAAI,YAAA,GAAe,GAAG,IAAI;AACnD,eAAO,KAAK,WAAW,IAAI,YAAA,GAAe,GAAG,IAAI;AAAA,MACnD;AAAA,IACF;AAAA,EAAA;AAEJ;;"}
@@ -4,6 +4,7 @@ const logger = require("../logger.js");
4
4
  const softconfig = require("../softconfig.js");
5
5
  const version = require("../version.js");
6
6
  const index$2 = require("../util/index.js");
7
+ const brdb = require("../util/brdb.js");
7
8
  const file = require("../util/file.js");
8
9
  const index = require("../webserver/backend/index.js");
9
10
  const brs = require("brs-js");
@@ -18,6 +19,25 @@ const plugin = require("./plugin.js");
18
19
  const wrapper = require("./wrapper.js");
19
20
  const MISSING_CMD = '"Command not found. Type <color=\\"ffff00\\">/help</> for a list of commands or <color=\\"ffff00\\">/plugins</> for plugin information."';
20
21
  const WHOLE_WORLD_EXTENT = 1e9;
22
+ function brsRemoved(version2) {
23
+ return version2 > 0 && version2 >= commands.PREFAB_VERSION;
24
+ }
25
+ function warnRemoved(version2, method, since, release, replacement) {
26
+ if (!(version2 > 0 && version2 >= since)) return false;
27
+ logger.default.warnp(
28
+ `omegga.${method}() uses a console command removed in Brickadia ${release}. This call has no effect - use ${replacement} instead.`
29
+ );
30
+ return true;
31
+ }
32
+ function writeTempPrefab(omegga, saveData) {
33
+ const ref = omegga._tempSavePrefix + Date.now() + "_" + omegga._tempCounter.save++;
34
+ const file$1 = path.join(omegga.prefabPath, ref + ".brz");
35
+ if (!file$1.startsWith(omegga.prefabPath))
36
+ throw "prefab file not in Saved/Prefabs directory";
37
+ file.mkdir(omegga.prefabPath);
38
+ fs.writeFileSync(file$1, new Uint8Array(brs.writeBrzLegacy(saveData)));
39
+ return { ref, file: file$1 };
40
+ }
21
41
  class Omegga extends wrapper.default {
22
42
  /**
23
43
  * Omegga instance
@@ -446,30 +466,6 @@ class Omegga extends wrapper.default {
446
466
  const presetPath = path.join(this.presetPath, "Environment");
447
467
  return fs.existsSync(presetPath) ? glob.sync(presetPath + "/**/*.bp").map((f) => path.basename(f).replace(/\.bp$/, "")) : [];
448
468
  }
449
- /**
450
- * Whether the running game version has removed the legacy .brs bricks console
451
- * commands (Bricks.Save/Load/ClearAll/ClearRegion, World.LoadAdditive) in
452
- * favor of the prefab (`br.Prefab.*`) and world (`br.World.Clear*`) commands.
453
- * Removed at Brickadia CL{@link PREFAB_VERSION}.
454
- */
455
- #brsRemoved() {
456
- return this.version > 0 && this.version >= commands.PREFAB_VERSION;
457
- }
458
- /**
459
- * Warn that a method backed by a removed console command is a no-op on the
460
- * running game version, and return whether the caller should bail.
461
- * @param method the omegga method being called (for the message)
462
- * @param since CL version the underlying command was removed at
463
- * @param release human release name for that version (e.g. `EA2`, `EA3`)
464
- * @param replacement suggested replacement method/API
465
- */
466
- #warnRemoved(method, since, release, replacement) {
467
- if (!(this.version > 0 && this.version >= since)) return false;
468
- logger.default.warnp(
469
- `omegga.${method}() uses a console command removed in Brickadia ${release}. This call has no effect - use ${replacement} instead.`
470
- );
471
- return true;
472
- }
473
469
  clearBricks(target, quiet = false) {
474
470
  if (typeof target === "object" && target.id) target = target.id;
475
471
  else if (typeof target === "string" && !index$2.uuid.match(target)) {
@@ -489,7 +485,7 @@ class Omegga extends wrapper.default {
489
485
  }
490
486
  const center = region.center.join(" ");
491
487
  const extent = region.extent.join(" ");
492
- if (this.#brsRemoved()) {
488
+ if (brsRemoved(this.version)) {
493
489
  const bricks = options?.bricks ?? true ? 1 : 0;
494
490
  const entities = options?.entities ?? false ? 1 : 0;
495
491
  this.writeln(
@@ -507,7 +503,7 @@ class Omegga extends wrapper.default {
507
503
  bricks = true,
508
504
  entities = false
509
505
  } = typeof options === "boolean" ? { quiet: options } : options;
510
- if (this.#brsRemoved()) {
506
+ if (brsRemoved(this.version)) {
511
507
  this.writeln(
512
508
  `${this.Console.World.ClearAll} ${bricks ? 1 : 0} ${entities ? 1 : 0} ${quiet ? 1 : 0}`
513
509
  );
@@ -516,7 +512,13 @@ class Omegga extends wrapper.default {
516
512
  this.writeln(`${this.Console.Bricks.ClearAll} ${quiet ? 1 : ""}`);
517
513
  }
518
514
  saveBricks(saveName, region) {
519
- if (this.#warnRemoved("saveBricks", commands.PREFAB_VERSION, "EA3", "savePrefab"))
515
+ if (warnRemoved(
516
+ this.version,
517
+ "saveBricks",
518
+ commands.PREFAB_VERSION,
519
+ "EA3",
520
+ "savePrefab"
521
+ ))
520
522
  return;
521
523
  if (!saveName) return;
522
524
  if (!(saveName.startsWith('"') && saveName.endsWith('"')))
@@ -530,7 +532,8 @@ class Omegga extends wrapper.default {
530
532
  else this.writeln(`${this.Console.Bricks.Save} ${saveName}`);
531
533
  }
532
534
  async saveBricksAsync(saveName, region) {
533
- if (this.#warnRemoved(
535
+ if (warnRemoved(
536
+ this.version,
534
537
  "saveBricksAsync",
535
538
  commands.PREFAB_VERSION,
536
539
  "EA3",
@@ -563,7 +566,13 @@ class Omegga extends wrapper.default {
563
566
  correctPalette = false,
564
567
  correctCustom = false
565
568
  } = {}) {
566
- if (this.#warnRemoved("loadBricks", commands.PREFAB_VERSION, "EA3", "loadPrefab"))
569
+ if (warnRemoved(
570
+ this.version,
571
+ "loadBricks",
572
+ commands.PREFAB_VERSION,
573
+ "EA3",
574
+ "loadPrefab"
575
+ ))
567
576
  return;
568
577
  if (!(saveName.startsWith('"') && saveName.endsWith('"')))
569
578
  saveName = `"${saveName}"`;
@@ -578,7 +587,8 @@ class Omegga extends wrapper.default {
578
587
  correctPalette = false,
579
588
  correctCustom = false
580
589
  } = {}) {
581
- if (this.#warnRemoved(
590
+ if (warnRemoved(
591
+ this.version,
582
592
  "loadBricksOnPlayer",
583
593
  commands.EA2_VERSION,
584
594
  "EA2",
@@ -617,42 +627,12 @@ class Omegga extends wrapper.default {
617
627
  return fs.existsSync(file2) ? file2 : void 0;
618
628
  }
619
629
  async getWorldRevisions(worldName) {
620
- if (!this.started || this.starting || this.stopping) {
621
- throw new Error("Server is not started");
622
- }
623
630
  worldName = worldName.replace(/\.brdb$/i, "");
624
- if (!worldName || !this.getWorldPath(worldName)) {
631
+ const path2 = this.getWorldPath(worldName);
632
+ if (!worldName || !path2) {
625
633
  throw new Error(`World "${worldName}" does not exist`);
626
634
  }
627
- let numRevisions = 0;
628
- const revisionsRaw = await this.watchLogChunk(
629
- `${this.Console.World.ListRevisions} "${worldName}"`,
630
- /^LogBRBundleManager: (There are (?<numRevisions>\d+) revisions|Revision (?<revision>\d+) - (?<date>[\d.-]+): (?<note>.+))$/,
631
- {
632
- last: (match) => Number(match.groups.reverse) === numRevisions,
633
- first: (match) => {
634
- if (match.groups?.numRevisions !== void 0) {
635
- numRevisions = Number(match.groups.numRevisions);
636
- return true;
637
- }
638
- return false;
639
- }
640
- }
641
- );
642
- if (!revisionsRaw) return [];
643
- return revisionsRaw.map((match) => {
644
- if (match.groups?.numRevisions !== void 0) {
645
- return null;
646
- }
647
- const revision = match.groups.revision ? Number(match.groups.revision) : 0;
648
- const dateStr = match.groups.date.replace(
649
- /(\d{4})\.(\d{2})\.(\d{2})-(\d{2})\.(\d{2})\.(\d{2})/,
650
- "$1-$2-$3T$4:$5:$6Z"
651
- );
652
- const date = new Date(dateStr);
653
- const note = match.groups.note || "";
654
- return { index: revision, date, note };
655
- }).filter(Boolean);
635
+ return brdb.readBrdbRevisions(path2) ?? [];
656
636
  }
657
637
  async loadWorld(worldName) {
658
638
  worldName = worldName.replace(/\.brdb$/i, "");
@@ -799,8 +779,14 @@ class Omegga extends wrapper.default {
799
779
  correctPalette = false,
800
780
  correctCustom = false
801
781
  } = {}) {
802
- if (this.#warnRemoved("loadSaveData", commands.PREFAB_VERSION, "EA3", "loadPrefab"))
782
+ if (brsRemoved(this.version)) {
783
+ const { ref, file: file2 } = writeTempPrefab(this, saveData);
784
+ this.loadPrefab(ref, { offX, offY, offZ });
785
+ setTimeout(() => {
786
+ if (fs.existsSync(file2)) fs.unlinkSync(file2);
787
+ }, 5e3);
803
788
  return;
789
+ }
804
790
  const saveFile = this._tempSavePrefix + Date.now() + "_" + this._tempCounter.save++;
805
791
  this.writeSaveData(saveFile, saveData);
806
792
  await this.watchLogChunk(
@@ -825,15 +811,24 @@ class Omegga extends wrapper.default {
825
811
  correctPalette = false,
826
812
  correctCustom = false
827
813
  } = {}) {
828
- if (this.#warnRemoved(
814
+ player = typeof player === "string" ? this.getPlayer(player) : player;
815
+ if (!player) return;
816
+ if (brsRemoved(this.version)) {
817
+ const { ref, file: file2 } = writeTempPrefab(this, saveData);
818
+ this.givePrefabToPlayer(ref, player);
819
+ setTimeout(() => {
820
+ if (fs.existsSync(file2)) fs.unlinkSync(file2);
821
+ }, 5e3);
822
+ return;
823
+ }
824
+ if (warnRemoved(
825
+ this.version,
829
826
  "loadSaveDataOnPlayer",
830
827
  commands.EA2_VERSION,
831
828
  "EA2",
832
829
  "loadPrefabOnPlayer"
833
830
  ))
834
831
  return;
835
- player = typeof player === "string" ? this.getPlayer(player) : player;
836
- if (!player) return;
837
832
  const saveFile = this._tempSavePrefix + Date.now() + "_" + this._tempCounter.save++;
838
833
  this.writeSaveData(saveFile, saveData);
839
834
  await this.watchLogChunk(
@@ -852,8 +847,54 @@ class Omegga extends wrapper.default {
852
847
  }
853
848
  }
854
849
  async getSaveData(region) {
855
- if (this.#warnRemoved("getSaveData", commands.PREFAB_VERSION, "EA3", "the prefab API"))
856
- return void 0;
850
+ if (brsRemoved(this.version)) {
851
+ const ref = this._tempSavePrefix + Date.now() + "_" + this._tempCounter.save++;
852
+ const file2 = await this.savePrefabAsync(ref, { region });
853
+ if (!file2) return void 0;
854
+ try {
855
+ const MAIN_GRID = 1;
856
+ const reader = brs.WorldReader.from(new Uint8Array(fs.readFileSync(file2)));
857
+ const bricks = [...reader.bricks(MAIN_GRID)].map((b) => ({
858
+ ...b,
859
+ physical_index: 0,
860
+ components: {}
861
+ }));
862
+ let brickOffset = 0;
863
+ for (const chunk of reader.brickChunkIndex(MAIN_GRID)) {
864
+ if (chunk.numComponents > 0) {
865
+ const { components } = reader.componentChunk(
866
+ MAIN_GRID,
867
+ chunk.index
868
+ );
869
+ for (const c of components) {
870
+ const brick = bricks[brickOffset + c.brickIndex];
871
+ if (brick) brick.components[c.typeName] = c.data ?? {};
872
+ }
873
+ }
874
+ brickOffset += chunk.numBricks;
875
+ }
876
+ return {
877
+ version: 10,
878
+ map: this.currentMap ?? "Unknown",
879
+ author: { id: this.host?.id ?? "", name: this.host?.name ?? "" },
880
+ host: { id: this.host?.id ?? "", name: this.host?.name ?? "" },
881
+ description: "",
882
+ brick_count: bricks.length,
883
+ mods: [],
884
+ brick_assets: reader.brickAssets(),
885
+ colors: [],
886
+ materials: reader.materials(),
887
+ physical_materials: [],
888
+ brick_owners: reader.brickOwners(),
889
+ game_version: this.version,
890
+ save_time: new Uint8Array(),
891
+ bricks,
892
+ components: {}
893
+ };
894
+ } finally {
895
+ if (fs.existsSync(file2)) fs.unlinkSync(file2);
896
+ }
897
+ }
857
898
  const saveFile = this._tempSavePrefix + Date.now() + "_" + this._tempCounter.save++;
858
899
  await this.saveBricksAsync(saveFile, region);
859
900
  const savePath = this.getSavePath(saveFile);
@@ -881,8 +922,9 @@ class Omegga extends wrapper.default {
881
922
  overrideUserId = ""
882
923
  } = {}) {
883
924
  if (!path2) return;
925
+ const rootPart = rootEntityPersistentIndex >= 0 ? ` ${rootEntityPersistentIndex} ${mirrorAxes}${overrideUserId ? ` "${overrideUserId}"` : ""}` : "";
884
926
  this.writeln(
885
- `${this.Console.Prefab.Load} "${path2}" ${offX} ${offY} ${offZ} ${atOriginalPosition ? 1 : 0} ${orientation} ${rootEntityPersistentIndex} ${mirrorAxes}${overrideUserId ? ` "${overrideUserId}"` : ""}`
927
+ `${this.Console.Prefab.Load} "${path2}" ${offX} ${offY} ${offZ} ${atOriginalPosition ? 1 : 0} ${orientation}${rootPart}`
886
928
  );
887
929
  }
888
930
  /**