Chris Bailey
Wizard

Group: Members
Posts: 602
Joined: Sep 13, 2008
|
#1 id:36272 Posted Oct 13, 2009, 5:05 pm
|
So, I've made about a million mapping systems now, and I've run into the same problems with each one. I've decided that it might help if I make this one as efficient as possible as I go along, instead of trying to "fix" it afterwards. So, the only thing this has in place is a basic structure for the "dungeon/area", an some basic structures for each "room/sector" in the dungeon. It does not take into account the display of players, npcs or items.
Code (text): 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 |
MAP_WIDTH = 15 # The width of the map.
MAP_HEIGHT = 15 # The height of the map.
# Basic sector type.
class DungeonSector
attr_accessor :passable, :view, :type
def initialize
@passable = true # Can you walk across this sector?
@view = " " # How the sector is displayed.
end
end
# A floor sector
class FloorSector < DungeonSector
def initialize(type=:cement)
@type = type # A generic type.
@view = case type
when :cement
"."
end
end
end
# A wall sector
class WallSector < DungeonSector
def initialize(type=:cement)
@passable = false
@type = type
@view = case type
when :door
"$"
when :cement
"#"
end
end
end
# The dungeon structure.
class Dungeon
attr_accessor :map, :name, :level
def initialize
@map = Array.new(MAP_WIDTH) { Array.new(MAP_HEIGHT)} # A 2D Array
@name = "New Dungeon" # The name of the dungeon.
MAP_HEIGHT.times do |y|
MAP_WIDTH.times do |x|
@map[x][y] = FloorSector.new
end
end
end
def view
buf = String.new # A buffer to hold the string.
# Iterates through the 2 dimensional array "map" and dumps the "view"
# of each sector, in order, into the buffer.
15.times do |y|
buf << "\r\n" if y > 0
15.times do |x|
buf << @map[x][y].view
end
end
return buf # Return the string created from the map.
end
end
|
|
|
......................... If what Proust says is true, that happiness is the absence of fever, then I will never know happiness. For I am possessed by a fever for knowledge, experience, and creation.
|
|
|
|
Chris Bailey
Wizard

Group: Members
Posts: 602
Joined: Sep 13, 2008
|
#3 id:36274 Posted Oct 13, 2009, 5:13 pm
|
I should have elaborated on that. I was just seeing if there was any particular problem with this portion before I delved into the real issues. The first problem that comes to mind is when adding color to the "view" of each sector. It will change a string like ".", into "#w.". This seems like a non-issue at first, but even with a map size of 15x15, this quickly turns into a string of 15*15*3 (675) characters. Since this map is displayed to EACH player, EVERY time they move or type look, it gets to be a lot. Especially if I decide to increase the size of the map. I came up with a way of causing color to bleed across identically colored sectors, but it was a hack. Any advice on how to handle this large strings properly?
|
|
......................... If what Proust says is true, that happiness is the absence of fever, then I will never know happiness. For I am possessed by a fever for knowledge, experience, and creation.
|
|
David Haley
Wizard


Group: Members
Posts: 6,874
Joined: Jun 30, 2007
|
#4 id:36275 Posted Oct 13, 2009, 5:21 pm
|
It's hard to talk about general problems without having the whole context.
Do you display the entire map each time, or only a window onto it?
If it's the entire map, things are easier because you can make a pass on it (preprocessing it if you will) and do "line-length compression" on the colors. In other words, when the color changes, store a color code at that point, and don't store another one until (a) the line ends or (b) the color changes.
If you're doing a window at a time, you can't do the one-time pass approach (unless I suppose you store the compressed window for each possible window, but that can be silly depending on how big your world is and how many possible windows there are). It would still be pretty easy to only emit a color code if you need to, for example by simply keeping track of the previous color on this line and emitting if and only if the new tile's color is different. This will be only marginally more CPU intensive (it's just comparisons, after all!) but will give you the same memory savings.
|
|
|
Chris Bailey
Wizard

Group: Members
Posts: 602
Joined: Sep 13, 2008
|
#5 id:36276 Posted Oct 13, 2009, 5:28 pm
|
DH - I am processing the entire map for each view. I had considered processing only what the player has "seen" so far, but with such a small map, what's the point? I suppose I could put that color hack back in, it did make a difference. Let me put it in there and see what ya think.
|
|
......................... If what Proust says is true, that happiness is the absence of fever, then I will never know happiness. For I am possessed by a fever for knowledge, experience, and creation.
|
|
Chris Bailey
Wizard

Group: Members
Posts: 602
Joined: Sep 13, 2008
|
#6 id:36278 Posted Oct 13, 2009, 5:46 pm
|
Non tested, but I think this will have that effect.
Code (text): 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 |
def view
buf = String.new # A buffer to hold the string.
# Iterates through the 2 dimensional array "map" and dumps the "view"
# of each sector, in order, into the buffer.
last_color = @map[0][0].view[0..1]
15.times do |y|
buf << "\r\n" if y > 0
15.times do |x|
if @map[x][y].view[0..1] == last_color
buf << @map[x][y].view[2]
else
last_color = @map[x][y].view[0..1]
buf << @map[x][y].view
end
end
end
|
|
|
......................... If what Proust says is true, that happiness is the absence of fever, then I will never know happiness. For I am possessed by a fever for knowledge, experience, and creation.
|
|
|
|
Chris Bailey
Wizard

Group: Members
Posts: 602
Joined: Sep 13, 2008
|
#8 id:36281 Posted Oct 13, 2009, 6:25 pm
|
Scandum - Will do
|
|
......................... If what Proust says is true, that happiness is the absence of fever, then I will never know happiness. For I am possessed by a fever for knowledge, experience, and creation.
|
|
|
|
Runter
Wizard


Group: Members
Posts: 1,850
Joined: Jun 1, 2006
|
#10 id:36287 Posted Oct 13, 2009, 10:26 pm
|
Chris Bailey said:I should have elaborated on that. I was just seeing if there was any particular problem with this portion before I delved into the real issues. The first problem that comes to mind is when adding color to the "view" of each sector. It will change a string like ".", into "#w.". This seems like a non-issue at first, but even with a map size of 15x15, this quickly turns into a string of 15*15*3 (675) characters. Since this map is displayed to EACH player, EVERY time they move or type look, it gets to be a lot. Especially if I decide to increase the size of the map. I came up with a way of causing color to bleed across identically colored sectors, but it was a hack. Any advice on how to handle this large strings properly?
I thought this same exact discussion took place 6 months ago? :P (Even with solutions specifically with Ruby in mind.)
If you decide on using a string filter on your map output there are examples already posted on this forum. In a Ruby specific implementation I would suggest using regular expression blocks or writing your own C iteration implementation to extend Ruby. They're both very fast when compared to a pure Ruby implementation.
|
......................... CoralMud project
For once you have tasted flight Ruby you will walk the earth with your eyes turned skywards,
for there you have been and there you will long to return. --
Leonardo Da Vinci Yukihiro Matsumoto
Last edited Oct 13, 2009, 10:33 pm by Runter
|
|
Chris Bailey
Wizard

Group: Members
Posts: 602
Joined: Sep 13, 2008
|
#11 id:36288 Posted Oct 13, 2009, 10:34 pm
|
Runter - You are right, I completely forgot what came of it. =(
DH - The next issue involves tracking information about each room/sector on the map. There are a lot of small things I'm adding into this one like doors, traps, things that may be climbed or jumped over, etc.. I'm not sure if I should store all of this information inside each sector, or perhaps just store the coordinates of these special things in on the map itself and overlay it? I know it sounds odd, I just want to make this as efficient as possible, the whole map thing is just a huge resource vacuum for me =(
|
|
......................... If what Proust says is true, that happiness is the absence of fever, then I will never know happiness. For I am possessed by a fever for knowledge, experience, and creation.
|
|
Runter
Wizard


Group: Members
Posts: 1,850
Joined: Jun 1, 2006
|
#12 id:36289 Posted Oct 13, 2009, 10:37 pm
|
Chris Bailey said:Runter - You are right, I completely forgot what came of it. =(
DH - The next issue involves tracking information about each room/sector on the map. There are a lot of small things I'm adding into this one like doors, traps, things that may be climbed or jumped over, etc.. I'm not sure if I should store all of this information inside each sector, or perhaps just store the coordinates of these special things in on the map itself and overlay it? I know it sounds odd, I just want to make this as efficient as possible, the whole map thing is just a huge resource vacuum for me =(
Overlaying it isn't a bad idea, but I can tell you what is a bad idea: Having tons of unused variables within pure Ruby. That translates to a ton of inefficiency.
But typically I think over thinking within a higher level language defeats the purpose of the language itself unless it's absolutely vital. You might remember this thread.
|
......................... CoralMud project
For once you have tasted flight Ruby you will walk the earth with your eyes turned skywards,
for there you have been and there you will long to return. --
Leonardo Da Vinci Yukihiro Matsumoto
Last edited Oct 13, 2009, 10:40 pm by Runter
|
|
Chris Bailey
Wizard

Group: Members
Posts: 602
Joined: Sep 13, 2008
|
#13 id:36290 Posted Oct 13, 2009, 10:45 pm
|
Oh yeah! Runter - I've been out of it for awhile, I forget things easily :P
|
|
......................... If what Proust says is true, that happiness is the absence of fever, then I will never know happiness. For I am possessed by a fever for knowledge, experience, and creation.
|
|
David Haley
Wizard


Group: Members
Posts: 6,874
Joined: Jun 30, 2007
|
#14 id:36307 Posted Oct 14, 2009, 12:23 pm
|
Runter correctly points out that you don't want lots of stuff hanging around even if null because that can be inefficient. For example, you wouldn't want an overlay per type of thing, nor would you want a slot for each type of thing on each sector type. The optimal solution depends on what exactly your constraints are: can multiple things be overlaid on a single square, or just one? How many of these do you have (what is their frequency)? Do they change? etc.
One thing you can do that would be not-horrible would be to have a single "extra data" on each sector type. This would be nil if there is no extra data, and point to some kind of object if there is data. If you can have several things on each square, it could have one slot per thing, or be a list of things. If you can only have one extra thing, it would be just the thing itself. This way, you save especially for the multiple-thing-case, because although you have a flat overhead on each sector, you only incur the extra overhead of storing the slots if you actually have stuff there.
You could also specialize your sector class to have a version with extra stuff and a version without extra stuff; this could let you eliminate the overhead entirely on squares that don't have extras. If the extras can move around, you will have to juggle between sector class types, which can be annoying and perhaps even defeat the purpose.
-------
Oh, and by the way... just to indulge in some silliness to mark the occasion......
Dav-eta! What does the scanner say about the post count?!
|
Last edited Oct 14, 2009, 12:24 pm by David Haley
|
|
Chris Bailey
Wizard

Group: Members
Posts: 602
Joined: Sep 13, 2008
|
#15 id:36321 Posted Oct 14, 2009, 9:09 pm
|
LOL @ 5000.
How about I just whip up a little method that will add and remove these "Extras" from an array in the sector. If there is nothing, the array will not exist, and it will grow as you add things to it. I could remove things in such a way as not to make the array sparse as things are moved around and stuff.
|
|
......................... If what Proust says is true, that happiness is the absence of fever, then I will never know happiness. For I am possessed by a fever for knowledge, experience, and creation.
|
|