{"id":29928614,"url":"https://github.com/meshiest/brs-js","last_synced_at":"2025-08-02T14:09:59.443Z","repository":{"id":35117159,"uuid":"208834461","full_name":"Meshiest/brs-js","owner":"Meshiest","description":"Brickadia save file parsing library","archived":false,"fork":false,"pushed_at":"2025-07-12T21:10:32.000Z","size":2300,"stargazers_count":4,"open_issues_count":1,"forks_count":6,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-12T21:25:25.403Z","etag":null,"topics":["brickadia","decoding-library","encoding-library","save-files"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/brs-js","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Meshiest.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-09-16T15:29:35.000Z","updated_at":"2025-07-12T21:10:36.000Z","dependencies_parsed_at":"2023-01-15T14:10:25.285Z","dependency_job_id":null,"html_url":"https://github.com/Meshiest/brs-js","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Meshiest/brs-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meshiest%2Fbrs-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meshiest%2Fbrs-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meshiest%2Fbrs-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meshiest%2Fbrs-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Meshiest","download_url":"https://codeload.github.com/Meshiest/brs-js/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meshiest%2Fbrs-js/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268401594,"owners_count":24244464,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-02T02:00:12.353Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["brickadia","decoding-library","encoding-library","save-files"],"created_at":"2025-08-02T14:09:58.361Z","updated_at":"2025-08-02T14:09:59.401Z","avatar_url":"https://github.com/Meshiest.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# brs.js\n\nRead and write Brickadia save files (.brs)\n\nCurrently supports save versions \u003c= 10\n\n**Warning:** __Unreal Engine uses numbers potentially larger than Javascript can handle.__\n\n## Install\n\n`npm install brs-js`\n\n## Documentation and Usage\n\n**Node:**\n\n    const brs = require('brs-js');\n\n**ES6:**\n\n    import brs from 'brs-js';\n\n**Web:**\n\nHead: `\u003cscript src=\"https://cdn.jsdelivr.net/npm/brs-js/dist/dist.js\"\u003e\u003c/script\u003e`\n\nScript: `window.BRS`\n\n### Examples\n\nExamples are available in the `examples/` directory. All `.js` examples are for node, `.html` are for web.\n\n### Save Object\n\nThe Save Object is the input and output of this program. It represents the decoded/decompressed contents of the save.\nStrings can be UCS-2 or UTF-8. UUIDs follow the spec. The `save_time` field is 8 bytes (Little Endian) instead of a long.\nUnsigned ints, while unlikely, may overflow.\n\n```javascript\n{\n  version: short,\n  map: string,\n  author: {id: uuid, name: string},\n  host: {id: uuid, name: string} // (v8+ only)\n  description: string,\n  save_time: UTC as 8 bytes,\n  brick_count: int,\n  mods: string array,\n  brick_assets: [string],\n    // --- See bottom of page for known bricks ---\n  colors: [[byte, byte, byte, byte], ... ],\n  physical_materials: [string], // BPMC_Default\n  materials: [string],\n    // --- Known available materials\n    // BMC_Ghost\n    // BMC_Ghost_Fail\n    // BMC_Plastic\n    // BMC_Glass\n    // BMC_TranslucentPlastic\n    // BMC_Glow\n    // BMC_Metallic\n    // BMC_Hologram\n  brick_owners: [{\n    id: uuid,\n    name: string,\n    displayName: string, // (v14+ only)\n    bricks: int // (v8+ only)\n  }, ... ],\n  components: {\n    [componentName]: {\n      version: int,\n      brick_indices: [int, ...],\n      properties: {[name]: [value], ...},\n    },\n    ...\n  },\n  wires: [{\n    source: {\n      component: string, // component name\n      brick_index: int, // index of the brick in `bricks`\n      port: string, // port name\n    },\n    target: {\n      component: string, // component name\n      brick_index: int, // index of the brick in `bricks`\n      port: string, // port name\n    },\n  }]\n  bricks: [{\n    asset_name_index: int,\n    size: [uint, uint, uint],\n      // must be [0, 0, 0] for all B_ prefixed brick_assets\n      // must NOT be [0, 0, 0] for all PB_ prefixed brick_assets\n      // 1x1 brick has size [5, 5, 6]\n      // 1x1F plate has size [5, 5, 2]\n    position: [int, int, int],\n    direction: 0-5,\n      // --- Directions (facing axis) ---\n      // 0: X Positive\n      // 1: X Negative\n      // 2: Y Positive\n      // 3: Y Negative\n      // 4: Z Positive\n      // 5: Z Negative\n    rotation: 0-3,\n      // --- Rotations (along the facing axis) ---\n      // 0: 0 Deg\n      // 1: 90 Deg\n      // 2: 180 Deg\n      // 3: 270 Deg\n    collision: {\n      player: bool,\n      weapon: bool,\n      interaction: bool,\n      tool: bool,\n      physics: bool, // disable physics collision\n    }, // or bool\n    visibility: bool,\n    material_index: uint,\n    physical_index: uint,\n    material_intensity: 0-10,\n    color: uint or [byte, byte, byte, byte] or (v9) -\u003e [byte, byte, byte],\n    owner_index: uint,\n    components: {\n      [componentName]: {\n        [propName]: [propVal],\n        ...\n      },\n      ...\n    },\n  }, ... ],\n}\n```\n\n**Fields:** (optional fields during `brs.write(save)` will be set to default)\n\n| field                       | type   | default                              | optional | description                      |\n|-----------------------------|--------|--------------------------------------|----------|----------------------------------|\n| version                     | short  | Latest Save Version                  | auto     | Save file version                |\n| game_version                | int    | Game Version                         | \u0026#9745;  | Saving version of the game       |\n| map                         | string | 'Unknown'                            | \u0026#9745;  | Map where the save was generated |\n| author.id                   | uuid   | 00000000-0000-0000-0000-000000000000 | \u0026#9745;  | Save author UUID                 |\n| author.name                 | string | 'Unknown'                            | \u0026#9745;  | Save author name                 |\n| description                 | string | '' (Empty String)                    | \u0026#9745;  | Save author name                 |\n| save_time                   | array  | [0, 0, 0, 0, 0, 0, 0, 0]             | \u0026#9745;  | UTC in bytes of creation time    |\n| brick_count                 | int    | Number of bricks in `bricks`         | auto     | Number of bricks in save         |\n| mods                        | array  | []                                   | \u0026#9745;  | In game mods required for load   |\n| brick_assets                | array  | ['PB_DefaultBrick']                  | \u0026#9745;  | List of brick assets             |\n| colors                      | array  | []                                   | \u0026#9745;  | List of colorset colors          |\n| materials                   | array  | ['BMC_Plastic']                      | \u0026#9745;  | List of used materials           |\n| physical_materials          | array  | []                                   | \u0026#9745;  | List of physical materials       |\n| brick_owners                | array  | [{}]                                 | \u0026#9745;  | Brick owner list                 |\n| brick_owners[].id           | uuid   | 00000000-0000-0000-0000-000000000000 | \u0026#9745;  | Brick owner list user uuid       |\n| brick_owners[].name         | string | 'Unknown'                            | \u0026#9745;  | Brick owner list user name       |\n| brick_owners[].display_name | string | 'Unknown'                            | \u0026#9745;  | Brick owner list display name    |\n| preview                     | array  | undefined                            | \u0026#9745;  | 1280x720 png screenshot data     |\n| bricks                      | array  |                                      |          | List of bricks in the save       |\n| bricks[].asset_name_index   | int    | 0 (0 indexed)                        | \u0026#9745;  | Index of asset in `brick_assets` |\n| bricks[].size               | array  |                                      |          | Brick size                       |\n| bricks[].position           | array  |                                      |          | Brick position                   |\n| bricks[].direction          | int    | 4 (Positive Z, Upward)               | \u0026#9745;  | Brick axis / facing direction    |\n| bricks[].rotation           | int    | 0 (0 degrees)                        | \u0026#9745;  | Brick rotation on axis           |\n| bricks[].collision          | bool   | true                                 | \u0026#9745;  | Brick has collision with players |\n| bricks[].collision          | object |                                      | \u0026#9745;  | Brick collision in general       |\n| bricks[].visibility         | bool   | true                                 | \u0026#9745;  | Brick renders to players         |\n| bricks[].material_index     | int    | 0 (0 indexed)                        | \u0026#9745;  | Index of material in `materials` |\n| bricks[].material_intensity | int    | 0 (0 indexed)                        | \u0026#9745;  | Material intensity (0-10)        |\n| bricks[].physical_index     | int    | 0 (0 indexed)                        | \u0026#9745;  | Index of physical material       |\n| bricks[].color *(colorset)* | int    | 0                                    | \u0026#9745;  | Index of color in `colors`       |\n| bricks[].color *(rgba)*     | array  | [255, 255, 255, 255]                 | \u0026#9745;  | Color in RGBA Bytes              |\n| bricks[].color *(rgb)*      | array  | [255, 255, 255] *(v9+)*              | \u0026#9745;  | Color in RGBA Bytes              |\n| bricks[].owner_index        | int    | 1 (1 indexed)                        | \u0026#9745;  | Index of owner in `brick_owners` |\n| bricks[].components         | object | {}                                   | \u0026#9745;  | Components on this brick         |\n| components                  | object | {}                                   | \u0026#9745;  | List of components in the save   |\n| components[].version        | int    |                                      |          | Game version for this component  |\n| components[].brick_indices  | array  |                                      |          | Indices of assigned bricks       |\n| components[].properties     | object |                                      |          | Map of properties names and types|\n\n### Function `brs.read(buffer, options)`\n\n**Returns**: Save Object\n\nIn node, the buffer can be obtained from `fs.readFile` without an encoding specified. In web, the buffer can be obtained via `File.arrayBuffer()`. Be sure to resolve promises where necessary.\n\n| parameter   | type                | description                             |\n|-------------|---------------------|-----------------------------------------|\n| `buffer`    | Uint8Array / Buffer | Input bytes to be parsed                |\n| `options`   | Object              | Options for the parser, see table below |\n\n#### Options\n\n| name      | type    | description              | default |\n|-----------|---------|--------------------------|---------|\n| `bricks`  | boolean | Whether to read bricks   | `true`  |\n| `preview` | boolean | Whether to copy previews | `false` |\n\n### Function `brs.write(saveObj)`\n\n**Returns**: Uint8Array\n\nIn node, the buffer can be saved with from `fs.writeFile(fileName, buffer)`. In web, the buffer can be made into a `new Blob([buffer])`, and can be downloaded with an `\u003ca download\u003e` with `href` as `URL.createObjectURL(blob)`.\n\n| parameter   | type        | description                            |\n|-------------|-------------|----------------------------------------|\n| `saveObj`   | Save Object | Save Object to be turned into a buffer |\n\n### Brick Assets\n\nNotes:\n\n  - Size must be [0, 0, 0] for bricks using non-procedural brick assets\n  - Size must NOT be [0, 0, 0] for bricks using procedural brick assets\n  - 1x1 brick has size [5, 5, 6] and 'PB_DefaultBrick' brick asset\n  - 1x1F plate has size [5, 5, 2] and 'PB_DefaultBrick' brick asset\n\n\n| name | procedural |\n|------|------------|\n| PB_DefaultBrick | \u0026#9745; |\n| PB_DefaultRamp | \u0026#9745; |\n| PB_DefaultRampCrest | \u0026#9745; |\n| PB_DefaultRampCrestCorner | \u0026#9745; |\n| PB_DefaultRampCrestEnd | \u0026#9745; |\n| PB_DefaultRampInnerCornerInverted | \u0026#9745; |\n| PB_DefaultRampInverted | \u0026#9745; |\n| PB_DefaultSideWedge | \u0026#9745; |\n| PB_DefaultSideWedgeTile | \u0026#9745; |\n| PB_DefaultTile | \u0026#9745; |\n| PB_DefaultWedge | \u0026#9745; |\n| PB_DefaultMicroBrick | \u0026#9745; |\n| PB_DefaultMicroWedge | \u0026#9745; |\n| B_1x1_Brick_Side | |\n| B_1x1_Brick_Side_Lip | |\n| B_1x1_Cone | |\n| B_1x1_Round | |\n| B_1x1F_Octo | |\n| B_1x1F_Round | |\n| B_1x2_Overhang | |\n| B_1x2f_Plate_Center | |\n| B_1x2f_Plate_Center_Inv | |\n| B_1x4_Brick_Side | |\n| B_1x_Octo | |\n| B_1x_Octo_90Deg | |\n| B_1x_Octo_90Deg_Inv | |\n| B_1x_Octo_T | |\n| B_1x_Octo_T_Inv | |\n| B_2x1_Slipper | |\n| B_2x2_Cone | |\n| B_2x2_Corner | |\n| B_2x2_Overhang | |\n| B_2x2_Round | |\n| B_2x2_Slipper | |\n| B_2x2F_Octo | |\n| B_2x2F_Octo_Converter | |\n| B_2x2F_Octo_Converter_Inv | |\n| B_2x2f_Plate_Center | |\n| B_2x2f_Plate_Center_Inv | |\n| B_2x2F_Round | |\n| B_2x4_Door_Frame | |\n| B_2x_Cube_Side | |\n| B_2x_Octo | |\n| B_2x_Octo_90Deg | |\n| B_2x_Octo_90Deg_Inv | |\n| B_2x_Octo_Cone | |\n| B_2x_Octo_T | |\n| B_2x_Octo_T_Inv | |\n| B_4x4_Round | |\n| B_8x8_Lattice_Plate | |\n| B_Bishop | |\n| B_Bone | |\n| B_BoneStraight | |\n| B_Branch | |\n| B_Bush | |\n| B_Cauldron | |\n| B_Chalice | |\n| B_CheckPoint | |\n| B_Coffin | |\n| B_Coffin_Lid | |\n| B_Fern | |\n| B_Flame | |\n| B_Flower | |\n| B_Gravestone | |\n| B_GoalPoint | |\n| B_Handle | |\n| B_Hedge_1x1 | |\n| B_Hedge_1x1_Corner | |\n| B_Hedge_1x2 | |\n| B_Hedge_1x4 | |\n| B_Inverted_Cone | |\n| B_Jar | |\n| B_King | |\n| B_Knight | |\n| B_Ladder | |\n| B_Pawn | |\n| B_Picket_Fence | |\n| B_Pine_Tree | |\n| B_Pumpkin | |\n| B_Pumpkin_Carved | |\n| B_Queen | |\n| B_Rook | |\n| B_Sausage | |\n| B_Small_Flower | |\n| B_SpawnPoint | |\n| B_Swirl_Plate | |\n| B_Turkey_Body | |\n| B_Turkey_Leg | |\n| B_1x1_Gate_Constant | |\n| B_1x1_Gate_Subtract | |\n| B_1x1_Gate_Multiply | |\n| B_1x1_Gate_ModFloored | |\n| B_1x1_Gate_Mod | |\n| B_1x1_Gate_Divide | |\n| B_1x1_Gate_Blend | |\n| B_1x1_Gate_Add | |\n| B_1x1_Gate_XOR | |\n| B_1x1_Gate_OR | |\n| B_1x1_Gate_NOR | |\n| B_1x1_Gate_NAND | |\n| B_1x1_Gate_EdgeDetector | |\n| B_1x1_Gate_Floor | |\n| B_1x1_Gate_Ceiling | |\n| B_1x1_EntityGate_ReadBrickGrid | |\n| B_1x1_Gate_NotEqual | |\n| B_1x1_Gate_LessThanEqual | |\n| B_1x1_Gate_LessThan | |\n| B_1x1_Gate_GreaterThanEqual | |\n| B_1x1_Gate_GreaterThan | |\n| B_1x1_Gate_XOR_Bitwise | |\n| B_1x1_Gate_ShiftRight_Bitwise | |\n| B_1x1_Gate_ShiftLeft_Bitwise | |\n| B_1x1_Gate_OR_Bitwise | |\n| B_1x1_Gate_NOR_Bitwise | |\n| B_1x1_Gate_NAND_Bitwise | |\n| B_1x1_Gate_AND_Bitwise | |\n| B_1x1_Reroute_Node | |\n| B_1x1_Gate_Timer_Tick | |\n| B_1x1_Gate_Timer | |\n| B_1x1_NOT_Gate | |\n| B_1x1_Gate_AND | |\n| B_1x1_Gate_Equal | |\n| B_1x1_Gate_NOT_Bitwise | |\n\n## Development\n\nNPM Scripts (`npm run \u003ccmd\u003e`)\n\n| name  | description                                              |\n|-------|----------------------------------------------------------|\n| build | Build library in development mode                        |\n| watch | Auto-build library in development mode when files change |\n| dist  | Build library in production mode                         |\n| test  | Run tests                                                |\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeshiest%2Fbrs-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeshiest%2Fbrs-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeshiest%2Fbrs-js/lists"}