Role of Scripting in Roguelikes

G

Guest

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

So I was looking at the NetHack code for the first time the other day.
Whew. Looks like it dates back to the time when utilizing
self-descriptive variable names with more than 8 characters was a
cardinal sin. A cursory look revealed that a lot of the actual game
data was saved in tables in .c files. All in all it looks like a piece
of software that has had new functionality bolted on to it every which
way for years and years. Which, of course, it has.

The only other roguelike whose inner workings I've looked at is
Angband, which I noticed used lua scripting for spell effects and maybe
some other things. Maybe more of the game data is saved in text files
too (though I'm not totally sure, it seems that way) On the whole
Angband seems to have more variants than NetHack, possibly because it's
easier to modify given these characteristics.

Which brings me to my question: how important is it to separate game
data from the game engine in a roguelike game? I'm not even focused on
other people making variants of my game right now. I'm in the beginning
phases of implementation and I know that down the road I will have
great ideas for things that I want to put in my game and I want a
design flexible enough to allow this type of modification even at a
late date. Thus it seems that the more I can separate the engine from
the data, the better.

So, roguelike developers, what parts of your game have you separated
out into databases/text files/scripts?

The basic approach that I am taking is that "effects" and "properties"
are coded directly into the engine and then game entities (tiles,
items, monsters, maybe spells) reference these properties. For example,
at the moment I am trying to come up with the best way to support a
tileset of dungeon primitives (floors, walls, water, lava, doors, ect).
I thought I would make a bunch of flags that the engine understands
like: WALKABLE, MISSILE_PASSABLE, SOLID, ISDOOR, ect. Then I would save
the data for each tile as an XML node with the filename of the bitmap
to draw the tile with, and a list of properties. A water tile would
have {MISSILE_PASSABLE} defined, a wooden door could have {ISDOOR,
SOLID}, a jail door with bars could be {ISDOOR, MISSILE_PASSABLE}

I think this approach is very flexible because I can add as many flags
as I want, even late in development.

These are just data files, not scripts. But surely there must be a
place for scripting in a roguelike for NPCs and maybe even dungeon
generation. What do you guys do?

The place where my approach gets fuzzy would be for objects like
fountains in NetHack. It seems like something with so many interactions
should be scripted instead of hardcoded into the engine. I guess the
part that confuses me a little is where datafiles should leave off and
scripting begin.

PS - can anyone recommend a good scripting language for roguelike
interactions that be can integrated in C#? I was thinking of using lua
or C#.
 
G

Guest

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

>PS - can anyone recommend a good scripting language for
>roguelike
>interactions that be can integrated in C#? I was thinking of
>using lua or C#.

As DG says : 'lua power !'

T.
 
G

Guest

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

David Damerell wrote:
> Quoting Telamon <shedletsky@stanford.edu>:
> >Whew. Looks like it dates back to the time when utilizing
> >self-descriptive variable names with more than 8 characters was a
> >cardinal sin. A cursory look revealed that a lot of the actual game
> >data was saved in tables in .c files.
>
> Some of which are automatically generated by the programs in the util
> subdirectory. Scary stuff, huh?
> --
> David Damerell <damerell@chiark.greenend.org.uk> flcl?
> Today is First Tuesday, Presuary.

Necessitating a complete recompile and negating one of the main
benefits of datafiles. Yes. Scary stuff.
 
G

Guest

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

If you are doing the engine in C#, I would suggest just using the the
..NET scripting extensions. If you do it properly, it allows you to
have C#, VBScript, and I think even Lua and Python with a support
library installation.

If you keep things in C# though, some people would suggest it would
provide for faster develoment - you're brain will not need to swtich
between the two languages as much, which might help your productivity.
 
G

Guest

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

Thanks that was helpful. I'm still up in the air insofar as hard coding
different spell effects. Scripting works fine for this in Angband, but
ideally anything that the AI would have to reason about would be hard
coded into the engine (if for no other reason than this would be easier
on myself). I may want to implement a planning engine which would mean
fast dos/undos of all involved actions is pretty important. But that is
looking perhaps too far ahead.
 

Antoine

Distinguished
Oct 5, 2003
241
0
18,680
Archived from groups: rec.games.roguelike.development (More info?)

copx wrote:
> "Telamon" <shedletsky@stanford.edu> schrieb im Newsbeitrag
> news:1119880498.561523.48780@g44g2000cwa.googlegroups.com...
> >So I was looking at the NetHack code for the first time the other day.
> >Whew. Looks like it dates back to the time when utilizing
> >self-descriptive variable names with more than 8 characters was a
> >cardinal sin.
> [snip]
>
> It's just jolly good UNIX/C tradition, man! /etc, anyone?
> Rogue itself is the grandmaster of abbreviated horror:
>
> I still remember "moat()"
> A "moat" is a ditch similar to one surrounding a fortification. But of
> course saving 5 letters by writing this instead of "monster_at" was worth
> it! (sarcasm)
>
> Or "chat()".. Be sure this as nothing to do with chatting..
> (here's rogue's definition: "#define chat(y,x) (_level[INDEX(y,x)])")
>
> > These are just data files, not scripts. But surely there must be a
> > place for scripting in a roguelike for NPCs and maybe even dungeon
> > generation. What do you guys do?
> [snip]
>
> Dialogs mainly. It would be insane to hard code the dialogs into the engine.

I think you exaggerate. All the dialogue in Guild is written into the
C++ source. Doesn't seem to do any harm, providing it's encapsulated
into specific parts of the source.

In fact all the Guild data is hard coded into the source, come to think
of it.

I fail to see why this is a problem (given that the game is not
supposed to be user-modifiable). 'Spose it adds a few minutes per
release in unnecessary builds, is all...

A.
 
G

Guest

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

Quoting Telamon <shedletsky@stanford.edu>:
>Whew. Looks like it dates back to the time when utilizing
>self-descriptive variable names with more than 8 characters was a
>cardinal sin. A cursory look revealed that a lot of the actual game
>data was saved in tables in .c files.

Some of which are automatically generated by the programs in the util
subdirectory. Scary stuff, huh?
--
David Damerell <damerell@chiark.greenend.org.uk> flcl?
Today is First Tuesday, Presuary.
 
G

Guest

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

At 27 Jun 2005 07:01:46 -0700,
Telamon wrote:

> So, roguelike developers, what parts of your game have you separated
> out into databases/text files/scripts?

It really depends on what you're planning, but there are some guidelines.

I'm doing things pretty much data-driven. There are configuration files
similar to those in Angband (and to what you described with flags), but
the meaning of flags, the sets of attribute values and their meaning, etc.
are hard-coded.

I separate the parts that are obviously data only -- the maps and map
templates, the monster and item definitions, etc., and the parts that
are supposed to be configurable, like keybindings and preferences.

I'm still uncertain about the messages -- they are obviously data, but are
tied closely with the code. Right now they are stored in a separate file
and referenced by constants -- but I'm not happy with this approach.

I don't plan on doing any scripting -- recompiling one module and linking
the executable isn't much of a pain, and I think it's easier to
concentrate on one language at the time.

I've got limited experience with embedding interpreters -- if I had to
choose a language, I'd probably choose Python -- but it's mainly because
I already know how to use it and how to embed it in C.

I've heard LUA is pretty nice too, but I have hardly any experience with
it.

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

Guest

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

"Telamon" <shedletsky@stanford.edu> schrieb im Newsbeitrag
news:1119880498.561523.48780@g44g2000cwa.googlegroups.com...
>So I was looking at the NetHack code for the first time the other day.
>Whew. Looks like it dates back to the time when utilizing
>self-descriptive variable names with more than 8 characters was a
>cardinal sin.
[snip]

It's just jolly good UNIX/C tradition, man! /etc, anyone?
Rogue itself is the grandmaster of abbreviated horror:

I still remember "moat()"
A "moat" is a ditch similar to one surrounding a fortification. But of
course saving 5 letters by writing this instead of "monster_at" was worth
it! (sarcasm)

Or "chat()".. Be sure this as nothing to do with chatting..
(here's rogue's definition: "#define chat(y,x) (_level[INDEX(y,x)])")

> These are just data files, not scripts. But surely there must be a
> place for scripting in a roguelike for NPCs and maybe even dungeon
> generation. What do you guys do?
[snip]

Dialogs mainly. It would be insane to hard code the dialogs into the engine.
AFAIK all "heavy duty" commercial CRPGs today put the entire game logic into
scripts. The engine is only responsiblel for graphics, pathfinding,
low-level object handling etc.

copx
 
G

Guest

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

The Mon, 27 Jun 2005 09:04:34 -0700, after eating far too many mushrooms
of confusion konijn_ wrote:

>>PS - can anyone recommend a good scripting language for roguelike
>>interactions that be can integrated in C#? I was thinking of using lua or
>>C#.
>
> As DG says : 'lua power !'

Lua power!

--
DarkGod comes from | Do not meddle in the affairs of wizards
the hells for YOU ! :) | because they are subtle and quick to anger.
-----------------------+----------------------------------------------
ToME power! http://t-o-m-e.net
 
G

Guest

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

Quoting Telamon <shedletsky@stanford.edu>:
>David Damerell wrote:
>>Quoting Telamon <shedletsky@stanford.edu>:
>>>cardinal sin. A cursory look revealed that a lot of the actual game
>>>data was saved in tables in .c files.
>>Some of which are automatically generated by the programs in the util
>>subdirectory. Scary stuff, huh?
>Necessitating a complete recompile and negating one of the main
>benefits of datafiles. Yes. Scary stuff.

On the other hand, this does let it do automatic tokenisation of
monster/object names and the like, which is a big win. Also, while this
isn't an issue these days, the game starts much faster than roguelikes
with external data files to parse.
--
David Damerell <damerell@chiark.greenend.org.uk> flcl?
Today is First Tuesday, Presuary.
 
G

Guest

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

At 27 Jun 2005 13:03:52 -0700,
Antoine wrote:

> In fact all the Guild data is hard coded into the source, come to think
> of it.

> I fail to see why this is a problem (given that the game is not
> supposed to be user-modifiable). 'Spose it adds a few minutes per
> release in unnecessary builds, is all...

Well, it should be separated from the engine. It doesn't have to be in
separate data files -- separate source files are enough, I guess.

On the other hand, you might be tempted to choose the data structures
by their 'look' in given language, not by the way you're using them, and
C/C++ are pretty clumsy with representing complicated data types.

For example, I see no way of hardcoding a part of linked list other than
making a constructor function with a bunch of `add_item' calls.

Sure, you can still have the constants in the format that looks nice, and
convert them at initialization to the format that's convenient -- but it's
not very different from parsing a data file.

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

Guest

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

Telamon wrote:

> So I was looking at the NetHack code for the first time the other day.
> Whew. Looks like it dates back to the time when utilizing
> self-descriptive variable names with more than 8 characters was a
> cardinal sin. A cursory look revealed that a lot of the actual game
> data was saved in tables in .c files. All in all it looks like a piece
> of software that has had new functionality bolted on to it every which
> way for years and years. Which, of course, it has.

I seem to remember an old limitation for C compilers where the compiler( or
linker ) would cut all symbols to 8 characters. So, longsymbol1 and
longsymbol2 would mean the same thing in the end. You can see how dangerous
it would be then to have symbols more than 8 charaters long :)
 
G

Guest

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

The Mon, 27 Jun 2005 19:48:03 +0100, after eating far too many mushrooms
of confusion David Damerell wrote:

> Quoting Telamon <shedletsky@stanford.edu>:
>>David Damerell wrote:
>>>Quoting Telamon <shedletsky@stanford.edu>:
>>>>cardinal sin. A cursory look revealed that a lot of the actual game
>>>>data was saved in tables in .c files.
>>>Some of which are automatically generated by the programs in the util
>>>subdirectory. Scary stuff, huh?
>>Necessitating a complete recompile and negating one of the main benefits
>>of datafiles. Yes. Scary stuff.
>
> On the other hand, this does let it do automatic tokenisation of
> monster/object names and the like, which is a big win. Also, while this
> isn't an issue these days, the game starts much faster than roguelikes
> with external data files to parse.

Such things can be cached.
Angband does this.
ToME does this, it even bytecode compiles the lua scripts to not have
to reparse them(not that it's such a gain, the lua parser is extremely
fast and on my computer I don't notice any visible changes(there are,
I have benchmarked it but it's mostly meaningless on today's computers)

--
DarkGod comes from | Do not meddle in the affairs of wizards
the hells for YOU ! :) | because they are subtle and quick to anger.
-----------------------+----------------------------------------------
ToME power! http://t-o-m-e.net
 
G

Guest

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

Telamon wrote:
> David Damerell wrote:
> > Quoting Telamon <shedletsky@stanford.edu>:
> > >Whew. Looks like it dates back to the time when utilizing
> > >self-descriptive variable names with more than 8 characters was a
> > >cardinal sin. A cursory look revealed that a lot of the actual game
> > >data was saved in tables in .c files.
> >
> > Some of which are automatically generated by the programs in the util
> > subdirectory. Scary stuff, huh?
>
> Necessitating a complete recompile and negating one of the main
> benefits of datafiles. Yes. Scary stuff.

At least two modern roguelikes use this approach, IIRC.

CalcRogue, I believe, uses a preprocessor on its script files to turn
them into C code which makes the actual scripting functions.

POWDER, I know, transforms all of its data files into C code.

I made this decision out of necessity, as the Gameboy Advance's lack of
filesystem meant that the easiest way to get data into your game is by
..C files. Indeed, even the bitmaps are all converted to .C.

I certainly wouldn't recommend converting your graphic files to .C
(though, having a self-contained .exe does have its benefits). I
would, however, recommend that data files be converted to .C.

First, let us look at the supposed disadvantages:
1) Have to recompile. If you are only changing data values rather than
structures, you only have to recompile the relevant data files. The
cost of this is probably comparable to the cost of re-starting your
program anyways.
2) Easy edit by third parties. Other people can edit your data files
without access to source. Presupposes that people are interested in
making variants of your game before you even make it, however.

So, what is good about .C data files?

First, there is good support for custom structures. You can have the
data files define your definition structures, allowing you to directly
access them in .C in the expected fashion.

For example, I could do:

MATERIAL_NAMES
MOB::getMaterial() const
{
MATERIAL_NAMES material;

material = mobdefs[myDefinition].material;
return material;
}

Note several things about this function. First, we can have proper
type safety. The value of mobdefs[myDefinition].material can be of
type MATERIAL_NAMES (an enum, in this case). (In the case of my
implementation, I don't have this as I try and save space by forcing my
enums to be u8s. Those of you with infinite memory need not do that)

Next, note that any typo in either the material type or the "material"
accessor will result in a *compile time* error. Compile time errors
are your friend. It is much faster to fix a typo at compile time than
wait until a run-time exception and then try to track it down.
Especially when you consider that the run-time exception may only be
reached by a player, rather than by you.

Finally, where is MATERIAL_NAMES defined? That is defined by your data
file. You can automagically create enums for all of your materials.
This allows you to do special case code like:

if (mob->getMaterial() == MATERIAL_GOLD)
{
// Leprechans will be friendly.
}

External data files tend to end up with things like:

if (!strcmp(mob->getMaterial()->getName(), "glod"))
{
// This code is never executed.
}

Another nice feature of later gcc implementations is that they produce
warnings if you switch on an enum and have unused case labels. This
lets you tell if you have left a new spell unimplemented, for example.

If you want to see an example of the datafiles built like this, you can
look at You Only Live Once (http://www.zincland.com/7drl/liveonce) I
also provide the source for the program which transforms the datafiles
into .C code.

Transforming your data files into .C allows you to leverage .Cs type
support and syntax checking on all of your accesses to your datafiles.
This lets you make large classes of dataentry errors into compile time
errors rather than run time errors. And that saves your time and
results in more robust code.
--
Jeff Lait
(POWDER: http://www.zincland.com/powder)
 
G

Guest

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

Telamon wrote::

> So, roguelike developers, what parts of your game have you separated
> out into databases/text files/scripts?

In my H-World project I did this:

Text files:
Monster data, item data, level templates, room templates, dungeon
'feature' definitions and some UI config thingies.

Scripts:
Everything that seemed to be game dependent (e.g. different between game
modules). Common functionality is part of the engine. This separation is
a bit blurry, during the course of development the engine got leaner and
the scripts grew.

Images:
Monsters, items, UI skins

--
c.u. Hajo
http://h-world.simugraph.com
 
G

Guest

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

Quoting DarkGod <darkgod@t-o-m-e.nospam.net>:
>of confusion David Damerell wrote:
[Nethack's generation of code pre-compule from data...]
>>On the other hand, this does let it do automatic tokenisation of
>>monster/object names and the like, which is a big win. Also, while this
>>isn't an issue these days, the game starts much faster than roguelikes
>>with external data files to parse.
>Such things can be cached.
>Angband does this.

Angband starts visibly slower than NH as it slurps in even the cached data
files.

Of course this is an utterly meaningless difference these days, but I
expect it was non-trivial when NH was first written.

I think the automatic tokenisation remains a compelling advantage.
--
David Damerell <damerell@chiark.greenend.org.uk> Distortion Field!
Today is First Wednesday, Presuary.
 
G

Guest

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

On 2005-06-28 12:57:23, David Damerell <damerell@chiark.greenend.org.uk> wrote:

> Angband starts visibly slower than NH as it slurps in even the cached data
> files.
>
> Of course this is an utterly meaningless difference these days, but I
> expect it was non-trivial when NH was first written.

When Angband was first written I dont think it used external data either.
I know moria did not at least.

--
DarkGod comes from | Do not meddle in the affairs of wizards
the hells for YOU ! :) | because they are subtle and quick to anger.
-----------------------+----------------------------------------------
ToME power! http://t-o-m-e.net
 
G

Guest

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

Quoting DarkGod <darkgod@t-o-m-e.net>:
>David Damerell <damerell@chiark.greenend.org.uk> wrote:
>>Angband starts visibly slower than NH as it slurps in even the cached data
>>files.
>>Of course this is an utterly meaningless difference these days, but I
>>expect it was non-trivial when NH was first written.
>When Angband was first written I dont think it used external data either.

Er, what?

Obviously I mean the speed difference between external data and internal
data, either of which NH might have selected early on. I don't even know
which of Angband and NH predates the other off the top of my head. The
current difference between Angband and NH illustrates the difference
between the underlying techniques.
--
David Damerell <damerell@chiark.greenend.org.uk> Distortion Field!
Today is First Wednesday, Presuary.
 
G

Guest

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

Anybody else use Lex/yacc (or Flex/Bison) to
parse datafiles?

Bear
 
G

Guest

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

Ray Dillinger <bear@sonic.net> writes:

> Anybody else use Lex/yacc (or Flex/Bison) to
> parse datafiles?

Sort of. When I first began reading this group, there was a discussion going
on about map making apps, and I thought it would be interesting to try writing
such an app.

The way I decided to write it was to base it on interpreted commands such as
- "set terrain(5,5) to stone", "add monster(id=ORC_CHIEF) at (5,5)", etc. I
had a pretty good interactive command prompt finished, that used readline for
editing, history, etc. The parser understood quite a few commands, some basic
math and comparison expressions, and simple untyped variables. I also had a
separate grammar and parser for saved map files.

At that point, the discussion here had pretty much fizzled out. I didn't see
much point in writing something no one wanted, and I'd more or less done what
I'd set out to do, brushing up my rusty lex/yacc chops and learning curses
and readline. So I decided to call the project a successful experiment and
didn't develop it any further than that.

I think the idea is *very* sound. It sure beats the heck out of fragile fixed-
width records that break if you look at them the wrong way.

sherm--

--
Due to the amount of unreadable gibberish being posted from Google Groups,
I seldom read messages posted from there.

Cocoa/Perl: http://camelbones.sf.net Hire Me: http://www.dot-app.org
 
G

Guest

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

At Wed, 29 Jun 2005 02:05:22 GMT,
Ray Dillinger wrote:

> Anybody else use Lex/yacc (or Flex/Bison) to
> parse datafiles?

I planned at some time. I've got some experience with flex and bison, and
they fit the task very well.

But now I'm kind of in love with YAML and similar formats (structured ext
and restructured text, etc.), and these are hard to parse using bison and
flex (It is doable, by introducing tokens like 'indent' and 'unindent',
but it requires some hacks).

Anyways, I'd recommend flex/bison even for very simple formats -- they
svae you lots of work and do things efficiently.


--
Radomir `The Sheep' Dopieralski @**@_
<..> ] 0110110?
. . . ..v.vVvVVvVvv.v.. .