How to write a roguelike game? :)

G

Guest

Guest
Archived from groups: rec.games.roguelike.development (More info?)

This is a rough route map for the creators of roguelikes. I'm well aware that
there are many possible routes and that no two journeys are the same -- this is
a description of one of possibilities and maybe will help you to plan your own.

Please add your comments -- maybe we could make this article really
helpful. What are your own routes?

Step 1 -- Decide to write a game
--------------------------------

Most of you will have this step behind you already, but there are some hints
about the direction of the first step. The best reason to start developing your
own roguelike game I can think of, is to create a game that you will enjoy
playing yourself. It's like this in my case.

Don't start by asking around about the definition of roguelike game -- you don't
need it. If the game you write is not considered roguelike by others, but it's
still fun to play for you -- you succeeded. It's not like there's some kind of
a contest to write a game meeting certain specifications.

Don't plan too much. Of course, if you want certain things in your game, you
must write it so that there is room for them -- but don't even try to anticipate
everything -- it's just impossible. When you write a desig doc, you make a lot
of decissions. Most of the decissions can't be made without performing some test
first -- usually by writing small programsutilizing given feature. It's best to
make the decissions when your project has already reached apropriate stage --
when you don't need to write an additional program, because your project already
has everything you need.

It's no fun to just proceed according to plan -- leave some space for
improvisation. Don't be afraid about making mistakes or implementing something
in an inflexible way -- you can improve it when you need it -- most of the time
it will be ok.

Step 2 -- Hello world!
----------------------

Prepare your programming environment. Choose your language and platform, choose
apropriate compilers/interpreters, editor, version control, automated build, and
other utilities. Set them up so that you're comfortable with them.

Decide on which libraries you're going to use -- it can change later, but it's
usually a painful change. Don't think too much about portability -- it can be
fixed later. Think about what you need and what you're comfortable with.

Decide on the language you want to write comments and object names in your code,
as well as the language you want to be used in your game. I'd strongly recommend
using english in your source code -- you can get more help this way from others.

Write a simple 'Hello world!' program and test whether it works. Test your
libraries, etc. -- you don't want any surprises.

Start coding.

Step 3 -- It's a boy!
---------------------

Start with screen output and keyboard input. Decide preemptively on your screen
layout (easy, you can change it later) and make the routines that display map
characters, status lines and messages.

Make the routine to read key-presses (no config files, no keys redefinition).

Make a '@ walking around the empty screen' demo. Play with it a little, clean
things up, play some more, imagining the game is finished and you're playing it
;).

Make the message handling routines -- especially for the debugging messages --
they come in handy.

Step 4 -- The map
-----------------

Decide on your map structure. Don't over-generalize -- you can add things later.
Make your (empty) map displayed on the screen. Scrolled if you need it.
Add some elements to your map to see if they are displayed correctly (just
hard-code them, you don't need a level generator yet).

Make your '@' appear on the map -- not as it's element at first, just as
a cursor. Test the scrolling, maybe make a 'look' command.

Now turn '@' into creature. You still don't have time implemented, so the
keyboard-reading routines will just move it around the map. Include the checks
for walls in the movement code. Maybe add doors and open/close commands.

Step 5 -- Saving/Loading
------------------------

Read the map from a file instead of hard-coding it. You can play with it and test
different configurations if you make it human-readable from the start.

Add the 'save' command and the procedures to save your game -- the map at first,
then, gradually, all of other game elements. From now on, when you implement
something that needs saving, also implement saving it as soon as possible.

Once you work with files, you can make your preferences and keybindings config
files. Again, if you make them human-readable, you'll save yourself a lot of
trouble.

Now, when you're not sure how any element of the game works, you can save the
game to a file and just check it.

Step 6 -- It's alive! Alive!
----------------------------

Implement other creatures (monsters) and time. At a single monster for start.
Give him some simple AI (like, say, stay still, or maybe move randomly).

Start with my turn-your turn, then implement the time system you want (or,
usually, a simplification of it and gradually make it more complicated later).

Remember to test everything as you go.

Step 7 -- Interaction
---------------------

Add stats for your creatures. A simplification of the ones you envisioned,
probably. It's best to add stats as they are needed, not because they 'look
cool', but you might not be able to resist ;).

Make the creatures notice each other -- bump, attack, etc. Gradually improve
their AIs, so that they can chase the player.

Implement and test the combat system -- without equipment for now, just hardcode
the values. Do lots of testing.

Step 8 -- Data files
--------------------

Move the creature, map features, etc. definitions to data files. Forget about
scripting for now If something cannot be moved -- just leave it for now.

Step 9 -- Items
---------------

Add items. For start, just objects you can pick up -- no properties. Gradually
give them properties, kinds, stats, etc., implement inventory, picking up and
dropping, equipping and using (no effects yet), also stacking, containers (if
you want them), etc.

It's a large step, lots of testing needed.

Step 10 -- Magic
-----------------

Add item effects, special monster attacks, spells. Add items and monsters to
test them. You don;t need all the possible effects right away -- just the ones
needed for the next step.

Step 11 -- Simple game
----------------------

Try to make a simple, hard-coded game. Play it and give it to play to your
friends. Test the mechanics implemented so far. Check whether the game is fun.

Change everything you need to change. Don't forget to test a lot. Always ask
someone to test the games 'fun factor', or test it yourself after some time of
break -- it's hard to notice some things right away.

This step should take pretty long time, until you've got a playable, fun
mini-game.

Step 12 -- Levels
-----------------

Write your level generators. Implement moving between the levels, wilderness or
town if you want them, saving the levels on level change if you want them
persistent (so that they don't take up memory).

Spread your monsters and items on different depths. Add more monsters and items,
with their effects, as needed.

Step 13 -- Experience
---------------------

Start developing your experience system and skill system. Tune the monster's and
item's stats. Make character generation screen, classes, races, whatever.

Play your game a lot.

Step 14 -- Citizens
-------------------

Add NPCs, shopkeepers, simple quests -- if you need them all. Keep adding
features and tuning the stats.

Step 15 -- Free at last
-----------------------

Start adding and testing all the 'unique' features you thought are so cool
months (years?) ago, when you started the whole thing. Revise whether they are
really so cool.

Write that random plot generator, factions system, infinite wilderness
generator, neural network AI, etc. -- you can test them on a working game.


--
Radomir `The Sheep' Dopieralski @**@_
($s) 3 Ching!
. . . ..v.vVvVVvVvv.v.. .
 
G

Guest

Guest
Archived from groups: rec.games.roguelike.development (More info?)

Radomir 'The Sheep' Dopieralski wrote:
>[SNIP'd a good article]

You'll find me down at step 4 right now, but I've got the design
document slmost finished for the rest.
 
G

Guest

Guest
Archived from groups: rec.games.roguelike.development (More info?)

Radomir 'The Sheep' Dopieralski wrote:
> Step 9 -- Items
> ---------------
> Add items. For start, just objects you can pick up -- no properties.

I think it could be really wise to plan the object system.
In my project it has been the major pain in the behind, because
I didn't get it right at the first time. Plan all object types
AND all features for them from the beginning, even if you aren't
using them yet. Create just few items for each object type and
see how they work together. When everything is working like a
clock, THEN it's time to add more items.
 
G

Guest

Guest
Archived from groups: rec.games.roguelike.development (More info?)

Radomir 'The Sheep' Dopieralski <thesheep@ sheep.prv.pl> writes:
> This is a rough route map for the creators of roguelikes. I'm well
> aware that there are many possible routes and that no two journeys
> are the same -- this is a description of one of possibilities and
> maybe will help you to plan your own.

Nice. Not far off the order that I did my first game in, actually.
Nowadays I tend to write the level generator first, but only because I
like writing level generators and watching the different maps they
make.

I noticed you missed out field-of-view. If you're going to have this,
put it in somewhere between steps 7 and 11 because adding *any* FOV
algorithm takes a bit of time later.

Once you have an @ walking around and hitting things (around step 7)
that can hit back, the order you do the rest of the game in becomes
far less important. Just add things in the order that seems fun *but
start with the small ones*.

> Step 5 -- Saving/Loading
> ------------------------
>
> Add the 'save' command and the procedures to save your game -- the map
> at first, then, gradually, all of other game elements. From now on,
> when you implement something that needs saving, also implement saving
> it as soon as possible.

Absolutely. First time round I left save/load until I'd already got a
multi-level dungeon with creatures, items, special effects, etc,
because back when it was a single-level game that took about ten
minutes to beat if that, it hardly seemed worth it. It took most of a
week to add save/load, and another week to debug it.

Even after that I often had bugs that only came up on reload because
of a bug in save/load (stuff like "If, after reloading, you pick up an
axe and wield it in your left hand, and the axe existed but was on the
floor before you saved, it will go horribly wrong").

This time round I have an easier job since I'm just storing
*everything* that could change during the game in a GameState
structure and when I get round to save/load I'll be using the
language's built-in any->String converter to save that structure.

If you can use that approach (the entire save/load routine will
probably be less than 50 lines of code) then you can afford to put off
adding save/load until the game is big enough that you might want to
do it. Otherwise *add it early and test it often*.

> Add stats for your creatures. A simplification of the ones you envisioned,
> probably. It's best to add stats as they are needed, not because they 'look
> cool', but you might not be able to resist ;).

I've never been able to resist that. It's not so much a problem if you
have a clear idea at the start of what each stat will be used for
*and* none of those ideas require anything extremely complicated.

--
Chris
 
G

Guest

Guest
Archived from groups: rec.games.roguelike.development (More info?)

Radomir 'The Sheep' Dopieralski wrote:
> What good will do all your planning, when you can't test?

It's called "planning" for a reason. Plan it before you
implement it:)

> But in most cases you really coudn't have. You can't foresee everything.
> The 'good planning' is only possible if you did it before

Not really. It's possible if you know what you need. If you don't
know then it's going to take actual trying anyway.
Besides bad and incomplete planning is better than just starting
to code, not knowing what you need.
One good example of planning is the datatypes you need for the
variables of the object. Is 'duration' going to be int or can you
handle it with char (byte) or short? Planning the datatype and
limits for the variable is important right from the beginning.
What flags you need? Static or dynamic variable? What things
you can automatically set using basic data? What are the actual
data variables that you need for the objects? etc. etc. Many
questions you can answer before starting to write the code.
 
G

Guest

Guest
Archived from groups: rec.games.roguelike.development (More info?)

Krice wrote:
> Radomir 'The Sheep' Dopieralski wrote:
> > What good will do all your planning, when you can't test?
>
> It's called "planning" for a reason. Plan it before you
> implement it:)

The tendency, however, is to overplan. I did very little planning for
POWDER - the four sheets in question have been posted here in the past.
Nonetheless, half that planning has turned out to be wasted as I never
went in that direction.

Sheep had an excellent point in the article: It is very boring to just
fill in points from a plan. Data entry in a roguelike is the hard
part. By "hard", I mean the part that people don't do.

Why do you think so many people want random plot generators? It is
because they don't want to do the work of writing a normal plot, but
instead can just do the fun part of writing magic chained plot
generators. The trouble is a random plot generator is strictly harder
than a normal plot. And it is hard to write a normal plot.

My entry into the story-based roguelikes would be You Only Live Once,
http://www.zincland.com/7drl/liveonce, on which I spent most of the
time typing and proofing dialogue.

The thing about writing a story, or writing a roguelike, is that there
is a strong improvisional component. It is like jamming music, but
maybe at a slower pace. Your roguelike takes a life of its own - it
tells you what the direction to go should be. It is like being a stone
carver - you don't want to just force the stone into a certain shape,
but work with the stone to bring out the shape that was there all
along.

This is why Sheeps comment about playing your own roguelike cannot be
stressed enough. That is how you get in tune with it. That is how you
know what direction to move in. Listen to your roguelike, not to your
design docs.

But, I could just be crazy :>

> > But in most cases you really coudn't have. You can't foresee everything.
> > The 'good planning' is only possible if you did it before
>
> Not really. It's possible if you know what you need. If you don't
> know then it's going to take actual trying anyway.
> Besides bad and incomplete planning is better than just starting
> to code, not knowing what you need.
> One good example of planning is the datatypes you need for the
> variables of the object.

I disagree rather strongly with that point.

I contend that you should intentionally design your system to be
agnostic to the actual storage of the variables in your objects. You
should design it *expecting* your datatypes to change. *Expecting*
there to be new labels you need to add. Your planning, as such, should
not be: "What fields do I need in an Item?" but "How do I make
maintaining 100 items as easy as possible?

> Is 'duration' going to be int or can you
> handle it with char (byte) or short? Planning the datatype and
> limits for the variable is important right from the beginning.

Speaking as someone writing for a system with rather limitted RAM
headroom, and hence a strong interest in choosing u8 vs int, I don't
see the need to plan from the beginning.

My tile bitmap indices, for example, are u8s. Very soon now I'm going
to hit 256 bitmaps and need to rewrite my tile engine with u16s or some
other clever approach. I don't see this as a lack of foresight, but
rather just another iterative change to the project. I originally
worked under the assumption that all the tiles fit in the GBAs VRAM
which was broken quite a long time ago.

> What flags you need? Static or dynamic variable? What things
> you can automatically set using basic data? What are the actual
> data variables that you need for the objects? etc. etc. Many
> questions you can answer before starting to write the code.

This is why I elected to have my data structures be created
automagically from configuration files. If I find I need another field
added to the item definition, I can just add it to the configuration
file and have it properly updated in the struct and added as the
appropriate default everywhere it matters.

For working on a roguelike in C or C++, I strongly recommend something
like my enummaker program to automate the creation of enums and
structures corresponding to your data types. It allows you to shift to
the compiler a large amount of type checking which otherwise would be
hard to find run time errors. You can find the source in the
aforementioned You Only Live Once package.
--
Jeff Lait
(POWDER: http://www.zincland.com/powder)
 
G

Guest

Guest
Archived from groups: rec.games.roguelike.development (More info?)

Radomir 'The Sheep' Dopieralski wrote:
> This is a rough route map for the creators of roguelikes. I'm well aware that
> there are many possible routes and that no two journeys are the same -- this is
> a description of one of possibilities and maybe will help you to plan your own.

Woohoo! Well written!

This should be printed and tacked to the wall of all aspiring roguelike
developers.

> Please add your comments -- maybe we could make this article really
> helpful. What are your own routes?

Mine is very close to this. Still working on step 13, though :>

> Play your game a lot.

This is the advice that I think is very important. By playing your
game, you gain the motivation to keep working on it. By playing your
game, you will get a list of 20 little items of polish that would make
the game 0.05% better. Having features that are well polished is more
important than just having features.
--
Jeff Lait
(POWDER: http://www.zincland.com/powder)
 
G

Guest

Guest
Archived from groups: rec.games.roguelike.development (More info?)

At 13 Aug 2005 11:59:09 -0700,
Krice wrote:

> Radomir 'The Sheep' Dopieralski wrote:
>> But in most cases you really coudn't have. You can't foresee everything.
>> The 'good planning' is only possible if you did it before
>
> Not really. It's possible if you know what you need. If you don't
> know then it's going to take actual trying anyway.

That's what I'm trying to say. You won't know what you need until you
actually reach there -- ither in your code, or on paper -- but in the
latter case, you still have to rewrite it into code...

> Besides bad and incomplete planning is better than just starting
> to code, not knowing what you need.

I tend to disagree. You basically say guessing is better than actually
going there and checking yourself?

> One good example of planning is the datatypes you need for the
> variables of the object. Is 'duration' going to be int or can you
> handle it with char (byte) or short?

Somehow I don't get it. How is it important? What kind of language doesn't
permit to change this easily if you chosed wrong?

> Planning the datatype and
> limits for the variable is important right from the beginning.

In most cases you cn safely use an int and forget about it -- you rarely
use numbers greater than MAXINT (turn count comes to mind), or care about
a few bytes of memory (large, multidimenshional arrays come to mind).

> What flags you need?

If you'r approach is so inflexible that you can't add more flags later,
then you're doomed anyways.

> Static or dynamic variable?

Again, wait until you can tell.

> What things
> you can automatically set using basic data?

I don't understand this. Could you elaborate?

> What are the actual
> data variables that you need for the objects? etc. etc.

Again, you add them as you need them. This way you don't end up missing
one you forgot about, but still having others without any use (or even
worse, used forcibly when really not needed).

> Many
> questions you can answer before starting to write the code.

Sure, but you can answer them later as well, or even better ;)

I believe this is connected with one's programming style and general
approach to the task. It's a religious thing -- we can discuss it ad
infinitum, without really convincing anyone.

But still, seeing other points of view can be interesting.

--
Radomir `The Sheep' Dopieralski @**@_
(*+) 3 Sparkle
. . . ..v.vVvVVvVvv.v.. .
 
G

Guest

Guest
Archived from groups: rec.games.roguelike.development (More info?)

Rioshin an'Harthen wrote:
> The waterfall model's main problem is too much design, trying
> to get everything down in one design document before writing
> even one line of code.

I was talking about the object system, which is just a part of the
game. An important part.. I can just say that without planning,
using "iterative" style, I've been re-programming the object system
again and again. With careful planning that could have been
avoided, or there could have been less re-programming.
 
G

Guest

Guest
Archived from groups: rec.games.roguelike.development (More info?)

Rioshin an'Harthen wrote:
> "Radomir 'The Sheep' Dopieralski" wrote:
> > Krice wrote:
> >>
> >> Many questions you can answer before starting to write the code.
> >
> > Sure, but you can answer them later as well, or even better ;)
> >
> > I believe this is connected with one's programming style and general
> > approach to the task. It's a religious thing -- we can discuss it ad
> > infinitum, without really convincing anyone.
>
> Looks to me like a conflict of software engineering models. :)
>
> Kind of like Krice prefering more of a waterfall model, while Radomir going
> for more of an iterative model. Both have their good points, and their bad
> ones. :)
>
> Let me apologize up now for going into rant mode, but I don't agree with
> either model. Thus, I've tried to design something of a software engineering
> model of my own, suitable for my needs, trying to combine the best parts
> of both extremities.

Hate to tell you but Aristotle beat you to this design model by a few
thousand years.

I don't think anyone but architecture astronauts seriously considered a
"Design Everything Before Any Code" to mean design *everything*.
Likewise, the iterative process doesn't mean to start coding blindly
either.

"Moderation in everything, including moderation."
--
Jeff Lait
(POWDER: http://www.zincland.com/powder)
 
G

Guest

Guest
Archived from groups: rec.games.roguelike.development (More info?)

"Radomir 'The Sheep' Dopieralski" wrote:
> Krice wrote:
>>
>> Many questions you can answer before starting to write the code.
>
> Sure, but you can answer them later as well, or even better ;)
>
> I believe this is connected with one's programming style and general
> approach to the task. It's a religious thing -- we can discuss it ad
> infinitum, without really convincing anyone.

Looks to me like a conflict of software engineering models. :)

Kind of like Krice prefering more of a waterfall model, while Radomir going
for more of an iterative model. Both have their good points, and their bad
ones. :)

Let me apologize up now for going into rant mode, but I don't agree with
either model. Thus, I've tried to design something of a software engineering
model of my own, suitable for my needs, trying to combine the best parts
of both extremities.

<RANT>
Ok, I'll give my input on this:

The waterfall model's main problem is too much design, trying to get
everything down in one design document before writing even one line of code.
This tends to make the design decisions be like acts of God, with almost no
chance to redesign areas turning out to be just wrong. And the main good
thing
with the waterfall model is that we know exactly where we're going and how,
since everything has been designed already.

Now, the iterative model takes a different look at things. We start with a
general
design of what we're trying to accomplish, write some code, test it, and
check for
upcoming risks in the process of development. And we start the rounds again,
going further on in the design, implementing the parts designed, test...
Somewhat like
a merry-go-round. The main problem in this case is a lack of design, we're
not quite
sure where we're going and may have to rewrite portions as the design
solidifies,
while the good point is the flexibility of the design and implementation
process.

That's just to begin with. Now comes a few ideas I have on how to write my
own
roguelike (when I get around to it - I've ideas floating in my head on the
setting and
details, but haven't put anything down as of yet).

Since the main problem of the waterfall is too much design, and the main
problem
of the iterative model is too little design, and there's a definite need to
know something
of the design prior to writing any implementation (I trust we can agree on
that --
otherwise we'll have to rewrite tons of stuff in the code), such as what
features will be
needed, etc., we'll have to design something, rough outlines of the game,
with more
detail added into the more complex parts, such as object management.

What I'm aiming for before I start to write code for my own roguelike is a
design
document along the lines of something after a dozen or so rounds of the
iterative
model - or something about a fifth to a third of what is in the full design
document.
This will let me have something to start from, with something of a knowledge
of
where I'll be going with the game, and then I'll iterate through writing a
part of the
code, testing it, and adding more to the design.

Now I have the best of both - a flexible design and implementation process
with
enough design decisions made up front that I have a clear idea of where I'm
proceeding. And as I iterate further and further, the idea of the result is
getting
clearer. When I reach another design phase, I have enough information
already
to better be able to build upon it, and can add designing accordingly.

If I find a need for adding eg. objects without having designed the
structure or
class earlier, I can add basic null objects without impacting the design,
eg. to test
inventory management. And because I have an idea of where I'm going, I also
have
an idea of where the object system is going, even when I haven't designed
it. So I'm
able to add a few properties to test the system better. If I have to change
the type
from a signed short to a signed long later on, then so be it. At least I've
been able to
test it out. And when I next come to a design phase, I'll design the area
where I've
had to make ad hoc descisions.
</RANT>

Ok, sorry for ranting... :)
 
G

Guest

Guest
Archived from groups: rec.games.roguelike.development (More info?)

"Radomir 'The Sheep' Dopieralski" <thesheep@ sheep.prv.pl> wrote in
message news:slrndfq2bb.nao.thesheep@atos.wmid.amu.edu.pl...
> [great article]

Five stars Sheep. Not much more to add; you said it all!

Great job.

--
Glen
L:pyt E+++ T-- R+ P+++ D+ G+ F:*band !RL RLA-
W:AF Q+++ AI++ GFX++ SFX-- RN++++ PO--- !Hp Re-- S+
 
G

Guest

Guest
Archived from groups: rec.games.roguelike.development (More info?)

Rioshin an'Harthen wrote:
> Once done, well... had to start from the beginning, since the
> design didn't work as it should have.

Guess that was not the fault of the design, but the designers:)
The design should be a rough outline of the project, nothing
too detailed, because the final work is done in programming.
 
G

Guest

Guest
Archived from groups: rec.games.roguelike.development (More info?)

"Jeff Lait" wrote:
> Rioshin an'Harthen wrote:
>> "Radomir 'The Sheep' Dopieralski" wrote:
>>> Krice wrote:
>>>>
>>>> Many questions you can answer before starting to write the code.
>>>
>>> Sure, but you can answer them later as well, or even better ;)
>>>
>>> I believe this is connected with one's programming style and general
>>> approach to the task. It's a religious thing -- we can discuss it ad
>>> infinitum, without really convincing anyone.
>>
>> Looks to me like a conflict of software engineering models. :)
>>
>> Kind of like Krice prefering more of a waterfall model, while Radomir
>> going
>> for more of an iterative model. Both have their good points, and their
>> bad
>> ones. :)
>>
>> Let me apologize up now for going into rant mode, but I don't agree with
>> either model. Thus, I've tried to design something of a software
>> engineering
>> model of my own, suitable for my needs, trying to combine the best parts
>> of both extremities.
>
> Hate to tell you but Aristotle beat you to this design model by a few
> thousand years.

I know he did - I'm a software engineer by profession. :) I just wrote that
in
first-person since it suited me better to, and since I've given a lot of
thought on
which model I prefer to use when I get started on my own roguelike.

> I don't think anyone but architecture astronauts seriously considered a
> "Design Everything Before Any Code" to mean design *everything*.
> Likewise, the iterative process doesn't mean to start coding blindly
> either.

True, it doesn't mean that, necessarily. Yet I've been involved in software
engineering processes where the design team has been separate from the
programming team, and the designs we've got... Full detail on everything,
and nothing but implementation and testing left. Once done, well... had to
start from the beginning, since the design didn't work as it should have.
That's
what too much design can do.

And the iterative model - it's not coding blindly, nor did I say it is. When
I've
used it in my professional life, it's usually been with too little design up
front,
which is the main problem with it. When not having to design everything,
people
usually design too little before delving into the programming side.

That's why I went for the model I presented in my previous post: enough
design
to get started, without having too much design for the design to evolve
naturally
during the development stages.