1
Fork 0
mirror of https://github.com/Steffo99/lihzahrd.git synced 2024-11-21 23:54:23 +00:00

Start work on tile data

This commit is contained in:
Steffo 2019-08-09 15:16:57 +02:00
parent 67e3627a68
commit 6f8b9b75b3
13 changed files with 278 additions and 155 deletions

View file

@ -1,4 +1,3 @@
from . import header
from .world import World from .world import World
__all__ = ["header", "World"] __all__ = ["World"]

View file

@ -6,7 +6,6 @@ from .bossesdefeated import BossesDefeated
from .clouds import Clouds from .clouds import Clouds
from .coordinates import Coordinates from .coordinates import Coordinates
from .events import Events from .events import Events
from .filereader import FileReader
from .fourpartsplit import FourPartSplit from .fourpartsplit import FourPartSplit
from .generatorinfo import GeneratorInfo from .generatorinfo import GeneratorInfo
from .hardmodeore import HardmodeTier1Ore, HardmodeTier2Ore, HardmodeTier3Ore from .hardmodeore import HardmodeTier1Ore, HardmodeTier2Ore, HardmodeTier3Ore
@ -19,7 +18,6 @@ from .oldonesarmytiers import OldOnesArmyTiers
from .party import Party from .party import Party
from .pillarsinfo import PillarsInfo from .pillarsinfo import PillarsInfo
from .rain import Rain from .rain import Rain
from .rect import Rect
from .sandstorm import Sandstorm from .sandstorm import Sandstorm
from .savednpcs import SavedNPCs from .savednpcs import SavedNPCs
from .shadoworbs import ShadowOrbs from .shadoworbs import ShadowOrbs

View file

View file

@ -42,7 +42,7 @@ class FileReader:
def double(self) -> float: def double(self) -> float:
return struct.unpack("d", self.file.read(8))[0] return struct.unpack("d", self.file.read(8))[0]
def bit(self) -> typing.Tuple[bool, bool, bool, bool, bool, bool, bool, bool]: def bits(self) -> typing.Tuple[bool, bool, bool, bool, bool, bool, bool, bool]:
data = struct.unpack("B", self.file.read(1))[0] data = struct.unpack("B", self.file.read(1))[0]
return (bool(data & 0b1000_0000), return (bool(data & 0b1000_0000),
bool(data & 0b0100_0000), bool(data & 0b0100_0000),

View file

@ -0,0 +1,6 @@
from .liquid import Liquid
from .rleencoding import RLEEncoding
from .shape import Shape
from .wires import Wires
__all__ = ["Liquid", "RLEEncoding", "Shape", "Wires"]

18
lihzahrd/tiles/liquid.py Normal file
View file

@ -0,0 +1,18 @@
import enum
class Liquid(enum.IntEnum):
NO_LIQUID = 0
WATER = 1
LAVA = 2
HONEY = 3
@classmethod
def from_flags(cls, flags1):
if flags1[3] and flags1[4]:
return cls.HONEY
if flags1[4]:
return cls.LAVA
if flags1[3]:
return cls.WATER
return cls.NO_LIQUID

View file

@ -0,0 +1,11 @@
import enum
class RLEEncoding(enum.IntEnum):
NO_COMPRESSION = 0
SINGLE_BYTE = 1
DOUBLE_BYTE = 2
@classmethod
def from_flags(cls, flags1):
return cls(flags1[7] * 2 + flags1[6])

14
lihzahrd/tiles/shape.py Normal file
View file

@ -0,0 +1,14 @@
import enum
class Shape(enum.IntEnum):
NORMAL = 0
HALF_TILE = 1
TOP_RIGHT_SLOPE = 2
TOP_LEFT_SLOPE = 3
BOTTOM_RIGHT_SLOPE = 4
BOTTOM_LEFT_SLOPE = 5
@classmethod
def from_flags(cls, flags2):
return cls(flags2[6] * 4 + flags2[5] * 2 + flags2[4])

18
lihzahrd/tiles/tile.py Normal file
View file

@ -0,0 +1,18 @@
import enum
class Liquid(enum.IntEnum):
NO_LIQUID = 0
WATER = 1
LAVA = 2
HONEY = 3
@classmethod
def from_flags(cls, flags13, flags14):
if flags13 and flags14:
return cls.HONEY
if flags14:
return cls.LAVA
if flags13:
return cls.WATER
return cls.NO_LIQUID

12
lihzahrd/tiles/wires.py Normal file
View file

@ -0,0 +1,12 @@
class Wires:
def __init__(self,
red: bool = False,
green: bool = False,
blue: bool = False,
yellow: bool = False,
actuator: bool = False):
self.red: bool = red
self.green: bool = green
self.blue: bool = blue
self.yellow: bool = yellow
self.actuator: bool = actuator

View file

@ -1,42 +1,45 @@
import uuid import uuid
import math import math
from . import header as h from .header import *
from .savedata import filereader
from .tiles import *
class World: class World:
"""The Python representation of a Terraria world.""" """The Python representation of a Terraria world."""
def __init__(self, def __init__(self,
version: h.Version, version: Version,
savefile_type: int, savefile_type: int,
revision: int, revision: int,
is_favorite: bool, is_favorite: bool,
name: str, name: str,
generator: h.GeneratorInfo, generator: GeneratorInfo,
uuid_: uuid.UUID, uuid_: uuid.UUID,
id_: int, id_: int,
bounds: h.Rect, bounds: Rect,
size: h.Coordinates, size: Coordinates,
is_expert: bool, is_expert: bool,
created_on, created_on,
styles: h.Styles, styles: Styles,
backgrounds: h.Backgrounds, backgrounds: Backgrounds,
spawn_point: h.Coordinates, spawn_point: Coordinates,
underground_level: float, underground_level: float,
cavern_level: float, cavern_level: float,
time: h.Time, time: Time,
events: h.Events, events: Events,
dungeon_point: h.Coordinates, dungeon_point: Coordinates,
world_evil: h.WorldEvilType, world_evil: WorldEvilType,
saved_npcs: h.SavedNPCs, saved_npcs: SavedNPCs,
altars_smashed: h.AltarsSmashed, altars_smashed: AltarsSmashed,
is_hardmode: bool, is_hardmode: bool,
shadow_orbs: h.ShadowOrbs, shadow_orbs: ShadowOrbs,
bosses_defeated: h.BossesDefeated, bosses_defeated: BossesDefeated,
anglers_quest: h.AnglerQuest, anglers_quest: AnglerQuest,
clouds: h.Clouds, clouds: Clouds,
cultist_delay: int): cultist_delay: int):
self.version: h.Version = version self.version: Version = version
"""The game version when this savefile was last saved.""" """The game version when this savefile was last saved."""
self.savefile_type = savefile_type self.savefile_type = savefile_type
@ -51,7 +54,7 @@ class World:
self.name: str = name self.name: str = name
"""The name the world was given at creation. Doesn't always match the filename.""" """The name the world was given at creation. Doesn't always match the filename."""
self.generator: h.GeneratorInfo = generator self.generator: GeneratorInfo = generator
"""Information about the generation of this world.""" """Information about the generation of this world."""
self.uuid: uuid.UUID = uuid_ self.uuid: uuid.UUID = uuid_
@ -60,10 +63,10 @@ class World:
self.id: int = id_ self.id: int = id_
"""The world id. Used to name the minimap file.""" """The world id. Used to name the minimap file."""
self.bounds: h.rect.Rect = bounds self.bounds: Rect = bounds
"""The world size in pixels.""" """The world size in pixels."""
self.size: h.Coordinates = size self.size: Coordinates = size
"""The world size in tiles.""" """The world size in tiles."""
self.is_expert: bool = is_expert self.is_expert: bool = is_expert
@ -72,13 +75,13 @@ class World:
self.created_on = created_on self.created_on = created_on
"""The date and time this world was created in.""" """The date and time this world was created in."""
self.styles: h.Styles = styles self.styles: Styles = styles
"""The styles of various world elements.""" """The styles of various world elements."""
self.backgrounds: h.Backgrounds = backgrounds self.backgrounds: Backgrounds = backgrounds
"""The backgrounds of the various biomes.""" """The backgrounds of the various biomes."""
self.spawn_point: h.Coordinates = spawn_point self.spawn_point: Coordinates = spawn_point
"""The coordinates of the spawn point.""" """The coordinates of the spawn point."""
self.underground_level: float = underground_level self.underground_level: float = underground_level
@ -87,61 +90,100 @@ class World:
self.cavern_level: float = cavern_level self.cavern_level: float = cavern_level
"""The depth at which the cavern biome starts.""" """The depth at which the cavern biome starts."""
self.time: h.Time = time self.time: Time = time
"""Game time related information.""" """Game time related information."""
self.events: h.Events = events self.events: Events = events
"""Currently ongoing world events.""" """Currently ongoing world events."""
self.dungeon_point: h.Coordinates = dungeon_point self.dungeon_point: Coordinates = dungeon_point
"""The Old Man spawn point.""" """The Old Man spawn point."""
self.world_evil: h.WorldEvilType = world_evil self.world_evil: WorldEvilType = world_evil
"""Whether the world has Corruption or Crimson.""" """Whether the world has Corruption or Crimson."""
self.saved_npcs: h.SavedNPCs = saved_npcs self.saved_npcs: SavedNPCs = saved_npcs
"""The NPCs that were rescued by the player.""" """The NPCs that were rescued by the player."""
self.altars_smashed: h.AltarsSmashed = altars_smashed self.altars_smashed: AltarsSmashed = altars_smashed
"""Information related to the destruction of Demon Altars with a Pwnhammer.""" """Information related to the destruction of Demon Altars with a Pwnhammer."""
self.is_hardmode: bool = is_hardmode self.is_hardmode: bool = is_hardmode
"""Whether or not the world is in hardmode.""" """Whether or not the world is in hardmode."""
self.shadow_orbs: h.ShadowOrbs = shadow_orbs self.shadow_orbs: ShadowOrbs = shadow_orbs
"""Information related to the Shadow Orbs or Crimson Hearts in the world.""" """Information related to the Shadow Orbs or Crimson Hearts in the world."""
self.bosses_defeated: h.BossesDefeated = bosses_defeated self.bosses_defeated: BossesDefeated = bosses_defeated
"""Which bosses have been defeated in the world.""" """Which bosses have been defeated in the world."""
self.anglers_quest: h.AnglerQuest = anglers_quest self.anglers_quest: AnglerQuest = anglers_quest
"""Information about today's Angler's Quest.""" """Information about today's Angler's Quest."""
self.clouds: h.Clouds = clouds self.clouds: Clouds = clouds
self.cultist_delay: int = cultist_delay self.cultist_delay: int = cultist_delay
def __repr__(self): def __repr__(self):
return f'<World "{self.name}">' return f'<World "{self.name}">'
@property @property
def crimson_hearts(self) -> h.shadoworbs.ShadowOrbs: def crimson_hearts(self) -> ShadowOrbs:
return self.shadow_orbs return self.shadow_orbs
@crimson_hearts.setter @crimson_hearts.setter
def crimson_hearts(self, value): def crimson_hearts(self, value):
self.shadow_orbs = value self.shadow_orbs = value
@staticmethod
def _read_tiles(fr: FileReader, tileframeimportant):
flags1 = fr.bits()
has_tile = flags1[1]
has_wall = flags1[2]
liquid = Liquid.from_flags(flags1)
extended_block_id = flags1[5]
rle_compression = RLEEncoding.from_flags(flags1)
if flags1[0]:
flags2 = fr.bits()
shape = Shape.from_flags(flags2)
if flags2[0]:
flags3 = fr.bits()
is_active = not flags3[2]
wires = Wires(red=flags2[1], green=flags2[2], blue=flags2[3], yellow=flags3[5], actuator=flags3[1])
is_tile_painted = flags3[3]
is_wall_painted = flags3[4]
else:
is_active = True
wires = Wires(red=flags2[1], green=flags2[2], blue=flags2[3])
is_tile_painted = False
is_wall_painted = False
else:
shape = Shape.NORMAL
is_active = True
wires = Wires()
is_tile_painted = False
is_wall_painted = False
if has_tile:
if extended_block_id:
block_id = fr.uint2()
else:
block_id = fr.uint1()
else:
block_id = None
if tileframeimportant:
...
breakpoint()
@classmethod @classmethod
def create_from_file(cls, file): def create_from_file(cls, file):
"""Create a World object from a .wld file.""" """Create a World object from a .wld file."""
# This code is a mess. # This code is a mess.
f = h.filereader.FileReader(file) f = filereader.FileReader(file)
version = h.version.Version(f.int4()) version = Version(f.int4())
relogic = f.string(7) relogic = f.string(7)
savefile_type = f.uint1() savefile_type = f.uint1()
if version != h.version.Version("1.3.5.3") or relogic != "relogic" or savefile_type != 2: if version != Version("1.3.5.3") or relogic != "relogic" or savefile_type != 2:
raise NotImplementedError("This parser can only read Terraria 1.3.5.3 save files.") raise NotImplementedError("This parser can only read Terraria 1.3.5.3 save files.")
revision = f.uint4() revision = f.uint4()
@ -150,29 +192,29 @@ class World:
# Pointers and tileframeimportant # Pointers and tileframeimportant
_ = [f.int4() for _ in range(f.int2())] _ = [f.int4() for _ in range(f.int2())]
tileframeimportant_size = math.ceil(f.int2() / 8) tileframeimportant_size = math.ceil(f.int2() / 8)
_ = [] tileframeimportant = []
for _ in range(tileframeimportant_size): for _ in range(tileframeimportant_size):
current_bit = f.bit() current_bit = f.bits()
_ = [*_, *current_bit] tileframeimportant = [*tileframeimportant, *current_bit]
name = f.string() name = f.string()
generator = h.GeneratorInfo(f.string(), f.int4()) generator = GeneratorInfo(f.string(), f.int4())
uuid_ = f.uuid() uuid_ = f.uuid()
id_ = f.int8() id_ = f.int8()
bounds = f.rect() bounds = f.rect()
world_size = h.Coordinates(y=f.int4(), x=f.int4()) world_size = Coordinates(y=f.int4(), x=f.int4())
is_expert = f.bool() is_expert = f.bool()
created_on = f.datetime() created_on = f.datetime()
world_styles = h.Styles(moon=h.moonstyle.MoonStyle(f.uint1()), world_styles = Styles(moon=MoonStyle(f.uint1()),
trees=h.fourpartsplit.FourPartSplit(separators=[f.int4(), f.int4(), f.int4()], trees=FourPartSplit(separators=[f.int4(), f.int4(), f.int4()],
properties=[f.int4(), properties=[f.int4(),
f.int4(), f.int4(),
f.int4(), f.int4(),
f.int4()]), f.int4()]),
moss=h.fourpartsplit.FourPartSplit(separators=[f.int4(), f.int4(), f.int4()], moss=FourPartSplit(separators=[f.int4(), f.int4(), f.int4()],
properties=[f.int4(), properties=[f.int4(),
f.int4(), f.int4(),
f.int4(), f.int4(),
@ -182,19 +224,19 @@ class World:
bg_underground_jungle = f.int4() bg_underground_jungle = f.int4()
bg_hell = f.int4() bg_hell = f.int4()
spawn_point = h.Coordinates(f.int4(), f.int4()) spawn_point = Coordinates(f.int4(), f.int4())
underground_level = f.double() underground_level = f.double()
cavern_level = f.double() cavern_level = f.double()
current_time = f.double() current_time = f.double()
is_daytime = f.bool() is_daytime = f.bool()
moon_phase = h.MoonPhase(f.uint4()) moon_phase = MoonPhase(f.uint4())
blood_moon = f.bool() blood_moon = f.bool()
eclipse = f.bool() eclipse = f.bool()
dungeon_point = h.Coordinates(f.int4(), f.int4()) dungeon_point = Coordinates(f.int4(), f.int4())
world_evil = h.WorldEvilType(f.bool()) world_evil = WorldEvilType(f.bool())
defeated_eye_of_cthulhu = f.bool() # Possibly. I'm not sure. defeated_eye_of_cthulhu = f.bool() # Possibly. I'm not sure.
defeated_eater_of_worlds = f.bool() # Possibly. I'm not sure. defeated_eater_of_worlds = f.bool() # Possibly. I'm not sure.
@ -217,7 +259,7 @@ class World:
defeated_frost_moon = f.bool() defeated_frost_moon = f.bool()
defeated_pirates = f.bool() defeated_pirates = f.bool()
shadow_orbs = h.ShadowOrbs(smashed_at_least_once=f.bool(), shadow_orbs = ShadowOrbs(smashed_at_least_once=f.bool(),
spawn_meteorite=f.bool(), spawn_meteorite=f.bool(),
evil_boss_counter=f.int4()) evil_boss_counter=f.int4())
@ -227,19 +269,19 @@ class World:
invasion_delay = f.int4() invasion_delay = f.int4()
invasion_size = f.int4() invasion_size = f.int4()
invasion_type = h.InvasionType(f.int4()) invasion_type = InvasionType(f.int4())
invasion_position = f.double() invasion_position = f.double()
time_left_slime_rain = f.double() time_left_slime_rain = f.double()
sundial_cooldown = f.uint1() sundial_cooldown = f.uint1()
rain = h.Rain(is_active=f.bool(), time_left=f.int4(), max_rain=f.single()) rain = Rain(is_active=f.bool(), time_left=f.int4(), max_rain=f.single())
hardmode_ore_1 = h.HardmodeTier1Ore(f.int4()) hardmode_ore_1 = HardmodeTier1Ore(f.int4())
hardmode_ore_2 = h.HardmodeTier2Ore(f.int4()) hardmode_ore_2 = HardmodeTier2Ore(f.int4())
hardmode_ore_3 = h.HardmodeTier3Ore(f.int4()) hardmode_ore_3 = HardmodeTier3Ore(f.int4())
altars_smashed = h.AltarsSmashed(count=smashed_altars_count, altars_smashed = AltarsSmashed(count=smashed_altars_count,
ore_tier1=hardmode_ore_1, ore_tier1=hardmode_ore_1,
ore_tier2=hardmode_ore_2, ore_tier2=hardmode_ore_2,
ore_tier3=hardmode_ore_3) ore_tier3=hardmode_ore_3)
@ -253,7 +295,7 @@ class World:
bg_desert = f.int1() bg_desert = f.int1()
bg_ocean = f.int1() bg_ocean = f.int1()
backgrounds = h.Backgrounds(bg_underground_snow=bg_underground_snow, backgrounds = Backgrounds(bg_underground_snow=bg_underground_snow,
bg_underground_jungle=bg_underground_jungle, bg_underground_jungle=bg_underground_jungle,
bg_hell=bg_hell, bg_hell=bg_hell,
bg_forest=bg_forest, bg_forest=bg_forest,
@ -265,7 +307,7 @@ class World:
bg_desert=bg_desert, bg_desert=bg_desert,
bg_ocean=bg_ocean) bg_ocean=bg_ocean)
clouds = h.Clouds(bg_cloud=f.int4(), cloud_number=f.int2(), wind_speed=f.single()) clouds = Clouds(bg_cloud=f.int4(), cloud_number=f.int2(), wind_speed=f.single())
angler_today_quest_completed_by_count = f.uint1() angler_today_quest_completed_by_count = f.uint1()
angler_today_quest_completed_by = [] angler_today_quest_completed_by = []
@ -274,15 +316,15 @@ class World:
saved_angler = f.bool() saved_angler = f.bool()
angler_today_quest_target = h.AnglerQuestFish(f.int4()) angler_today_quest_target = AnglerQuestFish(f.int4())
anglers_quest = h.AnglerQuest(current_goal=angler_today_quest_target, anglers_quest = AnglerQuest(current_goal=angler_today_quest_target,
completed_by=angler_today_quest_completed_by) completed_by=angler_today_quest_completed_by)
saved_stylist = f.bool() saved_stylist = f.bool()
saved_tax_collector = f.bool() saved_tax_collector = f.bool()
invasion_size_start = f.int4() # ??? invasion_size_start = f.int4() # ???
invasion = h.Invasion(delay=invasion_delay, invasion = Invasion(delay=invasion_delay,
size=invasion_size, size=invasion_size,
type_=invasion_type, type_=invasion_type,
position=invasion_position, position=invasion_position,
@ -295,7 +337,7 @@ class World:
mob_kills[mob_id] = f.int4() mob_kills[mob_id] = f.int4()
fast_forward_time = f.bool() fast_forward_time = f.bool()
time = h.Time(current=current_time, time = Time(current=current_time,
is_daytime=is_daytime, is_daytime=is_daytime,
moon_phase=moon_phase, moon_phase=moon_phase,
sundial_cooldown=sundial_cooldown, sundial_cooldown=sundial_cooldown,
@ -308,9 +350,9 @@ class World:
defeated_ice_queen = f.bool() defeated_ice_queen = f.bool()
defeated_santa_nk1 = f.bool() defeated_santa_nk1 = f.bool()
defeated_everscream = f.bool() defeated_everscream = f.bool()
defeated_pillars = h.PillarsInfo(solar=f.bool(), vortex=f.bool(), nebula=f.bool(), stardust=f.bool()) defeated_pillars = PillarsInfo(solar=f.bool(), vortex=f.bool(), nebula=f.bool(), stardust=f.bool())
lunar_events = h.LunarEvents(pillars_present=h.PillarsInfo(solar=f.bool(), lunar_events = LunarEvents(pillars_present=PillarsInfo(solar=f.bool(),
vortex=f.bool(), vortex=f.bool(),
nebula=f.bool(), nebula=f.bool(),
stardust=f.bool()), stardust=f.bool()),
@ -323,17 +365,17 @@ class World:
partying_npcs = [] partying_npcs = []
for _ in range(partying_npcs_count): for _ in range(partying_npcs_count):
partying_npcs.append(f.int4()) partying_npcs.append(f.int4())
party = h.Party(thrown_by_party_center=party_center_active, party = Party(thrown_by_party_center=party_center_active,
thrown_by_npcs=party_natural_active, thrown_by_npcs=party_natural_active,
cooldown=party_cooldown, cooldown=party_cooldown,
partying_npcs=partying_npcs) partying_npcs=partying_npcs)
sandstorm = h.Sandstorm(is_active=f.bool(), sandstorm = Sandstorm(is_active=f.bool(),
time_left=f.int4(), time_left=f.int4(),
severity=f.single(), severity=f.single(),
intended_severity=f.single()) intended_severity=f.single())
events = h.Events(blood_moon=blood_moon, events = Events(blood_moon=blood_moon,
solar_eclipse=eclipse, solar_eclipse=eclipse,
invasion=invasion, invasion=invasion,
slime_rain=time_left_slime_rain, slime_rain=time_left_slime_rain,
@ -343,7 +385,7 @@ class World:
lunar_events=lunar_events) lunar_events=lunar_events)
saved_bartender = f.bool() saved_bartender = f.bool()
saved_npcs = h.SavedNPCs(goblin_tinkerer=saved_goblin_tinkerer, saved_npcs = SavedNPCs(goblin_tinkerer=saved_goblin_tinkerer,
wizard=saved_wizard, wizard=saved_wizard,
mechanic=saved_mechanic, mechanic=saved_mechanic,
angler=saved_angler, angler=saved_angler,
@ -351,9 +393,9 @@ class World:
tax_collector=saved_tax_collector, tax_collector=saved_tax_collector,
bartender=saved_bartender) bartender=saved_bartender)
old_ones_army = h.OldOnesArmyTiers(f.bool(), f.bool(), f.bool()) old_ones_army = OldOnesArmyTiers(f.bool(), f.bool(), f.bool())
bosses_defeated = h.BossesDefeated(eye_of_cthulhu=defeated_eye_of_cthulhu, bosses_defeated = BossesDefeated(eye_of_cthulhu=defeated_eye_of_cthulhu,
eater_of_worlds=defeated_eater_of_worlds, eater_of_worlds=defeated_eater_of_worlds,
skeletron=defeated_skeletron, skeletron=defeated_skeletron,
queen_bee=defeated_queen_bee, queen_bee=defeated_queen_bee,
@ -378,6 +420,8 @@ class World:
lunar_pillars=defeated_pillars, lunar_pillars=defeated_pillars,
old_ones_army=old_ones_army) old_ones_army=old_ones_army)
# Tile data starts here # Tile data starts here
first_tile = cls._read_tiles(f)
world = World(version=version, savefile_type=savefile_type, revision=revision, is_favorite=is_favorite, world = World(version=version, savefile_type=savefile_type, revision=revision, is_favorite=is_favorite,
name=name, generator=generator, uuid_=uuid_, id_=id_, bounds=bounds, size=world_size, name=name, generator=generator, uuid_=uuid_, id_=id_, bounds=bounds, size=world_size,
is_expert=is_expert, created_on=created_on, styles=world_styles, backgrounds=backgrounds, is_expert=is_expert, created_on=created_on, styles=world_styles, backgrounds=backgrounds,

3
test.py Normal file
View file

@ -0,0 +1,3 @@
import lihzahrd
lihzahrd.World.create_from_file(open("Small_Example.wld", "rb"))