Skip to content

Commit 68426cf

Browse files
Improve version handling (#23)
* Add a script to minify the json This is in the setup.py but it is useful to be able to run it on its own * Update pymctranslate * Improve version handling Remove min_version and max_version. These behaviour of these properties was confusing. Add (min/max/max_known) semantic_version and block_version properties. These are clearer what they do. max_known indicates a real version to use as an upper bound. max is generally not a real version and exists purely to catch future versions. * Remove unused class * Reformat * Reformat * Expose get_max_known_block_version to C++
1 parent 4db8af9 commit 68426cf

File tree

11 files changed

+243
-29
lines changed

11 files changed

+243
-29
lines changed

src/amulet/game/abc/biome.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def to_universal(self, biome: Biome) -> Biome:
137137
return self._to_universal[(biome.namespace, biome.base_name)]
138138
except KeyError:
139139
raise BiomeTranslationError(
140-
f"Biome {biome} does not exist in version {self._game_version.platform} {self._game_version.min_version}"
140+
f"Biome {biome} does not exist in version {self._game_version.platform} {self._game_version.min_semantic_version}"
141141
)
142142

143143
def from_universal(
@@ -153,7 +153,7 @@ def from_universal(
153153
namespace, base_name = self._from_universal[biome]
154154
except KeyError:
155155
raise BiomeTranslationError(
156-
f"Biome {biome} does not exist in version {self._game_version.platform} {self._game_version.min_version}"
156+
f"Biome {biome} does not exist in version {self._game_version.platform} {self._game_version.min_semantic_version}"
157157
)
158158
else:
159159
return Biome(target_platform, target_version, namespace, base_name)

src/amulet/game/abc/block.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ def to_universal(
244244
translator = self._to_universal[(block.namespace, block.base_name)]
245245
except KeyError:
246246
raise BlockTranslationError(
247-
f"Block {block} does not exist in version {self._game_version.platform} {self._game_version.min_version}"
247+
f"Block {block} does not exist in version {self._game_version.platform} {self._game_version.min_semantic_version}"
248248
)
249249

250250
output, extra_output, extra_needed, cacheable = translator.run(
@@ -294,7 +294,7 @@ def from_universal(
294294
translator = self._from_universal[(block.namespace, block.base_name)]
295295
except KeyError:
296296
raise BlockTranslationError(
297-
f"Block {block} does not exist in version {self._game_version.platform} {self._game_version.min_version}"
297+
f"Block {block} does not exist in version {self._game_version.platform} {self._game_version.min_semantic_version}"
298298
)
299299

300300
output, extra_output, extra_needed, cacheable = translator.run(

src/amulet/game/abc/version.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,11 @@ namespace game {
1717
return std::make_shared<BlockData>(_obj.attr("block"));
1818
}
1919

20+
VersionNumber GameVersion::get_max_known_block_version()
21+
{
22+
py::gil_scoped_acquire gil;
23+
return _obj.attr("max_known_block_version").cast<VersionNumber>();
24+
}
25+
2026
} // namespace game
2127
} // namespace Amulet

src/amulet/game/abc/version.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ namespace py = pybind11;
1616
namespace Amulet {
1717
namespace game {
1818

19-
class GameVersionImpl;
20-
2119
class GameVersion : public PyObjWrapper {
2220
public:
2321
using PyObjWrapper::PyObjWrapper;
2422
using PyObjWrapper::operator=;
2523

24+
AMULET_GAME_EXPORT VersionNumber get_max_known_block_version();
25+
2626
AMULET_GAME_EXPORT std::shared_ptr<BiomeData> get_biome_data();
2727
AMULET_GAME_EXPORT std::shared_ptr<BlockData> get_block_data();
2828
};

src/amulet/game/abc/version.py

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,90 @@ def platform(self) -> str:
2323

2424
@property
2525
@abstractmethod
26-
def min_version(self) -> VersionNumber:
27-
"""The minimum game version this instance can be used with."""
26+
def min_semantic_version(self) -> VersionNumber:
27+
"""
28+
The minimum semantic version this instance can be used with.
29+
30+
>>> game_version: GameVersion
31+
>>> game_version.min_semantic_version
32+
VersionNumber(1, 21, 9)
33+
"""
34+
raise NotImplementedError
35+
36+
@property
37+
@abstractmethod
38+
def max_known_semantic_version(self) -> VersionNumber:
39+
"""
40+
The maximum known semantic version this instance can be used with.
41+
This instance may be compatible with higher versions but this is the highest it is known to work with.
42+
43+
>>> game_version: GameVersion
44+
>>> game_version.max_known_semantic_version
45+
VersionNumber(1, 21, 9)
46+
"""
47+
raise NotImplementedError
48+
49+
@property
50+
@abstractmethod
51+
def max_semantic_version(self) -> VersionNumber:
52+
"""
53+
The maximum semantic version this instance should accept.
54+
Note that this is usually not a valid version.
55+
56+
>>> game_version: GameVersion
57+
>>> game_version.max_semantic_version
58+
VersionNumber(1, 22, 10, -1)
59+
VersionNumber(2, -1) # This is used in the newest version.
60+
"""
2861
raise NotImplementedError
2962

3063
@property
3164
@abstractmethod
32-
def max_version(self) -> VersionNumber:
33-
"""The maximum game version this instance can be used with."""
65+
def min_block_version(self) -> VersionNumber:
66+
"""
67+
The minimum block version this instance can be used with.
68+
69+
>>> game_version: GameVersion
70+
>>> game_version.min_block_version
71+
# Java - data version
72+
VersionNumber(4553) # 1.21.9 Release Candidate 1
73+
# Bedrock - uint8[4] interpreted as uint32
74+
VersionNumber(18168865) # 1.21.60.33
75+
"""
76+
raise NotImplementedError
77+
78+
@property
79+
@abstractmethod
80+
def max_known_block_version(self) -> VersionNumber:
81+
"""
82+
The maximum known block version this instance can be used with.
83+
This instance may be compatible with higher versions but this is the highest it is known to work with.
84+
85+
>>> game_version: GameVersion
86+
>>> game_version.max_known_block_version
87+
# Java - data version
88+
VersionNumber(4554) # 1.21.9
89+
# Bedrock - uint8[4] interpreted as uint32
90+
VersionNumber(18168865) # 1.21.60.33
91+
"""
92+
raise NotImplementedError
93+
94+
@property
95+
@abstractmethod
96+
def max_block_version(self) -> VersionNumber:
97+
"""
98+
The maximum block version this instance should accept.
99+
Note that this is usually not a valid version.
100+
101+
>>> game_version: GameVersion
102+
>>> game_version.max_block_version
103+
# Java - data version
104+
VersionNumber(4554) # Java Edition 1.21.9
105+
VersionNumber(2147483647) # The newest version uses max(int32) to catch all future versions.
106+
# Bedrock - uint8[4] interpreted as uint32
107+
VersionNumber(18168865) # 1.21.60.33
108+
VersionNumber(4294967295) # The newest version uses max(uint32) to catch all future versions.
109+
"""
34110
raise NotImplementedError
35111

36112
@property

src/amulet/game/bedrock/_version.py

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,24 @@ class BedrockGameVersion(GameVersion):
2626

2727
def __init__(
2828
self,
29-
min_data_version: VersionNumber,
30-
max_data_version: VersionNumber,
29+
min_block_version: VersionNumber,
30+
max_known_block_version: VersionNumber,
31+
max_block_version: VersionNumber,
3132
min_semantic_version: VersionNumber,
33+
max_known_semantic_version: VersionNumber,
3234
max_semantic_version: VersionNumber,
3335
) -> None:
3436
"""Do not use this."""
35-
self._min_data_version = min_data_version
36-
self._max_data_version = max_data_version
37+
self._min_block_version = min_block_version
38+
self._max_known_block_version = max_known_block_version
39+
self._max_block_version = max_block_version
3740
self._min_semantic_version = min_semantic_version
41+
self._max_known_semantic_version = max_known_semantic_version
3842
self._max_semantic_version = max_semantic_version
3943

4044
def supports_version(self, platform: str, version: VersionNumber) -> bool:
4145
return platform == "bedrock" and (
42-
self._min_data_version <= version <= self._max_data_version
46+
self._min_block_version <= version <= self._max_block_version
4347
or self._min_semantic_version <= version <= self._max_semantic_version
4448
)
4549

@@ -50,9 +54,11 @@ def from_json(
5054
with open(os.path.join(version_path, "__init__.json")) as f:
5155
init = json.load(f)
5256
assert init["platform"] == "bedrock"
53-
min_data_version = VersionNumber(init.get("data_version", -1))
54-
max_data_version = VersionNumber(init.get("data_version_max", -1))
57+
min_block_version = VersionNumber(init.get("data_version", -1))
58+
max_known_block_version = VersionNumber(init.get("data_version_max_known", -1))
59+
max_block_version = VersionNumber(init.get("data_version_max", -1))
5560
min_semantic_version = VersionNumber(*init["version"])
61+
max_known_sematic_version = VersionNumber(*init["version_max_known"])
5662
max_semantic_version = VersionNumber(*init["version_max"])
5763

5864
block_format = {
@@ -64,9 +70,11 @@ def from_json(
6470
universal_version = get_game_version("universal", VersionNumber(1))
6571

6672
self = cls(
67-
min_data_version,
68-
max_data_version,
73+
min_block_version,
74+
max_known_block_version,
75+
max_block_version,
6976
min_semantic_version,
77+
max_known_sematic_version,
7078
max_semantic_version,
7179
)
7280

@@ -148,20 +156,36 @@ def from_json(
148156
return self
149157

150158
def __repr__(self) -> str:
151-
return f"BedrockGameVersion({self.min_version!r})"
159+
return f"BedrockGameVersion({self.min_semantic_version!r})"
152160

153161
@property
154162
def platform(self) -> str:
155163
return "bedrock"
156164

157165
@property
158-
def min_version(self) -> VersionNumber:
166+
def min_semantic_version(self) -> VersionNumber:
159167
return self._min_semantic_version
160168

161169
@property
162-
def max_version(self) -> VersionNumber:
170+
def max_known_semantic_version(self) -> VersionNumber:
171+
return self._max_known_semantic_version
172+
173+
@property
174+
def max_semantic_version(self) -> VersionNumber:
163175
return self._max_semantic_version
164176

177+
@property
178+
def min_block_version(self) -> VersionNumber:
179+
return self._min_block_version
180+
181+
@property
182+
def max_known_block_version(self) -> VersionNumber:
183+
return self._max_known_block_version
184+
185+
@property
186+
def max_block_version(self) -> VersionNumber:
187+
return self._max_block_version
188+
165189
@property
166190
def block(self) -> BedrockBlockData:
167191
return self._block

src/amulet/game/game.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def _get_versions() -> dict[str, list[GameVersion]]:
3636
versions: object = pickle.loads(gzip.decompress(pkl.read()))
3737

3838
def version_sort(v: GameVersion) -> VersionNumber:
39-
return v.min_version
39+
return v.min_semantic_version
4040

4141
sorted_versions: dict[str, list[GameVersion]] = {}
4242
for platform, version_list in dynamic_cast(versions, dict).items():

src/amulet/game/java/version.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,18 @@ class JavaGameVersion(GameVersion):
2727
def __init__(
2828
self,
2929
min_data_version: VersionNumber,
30+
max_known_data_version: VersionNumber,
3031
max_data_version: VersionNumber,
3132
min_semantic_version: VersionNumber,
33+
max_known_semantic_version: VersionNumber,
3234
max_semantic_version: VersionNumber,
3335
):
3436
"""Do not use this."""
3537
self._min_data_version = min_data_version
38+
self._max_known_data_version = max_known_data_version
3639
self._max_data_version = max_data_version
3740
self._min_semantic_version = min_semantic_version
41+
self._max_known_semantic_version = max_known_semantic_version
3842
self._max_semantic_version = max_semantic_version
3943

4044
@classmethod
@@ -45,8 +49,10 @@ def from_json(
4549
init = json.load(f)
4650
assert init["platform"] == "java"
4751
min_data_version = VersionNumber(init["data_version"])
52+
max_known_data_version = VersionNumber(init["data_version_max_known"])
4853
max_data_version = VersionNumber(init["data_version_max"])
4954
min_semantic_version = VersionNumber(*init["version"])
55+
max_known_semantic_version = VersionNumber(*init["version_max_known"])
5056
max_semantic_version = VersionNumber(*init["version_max"])
5157

5258
block_format = init["block_format"]
@@ -55,8 +61,10 @@ def from_json(
5561

5662
self = cls(
5763
min_data_version,
64+
max_known_data_version,
5865
max_data_version,
5966
min_semantic_version,
67+
max_known_semantic_version,
6068
max_semantic_version,
6169
)
6270

@@ -153,7 +161,7 @@ def from_json(
153161
return self
154162

155163
def __repr__(self) -> str:
156-
return f"JavaGameVersion({self.min_version!r})"
164+
return f"JavaGameVersion({self.min_semantic_version!r})"
157165

158166
def supports_version(self, platform: str, version: VersionNumber) -> bool:
159167
return platform == "java" and (
@@ -166,11 +174,39 @@ def platform(self) -> str:
166174
return "java"
167175

168176
@property
169-
def min_version(self) -> VersionNumber:
177+
def min_semantic_version(self) -> VersionNumber:
178+
return self._min_semantic_version
179+
180+
@property
181+
def max_known_semantic_version(self) -> VersionNumber:
182+
return self._max_known_semantic_version
183+
184+
@property
185+
def max_semantic_version(self) -> VersionNumber:
186+
return self._max_semantic_version
187+
188+
@property
189+
def min_data_version(self) -> VersionNumber:
190+
return self._min_data_version
191+
192+
@property
193+
def max_known_data_version(self) -> VersionNumber:
194+
return self._max_known_data_version
195+
196+
@property
197+
def max_data_version(self) -> VersionNumber:
198+
return self._max_data_version
199+
200+
@property
201+
def min_block_version(self) -> VersionNumber:
170202
return self._min_data_version
171203

172204
@property
173-
def max_version(self) -> VersionNumber:
205+
def max_known_block_version(self) -> VersionNumber:
206+
return self._max_known_data_version
207+
208+
@property
209+
def max_block_version(self) -> VersionNumber:
174210
return self._max_data_version
175211

176212
@property

src/amulet/game/universal/_version.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,27 @@ def platform(self) -> str:
5252
return "universal"
5353

5454
@property
55-
def min_version(self) -> VersionNumber:
55+
def min_semantic_version(self) -> VersionNumber:
5656
return VersionNumber(1)
5757

5858
@property
59-
def max_version(self) -> VersionNumber:
59+
def max_known_semantic_version(self) -> VersionNumber:
60+
return VersionNumber(1)
61+
62+
@property
63+
def max_semantic_version(self) -> VersionNumber:
64+
return VersionNumber(1)
65+
66+
@property
67+
def min_block_version(self) -> VersionNumber:
68+
return VersionNumber(1)
69+
70+
@property
71+
def max_known_block_version(self) -> VersionNumber:
72+
return VersionNumber(1)
73+
74+
@property
75+
def max_block_version(self) -> VersionNumber:
6076
return VersionNumber(1)
6177

6278
@property

submodules/PyMCTranslate

0 commit comments

Comments
 (0)