reticulator


Namereticulator JSON
Version 0.2.0b0 PyPI version JSON
download
home_page
SummaryReticulator is a library for interacting with Minecraft Bedrock Add-ons programmatically.
upload_time2023-11-11 14:19:24
maintainer
docs_urlNone
author
requires_python
licenseMIT License Copyright (c) 2021 LIAM KOEHLER Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords minecraft bedrock-edition bedrock-addons
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Reticulator

Reticulator is a library for parsing Minecraft Bedrock Add-ons, and interacting with them programmatically. First you read the project into a virtual filesystem, which is represented by a nested list of classes. You can read and write to these data structures. When you are finished, you can save your changes back to the filesystem.

Reticulator is built as a wrapper around the 'dpath' library, which gives you a powerful interface for interacting with the raw json, if desired.

### Minimal Example

This small example shows you a minimal example of opening a project, making some changes, and then saving the results:

```py
import reticulator

# Open up a new Reticulator project. There are various ways to do this.
project = reticulator.Project('./path/to/bp', './path/to/rp')
bp = project.behavior_pack

# Step through the project in a comfortable manor, and adjust the 'health' component.
for entity in bp.entities:
	for component in entity.components:
		if component.id == "minecraft:health":
			print(f"Adjusted Health for {entity.identifier}.")
			component.set_jsonpath('value', 10)

# When you are finished, you can save your changes back to the filesystem
project.save()
```

# Documentation

## Project Structure

### Importing and Installing

Reticulator is available on `pip` package manager. In most cases, you're going to want to install using `pip install reticulator`. Once installed, you can import into your project however you find convenient. To keep the documentation concise, the documentation will assume you're imported the full namespace: 

```py
from reticulator import *
```

### Loading your Project

Reticulator is purpose built for reading and writing Bedrock add-ons. The bedrock wiki contains detailed information about the folder [layout of the folders](https://wiki.bedrock.dev/documentation/pack-structure.html). Reticulator can load projects matching this format.

To load a project with both an RP and a BP, you can use the `Project` class. A `Project` holds a reference to both packs, and allows classes in one side to be aware of the other. For example, an Entity has a definition file in both packs.

```py
project = Project('./path/to/bp', './path/to/rp')
bp = project.behavior_pack
rp = project.resource_pack
```

If you only have a single, stand-alone pack, you can open it directly using `BehaviorPack` or `ResourcePack`, which both inherit from `Pack`:

```py
bp = BehaviorPack('./path/to/bp')
```

### Saving your Project

When you make a change in a reticulator class, it won't be saved back to the filesystem by default. Rather, it will be held in-memory, in a 'virtual filesystem'. To convert this virtual filesystem back into real files, you need to `save` your project.

Here is an example of opening a project, changing the identifier of an entity, and then saving that entity back into the filesystem:

```py
bp = BehaviorPack('./path/to/bp')

entity = bp.get_entity('minecraft:snail')
entity.identifier = 'minecraft:sirlich'

bp.save()
```

The `save()` here will put the files into the packs `output_directory`. By default, that will be the folder where the project files were read from. In other words reticulator is optimized for reading files, and saving the changes back into the same location. This makes it perfect for [Regolith](https://bedrock-oss.github.io/regolith/).

If you want to change the `output_directory` you can do so from the `Pack`:

```py
bp = BehaviorPack('./path/to/bp')

entity = bp.get_entity('minecraft:snail')
entity.identifier = 'minecraft:sirlich'

bp.output_location = './path/to/save/to'
bp.save()
```

In the above example, you may notice that only the file containing `minecraft:sirlich` will be exported. That's because regolith is *lazy* and doesn't do more work than needed: only edited files are exported. Once again, regolith is optimized for destructive-writing into the same folder where the files were read.

To force Regolith to write every file it knows about, you must call save like this:

```py
bp.save(force=True)
```

## Interacting with the Class-Tree

Regolith is designed as a nested tree of classes, each class representing a 'part' of the add-on system which you may want to interact with. Here are a collection of small examples, showcasing the kind of read-calls that Reticulator supports:

Print warnings for miss-matched entities:

```py
project = Project('./path/to/bp', './path/to/rp')
rp = project.resource_pack

for entity in rp.entities:
	if entity.counterpart == None:
		print(f"WARNING: Entity {entity.identifier} has a resource pack definition, but no behavior pack definition!")
```

Ensure that models aren't too complex:

```py
rp = ResourcePack('./path/to/rp')

for model in entity.models:
	cube_count = 0
	for bone in model.bones:
		cube_count += len(bone.cubes)

	if cube_count > 200:
		print(f"Model {model.identifier} contains {cube_count} cubes, which is too many!")
```

## Raw JSON Access

### DPATH

The class-tree is pretty cool, but sometimes it's just a bit too much boilerplate. Regolith provides a user-friendly wrapper around [dpath](https://pypi.org/project/dpath/), which allows you to access and manipulate the json directly.

In a nutshell, dpath allows you to interact with json using a string-path. For example the path: `minecraft:entity/description/identifier` could be used to get the identifier of an entity. You can use `*` to stand in for a single 'layer' or `**` to stand in for an arbitrary number of layers. For example: `**/identifier` would match ANY key called 'identifier' in the entity json.

The following methods are available on any json based class, but I will use an 'entity' to illustrate:
 - Get a path: `data = entity.get_jsonpath('path/to/field')`
 - Set a path: `entity.set_jsonpath('path/to/field', 'new value')`
 - Delete a path: `entity.delete_jsonpath('path/to/field')`
 - Delete a path and return the result: `data = entity.pop_jsonpath('path/to/field')`
 - Appends a value to a path (array expected): `entity.append_jsonpath('path/to/array', 10)`

And then here is a feature complete example, which shows deleting a specific component from all entities. `**` is a wildcard for matching the component wherever it may be found -in components, or component groups:

```py
bp = BehaviorPack('bp')

for entity in bp.entities:
    entity.delete_jsonpath('**/minecraft:minecraft:behavior.melee_attack')

bp.save()
```

### True JSON Access

If the DPATH methods don't please you, you're also welcome to interact with the json data directly, although this is discouraged. To do so, just access the `data` field on any json based class. For example:

```py
bp = BehaviorPack('./path/to/bp')
entity = bp.get_entity('minecraft:snail')

entity.data['minecraft:entity']['description']['identifier'] == 'minecraft:sirlich'
```

I hope you can see why this isn't my favorite way to use Regolith. 

## Language Files

Regolith offers strong support for language file editing. Here are a few examples:


Printing out data:

```py
rp = ResourcePack('./path/to/rp')
for language_file in rp.language_files:
	for translation in language_files:
		print(f"Translation: key='{translation.key}', value='{translation.value}')
```

Auto-translating entity names with place-holder:

```py
rp = ResourcePack('./path/to/rp')
en_us = rp.get_language_file('texts/en_US')

for entity in rp.entities:
	en_us.add_translation(Translation(f"item.spawn_egg.entity.{entity.identifier}.name", f"PLACEHOLDER NAME: {entity.identifier}", "# TODO"))

rp.save()
```

## Functions

We support functions, I just didn't document it yet

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "reticulator",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "MINECRAFT,BEDROCK-EDITION,BEDROCK-ADDONS",
    "author": "",
    "author_email": "",
    "download_url": "https://files.pythonhosted.org/packages/78/fb/f592401e72e82743e2ab2831e40ef772492b628e635486818340eca5096a/reticulator-0.2.0b0.tar.gz",
    "platform": null,
    "description": "# Reticulator\r\n\r\nReticulator is a library for parsing Minecraft Bedrock Add-ons, and interacting with them programmatically. First you read the project into a virtual filesystem, which is represented by a nested list of classes. You can read and write to these data structures. When you are finished, you can save your changes back to the filesystem.\r\n\r\nReticulator is built as a wrapper around the 'dpath' library, which gives you a powerful interface for interacting with the raw json, if desired.\r\n\r\n### Minimal Example\r\n\r\nThis small example shows you a minimal example of opening a project, making some changes, and then saving the results:\r\n\r\n```py\r\nimport reticulator\r\n\r\n# Open up a new Reticulator project. There are various ways to do this.\r\nproject = reticulator.Project('./path/to/bp', './path/to/rp')\r\nbp = project.behavior_pack\r\n\r\n# Step through the project in a comfortable manor, and adjust the 'health' component.\r\nfor entity in bp.entities:\r\n\tfor component in entity.components:\r\n\t\tif component.id == \"minecraft:health\":\r\n\t\t\tprint(f\"Adjusted Health for {entity.identifier}.\")\r\n\t\t\tcomponent.set_jsonpath('value', 10)\r\n\r\n# When you are finished, you can save your changes back to the filesystem\r\nproject.save()\r\n```\r\n\r\n# Documentation\r\n\r\n## Project Structure\r\n\r\n### Importing and Installing\r\n\r\nReticulator is available on `pip` package manager. In most cases, you're going to want to install using `pip install reticulator`. Once installed, you can import into your project however you find convenient. To keep the documentation concise, the documentation will assume you're imported the full namespace: \r\n\r\n```py\r\nfrom reticulator import *\r\n```\r\n\r\n### Loading your Project\r\n\r\nReticulator is purpose built for reading and writing Bedrock add-ons. The bedrock wiki contains detailed information about the folder [layout of the folders](https://wiki.bedrock.dev/documentation/pack-structure.html). Reticulator can load projects matching this format.\r\n\r\nTo load a project with both an RP and a BP, you can use the `Project` class. A `Project` holds a reference to both packs, and allows classes in one side to be aware of the other. For example, an Entity has a definition file in both packs.\r\n\r\n```py\r\nproject = Project('./path/to/bp', './path/to/rp')\r\nbp = project.behavior_pack\r\nrp = project.resource_pack\r\n```\r\n\r\nIf you only have a single, stand-alone pack, you can open it directly using `BehaviorPack` or `ResourcePack`, which both inherit from `Pack`:\r\n\r\n```py\r\nbp = BehaviorPack('./path/to/bp')\r\n```\r\n\r\n### Saving your Project\r\n\r\nWhen you make a change in a reticulator class, it won't be saved back to the filesystem by default. Rather, it will be held in-memory, in a 'virtual filesystem'. To convert this virtual filesystem back into real files, you need to `save` your project.\r\n\r\nHere is an example of opening a project, changing the identifier of an entity, and then saving that entity back into the filesystem:\r\n\r\n```py\r\nbp = BehaviorPack('./path/to/bp')\r\n\r\nentity = bp.get_entity('minecraft:snail')\r\nentity.identifier = 'minecraft:sirlich'\r\n\r\nbp.save()\r\n```\r\n\r\nThe `save()` here will put the files into the packs `output_directory`. By default, that will be the folder where the project files were read from. In other words reticulator is optimized for reading files, and saving the changes back into the same location. This makes it perfect for [Regolith](https://bedrock-oss.github.io/regolith/).\r\n\r\nIf you want to change the `output_directory` you can do so from the `Pack`:\r\n\r\n```py\r\nbp = BehaviorPack('./path/to/bp')\r\n\r\nentity = bp.get_entity('minecraft:snail')\r\nentity.identifier = 'minecraft:sirlich'\r\n\r\nbp.output_location = './path/to/save/to'\r\nbp.save()\r\n```\r\n\r\nIn the above example, you may notice that only the file containing `minecraft:sirlich` will be exported. That's because regolith is *lazy* and doesn't do more work than needed: only edited files are exported. Once again, regolith is optimized for destructive-writing into the same folder where the files were read.\r\n\r\nTo force Regolith to write every file it knows about, you must call save like this:\r\n\r\n```py\r\nbp.save(force=True)\r\n```\r\n\r\n## Interacting with the Class-Tree\r\n\r\nRegolith is designed as a nested tree of classes, each class representing a 'part' of the add-on system which you may want to interact with. Here are a collection of small examples, showcasing the kind of read-calls that Reticulator supports:\r\n\r\nPrint warnings for miss-matched entities:\r\n\r\n```py\r\nproject = Project('./path/to/bp', './path/to/rp')\r\nrp = project.resource_pack\r\n\r\nfor entity in rp.entities:\r\n\tif entity.counterpart == None:\r\n\t\tprint(f\"WARNING: Entity {entity.identifier} has a resource pack definition, but no behavior pack definition!\")\r\n```\r\n\r\nEnsure that models aren't too complex:\r\n\r\n```py\r\nrp = ResourcePack('./path/to/rp')\r\n\r\nfor model in entity.models:\r\n\tcube_count = 0\r\n\tfor bone in model.bones:\r\n\t\tcube_count += len(bone.cubes)\r\n\r\n\tif cube_count > 200:\r\n\t\tprint(f\"Model {model.identifier} contains {cube_count} cubes, which is too many!\")\r\n```\r\n\r\n## Raw JSON Access\r\n\r\n### DPATH\r\n\r\nThe class-tree is pretty cool, but sometimes it's just a bit too much boilerplate. Regolith provides a user-friendly wrapper around [dpath](https://pypi.org/project/dpath/), which allows you to access and manipulate the json directly.\r\n\r\nIn a nutshell, dpath allows you to interact with json using a string-path. For example the path: `minecraft:entity/description/identifier` could be used to get the identifier of an entity. You can use `*` to stand in for a single 'layer' or `**` to stand in for an arbitrary number of layers. For example: `**/identifier` would match ANY key called 'identifier' in the entity json.\r\n\r\nThe following methods are available on any json based class, but I will use an 'entity' to illustrate:\r\n - Get a path: `data = entity.get_jsonpath('path/to/field')`\r\n - Set a path: `entity.set_jsonpath('path/to/field', 'new value')`\r\n - Delete a path: `entity.delete_jsonpath('path/to/field')`\r\n - Delete a path and return the result: `data = entity.pop_jsonpath('path/to/field')`\r\n - Appends a value to a path (array expected): `entity.append_jsonpath('path/to/array', 10)`\r\n\r\nAnd then here is a feature complete example, which shows deleting a specific component from all entities. `**` is a wildcard for matching the component wherever it may be found -in components, or component groups:\r\n\r\n```py\r\nbp = BehaviorPack('bp')\r\n\r\nfor entity in bp.entities:\r\n    entity.delete_jsonpath('**/minecraft:minecraft:behavior.melee_attack')\r\n\r\nbp.save()\r\n```\r\n\r\n### True JSON Access\r\n\r\nIf the DPATH methods don't please you, you're also welcome to interact with the json data directly, although this is discouraged. To do so, just access the `data` field on any json based class. For example:\r\n\r\n```py\r\nbp = BehaviorPack('./path/to/bp')\r\nentity = bp.get_entity('minecraft:snail')\r\n\r\nentity.data['minecraft:entity']['description']['identifier'] == 'minecraft:sirlich'\r\n```\r\n\r\nI hope you can see why this isn't my favorite way to use Regolith. \r\n\r\n## Language Files\r\n\r\nRegolith offers strong support for language file editing. Here are a few examples:\r\n\r\n\r\nPrinting out data:\r\n\r\n```py\r\nrp = ResourcePack('./path/to/rp')\r\nfor language_file in rp.language_files:\r\n\tfor translation in language_files:\r\n\t\tprint(f\"Translation: key='{translation.key}', value='{translation.value}')\r\n```\r\n\r\nAuto-translating entity names with place-holder:\r\n\r\n```py\r\nrp = ResourcePack('./path/to/rp')\r\nen_us = rp.get_language_file('texts/en_US')\r\n\r\nfor entity in rp.entities:\r\n\ten_us.add_translation(Translation(f\"item.spawn_egg.entity.{entity.identifier}.name\", f\"PLACEHOLDER NAME: {entity.identifier}\", \"# TODO\"))\r\n\r\nrp.save()\r\n```\r\n\r\n## Functions\r\n\r\nWe support functions, I just didn't document it yet\r\n",
    "bugtrack_url": null,
    "license": "MIT License Copyright (c) 2021 LIAM KOEHLER Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
    "summary": "Reticulator is a library for interacting with Minecraft Bedrock Add-ons programmatically.",
    "version": "0.2.0b0",
    "project_urls": null,
    "split_keywords": [
        "minecraft",
        "bedrock-edition",
        "bedrock-addons"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "78fbf592401e72e82743e2ab2831e40ef772492b628e635486818340eca5096a",
                "md5": "b7c4b6d3f6b51c0274bb6297a5d58494",
                "sha256": "7c1afcc6babd799504e74b0f1c58fc5fd9b534267114f1e5bb5bfef30b864de5"
            },
            "downloads": -1,
            "filename": "reticulator-0.2.0b0.tar.gz",
            "has_sig": false,
            "md5_digest": "b7c4b6d3f6b51c0274bb6297a5d58494",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 30637,
            "upload_time": "2023-11-11T14:19:24",
            "upload_time_iso_8601": "2023-11-11T14:19:24.837416Z",
            "url": "https://files.pythonhosted.org/packages/78/fb/f592401e72e82743e2ab2831e40ef772492b628e635486818340eca5096a/reticulator-0.2.0b0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-11 14:19:24",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "reticulator"
}
        
Elapsed time: 0.14414s