Buildings, part three: ingame.

Now actually in the game!

Now actually in the game!

I’ve significantly trimmed up my entities.py file after storing entity data into a separate text file and reading it from there, by removing a lot of now-redundant “if entity is a monster: set stats, else if stairs: set foo, else if..” code, and in the process removed a few useless parameters and cleaned up entity creation code to a simple “creature = Entity(dict[“name/type”])” call. Next up is adding some more item types.

But staring longingly at the picture in the previous post made me want to put it in the game, so I did that too, partly to see how hard putting hand-made structures in a map is. Doing it by hand (defining a hard-coded numpy array, and merging it in and defining building boundaries etc so it plays nice with my algorithms) is simple enough, but if I plan on adding more handmade pieces, making it do that automatically will probably save time. Shouldn’t be an problem.

Advertisements

Towns and Buildings, Part Two.

Hypothetical building

Hypothetical building

The above is just a mockup created in GIMP of a hypothetical building. Did some looking, and hand-digital-painting buildings wouldn’t be worth the effort. However, I think tiles might just work fine for making unique buildings. In making the above I sort of went about it as if I were trying to make it algorithmically–mapping out hallway/room intersections, then floodfilling in some tiles to see what the result would look like, and well, it may not be “City built out of ancient husks of crab people,” the final result definitely doesn’t look like a bland old rectangle, that’s for sure.

Back to Morrowind/Oblivion, from my time playing with its built-in Construction Set I do know that their levels and such are all designed in terms of building blocks: t-junctions, 4-way junctions, corners, short hallways, long hallways, etc. Perhaps that idea could be utilized, in that not only are tiles the building blocks of a structure, so are “prefabs” defined in some external file as arrays. Then building styles could be applied at map generation that have weighted choices, so that style A has a higher chance of generating winding roads with clustered buildings intermittently, while style B has one or two monstrous interconnected structures that sprawls across the entire 70×70 grid, for example.

What is in a town + what’s planned.

First, I’m planning on getting a more coherent item system going, adding in a healing potion thing, and fleshing out the GUI a little before throwing up what I’ve got onto the other site for download.  Once that’s complete, it’s time to try my hand at NPCs/shops of some form, and possibly get a spell system working with targeting, and try to redo the town generation system.

Maps have been on my mind lately for some reason.  Sure it’s easy enough to come up with another dungeon algorithm, or even a wilderness one, and add it into the game in a way that makes sense–hit the border of the town, load a wilderness map; hit stairs down, load the next dungeon algorithm, or what have you.

What I’ve been thinking about though, is how exactly to make towns seem different from eachother.  The ultimate function of the “town level” in a Roguelike is for shops (loot), quests, and possible random scenarios (IE: coming across a tavern brawl, then segue that into a quest), all of which are simple enough in theory. It’s at this point where I’ll admit that I don’t really play Roguelikes all that often so I dont have experience with how others have done it, but what I can find off the net seems to show that there isn’t that much interest in how to algorithmically create a unique ‘town level’ in RL’s. There don’t seem to be many articles on the subject in RogueBasin (beyond a simple “take an area and fill it with rectangles + a door” advice on one dev FAQ), and some RLs like Nethack don’t even feature an overworld. Some others use hardcoded maps of 3-5 buildings and use those for settlements.

What it feels like to me is that for algorithmically making a unique town, it’s just a matter of combining differences to make uniqueness–have city A use brown wooden walls, a simple fence for a border, “peasant” sprites, small to medium sized rooms, while city B has stone gates, a wider mix of npc sprites, and larger buildings, and maybe a river running through it.

Still, something like that doesn’t feel significant enough, and I almost want to say it’s the nature of a Roguelike that does that, as things run on a grid. If you look at the towns in say, Morrowind (as I’ve been playing that recently, heh), those are all different. You’ve got the mud-brick adobe city that has the river cutting down the middle of it, the capital city broken into rectangular boxes (cantons, I think they were called?), you’ve got a nomadic settlement filled with yurts, as well as the traditional imperial forts, that one place whose buildings are made out of ancient giant crab shells… It’s like every city has a completely different architecture with uneven/winding paths, which isn’t something that can be easily shown on a system that works in terms of squares on a grid.

I’m probably going to be thinking about this some more. One solution would be to include more building shapes–circles, pentagons, and so on, as well as intersections between them. Another option could be to just rebuild how I’ve made the maps–replace each building with a handmade sprite, even though that could take a while, for example.

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

That there “fun factor”.

Started on getting all my entities defined within a file, now it’s just a matter of adding in more properties so that trees and doors and such can go in too. I ended up using configparser to do the job as I had with some other files and it turned out to be pretty straightforward. Included in this file are the following properties:

relevant combat data
speed
“AI state”
faction
x/y coordinates of the tilesheet where the guy is located

Besides this, I’ve added in a level transporter/stairs so that as a player, the gameplay right now consists of going to the stairs, entering the cave, and then finding your way through to the other side without losing all of your health.

One nuance I’m discovering is that it feels really fake with how the pathfinding works–specifically, that every single creature in the area will chase you only from a certain scent value, currently set at 10 squares away (give or take depending on obstructions). What would make more sense is if, say a hunter could track and follow you farther than a little mushroom could, or what have you. I’ve got a few ideas rolling around in my head to give that effect, currently the most likely is to directly add in a “search depth” parameter to the entities, and floodfill out a wider range and check that way.

But a wider flood range means that the game will probably take a performance hit from doing a large recursive floodfill, and there’s got to be a way to trick the player into only thinking that one thing is tracking you more aggressively than another…

Another trick to pathing I’ve heard about (that I think Quake 3 bots use, actually..) is that the game tracks where the player moves (say, storing the coordinates in a list/array), and then the AI would find that path and follow it using that list. Perhaps alternative path strategies could work.

I could also use A*, but at this point I want to see if I can do this in a sneaky way without resorting to it. >_>;

another mental note for later: speed currently only works by slowing down the entities relative to the player, not giving the monsters additional turns. That needs tweaking.

Ideas.

Haven’t been putting much work into this lately; mainly distracted by some other toys and things as of late so I haven’t been able to get any good ideas going in my head. In terms of taking what I’ve got now, and making it functional, Graff is relatively close in that regard. The “fun” part of “functional” is definitely not there yet, but in terms of “allow the player to enter a dungeon, kill things, grab loot, and exit back out”, the pieces are there, but not put together or fleshed out. In terms of what could go in, here’s a list of ideas off the top of my head:

-Random element to combat
-Combat “abilities”
-Healing
-Shops;NPCs
-Monster variety; new monster behaviors
-Line of sight pathing
-Discrete turn system
-Field of View
-More GUI elements
-More map algorithms
-More transparent or player-affecting item/stat system
-More discrete map transitions than “press W or E”

With combat, out of the above list monster behaviors and combat abilities have the most potential to make things interesting. With abilities, I was thinking of having some sort of system where the player can press a key or hit a button that, for example does a “sweeping” move that hits all adjacent targets, or if the player moves in a direction for 2 squares and then collides with an entity, a “lance” ability is triggered that causes a knockback effect, for example.

Monster behavior is simply new AI patterns. There could be “squads” of entities that all follow a leader until that leader is within range of a target, then the squad begins to follow the target to attack. Likewise ranged attackers could mix things up, as well as trap layers, and so on.

Randomness to combat shouldn’t be that difficult; simply instead of returning (attacker.atk – target.def), return random range(attacker.atk – target.def) within some tolerance.

Though the first issue I should probably tackle is the managing of AI behavior. Currently it’s all hardcoded, and I’d like to get some portion of the entities into a separate file that’s loaded at the start of the game. Perhaps something as simple as the creature’s stats, name, and default AI package, as well as any status effects/resists, and that way adding a new creature is just a matter of writing a new entry into a config file, instead of jamming it into Entity.py somehow.

0.0.6B

And again.

_Hopefully_ I ironed out the bugs out of this one. The most significant change is that the main game loop has been somewhat altered. The latter half of the functions above are now called at a different time within some of the other functions so that the order now is close to:

get keypress
player moves
“generate view” called
find visible entities on screen by worldcoords, set their current x,y values
set on scentmap which tiles are blocked by entities or wall tiles
floodfill from the player’s position a scent
for each entity that is on screen:
..take a turn: decide where to move by finding higher scent value
..set tile entity is on to “not blocking”
..”move” -> check new tile’s blocking status, if clear: set world coords and screen coords
..set this new tile to a status of ‘blocking’
end

Essentially I’m trying to bring the loop down to “player takes a turn -> entity takes a turn -> entity takes turn -> repeat”, and that has crushed most of the bugs I’ve discovered. I think what my problem was, was that the flood fill and scent maps were lagging and causing the problems. Oh well, should be good now.

0.0.6

EDIT: Ooh shiny, a featured page under WP’s roguelike tag. Well I’ve got a newer post up here that’s got some changes from this one, if you’re interested.

Next release is up.

Combat is extremely basic at the moment, and not at all where I’d like it, but I have a change of plans. My code has gotten to the point where, although it makes sense from a “I can follow the dots down the line from player input -> game draws to screen” perspective, it seems like each time I make a minor change, the AI’s following behaivor reverts back to doing something odd that I thought I already fixed. Currently here’s the basic game logic loop:

player presses a key (say, a movement key)

Scene.filterkeys() is called

that calls Player.move():
..player.x,player.y, and world coords are set
..generateview() is called -> screen re-establishes what tiles are where and what they look like

enter Scene.update() loop:
player.update() called:
..nothing relevant happens, oddly

tiles update:
..nothing important, just sets up which tiles are dirty for dirty rectangle updates

checkentityvisible() called:
..if entity in list is within bounds of the screen, add to livingspritegroup

updatenodemap:
set a matrix according to each tile's blocking status within the viewable screen

updateScentMaps(playercoords):
..do a floodfill of "scent" for collab diffusion followers to hone in on

update livingspriteGroup:
..move according to scentmap/generateview() changes

draw everything

exit update, await next input

Its mainly the latter half of the set, where the miscellaneous functions (scent map, etc) are called is where things get messy. At this point I’m going to get down to finding out how to simplify and unify (and probably rewrite) everything, particularly in terms of collision. “When is collision handled?” is not a very easy question to answer at this point in time.