Saturday, March 12, 2011

Design Decisions: Grid type.

First of all, this blog is not dead.  There has been a lot of work going on the implementation of Lorem Ipsum I (as the roguelike is now going to be called).

 One of the decisions most roguelike developers never have to face is how to lay out their tiles, and what shape they will be.  Given the constraint of working with curses, the choice of a rectangular grid with square -- well, rectangular of 2x1 dimensions -- tiles is an obvious one.  Rectangular grids pose many advantages:
  • Rectangular grids lend themselves naturally to rectangular rooms in a dungeon map, for an easy correspondence to the real world;
  • Similarly they promote 90 degree angles in corridors, which is also quite natural;
  • They are easy to visualize and describe -- for that matter they may be effectively stored in a text file, either for a saved game or for a post-mortem character dump;
  • As has been mentioned before, they are the only sensible choice when working with curses;
  • Most computations get easier, for instance distance between tiles is trivial to compute, as the square root of x^2+y^2.
They also have certain disadvantages of varying gravity:
  • Using curses and monospace fonts, visually the distance between horizontal and vertical tiles is off by a factor of two.  This is a result of most monospace fonts being 2x1;
  • Worse yet, diagonal distances are off by a square root of two, and the developer is left with an uncomfortable task of reconciling what that will mean in game terms.  Common approaches involve assuming that diagonal movement is as expensive as that along the axes (which distorts distance favoring diagonal movement), or treating it to be 1.5 times as expensive (a crude approximation of the square root of two, but generally functional), which also entails tailoring the game to support 'fractional' movement;
  • On the same note, rectangular grids mean a player character can be surrounded from 8 sides... with four of the sides being a different distance 'off', potentially;
  • Lastly, rectangular grids make line of sight and field of view algorithms harder.  For instance, if two 'wall' tiles are touching on a diagonal, do they block line of sight?  Why or why not?
Hence, after a bit of deliberation I have decided to go with hexagonal tiles on a hexagonal grid.  To be exact, in my case the tiles themselves are mathematically circles inscribed inside the hexagons, but the principle is the same.  While certain math gets more difficult as a result, there is the trade-off of not distorting distance or treating half of the adjacent tiles as somehow special, while presenting a more organic look to the user.  Furthermore, while room layouts get a bit stranger, these grids are quite a charm for caves.
The layout also happens to be surprisingly easy -- working with monospace fonts of 2x1, successive columns can be staggered by half a tile's height presenting a pseudo hexagonal grid which looks pretty damn good.  For greater effect, I have included an option to offset the columns away from each other by a factor of 1.75, which approximates the distance between actual hexagonal tiles.  While this wastes some screen real estate, the outcome looks particularly even as a result.
Here is an image showcasing a hexagonal grid, as well as the new FOV algorithm (to be discussed later):

Wednesday, January 26, 2011

Design Decisions: Choosing an output library.

When developing in Python, the options for the output are rather limited -- only curses and SDL (via pygame) are available.  In theory there's also libtcod, which sits on top of pygame, but despite how much it touts being cross-platform unlike straight up pygame it refuses to work on 64-bit OS X, making it a poor choice for this particular developer.
Of the remaining two, curses is easier to use and is, in theory, more cross-platform.  It opens up the option to run the game in any terminal, in screen or over ssh.  It could then conceivably be adapted to run via dgamelaunch -- a definite plus.  Now, the downsides:  the output is entirely at the mercy of the terminal, and there may need to be specific code changes to enable the game to display properly on any available terminals.  It also leaves it up the user to properly configure their terminal colors, and furthermore the color options are going to necessarily be limited to xterm-colors to allow for widest support.
Pygame, on the other hand, is more challenging to develop for, as it deals with images rather than characters.  Hence, more aspects of the game would need to be written from scratch.  The benefits are huge, however -- cross platform compatibility ends up actually being greater, even as far as (in theory) running on Android devices.  Additional huge pluses are: ability to have hexagonal grids (which is something I have been seriously considering), and a multitude of colors for greater gradations (important when lighting has significant in-game implications).

For now the winner is clearly pygame.

Thursday, January 13, 2011

Design Decisions: Picking a language.

Ultimately I have managed to boil it down to two choices -- C++, and Python.  While Lua is popular lately and would open up the opportunity for me to use the TOME library, I chose not to spend the time to learn a different language when I can focus on improving my expertise in a language I can use for work.
Between the two, C++ offers the advantage of static typing, and, as a result, a more rigid development structure that may be of benefit as the project gets larger.  Python, on the other hand, offers rapid development and a pleasant and intuitive syntax.  I have settled on using Python for now and perhaps delegate any potential computationally intensive processing to a C++ library I can always introduce.  Pyrex was considered, but for the time being not thought necessary.

A trivial roguelike.

Created a trivial roguelike using python + pygame.  It is completely useless as a game, but could be a good starting point for someone else trying to write something in the genre.

https://github.com/megawidget/trapped

Wednesday, January 12, 2011

It has begun.

I have finally broken down and decided to code up my own Roguelike, from scratch -- an idea I have been mulling over for a while now.  This blog is intended to keep track of my misadventures, solicit advice, and act as a motivational tool for me to continue this daunting task.