Some ideas that could be useful ?
As shared by Esa Ilari Vuokko.
Comments and bugfixes ;) to eivuokko@mbnet.fi
I've played roguelike games for 7 years now. First I hacked Moria,
which I got from friend (no modem or net connection :(). Then I got
Omega which I still play (newer version, thought ;). At that time I
got rid of Basic I was programming with and got Turbo Pascal. Well,
I tried to do some pathetic games myself but they were just dead
as they were real mode programs. Then (not earlier) I got nethack
which I didn't like at that time. I hated djgpp (it's not bad, it's
ugly in msdos) so I was bounded to real mode. Then I got Linux and
installed it few times with no success (one time I installed it on
broken hd, guess did it work, no - it just paniced suddenly ;). And
I played ADOM, a lot. And then little Nethack and Omega.
Because Linux I got all so mighty gcc and make. After playing for a
while with graphics stuff (in linux and in win) and in winenv doing
some accounting program (with delphi, thought I quitted after it
started compiling wrong - I mean(debugged) it) I got an idea. In an
accounting program we move money from one account to another (I'm sorry
I know finnish terminology better than english). Well those accounts
must be linked list because : they must be easy to create, modify and
delete. Nothing new - a linked list. Of course all objects in rg should
be in linked lists. But the what if even attributes were linked lists ?
So that we had a linked list which can store data (some 16 bytes is enough)
and a name (string) and children list.
Listing attributes, skills, and everything that describes object with
such presentation would be quite flexible. But if one does such game,
and many people contribute to it ? It can go way off road as everybody
add something new. A bloated memory use, and unneeded complexity are
real threats. As normally, say ADOM, player char needs more memory
(more variables) than npc. But in this approach we give npc only those
skills and attributes it needs and we are still able to use same routines
on both, player and npc.
Of course above system can be optimized. I've defined it like this :
Okey, I've got a bit more complex.
class List {
private:
List *child,*next,*parent;
int id;
int data[4];
Link(List *);
Unlink(List *);
Query(int,int,int,int,int);
public:
int *Data();
char *Name();
int *Data(char *);
List *Name(char *);
int *Data(int,int,int,int,int);
List *Name(int,int,int,int,int);
Item *Index(int);
int Index(Item *);
int Count();
List *Add();
List *Remove();
} ;
Quite clear, I think. Id can be converted (by another class) to char.
Almost all ints are for quick query. I use dot as delimiter between child
and parent and I don't have plurals. "skill.weapon.blade.short".
Then I wanted an engine that doesn't need special cases. It would be
(sorry for saying this) stupid to do special levels, which have special
if of switch statement in level code. How could one have such a really
flexible system ? Well I read Thomas Biskup's ideas of JADE. I don't know
whetever he meant the same as I with the mentioning everything to be
event based. So what I'm chasing here is that every object should have
message handler list, which would handle requests to do something.
Say we have a character A. A has handler list of next functions
(stacked):
creature_shield_deflector,
creature_ro_poison_res,
creature_basic_poison,
player_non_ai,
basic_creature_handler.
First a monster(mage) B would shoot an firebolt to A. Firebolt code would
send a message to A that some fire damage is coming. First this message
would reach first handler in list, creature_shield_deflector. That would
say "no,no fire damage" and that would be it, no damage to creature. Then
B would throw a acidbolt. Well this time deflector would say nothing as
wouldn't other before basic_creature_handler. That would make some damage
to creature and spare some to inventory too (and send approciate messages
to items). Then would engine send TIMEUPDATE to creature, which would be
handled first by creature_basic_poison. Well it seems this creature has
poisoning and handler would notice that it just ending. First it sends to
creature A (self) damage message of poison, which would end to
creature_ro_poison_res, and no damage. Then it would return
UNLINK_AND_CONTINUE so that it would be removed from list and message
(TIMEUPDATE) would be sent on. Then message would reach basic_handler which
would add some speed to energy (ADOM) or add a timepulse (nethack,angband).
If it would be creature's turn to move, it would send message ACTION to
itself (creature A). That would be caught by player_non_ai which would wait
for keypress and then do whatever is defined and player wishes to do.
Because paragraph above seems a bit unclear ;) I'll do an easier
table here :
1 creature_shield_deflector,
2 creature_ro_poison_res,
3 creature_basic_poison,
4 player_non_ai,
5 basic_creature_handler.
Messages :
Fire damage
1 - take message (do nothing) return KEEP_AND_STOP -> that's it.
Acid damage
1 - no action, return KEEP_AND_CONTINUE
2 - no action, return KEEP_AND_CONTINUE
3 - no action, return KEEP_AND_CONTINUE
4 - no action, return KEEP_AND_CONTINUE
5 - Share damage to creature and inventory, send damage message to
inventory. Return KEEP_AND_STOP.
TIMEUPDATE
1 - no action, return KEEP_AND_CONTINUE
2 - no action, return KEEP_AND_CONTINUE
3 - Check if it's poison time. If it is send poison damage to self:
Poison damage
1 - no action, return KEEP_AND_CONTINUE
2 - Take message (do nothing) and return KEEP_AND_STOP.
If poison is diluted enough return UNLINK_AND_CONTINUE
else return KEEP_AND_CONTINUE
4 - no action return KEEP_AND_CONTINUE
5 - Check whetever it's time to move or not (some way to count time
compared to time). If it is send ACTION to self.
ACTION
1 - no action, return KEEP_AND_CONTINUE
2 - no action, return KEEP_AND_CONTINUE
3 - no action, return KEEP_AND_CONTINUE
4 - Normal player's turn in roguelike games.
return KEEP_AND_STOP.
KEEP_AND_CONTINUE, UNLINK_AND_STOP etc mean whatever function which
handles handler lists should keep sending message on in list and if
handler should be removed from list.
Yes, I know, this is really heavy way to do things. But if we can count
on fast 486, it is REALLY flexible. I think that with handlers lists and
description lists we can mimic any game we want or make just about anything
we want (well world conquest is a _bit_ hard maybe, but as rg game anything)
I'm sorry if there's too many errors in my english. I didn't mean to
be offensive either but I needed to make my point clear (if it can be
done at all). If someone has implemented this allready, good, sorry to
say that I were to late.
I'm sorry if there is something that have been published before and
I don't want to claim that I've been first to thing this kind of things
but I haven't seen anything like this before (I haven't read too much).
Anyway Copyright 2000 Esa Ilari Vuokko. I don't (of course) take any
responsibility of anything you do or don't do with this text. It can be
freely copied and published electronically as long as it isn't modified.
|