Not much worth blogging about as of yet…

Primarily because I’m going back to info gathering to get some material to think up this world thing. Got a few more maps plotted out of preliminary class combos, though. I figure a specialization tree, where you start with the basic Fighter/Rogue/Mage templates and branch out from there could work for starters.

A scrolling tile map you say?

So, my blog stats spiked today.  I’m not sure if it’s a fluke, bots, or my using post tags having some sort of effect, but in either case this wordpress stuff says something about top searchings being for a scrolling tile map.  Whether it was just one guy who searched for it, as long as it lets me procrastinate on getting real work done on this, I guess I’ll post about how I actually got scrolling to work with pygame.

First of all, I’ve got hidden away in Scene.py a class called Tile (or Maptile or something to that effect).  Ultimate it’s a 32×32 pygame sprite that, for now, has stored on it just an image and its rect.  During map intialization, the class that holds the overall Map ends up intializing a 32×24 grid of these things, and sets their rects all to be (X Y 32 32), with XY being the topleft corner coordinates on the pygame display window.  Why 32×24?  My game window is 1024×768, and if you divide those by 32 (the size of each tile), thats how many tiles you break the scene into.

Independent of this, I have a separate piece of code that basically makes a giant 70×70 2d character array representing the gameworld.  Well, technically it uses Python’s Numeric module and so it uses numbers instead, but eh.  So the array might look like this:

[[1,1,1,1],
[1,0,0,1],
[1,0,0,1],
[1,1,1,1]]

Where 1 = wall, 0 = floor.

To get scrolling action going, ultimately I have a function called GenerateView, with it taking an input of XY coordinates representing the topleft coords of the display window.  First, this function clips off the topleft coords if they are out of bounds–say the player is already in the topleft and generate view gets called; if we want the player centered, and the player is already at (0,0), then using the above schema it would take an input of (-1,-1) and try to access nonexistant tiles to draw from!

So once the coords get clipped to within proper values, it’s simply a matter of reading the character array and starting from the topleft coords, reassign each Tile() object the proper image based upon the value of that particular entry in the 2d array–oh, and reassigning the worldcoordinates, too.  There’s a little bit more to it for dirty rectangle updates, and that’s why I rewrote the function in the first place, but yeah. It’s right around here where I’d write in something for remembering where items and dropped loot are as well, but that’s not in yet.

Now that I’ve described that, the actual fun occurs within the Player class.  Put simply, every time the player moves in a direction, it checks to see if player.x and player.y are too big or too small–whatever values those are, are arbitrary.  If so, the above GenerateView function is called, the player picture gets moved back to the tile he should be on, and that’s that.

So to get constant scrolling in a turn-based tile system such as what I’ve got, GenerateView can be called any time the player leaves the center tile by having narrow bounds for player.x and player.y–if the player holds down the right arrow key, every update frame moves the player, it’s then found to be past the boundry each update, and then GenerateView is called each update to recenter the view on the player, giving the effect of scrolling.  In practice and with dirty rects, I only lose about 4 frames per seconds when I have constant scrolling, but of course that’s in a currently half-finished prototype that will probably be bulky and overloaded when/if I get done with this thing.  🙂 [update from the future: there really hasnt been much, if any, of performance issues so long as you code somewhat efficiently]

What’s one advantage to having GenerateView set each tile according to the 2d array that’s not related to scrolling?  If I want to modify the map (say with digging, spells damaging/converting tiles, whatever), all I have to do is change a cell in that 2d array from a 1 to a 0 and call GenerateView again, and everything else is taken care of.  🙂

Don’t forget to check out the front page for the latest!

Another day, another line of code.

You know how you plan to do something, you stare at it for a while, one thing leads to another and fives hours have passed and the only thing you’ve accomplished is gotten 30 more tabs of TvTrops open when you were just trying to look up fantasy cliches in equipment?

…Yeaah.

Quick sidenote: WordPress wiped out a section of this post, I’ll try to rewrite it as well as I can remember in my sleepy state of mind.

Okay so what my current plan is, is to have some sort of .ini or config file that defines all the armor types, in that there’s a section for location, armor material, and armor quality.  There are 4 locations, 8 materials, and 5 different qualities.  The problem I ran into, was that that leads to a lot of copy and pasting, and in terms of pure data that the game needs to track, most of it is single integer values.
This got me thinking to see if there’s some way to simplify it. Currently, material type, equip location, and quality are all that is really needed for statistical and equipment calculations: Simply apply some formula to the index values to calculate weight, defense, value, or whatever. So like in terms of purchase price in the game, a set of gloves has a base cost of 1. Then armor 2 has an index of 2, lets say that’s just added onto the value, and lets say the modifier is a multiplier. In that case, a pair of superior “armor 2” gloves has a total value of (1+2)*5, or 15 units. A similar idea could be applied to weight, or any other statistic.

now that’s all fine and good, but applying that to player.png and the visual display of such information…well, trying to grab a set of 4 coordinates from those index values COULD in theory be found, but that would be complicated.  Cue flipping back to learning about more cliches to try to avoid or drive into the ground.

That then led to my next thought–how important is it really to display player information on the actual screen beyond having a page list out what is equipped? That is, should I make it so that if you equip a pair of gloves, your character on the screen’s hands change colors? Or do I do it the way most other roguelike’s seem to go and they have default “player” pictures and you’re stuck with that same image throughout the game? On the one hand visual feedback is nice, on the other hand it could end up that anyone who plays this game (when the “game” part actually takes shape) ends up looking like a power ranger, except with less color coordination.

After asking one forum, those that have responded thus far seemed to not show much interest in the idea of seeing what the player equips on the screen, probably because roguelike players are instead used to seeing “@” as their player character. I’m probably going to scrap the “show the pants the player puts on visually” idea and go with premade player tiles at this rate; at the very least it means I can cut down on external config files and just keep it all in Python.

Dirty Rectangles are useful in turn-based movement…

Using dirty rectangles to only update the portions of the screen that actively change between screen refreshings make it so that I can get a constant ~33 fps while changing the view. I think if I can iron this system out I can make this even faster. 😀

Alrighty. I guess you could say this is a tutorial–or more just a drawn out explanation and insight into how my brain is so screwed up.  For those that don’t know, this at point #6 describes how dirty rectangles work.  Mine is slightly different, however.

So I’ve got a 32×24 grid of “tile” objects that represent each visible tile on the screen.  On that grid, each tile has a property called Dirty, and each tile is inside of a group. The basic process previously focused on a function called GenerateView, which was pretty straightforward, in that every time the player moves, all of the tiles are re-drawn on the screen, a simple and effective brute force method.

What I have going now, is this, with the initial condition is that Tile defaults to not Dirty:
step1: GenerateView():
Find out what symbol the tile will become
is the symbol the same or different to what Tile currently is?
If same: change worldcoords, done, dirty status is correct (not Dirty)
if different: change world coords, assert tile’s Dirty, add it to tileGroup.

Step 2: each Tile calls its update():
if Dirty: make not Dirty
if not Dirty: remove from tileGroup.

-so in effect, tileGroup now only contains all tiles that are asserted to be Dirty.

Step 3: tileGroup.drawTiles:
any sprite that was previously not dirty is no longer in the group, so those guys are not blitted.

(Step 4): Draw Player/entities on screen

that handles changes in the underlaying map. What of the objects on top of the map? Simple, assert dirty on the current square something is before it moves!

Step 0: entity movement:
handle input(move):
assert current Tile = Dirty, add tile to Tilegroup
move the player etc

Step 1:
generateView()
…etc

So I’m sort of half doing it. I need some way to pass a list of rects through to the main Play.py and call update(rects) to get full dirty-rect stuff going, but if I run into speed problems again I suppose I’ll do that. Currently my entire Scene class object gets pushed through Player, though, and my OCD makes me want to change that. I probably wont, though.

And I just realized something. For monsters, items, anything like that, every single time the player inputs something that tile automatically becomes dirty. That means that instead of handling it within the player movement code, I can probably bring it out to somewhere more sensible in Scene, and then from that, when I implement monsters and items, I can just have it so that every time the player moves, each monster and item tile it rests on is asserted dirty.

And now Scene has an assertDirty() function. How..appropriate. Replace step 0 above with a step 6. Once the screen is flipped, any tile the player is now standing on is asserted dirty there. Its also now in such a way that I can loop through monsters/items that may also happen to be standing on some tiles.

So, what’s the net result? A jump from 17 frames per second to around 33 on my machine when continuously scrolling. 🙂

Hm. Decisions…

So, next version that I will release I plan on having a working (or at least prototyped) inventory system, and likewise a prototype GUI.  Right now I’m working on the GUI, or at least thinking about how things will be planned out.

GUIs are going to be interesting though.  Aside from standard concerns about how to form a GUI that works, I’m going to have to answer a few other questions:

1. Should there be a standard screen size?  Currently I’ve been running with 1024×768.  Some quick testing shows I can definitely adjust the number of tiles placed down, but what about users that would want smaller screens?  Implementing lower (bigger?) res support at this stage isnt that difficult, but more importantly..

2. How much screen real estate should go to the UI?  I normally use 1440×900, and well at 1024×768 that doesnt give me much vertical room.  Horizontal room aplenty, but those combat logs sure will be small if I just add on to the bottom.  Which leads to #3:

3. Use nonstandard resolutions?  I could probably fit the essentials by adding a 100 pixel block to the side of the screen and put the rest on the actual gamemap region.  But then if someone wants to play the game in fullscreen mode, well they’re going to run into some issues with that if they are on an LCD monitor.

4. How should I handle resolution changes?  Right now I’m thinking of just cutting off some of the displayed tiles to maintain 32×32 size, but for all I know the RL community all plays these things on screens that go up to 320×240, in which case seeing all of 4 tiles will significantly affect AI and pathing if I go through with how I’m planning on working it, let alone player experience.

And one last question:

0.5. Scrolling?  Another thing I’m wondering is whether or not I should make this game always recenter the player to the screen’s middle.  I can do it right now just by changin boundary conditions for when the game recenters the view, but it comes at a slight (speed) cost if the player holds down a direction key.  Now a past change to the code made this particular part of the game 80% faster, but still.  Id like this game to be as fast as humanly possible in terms of performance.

Heh, maybe that means I should actually start advertising this thing so I can ask these questions to more people than just myself.  Speaking of which, you 4 fellas that are stopping by this site, leave a comment or two!  This blog is lonely.

Now we’re moving…

New version is up on the other site. Different map algorithms are now used, made Tile() use x,y worldcoords instead of y,x, and a few other changes. Now to have a somewhat workable inventory system. Possibly a GUI, too.

Back to 100%

That was far more pain than it was worth. On the flipside though, that cfg implementation that gave a framerate boost is now a full one frame faster per second. I guess that’s what newer versions of software do, heh. Now then, time to remanage my city.py and make it extendable so that other map algorithms can be used!

…Sometimes I wish I just decided to make a tetris clone. Ah well.