Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - naughty

Pages: 1 2 3 [4]
Programming / Re: Replayability
« on: February 22, 2013, 04:19:17 PM »
I don't replay roguelikes I've won very much. I've only beaten DCSS a few times and Brogue once though.

If there's some cool content I've not seen, some recent cool update or a vastly different play style I haven't tired then I'll pick it up again. Never with the same intensity as when I resolve to win though.

Programming / Re: Developing a world generation algorithm
« on: January 25, 2013, 10:02:29 AM »
I think the areas created by the overlaps look a little unnatural (even with 50 points), you could smooth them with cellular automata or a blur filter though.

I'm currently looking into voronoi diagrams for a graph based 2D roguelike and there's some great ideas in this polygonal island generation article. Instead of the overlapping you could pick a path along the edges of the diagram and widen it into a river. If you're using more points you could also combine some areas into lakes and just smooth out the shore lines.

As a side note by far the fastest and most robust implementation of voronoi I've found is in the boost polygon library but it's in C++.

You're definitely on an interesting track though.

Unless I'm missing something this is exactly the Dijkstra map technique Brogue uses.

Programming / Re: Corsed items on item-based RLs?
« on: January 08, 2013, 11:45:48 AM »
Having purely numeric negative effects just means players will use identification items to make sure they don't get burned or just not upgrade if they can get away with it. It does depend on how rare the cursed items are and how negative the effect is though.

I would propose that's it's more interesting to have a trade-off than a purely negative effect, e.g. the most powerful upgrade shards also stick the weapon to your hand like a traditional RL curse. There's a lot of bad effects that might be worth the cost of a more powerful weapon and would make an interesting choice.

This also reminds me of an idea about using 'haunted' instead of 'cursed'. The idea being that a haunted item requires appeasement before you can unequip it, e.g. wrathful ghost demands the souls of 2d8 enemies, thirsty ghost wants you to drink potions or just plain steals the next 2d3 potions you pick up and so on.

Programming / Re: When to use scripting languages?
« on: January 08, 2013, 11:30:47 AM »
jRuby and Ruby in general don't have a great reputation for speed. Clojure is pretty fast but a very different language to Ruby.

If the JVM is your primary concern it might be worth looking at Groovy or any of the other JVM languages.

If speed is your primary concern a C/C++ core with LuaJIT as the scripting language would be your best bet. There's a few 2D engines already that do this like Love, MOAI and so on. LuaJIT can be faster than Java so you can safely write more of your game in script without worrying about performance too much.

As for when and how to use scripting there's one primary model that seems to work the best. You have a small, fast engine written in your 'fast' language (JVM, C/C++ and so on) and then write most of the game logic in the scripting language. Anything that's too slow in script (e.g. A*, flood-filling) you move into the fast language. The key point is that you want the interface between the engine and the game to be as small and simple as possible or it becomes a nightmare to maintain.

Programming / Re: Why Auto-Explore is Missing the Point
« on: December 06, 2012, 12:37:13 PM »
It's also not just overly large levels that give an incentive to add auto-explore. Overly connected levels have the same issue as well, i.e. the more linear a level is the less likely back-tracking is needed and the more likely 'exploration' goes into the black.
Then I think developers should realise this and make linear levels if they don't want exploration in their game.  Too many roguelikes assume they have to have rooms and corridors in a 80x24 grid when that's not actually suitable to their gameplay.

I totally agree but I think the current technology the community uses to make dungeons isn't currently refined enough to allow smarter level design to emerge. There's notable examples trying something new though like Brogue (which also has auto-explore) but it's still based on 'fill the box with spray and pray'. The constraint propagation work mentioned on Roguelike Radio #53 might be a good place to look, I've got a basic version working in Lua based on Ian Horswill's and Leif Foged's paper referenced in the episode.

There's probably room for UI improvements as well to make navigating already explored areas easier with a keyboard as well. I just think it's worth noting that it's an issue with keyboards as an input device as well as with level layout.

Also large levels can work really well in games from other genre's, e.g. Super Metroid and Dark Souls. But it puts a lots of responsibility on the designer to do a good job. I don't think roguelikes make such design impossible, just a lot harder due to the procedural gen.

Programming / Re: Why Auto-Explore is Missing the Point
« on: December 05, 2012, 02:21:47 PM »
I think there's a underlying issue that's not been addressed.

The keyboard is the worst input method for exploration. It doesn't have enough 'dynamic range' compared to a mouse, touch screen or even a thumb stick. Auto-explore is an attempt to try and solve this issue as well as overly large levels.

For combat and other close quarters activities in roguelikes the keyboard is superior to other input methods. Less chance of miss-clicks you'd get with a mouse or touch screen and much better control over diagonals compared to a d-pad. A counter example would be long range weapon targeting, keyboards aren't great there but systems like auto-target and remembering your previous target help to paper over the cracks.

Before crawl-style auto-explore you had the 'shift and direction key' linear auto-explore (did Angband do it first?) but that only helps with really long corridors. It works for going between rooms if the corridor entrances line up on a cardinal or diagonal direction but level generators are never constrained to make that work well.

It's also not just overly large levels that give an incentive to add auto-explore. Overly connected levels have the same issue as well, i.e. the more linear a level is the less likely back-tracking is needed and the more likely 'exploration' goes into the black.

Programming / Re: Floofill
« on: December 04, 2012, 02:43:13 PM »
This algorithm is correct, but you should change to the proper breadth-first search when the game starts running too slow (or if using inefficient algorithms is a shame for you).

I assume you mean the iterative rather than recursive implementation?

If so I totally agree with your point, a queue based and iterative solution would be faster. For my day job at a games company I would write the more optimal version. Similar logic applies to the original FloodFill() as well, it can be made a lot faster but requires more code and is trickier to understand.

I just wanted to show that changing FloodFill() to DistanceFill() isn't that scary and not too much work.

Programming / Re: Floofill
« on: December 04, 2012, 09:45:58 AM »
You can fix the recursive version to make distance/height/Dijkstra maps quite easily though:

Code: [Select]
void DistanceFillAux(int x, int y, int d)
  if ((Dungeon[x][y].Content == FLOOR) && (Dungeon[x][y].Depth > d))
    Dungeon[x][y].Depth = d;
  DistanceFillAux(x+1, y, d+1);
  DistanceFillAux(x-1, y, d+1);
  DistanceFillAux(x, y+1, d+1);
  DistanceFillAux(x, y-1, d+1);

void DistanceFill(int x, int y)
  // First we need to set all the tiles to the furthest away they can be.
  for (int dx=0; dx < DUNGEON_WIDTH; ++dx)
    for (int dy=0; dy < DUNGEON_HEIGHT; ++dy)
      Dungeon[dx][dy].Depth = INT_MAX;

  DistanceFillAux(x, y, 0);

The important changes are setting the Depth to INT_MAX at the start and using a > comparison on the Depth in the DistanceFillAux() test.

It's also easy (but a bit tedious to write) to change the above code to do distance maps from groups of tiles instead of just a single tile. Then you can use it like Brogue does to show a warning when your levitation potion is going to run out while you are over lava.

Programming / Re: Floofill
« on: December 03, 2012, 04:22:26 PM »
The point you made about more than just 0 and 1 reminded me of Brain Walker's (of Brogue fame) article about The Incredible Power of Dijkstra Maps. Although the algorithm mentioned at the top of the article isn't very optimal at all.

Programming / Re: map[x][y] or map[y][x]
« on: December 03, 2012, 10:57:53 AM »
In terms of [ x][y] versus [y][ x], it won't affect performance on modern machines either way, but tty based displays drew the screen from left to right top to bottom making [ x][y] make more sense. I think virtually everyone uses [ x][y], and every open source program I've seen uses [ x][y]. I use [ x][y] too. As Jo said, [ x][y] is the standard in math, physics, and most importantly programming.

There is an enormous performance difference (can be upto 100X on tight loops) between [x ][y ] and [y ][x ] but most roguelikes aren't performance sensitive enough to notice the difference. The difference is even bigger on more modern hardware because CPU clock rates are so high that memory latency is a big issue. This is something you really need to be aware of when writing very high performance software like high end games, scientific applications and so on.

This is vital knowledge for working on the engines of AAA games for example.

In C multidimensional arrays are laid out with the rightmost array index increasing first so:

Code: [Select]
char map[X][Y] = ...

// The above is the same as a 1D array laid out as:
{ [X0,Y0], [X0,Y1], ..., [X0,YN], [X1,Y0], [X1,Y1], ..., [X1,YN] ... }

Memory is broken up into little contiguous arrays called cache-lines (normally 64 bytes these days). Only so many cache lines can be in the L1 cache, which is the fastest to access memory apart from registers. Getting a new cache-line into the cache is a lot slower than using something already in the cache. So the fastest way to access memory (all things being equal) is to access memory very close to previously accessed memory. For example:

Code: [Select]
const int DIM = 256;
char map[DIM][DIM] = {0};

// This is 'column' major, it iterates through the Y dimension first.
for (int x=0; x < DIM; ++x) {
    for (int y=0; y < DIM; ++y) {
        map[x][y] = // something...

// This is 'row' major, it iterates through the X dimension first.
for (int y=0; y < DIM; ++y) {
    for (int x=0; x < DIM; ++x) {
        map[x][y] = // something...

Now the fast loop is 'column' major (top-to-bottom, left-to-right) but we have a natural assumption that we iterate in the same way we read, e.g. left-to-right, top-to-bottom. But to make that the fast way to loop you need to order you map as [y ][x ].

This is where the controversy comes from you can't have both [x ][y ] and 'left-to-right, top-to-bottom' iteration order you have to pick one if you want the best performance.

However most roguelikes don't need to care because they don't tax the hardware much at all but if you wanted to do FOV calculations on every tile for some reason you better do it the optimal way or it'll be a hell of a lot slower.

Programming / Re: Github, bitbucket etc.
« on: July 11, 2012, 03:43:49 PM »
I use git and google code and it's a great way to have some kind of off-site backup if you commit often enough.

Also I mostly code in my living room on a laptop but when I go upstairs to use my desktop and it's so much quicker to push to the server and then pull when I get upstairs than to use USB drive or even a network share.

There's also useful features like a dev wiki, bug tracking, download areas and so on. I haven't released yet so I've not battle tested all the features but it's nice to know they're there.

Programming / Re: Interesting advancement paths/combat mechanics
« on: May 31, 2012, 07:55:32 AM »
You're right about the focus on materials, I've been staring at a table of materials and properties for a while and getting nowhere :^)

I think TrueGod was an unconscious inspiration for the idea, I played it a while ago during a lunch break. I'll have another go and see
if there's anything else I can get from it.

Thanks for the reply, it's got me out of a rut.

Programming / Re: Interesting advancement paths/combat mechanics
« on: May 30, 2012, 04:04:16 PM »
I've been wrestling with an idea for a while about a different form of levelling. Instead of bumping
stats or choosing abilities when you level up you get to change a 'law' of the game's mechanics.

For example you could choose to make wood tougher than steel. So wooden weapons like arrows and clubs are
more effective against materials with a lower toughness value. Wooden armour would also be better at
mitgating damage. This applies to all wood though including the arrows and clubs used by monsters, also if there
was an enemy like an Ent (i.e. made of wood) it would deal more melee damage and be more resistant to damage itself.

The core concept is to change levelling from improving just your character to a global trade-off. So a law can't just
apply to player.

I've been having issues trying to sketch out the system though. On the one hand it's difficult to come
up with interesting laws to change but it's also a pig to try and balance. Let's say the @ is made of
meat, the optimal tactic is to make meat tougher than any other material and hit monsters with weapons
made of meat. So changing toughness needs some kind of trade off.

Other laws I've been looking at are changing the flammability of materials, whether a material is poisonous,
the melting and freezing points of materials, conductivity (for lightning) and quite a few others.

The idea has been driving me to distraction to be honest. I think it's a fun and workable but I haven't
been able to balance it yet.

Pages: 1 2 3 [4]