QuickBASIC/QBASIC newsletter

A Trick of the Trade
Since most people at the moment are writing RPG's, here's just a little article explianing a few
of the dos and do nots or RPG creating.... 

Aside from many peoples idea of what an RPG is (my opinion is that it doesn't have to have
1000 endings depending on whether or not you help the king), what makes many RPG's
interesting, well, for me at least is the dialogue engine. 

Another thing that makes QB rpgs interesting is the amount of non-hardcoded'ness that
is in them.  A perfect example of this is in Dave's Wrath of Sona, he created the ETX format,
which is in essance, a small programming or scripting language. 

If anyone remembers the late-great Milo's The RPG, they might have seen a few NPC files
around.  Well, these files contained the raw text that the assigned NPC said.  Now, this
system was far from complete, it was the first, that I'd seen, where NPC's dialogue was
controlled by external files, rather than being coded directly in the game itself. 

Now Nekro (Dave) and, exclusively, myself, have gone and taken that idea a few steps
furthur.  Dave has his ETX format which I am only vaguely familiar with, because of that, I
will discuss my engine's counterpart, the TLK format. 
Again, TLK (talk) is just a simple script format, thus, it is not compiled (I would have no
reason to teach my interpreter a whole different way to read the same thing)
and it uses many different commands to make different things happen.  I'll give an example of
something HARDCODED and then it's TLK SOFTCODED counterpart....

lets say I wanted my diologue box to be 30,30,150,90 filled with blue, and have an NPC say

locate 2,10 
print "Hello, welcome!" 
Okay, so it's a very basic and not very interesting example. Well, in TLK format, we set
things ahead of time, we know that our box is going to be a certain size and the text is going
to start in the box, so we can do these commands outside the engine file....
/SAY Hello, Welcome! 
/RST is a command that makes the box and resets the cursor position; /SAY takes the text
after it and prints is; /SLP waits for a keypress; and /END ends the file releasing control back
to the game's engine.... 

Now with this example, you may find it easy to change things around, so you may wonder,
"why should I code it like this?"  Well, when your game gets a lot bigger, you don't want to
have to change all sorts of code around, but if you have a file interpreter like this, then each
command does a little bit of the work, and you can work with the root commands.

Now, some of you may be wondering, "hmm, looks good, but how the hell do I make the
interpreter?"  Well, first of all you need an idea for the command set, lets say, to begin with,
you wanted a dialogue box shower, a printer, a sleeper and a beeper command, with lots of

For the box shower, you want to allow a color parameter, the printer, you want to allow
location and color parameters, the sleeper, you want to have a seconds parameter and a keypress parameter and the beeper, and you want to have a repetition parameter.

Now, this is how I would do it, it's not nessecarily the best or only way, but this is how I would parse the file...

I would set out to make the commands themselves, a certain length, so I always know what
I'm dealing with, and I also use some way to distinguish the commands from comments and

So make the following set....

The "|" is the distinguisher, and the commands themselves are 3 characters each, making it

Now for the box: You want to have a color parameter, so I would just have it read in the
number after it... 

The printer is a little more interesting, we don't know where the text will end, but we do know
that the location using LOCATE cannot be a three digit number, and that the color parameter
could be, so we read in number like this, ## ## ### text, so if we wanted to show text at
location 10, 1 with color 55 and print hello, we would do:
|PRT 10 01 055 Hello 

The sleeper (Hold) would just read in a number, and if it was 0, then just wait for the key

Beep, same deal... 

So you have a subroutine or something that has the interpretor in it, so you would being it like

open talkfile$ as input as #1  'talkfile being the script file to open 

 line input #1, parseit$   'get a line from the file... 

 comd$ = ucase$(mid$(parseit$, 1, 4))   'get the first 4 chars, the command... 

 if comd$ = "|BOX" then 
  line(30,30)-(150,90), val(mid$(parseit$, 6)),BF 'retrive the color parameter 
               'and draw the box.... 
 elseif comd$ = "|PRT" then 
  locate val(mid$(parseit$, 6,2)), val(mid$(parseit$, 9,2)) 
  COLOR val(mid$(parseit$, 12,3)) 
  print mid$(printit$,16) 

 elseif comd = "|HLD" then 
  if val(mid$(parseit$, 6)) > 0 then 
    SLEEP val(mid$(parseit$, 6)) 

 elseif comd$ = "|BEP" then 
   for i% = 1 to val(mid$(parseit$, 6)) 
   next i% 



The most complex of these is the PRT command, and how we get those MID$ will be
shown here, lets say we wanted to print HELLO WORLD! in color 15, at coords 15 and
20, here it would be... 

|PRT 15 20 015 HELLO WORLD

As you can see, the first coord starts at 6 and has 2 chars, and the next coord starts at 9 is 2
as well, the color start at 12 and lasts 3, and the text starts at 16 and just goes on until end.
That's why the is the last parameter, since it's length is unknown, and I don't feel like
programming a terminating character, we just use it as the last one, cause Mid's can go from
start% to end of string.

WOS's engine does things slightly differently, instead of doing the parsing, its commands just
know how much data is needed and has that many lines reserved for it, also, since it uses
HTML like commands, the commands can be any length.  If I were to convert the |PRT to a
WOS like example, it would be like this....

Since it knows it needs one line for the coords, 1 for the color and 1 for the string, of course,
this can be done a number of ways, just choose the one that suits you best.

Coming next month...
EVENT HANDLING: the true power of RPG's and the scripts combined, and can make your QB RPG more realistic that some commercial ones.