amulet-core 2.0a9__1.MSVC.19.43.34808.0-cp313-cp313-win_amd64.whl

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.

Potentially problematic release.


This version of amulet-core might be problematic. Click here for more details.

Files changed (45) hide show
  1. amulet/core/__init__.py +36 -0
  2. amulet/core/__pyinstaller/__init__.py +2 -0
  3. amulet/core/__pyinstaller/hook-amulet.core.py +4 -0
  4. amulet/core/_amulet_core.cp313-win_amd64.pyd +0 -0
  5. amulet/core/_amulet_core.pyi +7 -0
  6. amulet/core/_version.py +21 -0
  7. amulet/core/amulet_core.dll +0 -0
  8. amulet/core/amulet_core.lib +0 -0
  9. amulet/core/amulet_coreConfig.cmake +18 -0
  10. amulet/core/biome/__init__.pyi +75 -0
  11. amulet/core/biome/biome.hpp +53 -0
  12. amulet/core/block/__init__.pyi +270 -0
  13. amulet/core/block/block.hpp +156 -0
  14. amulet/core/block_entity/__init__.pyi +78 -0
  15. amulet/core/block_entity/block_entity.hpp +84 -0
  16. amulet/core/chunk/__init__.pyi +67 -0
  17. amulet/core/chunk/chunk.hpp +126 -0
  18. amulet/core/chunk/component/__init__.pyi +18 -0
  19. amulet/core/chunk/component/biome_3d_component.hpp +96 -0
  20. amulet/core/chunk/component/block_component.hpp +101 -0
  21. amulet/core/chunk/component/block_component.pyi +28 -0
  22. amulet/core/chunk/component/block_entity_component.hpp +119 -0
  23. amulet/core/chunk/component/section_array_map.hpp +129 -0
  24. amulet/core/chunk/component/section_array_map.pyi +77 -0
  25. amulet/core/dll.hpp +21 -0
  26. amulet/core/entity/__init__.pyi +105 -0
  27. amulet/core/entity/entity.hpp +100 -0
  28. amulet/core/palette/__init__.pyi +8 -0
  29. amulet/core/palette/biome_palette.hpp +65 -0
  30. amulet/core/palette/biome_palette.pyi +45 -0
  31. amulet/core/palette/block_palette.hpp +71 -0
  32. amulet/core/palette/block_palette.pyi +47 -0
  33. amulet/core/py.typed +0 -0
  34. amulet/core/selection/__init__.pyi +8 -0
  35. amulet/core/selection/box.hpp +86 -0
  36. amulet/core/selection/box.pyi +215 -0
  37. amulet/core/selection/group.hpp +80 -0
  38. amulet/core/selection/group.pyi +213 -0
  39. amulet/core/version/__init__.pyi +134 -0
  40. amulet/core/version/version.hpp +204 -0
  41. amulet_core-2.0a9.dist-info/METADATA +109 -0
  42. amulet_core-2.0a9.dist-info/RECORD +45 -0
  43. amulet_core-2.0a9.dist-info/WHEEL +6 -0
  44. amulet_core-2.0a9.dist-info/entry_points.txt +2 -0
  45. amulet_core-2.0a9.dist-info/top_level.txt +1 -0
@@ -0,0 +1,213 @@
1
+ from __future__ import annotations
2
+
3
+ import collections.abc
4
+ import types
5
+ import typing
6
+
7
+ import amulet.core.selection.box
8
+
9
+ __all__ = ["SelectionGroup"]
10
+
11
+ class SelectionGroup:
12
+ """
13
+ A container for zero or more :class:`SelectionBox` instances.
14
+
15
+ This allows for non-rectangular and non-contiguous selections.
16
+ """
17
+
18
+ __hash__: typing.ClassVar[None] = None # type: ignore
19
+ def __bool__(self) -> bool:
20
+ """
21
+ The number of :class:`SelectionBox` classes in the group.
22
+ """
23
+
24
+ @typing.overload
25
+ def __eq__(self, arg0: SelectionGroup) -> bool:
26
+ """
27
+ Does the contents of this :class:`SelectionGroup` match the other :class:`SelectionGroup`.
28
+
29
+ Note if the boxes do not exactly match this will return False even if the volume represented is the same.
30
+
31
+ :param other: The other :class:`SelectionGroup` to compare with.
32
+ :return: True if the boxes contained match.
33
+ """
34
+
35
+ @typing.overload
36
+ def __eq__(self, arg0: typing.Any) -> bool | types.NotImplementedType: ...
37
+ @typing.overload
38
+ def __init__(self) -> None:
39
+ """
40
+ Create an empty SelectionGroup.
41
+
42
+ >>> SelectionGroup()
43
+ """
44
+
45
+ @typing.overload
46
+ def __init__(self, box: amulet.core.selection.box.SelectionBox) -> None:
47
+ """
48
+ Create a SelectionGroup containing the given box.
49
+
50
+ >>> SelectionGroup(SelectionBox(0, 0, 0, 1, 1, 1))
51
+ """
52
+
53
+ @typing.overload
54
+ def __init__(
55
+ self, boxes: collections.abc.Iterable[amulet.core.selection.box.SelectionBox]
56
+ ) -> None:
57
+ """
58
+ Create a SelectionGroup from the boxes in the iterable.
59
+
60
+ >>> SelectionGroup([
61
+ >>> SelectionBox(0, 0, 0, 1, 1, 1),
62
+ >>> SelectionBox(1, 1, 1, 1, 1, 1)
63
+ >>> ])
64
+ """
65
+
66
+ def __iter__(self) -> typing.Iterator[amulet.core.selection.box.SelectionBox]:
67
+ """
68
+ An iterable of all the :class:`SelectionBox` classes in the group.
69
+ """
70
+
71
+ def __len__(self) -> int:
72
+ """
73
+ The number of :class:`SelectionBox` classes in the group.
74
+ """
75
+
76
+ def __repr__(self) -> str: ...
77
+ def __str__(self) -> str: ...
78
+ def contains_block(self, x: int, y: int, z: int) -> bool:
79
+ """
80
+ Is the block contained within the selection.
81
+
82
+ >>> selection1: AbstractBaseSelection
83
+ >>> (1, 2, 3) in selection1
84
+ True
85
+
86
+ :param x: The x coordinate of the block. Defined by the most negative corner.
87
+ :param y: The y coordinate of the block. Defined by the most negative corner.
88
+ :param z: The z coordinate of the block. Defined by the most negative corner.
89
+ :return: True if the block is in the selection.
90
+ """
91
+
92
+ def contains_point(self, x: float, y: float, z: float) -> bool:
93
+ """
94
+ Is the point contained within the selection.
95
+
96
+ >>> selection1: AbstractBaseSelection
97
+ >>> (1.5, 2.5, 3.5) in selection1
98
+ True
99
+
100
+ :param x: The x coordinate of the point.
101
+ :param y: The y coordinate of the point.
102
+ :param z: The z coordinate of the point.
103
+ :return: True if the point is in the selection.
104
+ """
105
+
106
+ @typing.overload
107
+ def intersects(self, other: amulet.core.selection.box.SelectionBox) -> bool:
108
+ """
109
+ Does this selection intersect ``other``.
110
+
111
+ :param other: The other selection.
112
+ :return: True if the selections intersect, False otherwise.
113
+ """
114
+
115
+ @typing.overload
116
+ def intersects(self, other: SelectionGroup) -> bool: ...
117
+ def translate(self, x: int, y: int, z: int) -> SelectionGroup:
118
+ """
119
+ Create a new :class:`SelectionGroup` based on this one with the coordinates moved by the given offset.
120
+
121
+ :param x: The x offset.
122
+ :param y: The y offset.
123
+ :param z: The z offset.
124
+ :return: The new selection with the given offset.
125
+ """
126
+
127
+ @property
128
+ def bounding_box(self) -> amulet.core.selection.box.SelectionBox:
129
+ """
130
+ A SelectionBox containing this entire selection.
131
+
132
+ :raises RuntimeError: If there are no boxes in the selection.
133
+ """
134
+
135
+ @property
136
+ def bounds(self) -> tuple[tuple[int, int, int], tuple[int, int, int]]:
137
+ """
138
+ The minimum and maximum x, y and z coordinates in the selection.
139
+
140
+ :raises RuntimeError: If there are no boxes in the selection.
141
+ """
142
+
143
+ @property
144
+ def max(self) -> tuple[int, int, int]:
145
+ """
146
+ The maximum x, y and z coordinates in the selection.
147
+
148
+ :raises RuntimeError: If there are no boxes in the selection.
149
+ """
150
+
151
+ @property
152
+ def max_x(self) -> int:
153
+ """
154
+ The maximum x coordinate in the selection.
155
+
156
+ :raises RuntimeError: If there are no boxes in the selection.
157
+ """
158
+
159
+ @property
160
+ def max_y(self) -> int:
161
+ """
162
+ The maximum y coordinate in the selection.
163
+
164
+ :raises RuntimeError: If there are no boxes in the selection.
165
+ """
166
+
167
+ @property
168
+ def max_z(self) -> int:
169
+ """
170
+ The maximum z coordinate in the selection.
171
+
172
+ :raises RuntimeError: If there are no boxes in the selection.
173
+ """
174
+
175
+ @property
176
+ def min(self) -> tuple[int, int, int]:
177
+ """
178
+ The minimum x, y and z coordinates in the selection.
179
+
180
+ :raises RuntimeError: If there are no boxes in the selection.
181
+ """
182
+
183
+ @property
184
+ def min_x(self) -> int:
185
+ """
186
+ The minimum x coordinate in the selection.
187
+
188
+ :raises RuntimeError: If there are no boxes in the selection.
189
+ """
190
+
191
+ @property
192
+ def min_y(self) -> int:
193
+ """
194
+ The minimum y coordinate in the selection.
195
+
196
+ :raises RuntimeError: If there are no boxes in the selection.
197
+ """
198
+
199
+ @property
200
+ def min_z(self) -> int:
201
+ """
202
+ The minimum z coordinate in the selection.
203
+
204
+ :raises RuntimeError: If there are no boxes in the selection.
205
+ """
206
+
207
+ @property
208
+ def selection_boxes(
209
+ self,
210
+ ) -> typing.Iterator[amulet.core.selection.box.SelectionBox]:
211
+ """
212
+ An iterator of the :class:`SelectionBox` instances stored for this group.
213
+ """
@@ -0,0 +1,134 @@
1
+ from __future__ import annotations
2
+
3
+ import types
4
+ import typing
5
+ from builtins import str as PlatformType
6
+
7
+ __all__ = [
8
+ "PlatformType",
9
+ "PlatformVersionContainer",
10
+ "VersionNumber",
11
+ "VersionRange",
12
+ "VersionRangeContainer",
13
+ ]
14
+
15
+ class PlatformVersionContainer:
16
+ """
17
+ A class storing platform identifier and version number.
18
+ Thread safe.
19
+ """
20
+
21
+ def __init__(self, platform: str, version: VersionNumber) -> None: ...
22
+ def __repr__(self) -> str: ...
23
+ @property
24
+ def platform(self) -> str:
25
+ """
26
+ Get the platform identifier.
27
+ """
28
+
29
+ @property
30
+ def version(self) -> VersionNumber:
31
+ """
32
+ Get the version number.
33
+ """
34
+
35
+ class VersionNumber:
36
+ """
37
+ This class is designed to store semantic versions and data versions and allow comparisons between them.
38
+ It is a wrapper around std::vector<std::int64_t> with special comparison handling.
39
+ The version can contain zero to max(int64) values.
40
+ Undefined trailing values are implied zeros. 1.1 == 1.1.0
41
+ All methods are thread safe.
42
+
43
+ >>> v1 = VersionNumber(1, 0, 0)
44
+ >>> v2 = VersionNumber(1, 0)
45
+ >>> assert v2 == v1
46
+
47
+ This class should also be used to store single number data versions.
48
+ >>> v3 = VersionNumber(3578)
49
+ """
50
+
51
+ def __contains__(self, arg0: int) -> bool: ...
52
+ @typing.overload
53
+ def __eq__(self, arg0: VersionNumber) -> bool: ...
54
+ @typing.overload
55
+ def __eq__(self, arg0: typing.Any) -> bool | types.NotImplementedType: ...
56
+ def __ge__(self, arg0: VersionNumber) -> bool: ...
57
+ @typing.overload
58
+ def __getitem__(self, item: typing.SupportsInt) -> int: ...
59
+ @typing.overload
60
+ def __getitem__(self, item: slice) -> list[int]: ...
61
+ def __gt__(self, arg0: VersionNumber) -> bool: ...
62
+ def __hash__(self) -> int: ...
63
+ def __init__(self, *args: typing.SupportsInt) -> None: ...
64
+ def __iter__(self) -> typing.Iterator[int]: ...
65
+ def __le__(self, arg0: VersionNumber) -> bool: ...
66
+ def __len__(self) -> int: ...
67
+ def __lt__(self, arg0: VersionNumber) -> bool: ...
68
+ def __repr__(self) -> str: ...
69
+ def __reversed__(self) -> typing.Iterator[int]: ...
70
+ def __str__(self) -> str: ...
71
+ def count(self, value: int) -> int: ...
72
+ def cropped_version(self) -> list[int]:
73
+ """
74
+ The version number with trailing zeros cut off.
75
+ """
76
+
77
+ def index(
78
+ self, value: int, start: int = 0, stop: int = 18446744073709551615
79
+ ) -> int: ...
80
+ def padded_version(self, len: int) -> list[int]:
81
+ """
82
+ Get the version number cropped or padded with zeros to the given length.
83
+ """
84
+
85
+ class VersionRange:
86
+ """
87
+ A class storing platform identifier and minimum and maximum version numbers.
88
+ Thread safe.
89
+ """
90
+
91
+ __hash__: typing.ClassVar[None] = None # type: ignore
92
+ @typing.overload
93
+ def __eq__(self, arg0: VersionRange) -> bool: ...
94
+ @typing.overload
95
+ def __eq__(self, arg0: typing.Any) -> bool | types.NotImplementedType: ...
96
+ def __init__(
97
+ self, platform: str, min_version: VersionNumber, max_version: VersionNumber
98
+ ) -> None: ...
99
+ def __repr__(self) -> str: ...
100
+ def contains(self, arg0: str, arg1: VersionNumber) -> bool:
101
+ """
102
+ Check if the platform is equal and the version number is within the range.
103
+ """
104
+
105
+ @property
106
+ def max_version(self) -> VersionNumber:
107
+ """
108
+ The maximum version number
109
+ """
110
+
111
+ @property
112
+ def min_version(self) -> VersionNumber:
113
+ """
114
+ The minimum version number
115
+ """
116
+
117
+ @property
118
+ def platform(self) -> str:
119
+ """
120
+ The platform identifier.
121
+ """
122
+
123
+ class VersionRangeContainer:
124
+ """
125
+ A class that contains a version range.
126
+ """
127
+
128
+ def __init__(self, version_range: VersionRange) -> None: ...
129
+ def __repr__(self) -> str: ...
130
+ @property
131
+ def version_range(self) -> VersionRange:
132
+ """
133
+ The version range.
134
+ """
@@ -0,0 +1,204 @@
1
+ #pragma once
2
+
3
+ #include <algorithm>
4
+ #include <cstdint>
5
+ #include <initializer_list>
6
+ #include <memory>
7
+ #include <sstream>
8
+ #include <string>
9
+ #include <vector>
10
+
11
+ #include <amulet/io/binary_reader.hpp>
12
+ #include <amulet/io/binary_writer.hpp>
13
+
14
+ #include <amulet/core/dll.hpp>
15
+
16
+ namespace Amulet {
17
+
18
+ typedef std::string PlatformType;
19
+
20
+ // This class is designed to store semantic versions and data versions and allow comparisons between them.
21
+ // It is a wrapper around std::vector<std::int64_t> with special comparison handling.
22
+ // The version can contain zero to max(int64) values.
23
+ // Undefined trailing values are implied zeros. 1.1 == 1.1.0
24
+ // All methods are thread safe.
25
+ class VersionNumber {
26
+ private:
27
+ std::vector<std::int64_t> _vec;
28
+
29
+ public:
30
+ // Get the underlying vector.
31
+ // Thread safe.
32
+ const std::vector<std::int64_t>& get_vector() const { return _vec; }
33
+
34
+ // Constructors
35
+ template <typename... Args>
36
+ requires std::is_constructible_v<std::vector<std::int64_t>, Args...>
37
+ VersionNumber(Args&&... args)
38
+ : _vec(std::forward<Args>(args)...)
39
+ {
40
+ }
41
+
42
+ VersionNumber(std::initializer_list<std::int64_t> args)
43
+ : _vec(args)
44
+ {
45
+ }
46
+
47
+ AMULET_CORE_EXPORT void serialise(BinaryWriter&) const;
48
+ AMULET_CORE_EXPORT static VersionNumber deserialise(BinaryReader&);
49
+
50
+ // Iterators
51
+ std::vector<std::int64_t>::const_iterator begin() const { return _vec.begin(); }
52
+ std::vector<std::int64_t>::const_iterator end() const { return _vec.end(); }
53
+ std::vector<std::int64_t>::const_reverse_iterator rbegin() const { return _vec.rbegin(); }
54
+ std::vector<std::int64_t>::const_reverse_iterator rend() const { return _vec.rend(); }
55
+
56
+ // Capacity
57
+ size_t size() const { return _vec.size(); }
58
+
59
+ // Element access
60
+ std::int64_t operator[](size_t index) const {
61
+ if (index >= _vec.size()) {
62
+ return 0;
63
+ }
64
+ return _vec[index];
65
+ }
66
+
67
+ // Comparison
68
+ auto operator<=>(const VersionNumber& other) const
69
+ {
70
+ size_t max_len = std::max(_vec.size(), other.size());
71
+ std::int64_t v1, v2;
72
+ for (size_t i = 0; i < max_len; i++) {
73
+ v1 = (*this)[i];
74
+ v2 = other[i];
75
+ if (v1 < v2) {
76
+ // Less than
77
+ return std::strong_ordering::less;
78
+ }
79
+ if (v1 > v2) {
80
+ // Greater than
81
+ return std::strong_ordering::greater;
82
+ }
83
+ }
84
+ // equal
85
+ return std::strong_ordering::equal;
86
+ }
87
+ bool operator==(const VersionNumber& other) const
88
+ {
89
+ return (*this <=> other) == 0;
90
+ }
91
+
92
+ // Convert the value to its string representation eg "1.1"
93
+ AMULET_CORE_EXPORT std::string toString() const;
94
+
95
+ // The version number with trailing zeros cut off.
96
+ AMULET_CORE_EXPORT std::vector<std::int64_t> cropped_version() const;
97
+
98
+ // Get the version number cropped or padded with zeros to the given length.
99
+ AMULET_CORE_EXPORT std::vector<std::int64_t> padded_version(size_t len) const;
100
+ };
101
+
102
+ // A class storing platform identifier and version number.
103
+ // Thread safe.
104
+ class PlatformVersionContainer {
105
+ private:
106
+ PlatformType _platform;
107
+ VersionNumber _version;
108
+
109
+ public:
110
+ // Get the platform identifier.
111
+ const PlatformType& get_platform() const { return _platform; }
112
+
113
+ // Get the version number.
114
+ const VersionNumber& get_version() const { return _version; }
115
+
116
+ template <typename PlatformT, typename VersionNumberT>
117
+ PlatformVersionContainer(
118
+ PlatformT&& platform,
119
+ VersionNumberT&& version)
120
+ : _platform(std::forward<PlatformT>(platform))
121
+ , _version(std::forward<VersionNumberT>(version))
122
+ {
123
+ }
124
+
125
+ AMULET_CORE_EXPORT void serialise(BinaryWriter&) const;
126
+ AMULET_CORE_EXPORT static PlatformVersionContainer deserialise(BinaryReader&);
127
+
128
+ // Comparison operators
129
+ auto operator<=>(const PlatformVersionContainer& other) const
130
+ {
131
+ auto cmp = _platform <=> other._platform;
132
+ if (cmp != 0) {
133
+ return cmp;
134
+ }
135
+ return _version <=> other._version;
136
+ }
137
+ bool operator==(const PlatformVersionContainer& other) const
138
+ {
139
+ return (*this <=> other) == 0;
140
+ }
141
+ };
142
+
143
+ // A class storing platform identifier and minimum and maximum version numbers.
144
+ // Thread safe.
145
+ class VersionRange {
146
+ private:
147
+ PlatformType _platform;
148
+ VersionNumber _min_version;
149
+ VersionNumber _max_version;
150
+
151
+ public:
152
+ // Get the platform identifier.
153
+ const PlatformType& get_platform() const { return _platform; }
154
+
155
+ // Get the minimum version number
156
+ const VersionNumber& get_min_version() const { return _min_version; }
157
+
158
+ // Get the maximum version number
159
+ const VersionNumber& get_max_version() const { return _max_version; }
160
+
161
+ template <typename PlatformT, typename MinVersionT, typename MaxVersionT>
162
+ VersionRange(
163
+ PlatformT&& platform,
164
+ MinVersionT&& min_version,
165
+ MaxVersionT&& max_version)
166
+ : _platform(std::forward<PlatformT>(platform))
167
+ , _min_version(std::forward<MinVersionT>(min_version))
168
+ , _max_version(std::forward<MaxVersionT>(max_version))
169
+ {
170
+ if (_min_version > _max_version) {
171
+ throw std::invalid_argument("min_version must be less than or equal to max_version");
172
+ }
173
+ }
174
+
175
+ AMULET_CORE_EXPORT void serialise(BinaryWriter&) const;
176
+ AMULET_CORE_EXPORT static VersionRange deserialise(BinaryReader&);
177
+
178
+ // Check if the platform is equal and the version number is within the range.
179
+ AMULET_CORE_EXPORT bool contains(const PlatformType& platform_, const VersionNumber& version) const;
180
+
181
+ // Equality operator
182
+ AMULET_CORE_EXPORT bool operator==(const VersionRange&) const;
183
+ };
184
+
185
+ // A class that contains a version range.
186
+ class VersionRangeContainer {
187
+ private:
188
+ VersionRange _version_range;
189
+
190
+ public:
191
+ // Get the version range.
192
+ const VersionRange& get_version_range() const { return _version_range; }
193
+
194
+ template <typename VersionRangeT>
195
+ VersionRangeContainer(
196
+ VersionRangeT&& version_range)
197
+ : _version_range(std::forward<VersionRangeT>(version_range))
198
+ {
199
+ }
200
+
201
+ AMULET_CORE_EXPORT void serialise(BinaryWriter&) const;
202
+ AMULET_CORE_EXPORT static VersionRangeContainer deserialise(BinaryReader&);
203
+ };
204
+ }
@@ -0,0 +1,109 @@
1
+ Metadata-Version: 2.4
2
+ Name: amulet-core
3
+ Version: 2.0a9
4
+ Summary: A Python library for reading/writing Minecraft's various save formats.
5
+ Author: James Clare, Ben Gothard
6
+ Project-URL: Homepage, https://www.amuletmc.com
7
+ Project-URL: Repository, https://github.com/Amulet-Team/Amulet-Core
8
+ Project-URL: Issues, https://github.com/Amulet-Team/Amulet-Core/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.11
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: amulet-compiler-target==1.0
14
+ Requires-Dist: numpy~=2.0
15
+ Requires-Dist: amulet-compiler-version==1.3.0.1297307203.19.43.34808.0
16
+ Requires-Dist: amulet_pybind11_extensions~=1.0.0.0
17
+ Requires-Dist: amulet_io~=1.0.0.0
18
+ Requires-Dist: amulet_nbt==4.0.0a20
19
+ Provides-Extra: docs
20
+ Requires-Dist: Sphinx>=1.7.4; extra == "docs"
21
+ Requires-Dist: sphinx-autodoc-typehints>=1.3.0; extra == "docs"
22
+ Requires-Dist: sphinx_rtd_theme>=0.3.1; extra == "docs"
23
+ Provides-Extra: dev
24
+ Requires-Dist: setuptools>=42; extra == "dev"
25
+ Requires-Dist: versioneer; extra == "dev"
26
+ Requires-Dist: packaging; extra == "dev"
27
+ Requires-Dist: wheel; extra == "dev"
28
+ Requires-Dist: pybind11[global]==2.13.6; extra == "dev"
29
+ Requires-Dist: amulet_pybind11_extensions~=1.0; extra == "dev"
30
+ Requires-Dist: pybind11_stubgen>=2.5.4; extra == "dev"
31
+ Requires-Dist: black>=22.3; extra == "dev"
32
+ Requires-Dist: isort; extra == "dev"
33
+ Requires-Dist: autoflake; extra == "dev"
34
+ Requires-Dist: mypy; extra == "dev"
35
+ Requires-Dist: types-pyinstaller; extra == "dev"
36
+ Requires-Dist: amulet-test-utils~=1.1; extra == "dev"
37
+ Dynamic: requires-dist
38
+
39
+ # Amulet Core
40
+
41
+ ![Build](../../workflows/Build/badge.svg)
42
+ ![Unittests](../../workflows/Unittests/badge.svg?event=push)
43
+ ![Stylecheck](../../workflows/Stylecheck/badge.svg?event=push)
44
+ [![Documentation](https://readthedocs.org/projects/amulet-core/badge)](https://amulet-core.readthedocs.io)
45
+
46
+ A Python 3 library to read and write data from Minecraft's various save formats.
47
+
48
+ This library provides the main world editing functionality for Amulet Map Editor
49
+
50
+ #### If you are looking for the actual editor it can be found at [Amulet Map Editor](https://github.com/Amulet-Team/Amulet-Map-Editor)
51
+
52
+
53
+ ## Documentation
54
+
55
+ Our online documentation can be found here: https://amulet-core.readthedocs.io
56
+
57
+ ## Installing
58
+ 1) Install Python 3.7
59
+ 2) We recommend setting up a [python virtual environment](https://docs.python.org/3/tutorial/venv.html) so you don't run into issues with dependency conflicts.
60
+ 3) run `pip install amulet-core` to install the library and all its dependencies.
61
+
62
+ ## Dependencies
63
+
64
+ This library uses a number of other libraries. These will be automatically installed when running the command above.
65
+ - Numpy
66
+ - [Amulet_NBT](https://github.com/Amulet-Team/Amulet-NBT)
67
+ - [PyMCTranslate](https://github.com/gentlegiantJGC/PyMCTranslate)
68
+
69
+ ## Contributing
70
+
71
+ ### For Development
72
+ Download the code to your computer, install python and run the following command from the root directory.
73
+ run `pip install -e .[dev]`
74
+ This command will install the library in development mode with the libraries required for development.
75
+ - [Black](https://github.com/ambv/black) (Required for formatting)
76
+ - Must be run before pushing a Pull Request
77
+
78
+ For information about contributing to this project, please see the contribution section [below](#contributing)
79
+
80
+ ### Code Formatting
81
+ For code formatting, we use the formatting utility [black](https://github.com/psf/black).
82
+ To run it, run the following command from your favorite terminal after installing: `black amulet tests`
83
+
84
+ In order for your pull request to be accepted, this command must be run to format every file.
85
+
86
+ ### Building the Documentation
87
+ To build the documentation locally, run the following command: `make html` and then navigate to the
88
+ generated directory `docs_build/html` in your favorite web browser
89
+
90
+ ### Branch Naming
91
+ Branches should be created when a certain bug or feature may take multiple attempts to fix. Naming
92
+ them should follow the following convention (even for forked repositories when a pull request is being made):
93
+
94
+ * For features, use: `impl-<feature name>`
95
+ * For bug fixes, use: `bug-<bug tracker ID>`
96
+ * For improvements/rewrites, use: `improv-<feature name>`
97
+ * For prototyping, use: `proto-<feature name>`
98
+
99
+ ### Pull Requests
100
+ We ask that submitted Pull Requests give moderately detailed notes about the changes and explain
101
+ any changes that were made to the program outside of those directly related to the feature/bug-fix.
102
+ Make sure to run all tests and formatting otherwise we cannot accept your pull request.
103
+
104
+ _Note: We will also re-run all tests before reviewing, this is to mitigate additional changes/commits
105
+ needed to pass all tests._
106
+
107
+ Once a Pull Request is submitted, we will mark the request for review, once that is done, we will
108
+ review the changes and provide any notes/things to change. Once all additional changes have been made,
109
+ we will merge the request.