You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+25-25Lines changed: 25 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,32 +1,32 @@
1
-
# Simple Binary Builder
1
+
# Build-A-File
2
2
3
-
Simple Binary Builder (SBB) is a framework that makes it easy to create custom binary file formats and assemble your data into them.
3
+
Build-A-File (BAF) is a framework that makes it easy to create custom binary file formats and assemble your data into them.
4
4
5
-
It was originally created to easily build binary data files for games targeting Amiga and other retro systems. However, SBB can be used for any general purpose. It was born as an internal-only tool, so it's a bit rough around the edges, but if you follow the rules then it gets the job done. :)
5
+
It was originally created to easily build binary data files for games targeting Amiga and other retro systems. However, BAF can be used for any general purpose. It was born as an internal-only tool, so it's a bit rough around the edges, but if you follow the rules then it gets the job done. :)
6
6
7
-
SBB is a one-way tool: It takes source data and builds it into a binary file. If you want to reverse-engineer existing binary files into an ORM, check out [Mr. Crowbar](https://github.com/moralrecordings/mrcrowbar), which inspired this project (and is probably much more well-written).
7
+
BAF is a one-way tool: It takes source data and builds it into a binary file. If you want to reverse-engineer existing binary files into an ORM, check out [Mr. Crowbar](https://github.com/moralrecordings/mrcrowbar), which inspired this project (and is probably much more well-written).
8
8
9
9
## Requirements
10
10
11
-
SBB requires Python 3.12 or higher.
11
+
BAF requires Python 3.12 or higher.
12
12
13
13
## Examples
14
14
15
15
### Basic example
16
16
17
-
With SBB, data structures are defined using `Block`s. Create a class that derives from `Block`, then annotate some property names, and a datatype for each property.
17
+
With BAF, data structures are defined using `Block`s. Create a class that derives from `Block`, then annotate some property names, and a datatype for each property.
18
18
19
-
In your TOML file, create some corresponding entries with the same names as your properties. When you load the TOML file to your `Block` class, SBB will automatically fill in all the properties with the data from the TOML file.
19
+
In your TOML file, create some corresponding entries with the same names as your properties. When you load the TOML file to your `Block` class, BAF will automatically fill in all the properties with the data from the TOML file.
20
20
21
-
Notice we have one property, `name_length`, that isn't in the TOML. That's because we want to programmatically give this a value, rather than define it in the TOML. To do this, create a setter method called `set_name_length()`. If SBB finds a setter method called `set_<property_name>`, it will use that to fill in the data with whatever value you return.
21
+
Notice we have one property, `name_length`, that isn't in the TOML. That's because we want to programmatically give this a value, rather than define it in the TOML. To do this, create a setter method called `set_name_length()`. If BAF finds a setter method called `set_<property_name>`, it will use that to fill in the data with whatever value you return.
22
22
23
23
Whatever data is given to the parent `Block` (in this case, the `dict` generated from our TOML file), that will also be passed to the setter method. So, if you need that data to determine your value, you can use it.
24
24
25
25
`example.py`:
26
26
27
27
```py
28
-
importsbb
29
-
fromsbb.datatypes import*
28
+
importbaf
29
+
frombaf.datatypes import*
30
30
31
31
32
32
classLevel(Block):
@@ -39,7 +39,7 @@ class Level(Block):
39
39
returnself.name.size()
40
40
41
41
42
-
level =sbb.build_toml('example.toml', Level)
42
+
level =baf.build_toml('example.toml', Level)
43
43
level_bytes = level.to_bytes()
44
44
print(level_bytes.hex())
45
45
# Write file to disk
@@ -68,7 +68,7 @@ You can nest `Block`s to create more complex data structures.
68
68
69
69
In this example, `Level` has two properties, `header` and `data`, which are each a `Block` of their own. The TOML file reflects this.
70
70
71
-
Remember that we're passing `Level` to `sbb.build_toml()`, which is how `Level` is specified as the top-level block.
71
+
Remember that we're passing `Level` to `baf.build_toml()`, which is how `Level` is specified as the top-level block.
72
72
73
73
```py
74
74
classLevelHeader(Block):
@@ -110,7 +110,7 @@ height = 128
110
110
111
111
In the above example, you'll notice that `name_length` is set using `self.name.size()`, and `data_offset` is set using `self.data.offset()`. These two functions work on any datatype, and you can use them in your setter without worrying about the order in which data is built.
112
112
113
-
Behind the scenes, SBB uses some aggressive reflection to figure out which properties have dependencies on others. For example, to figure out `data_offset`, SBB needs to know the size of `header`, so it builds `header` first. If there is a circular dependency, you will get an error.
113
+
Behind the scenes, BAF uses some aggressive reflection to figure out which properties have dependencies on others. For example, to figure out `data_offset`, BAF needs to know the size of `header`, so it builds `header` first. If there is a circular dependency, you will get an error.
114
114
115
115
### `Array`
116
116
@@ -156,11 +156,11 @@ spawn_y = 56
156
156
157
157
### Visualizer
158
158
159
-
After getting our `Level` object with `sbb.build_toml()`, we can use `sbb.visualize()` to view a tree of our file format.
159
+
After getting our `Level` object with `baf.build_toml()`, we can use `baf.visualize()` to view a tree of our file format.
You can build on top of SBB with custom datatypes that suit your purposes.
269
+
You can build on top of BAF with custom datatypes that suit your purposes.
270
270
271
-
For example, SBB doesn't have a built-in `Bool` datatype because `bool` can have different implementations depending on the platform. It's easy to define your own.
271
+
For example, BAF doesn't have a built-in `Bool` datatype because `bool` can have different implementations depending on the platform. It's easy to define your own.
272
272
273
273
```py
274
274
classBool(U8):
@@ -291,7 +291,7 @@ has_boss = true
291
291
292
292
Below is an example of a custom `List` datatype which combines item count, item offsets, and item data.
293
293
294
-
SBB ignores the annotations in the base `List` class—it only cares about those in the derived `Rooms` and `Spritesheets` classes. Notice how `items` contains a different `Array` type in `Rooms` and `Spritesheets`.
294
+
BAF ignores the annotations in the base `List` class—it only cares about those in the derived `Rooms` and `Spritesheets` classes. Notice how `items` contains a different `Array` type in `Rooms` and `Spritesheets`.
295
295
296
296
```py
297
297
classList(Block):
@@ -329,7 +329,7 @@ class Spritesheets(List):
329
329
330
330
### Overriding `__init__()`
331
331
332
-
You can override `__init__()` if you need to do something highly specific with your data that SBB can't handle automatically. Fill in whatever data you want manually, and then call `super().__init__(parent, data)` at the end (don't forget this step). SBB will kick in and build any remaining data based on your TOML.
332
+
You can override `__init__()` if you need to do something highly specific with your data that BAF can't handle automatically. Fill in whatever data you want manually, and then call `super().__init__(parent, data)` at the end (don't forget this step). BAF will kick in and build any remaining data based on your TOML.
333
333
334
334
Below, I have a list `Bobs`, but the data in the TOML needs to be processed into a more specific format before the list can be built.
If SBB catches an exception, it will add notes to the exception containing a traceback of your data structures, so you can pinpoint what data or setter caused the issue.
372
+
If BAF catches an exception, it will add notes to the exception containing a traceback of your data structures, so you can pinpoint what data or setter caused the issue.
373
373
374
-
SBB doesn't discard or sanitize the full Python traceback, so it's ugly by default. If you want it to look nice, catch the exception yourself and print `__notes__`, as shown below. However, the default Python exception will also show the notes at the bottom, so this is optional.
374
+
BAF doesn't discard or sanitize the full Python traceback, so it's ugly by default. If you want it to look nice, catch the exception yourself and print `__notes__`, as shown below. However, the default Python exception will also show the notes at the bottom, so this is optional.
0 commit comments