On Mon, 29 May 2000, Laurens Holst wrote:

> > No version number?
> 
> I thought about it, but no. Just don't start creating
> (and distributing) an editor until the fileformat
> includes everything.

Especially if you want to distribute an editor that is not final (I am in
favor of early releases, btw), changes in the file format can be expected.

And it's unrealistic to expect a file format to include "everything". I
think it's even possible to prove this mathematically... ;)
Anyway, there will always be something that is excluded, either because you
didn't think of it or because it will make the engine more complex and is
therefore delayed to the next version.

I am very much in favor of a version number. Many systems start out without
a version number, but included it later (for example MSX-DOS). But later
introduced version numbers are often ugly hacks. Introducing a version
number straight from version 0 is a better idea.

> In this case it shouldn't give any trouble since it's
> a quite simple fileformat. Eventually, any additions
> can always be added to the end of the file.

Additions can be, but not all changes are additions. For example, what if
you want to allow 3-layer maps in addition to 2-layer maps? Or if you
upgrade a value from 8-bit to 16-bit?

Besides, a version number is easier to check than the length of a file,
since the version number is actually data inside the file, but file length
is meta-info. Assume your game uses a cache system, then you would need to
add a file length administration to your caching system if you don't have a
version number.

> > > 8 bytes: filename (without ext.) of the
> > patterndata
> > 
> > Should this information be in the map file?
> 
> Yes. Easier to program AND to edit (the correct
> tilemap is automatically read from the file and
> loaded).

When this description becomes the engine format and not the edit format, I
don't think it's needed anymore.

About loading: maybe you don't even load from files. For speed, loading
from a library file is better. Some library systems keep a directory of all
filenames plus locations, but other systems (like mine) use compiled
tables: the MSX program doesn't know the name of the file the data came
from, only its offset in the library file and the file length. The
advantages of the compile system are that it's more compact and that
mismatched ("file not found") are detected at compile time instead of run
time.

> > > 1 byte: width (in tiles), possible values 256
> > (=0), 128, 64, 32, 16, 8
> > > 1 byte: heigth (in tiles), possible values - see
> > above
> > 
> > Why only powers of two?
> 
> Programming 'limitations'.

You were right to put it between quotes. I don't think other values are an
actual limitation.

A map plotting routine could look like this:

  for (int y = 0; y < screenHeight; y++) {
    for (int x = 0; x < screenWidth; x++) {
      int mapOffset = (offsetX + x) + (offsetY + y) * mapWidth;
      plotTile(tile[mapOffset], x, y);
    }
  }

where

  screenHeight is the number of files on the screen horizontally
  screenWidth is the number of files on the screen vertically
  offsetX is the X coordinate of the top-left corner of the view window
  offsetY is the Y coordinate of the top-left corner of the view window
    (view window is the part of the map that is visible on the screen)
  mapOffset is an index in the tile array (the actual map data)
  "x++" is the C/C++/Java shortened syntax for "x = x + 1"
    (actually, "++x" is that, but as used here, there's no difference)

Now, to speed up this routine, calculation of mapOffset is done
incrementally, like this:

  int mapOffset = offsetX + offsetY * mapWidth;
  for (int y = 0; y < screenHeight; y++) {
    for (int x = 0; x < screenWidth; x++) {
      plotTile(tile[mapOffset], x, y);
      mapOffset++;
    }
    mapOffset += mapWidth - screenWidth;
  }

In MSX assembly, all operations on mapOffset are trivial, except for the
multiplication at initialisation. But I don't think multiplication is that
hard, nor does the speed matter too much since it's only used for once
every map refresh.

> And hey, why not???

Because it limits the map designers. Ofcourse there should be limits, but
in such a way that the advantages outweight the disadvantages. That is not
the case for power-of-2 map sizes, in my opinion. A size like 192x80 would
be impossible.

Assume you want a map that is as large as the screen, that would be
impossible unless the screenHeight and screenWidth are powers of 2. Which
is unlikely, because (assuming SCREEN5 and 8x8 tiles) 32 * 8 pixels = 256
pixels, which leaves no room for a border, and 16 * 8 = 128 pixels, which
is only half a screen.

> > Also, I think using 16 bit sizes shouldn't be a
> > problem, since the Z80 can
> > perform 16 bit addition.
> 
> The problem is the address space. And using 16-bit
> address spaces (like width 512) makes it harder to
> program at several point in the engine.

On second thought, I guess you're right: all coordinates would have to be
16-bit: that of the player, of the object, the monsters, the NPCs etc.

> 256x64 is wide enough I think.

I think 256x256 is large enough, Ultima V (PC) used that and that was a
really large map...

256x64 is a consequence of a 16K limit on the map data itself, an issue to
be discussed elsewhere (this was about 8 or 16 bit sizes for map width and
height).

> Engine: 16k
> Tilemap: 16k
> Replayer: 16k
> Music: 16k
> "Storyline": 16k
> Loading-space: 16k
> Battle-mode: 16k
> Animations, additional gfx, reserve space: 16k
> --------------- +
>           128k

You forgot system RAM space. System RAM eats up about 11K (#D400 and up).

Music and replayer can fit into 16K together, with a little effort:
- MBWAVE driver doesn't fit, but that can be helped by separating
  initialisation code (alternative wave headers) from the rest, or
  decreasing the number of channels.
- MBM driver + song can fit, I did that before.
- MML driver Kinrou 5th is less than 6K, songs fit within remaining 10K.

Leaving loading space unused is not necessary.

Anyway, why not allow the designer of the game to make these choices? He
can decide to use a small replayer, fewer graphics, more than 128K RAM or
whatever he thinks is needed to make a larger map fit.

My suggestion: put an option in the toolkit that will tell you the map size
in bytes. The game designer can decide how much space is reserved for the
map data. Maybe the reserved space is even different for individual scenes
in the game. For example, a peaceful village doesn't need a battle mode,
that space can be used for map data instead.

> And besides, it is harder to program. Like the above,
> it's _possible_, and it won't take too much time away
> either. But it will increase the complexity of the
> engine and therefor results in:

That depends on how the engine maps the memory. Maybe it can use two pages
(#4000-#BFFF) with map data at the same time. Maybe it puts the map in VRAM
and keeps only the visible part of the map in RAM.

Maybe your game is a shoot-em-up or a race game instead of an RPG. Those
games use tile based maps as well. In such a game, the route over the map
is predetermined, so you could store the map in a compressed format and
decompress it as the level progresses.

What I want to say is: don't assume "we'll need this limit" before you
actually have the reasons why you need it. It is possible that some engine
implementation will have trouble with a map larger than 16K. Then that is
the time to impose a limit. But it should be a limit on the engine, not on
the file format, to avoid loss of flexibility.

> > I think the palette could be stored independantly of
> > the graphics data. The
> > graphics data will end up in VRAM, the palette in
> > RAM.
> 
> In the same file is
> - more logical, since the palette belongs to the gfx,
> it's silly to store it independantly. Requires more
> administration, disk-space, complexity, yuck.

Disk space is not an issue: a palette is 32 bytes.

About administration: you'll have to administrate anyway. To allow palette
fades, the palette must be in RAM somewhere. You can't just load it, send
it to the VDP and then forget the palette.

A map depends on a certain set of tile GFX, yet these are not stored in the
same file either.

I remembered programs I made in the past and I noticed that I almost never
put the palette in a file. In my latest projects, I put the palette
together with the script tables. The advantage is that it is directly at
the place the program needs it, you don't have to load and LDIR it first.

Another thing is that I always compress graphics. Using compressed graphics
conserves disk space and reduces loading time. Decompression is easier if
all data is actually graphics.

> - It doesn't make it more complex for the engine or
> something like that. It's even easier, less files to
> look up and open.

The engine wouldn't load the palette from a separate file, it would just
load it from a different file than the graphics.
  
> However the multiple palettes idea is good. However,
> it is hard to implement it all in the same file,
> because there are many possibilities. Like in a
> thunderstorm the palette should flash every now and
> then, while in lava only the red colors must fade. It
> is easier to hard-code it in the engine I think. I
> will leave room for such extensions in my engine.

If the palette is in the script section, it can be treated like animation:
every N interrupts a new palette "frame" is selected.

Putting it in the GFX file will make multiple palettes more risky: you
always have to make sure there is enough space to store all the palettes
when you load them.

> > There are also some issues you didn't address. For
> > example, you assumed
> > that 1 layer of tiles would be enough. I doubt that.
> > Birdseye games like
> > Metal Gear and Zelda use only 1 layer. But most
> > RPGs, like Xak and SD
> > Snatcher, use more than 1 layer.
> 
> Yes??? I doubt it... 256 different 8x8 tiles... Isn't
> that enough??? Only for big screens. But for that is
> is wise to use real graphics.

You misunderstood what I mean by layers. I do think that 256 different
tiles is enough. But I'm not sure that 256 values per tile is enough to
describe the map. Flags (open/wall), triggers etc could also be stored in
the map data. See for example the design that Maarten van Strien made.

> > [PA3 engine]
> I don't get the 'two backgrounds'-part.

There are two background bitmaps per scene, 176x80 in size. For one game
screen (176x160), one bitmap is plotted twice, once for the upper half of
the game screen and once for the bottom half. For every screen in a scene,
you can select which one of the two backgrounds is used.

> The gfx are quite limited, I really doubt they have a 16-bit
> tilemap.

PA3 has an 8-bit tilemap. But that is indeed limited, as you say.

> > Another issue: how should properties of tiles be
> > handled? 
> 
> The location in the tilemap.
> Row 0: walkthrough
> Row 1: walkthrough
> Row 2: non-walkthrough
> Row 3: non-walkthrough
> Row 4: non-walkthrough
> Row 5: non-walkthrough
> Row 6: trigger-tiles (damaging and event-tiles)
> Row 7: Overlay with background
> Row 8: Overlay without background (engine use only)

I think it's better to make a table that maps tile number to tile
properties. So if you want to know the properties of tile 23, you read
index 23 in the table and that value contains the properties of the tile.

A 256-byte table would be needed for 8 bits of properties, 512 bytes for
16 bits of properties.

> The latter brings me to the point that the tilemap
> fileformat has to be extended with 8x128=1024 bytes
> for the 8th row, which is kind of a mirror of the 7th
> row, but then without background.

Please explain what you mean by "overlay with background" and "overlay
without background"...
  
> Animation is not really an option in my engine (at
> least as far as I can see it now). The animations are
> reserved for the battle-mode.

Well, you will want to animate the player and NPC sprites at least, I
think. Animations that are not sprites are optional, although very pretty.

An idea: passive NPCs could be used as animations. For example: a waving
flag could be a sprite. It doesn't attack you, it doesn't talk to you, it
only animates. If the amount of animations is relatively small, such an
approach would be feasible and it wouldn't complicate the engine.

> > For example, don't copy blocks that haven't changed
> > from the previous frame
> > to this one. If most of the screen is filled with
> > grass tiles, many of
> > those tiles don't change if the screen is scrolled.
> 
> Really, I know my profession.

Relax, I'm not attacking you!

I think this is interesting info for people interested in games engines.
Some people already know it, some people don't.

> In my RPG-engine I don't do it like this. Why not???
> Well, it should ALWAYS scroll smooth, also in 'bad'
> conditions in which all the background differ from the
> previous.

That is one way to handle it. But if you make an engine that will perform
well in the worst case, it cannot do as much as an engine that performs
well 95% of the time.

Look at shoot-em-ups, many of them have slowdown when there are lots of
enemies. Sure, that's annoying, but wouldn't it be more annoying if there
could never be many enemies at the same time?

It's a trade-off. Your choice for "always smooth" is a clear one, but it's
not the only good choice.

> > Another thing is to know whether a tile needs
> > transparant copy or not.
> > Copying with transparancy is a lot slower. A 
> > tile doesn't need transparant
> > copy if it doesn't contain transparant pixels.
> 
> Ofcourse. See the "transparent row" in the tilemap.
> It's all there. You know what? This way, transparant
> tiles are even rendered transparantly only if there is
> a character standing behind it!

That trick only works if the number of combinations of background tiles and
transparant foreground tiles is not too large. If there are 10 background
tiles and 40 transparant foreground tiles, there are 400 combinations,
which takes up quite a bit of VRAM.

Ofcourse it is unlikely that all possible combinations actually occur in
the map, but it would be a lot of work for the engine to determine which
combinations are used and which aren't. This is better left to the editor,
like I described in one of my previous mails.

> > And finally, if you know a background tile will
> > be completely covered by a
> > foreground tile (the foreground tile doesn't
> > contain transparant pixels), don't copy the
> > background tile in the first place.
> 
> Sorry to say, but the things you state are kind of
> obvious.

It looks very obvious when you read it. But you have to design the engine
in such a way that it can take advantage of this trick.

And it even influences the map data structure. For example, if you use a
2-layer map, it could be faster to store the data as one layer of pairs
than as two layers of single values.

Illustration:

One layer of pairs:
  (layer[0].tile[0] , layer[1].tile[0]) ;
  (layer[0].tile[1] , layer[1].tile[1]) ;
  (layer[0].tile[2] , layer[1].tile[2]) ;
    ...
  (layer[0].tile[N-1] , layer[1].tile[N-1]) ;
  
Two layers of single values:
  layer[0].tile[0] ;
  layer[0].tile[1] ;
    ...
  layer[0].tile[N-1] ;
  layer[1].tile[0] ;
  layer[1].tile[1] ;
    ...
  layer[1].tile[N-1] ;

> Programming a
> smooth-scrolling engine really sucks though, believe
> me.

Yes, I believe that!

I once made a smooth scroll diskmagazine look-alike. It looked like the
final part of Almost Real, but more advanced: it could be scrolled up or
down by the reader.

A game engine has to scroll in 2 directions, so that makes it even more
complex. And there is activity on the screen, soft-sprites and such.

> Also, imho, a scrolling engine looks much, much better
> than a 'solid' one like the PA series have.

I do think that the PA3 engine is good enough to make fun games. I am
looking forward to the public release of the engine. By using this engine,
people can get more experience at creating RPGs.

> I think
> the only reason they created a solid engine for PA3
> (which was still used in the later games because they
> didn't want to -or couldn't- re-program it all,
> editors and engine etc.)

PA3 was the first in the series that was written in assembly. After PA3
Stefan Boer stopped and Peter Meulendijks had to create code, scenario and
graphics for The Lost World and Realms of Adventure. I cannot blame him if
he didn't want to do an engine redesign as well.

> was because it was originally
> programmed in Basic. And scrolling is a bit too much
> for a Basic environment. They couldn't change it to a
> scrolling engine afterwards because the RAM map and
> design style (how the screens 'fit' together) is
> entirely different.

The RAM map is not the real problem, I think. Moving from a fixed size map
to a map with arbitrary sizes requires some changes in the RAM map handling
engine, but not too much. But apart from plotting the map, handling enemies
etc is also very different, adapting that would be a lot of work.

Maybe adapting the tools was a problem, I cannot tell because I didn't see
them yet.

Bye,
                Maarten

****
MSX Mailinglist. To unsubscribe, send an email to [EMAIL PROTECTED]
and put "unsubscribe msx [EMAIL PROTECTED]" (without the quotes) in
the body (not the subject) of the message.
Problems? contact [EMAIL PROTECTED]
More information on MSX can be found in the following places:
 The MSX faq: http://www.faq.msxnet.org/
 The MSX newsgroup: comp.sys.msx
 The MSX IRC channel: #MSX on Undernet
****

Reply via email to