world is now loaded from json file(s)

This commit is contained in:
troido 2017-10-24 16:12:33 +02:00
parent 34a749e68a
commit 31d9ac0778
14 changed files with 6503 additions and 8 deletions

View File

@ -82,6 +82,7 @@ The idea is to make 3 different kind of areas:
## DONE
- load world from files
- more content (rooms, objects etc)
- multiple socket types (regular unix, abstract unix, inet), selectable as command line arguments
- configurable graphics

3
docs/client.md Normal file
View File

@ -0,0 +1,3 @@
# Client side architecture
The client most probably needs a full rewrite

View File

@ -4,7 +4,7 @@
The model is the part of the code that handles all game logic.
Outside code will send input to the model and call update on it in a given interval.
No part in the model has references to anything outside the model (except possibly callbacks/event listeners).
No part in the model has references to anything outside the model.
In the code, the model is represented by the World class.
Other important parts of the model are Player, Room, RoomData, GroundPatch, Entity and all components.
@ -19,3 +19,8 @@ Since most actual logic happens in the Rooms, this class is mainly for keeping t
## Room class
Rooms contain a part of the world, and are actually a model in themselves.
## Player class
The purpose of the player class is to keep a handle to the player entity that can be used by outside functions, and to keep the player data persistent between when the player leaves a room (either to go to another room, or because the player disconnected.

View File

@ -10,6 +10,7 @@ if sys.version_info[0] < 3:
sys.path.append(sys.path[0]+"/server/")
import mainloop
import argparse
import loader
defaultAdresses = {
@ -23,6 +24,7 @@ def main():
parser = argparse.ArgumentParser()
parser.add_argument("-a", "--address", help="The address of the socket. When the socket type is 'abstract' this is just a name. When it is 'unix' this is a filename. When it is 'inet' is should be in the format 'address:port', eg 'localhost:8080'. Defaults depends on the socket type")
parser.add_argument("-s", "--socket", help="the socket type. 'unix' is unix domain sockets, 'abstract' is abstract unix domain sockets and 'inet' is inet sockets. ", choices=["abstract", "unix", "inet"], default="abstract")
parser.add_argument("-w", "--world", help="A file to load the world from.", default="maps/worlddata.json")
args = parser.parse_args()
address = args.address
@ -33,6 +35,8 @@ def main():
elif args.socket == "inet":
hostname, sep, port = address.partition(':')
address = (hostname, int(port))
mainloop.Game(args.socket).start(address)
worldData = loader.loadWorld(args.world)
mainloop.Game(args.socket, worldData).start(address)
main()

62
maps/basement.json Normal file
View File

@ -0,0 +1,62 @@
{
"width": 64,
"height": 32,
"spawn": [30, 20],
"places": {
"stairup": [30, 20]
},
"grid": [
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ##################### ",
" #...................# ",
" #...................# ",
" #...................# ",
" #...................# ",
" #.........<.........# ",
" #...................# ",
" #...................# ",
" #...................# ",
" #...................# ",
" ##################### ",
" ",
" ",
" ",
" ",
" ",
" "
],
"mapping": {
",": "grass",
"Y": ["grass", "plant"],
"~": "water",
"o": ["grass", "stone"],
"*": ["grass", "pebble"],
"d": ["grass", "dummy"],
"#": "wall",
":": ["ground", "seed"],
".": "ground",
"^": ["spiketrap"],
"r": ["grass", "rabbit"],
"<": {
"type": "roomexit",
"args": ["begin", "stairdown"],
"kwargs": {"sprite": "stairup"}
},
" ": []
}
}

61
maps/begin.json Normal file
View File

@ -0,0 +1,61 @@
{
"width": 64,
"height": 32,
"spawn": [10, 5],
"places": {
"stairdown": [30, 20]
},
"grid": [
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,~~,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,~~~~~~~~~~,,,,,,,,,,,,,,,,,,,,",
",,,,,,o,,,,,,,,,,,*,,,,,,,,,,,,~~~~~~~~~~~~~~,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,~~~~~~~~~~~,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,~~~~~~,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,o,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,#####################,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,*,,,,,,,,,,,,,,#...................#,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,.,,,,.,#...................#,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,.,,,..,,,#...................#,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,.,.,,......................#,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,.,,,.,..............>.........#,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,..,....#...................#,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,#......#...................#,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,#.d..^.#...................#,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,########...................#,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,#####################,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,r,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,r,,,r,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,r,,,,,,,,,,,,,",
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"
],
"mapping": {
",": "grass",
"Y": ["grass", "plant"],
"~": "water",
"o": ["grass", "stone"],
"*": ["grass", "pebble"],
"d": ["grass", "dummy"],
"#": "wall",
":": ["ground", "seed"],
".": "ground",
"^": ["spiketrap"],
">": {
"type": "roomexit",
"args": ["basement","stairup"],
"kwargs": {"sprite": "stairdown"}
},
"r": ["grass", "rabbit"]
}
}

8
maps/world.json Normal file
View File

@ -0,0 +1,8 @@
{
"begin": "begin",
"rooms": {
"begin": "begin.json",
"basement": "basement.json"
}
}

6306
maps/worlddata.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
import utils
class Grid:
@ -59,7 +60,7 @@ class Grid:
def fromDict(data):
width, height = data["width"], data["height"]
field = data["field"] if "field" in data else []
field = data["field"] if "field" in data else utils.concat(data["grid"]) if "grid" in data else []
mapping = data["mapping"] if "mapping" in data else {}
grid = Grid(width, height)
for (i, val) in enumerate(field):

23
server/loader.py Normal file
View File

@ -0,0 +1,23 @@
import os.path
import json
def loadRoom(roomPath):
with open(roomPath) as roomFile:
room = json.load(roomFile)
for name, pos in room["places"].items():
room["places"][name] = tuple(pos)
return room
def loadWorld(worldPath):
with open(worldPath) as worldFile:
world = json.load(worldFile)
path = os.path.dirname(worldPath)
for name, room in world["rooms"].items():
if isinstance(room, str):
world["rooms"][name] = loadRoom(os.path.join(path, room))
return world

View File

@ -11,15 +11,17 @@ import sys
import world
import view
import worldgen
import json
import loader
class Game:
def __init__(self, socketType):
def __init__(self, socketType, worldData):
self.server = gameserver.GameServer(self, socketType)
self.world = world.World(worldgen.generateWorld())
self.world = world.World(worldData)
self.view = view.View(self.world)

View File

@ -28,6 +28,8 @@ class Room:
})
self.places = data.get("places", {})
for name, pos in self.places.items():
self.places[name] = tuple(pos)
self.field = {}

View File

@ -4,3 +4,23 @@
def clamp(val, lower, upper):
""" val if it's between lower and upper, else the closest of the two"""
return min(max(val, lower), upper)
def concat(arr):
"""Takes a list of sequences, returns the concatenation of the sequences """
if isinstance(arr[0], str):
return "".join(arr)
if isinstance(arr[0], bytes):
return b"".join(arr)
if isinstance(arr[0], list):
l = []
for s in arr:
l += s
return l
if isinstance(arr[0], tuple):
l = []
for s in arr:
l += s
return tuple(l)
else:
raise ValueError("type {} can't be concatenated".format(type(arr[0])))

View File

@ -126,7 +126,4 @@ def generateWorld():
}
}
#import json
#with open("worlddata.json", "w") as f:
#json.dump(worlddata, f, indent=2)
return worlddata