Monday, 5 March 2012

Data files and such

With any project, there is also software which is mostly invisible, and FreeRCT is no exception to this rule. In this case, software for creating data files.

At the start of the project, it was decided to have free graphics that anyone could create and add. To make that a reality, the program needs to accept a known file format, such that a game extension can be stored in a single file (to simplify distribution).
The rcd/data_format.pdf file is the key-file here, as it contains an independent description of the format (separate of any implementation). It serves as the master description of the file format.

At the start of the project, a quick and dirty approach was taken to create the data files. With special-case Python code, and a lot of copy/paste, a solution was coded quickly.
This code has worked well for the past six months in the development of the C++ code, but it was already clear it needed further work at some point.
After finishing most of the path puzzles, I wanted to extend the data format. Doing that in the old and hacky code did not seem very good, thus the time had come to cleanup first.

The data-file format description has been moved from Python to XML. The
actual data is now also captured in XML format.
As an example of what the new format looks like for a graphics artist, consider the fragment from rcd/freerct.xml below (with some small additions to make it a complete XML file):

<rcdfiles>
<file target="buildarrows_8bpp64.rcd" magic="RCDF" version="1">
<gameblock magic="BDIR" version="1">
<field name="width" value="64"/> <!-- Zoom-width -->
<sheet x-base="0" y-base="0" step="64" step="64"
fname="../sprites_src/objects/1x1/gui/orthbuildmark8bpp64.png"
names="ne,se,sw,nw" x-offset="-32" y-offset="-33"
width="64" height="64"/>
</gameblock>
</file>
</rcdfiles>
This describes the four arrows used for indicating the direction of path building. The data file is called 'buildarrows_8bpp64.rcd', and the data block containing arrows is called 'BDIR' (Build DIRection). It has five fields. The first field is the tile-width (so you can have different arrow sprites for different zoom-levels). Fields two to five are the four sprites, which are pulled from a sprite sheet, in the order north-east, south-east, south-west, and north-west (see the names attribute).

It is still quite a lot of data, but I think it is a big step forward from coding Python to define both the file format and the actual data.

Saturday, 11 February 2012

Long paths

I promise this is my last post about path building for a long time :)

Remember I talked about not liking having to click for every path tile you build? Today I give you an alternative, use the mouse instead!

It works in the following way. After opening the path build window, click at the place where you want to start (the while tile cursor sticks to the position). In the window, click 'Long' (as in 'long build'). Now the system tries to build a path to the mouse cursor position in the vertical plane through the tile cursor. (In the attached picture, the mouse cursor is where I added the red dot.) If you move the mouse, the path changes. When you are happy, click the mouse, and the path is fixated (that is, you can move the mouse without the path following you). Then, like the single tile, click 'Buy' to buy the entire path.

That's much faster, isn't it? :)

The basic idea seems to be working nicely. If you experiment a bit with it, you'll notice there are still some quirks that need to be figured out, but to be honest, I have had quite enough of path building for some time.

Sunday, 5 February 2012

Rewrite of the paths, connected path tiles

After the previous blog, I got a message from one Lord who found you could crash the program by building paths off the world (thanks for finding that, Lord).

Unfortunately, fixing proved difficult due to my somewhat naive way of coding it. There were three parties responsible: the world display, the path window, and a helper object that stored some selections. Rather than finding out who to blame exactly, I decided to rewrite it all, making the helper object the central entity. While you cannot see it at the outside, this makes the code much easier to deal with errors, since you know where to look. I fixed the off-world build problem, as well as few other problems.

Also invisible is the introduction of time. The game now keeps track of days, months and years.
Last but not least, the path tile building was changed to extend the edges of adjacent path tiles, which makes a much nicer path as you can see.

Sunday, 15 January 2012

Path building, part I

Laying a path in your park is the first step to getting visitors. In the past weeks I have been busy implementing creation of paths. At the right you can see the first result.

When you open the path build window, the cursor changes to a white (rotated) square, and allows you to select a starting tile or path.

Then you can select a build direction with the arrows in the gui which is shown as a flashing arrow in the world display. The arrows at the gui always correspond with what you see at the display, even if you rotate the world.

Next you can press a slope button (at the top of the gui). (I do have sprites for them, but they were not loaded yet.) If you click at another tile or path, the build continues there.

Finally, by pressing 'Buy' you buy the path, and the white square and the arrow move onto the new path (so you can 'buy' again).

I called this entry "part I" as the gui is not finished yet. The other buttons currently do not work, path sprites are not extended to their neighbours, and they need platforms to the ground, and a bar so people don't fall off.

Saturday, 17 December 2011

Let there be widgets


Filling the windows with some (inter-active) content was the next step. As you can see in the picture, the toolbar at the left now has two buttons. If you click at the right one, the window at the right is opened (a first version of the path building interface).

The sizes and positions of all widget elements are computed automatically, so if you change the text (eg use a different language than English) or if you use different arrow sprites, everything is moved around to fit the new sizes.

Note that the slightly shorter titlebar of the path build window is not a bug. The system thinks an 'X' close button is located there, but since there are no graphics for it yet, you cannot see it :)

Adding paths to the program would be a nice next step perhaps. I don't really like the 'build single path tile with each click' idea, so I am still pondering a better system, in particular for building in the air.

Tuesday, 8 November 2011

Windows


It is slowly becoming useful to be able to communicate with the program by means of pressing buttons, and by reading messages.
We have opted for sprite-based windows, to allow for easier customization. That means tomorrow we can create themed windows just by changing the sprites used to draw the windows.

The code was not really ready for such sprites, nor was it ready for more than a single window. Much of the blitter code (the code that copies the actual pixels to the screen) was rewritten, and the windows updating and managing code was restructured to support several windows being displayed at the same time.

In the image you can see the first result. The blue bar is part of the window manager that I use. At the top-left inside the window, a brown-ish window panel (with nothing on it yet) is displayed by the FreeRCT program, and below it the viewport window with the flat world and the white tile cursor.

Sunday, 9 October 2011

Mouse cursor handling


Today FreeRCT learned at what part of the game world you point your mouse. Quite useful for querying information, or edit something. The tile cursor is the first thing that is mouse-pointer aware. It is shown as the partially visible white square behind the bump. It follows the mouse pointer as you move the mouse around perfectly.

The trick that I used is that I re-used the drawing code. Basically, to decide what the mouse pointer points at, I 'draw' a single pixel at the coordinates of the mouse, and keep a record of what sprite gets drawn. Together with the sprite the used world position is stored. The real drawing code uses that position to display the white tile cursor.
The result is a pixel-perfect positioning of the tile cursor.

Since the drawing code itself is used, this will also work for other elements in the game, such as people, stalls, and rollercoaster graphics.