|
From: John A. T. <ja...@ja...> - 2005-10-11 16:13:54
|
Hello -- I have developed my own software for generating print-ready tiles
from the TileDesigner source and database, and I have been encouraged to
contribute that code to rails. Here is an outline of my proposal, and if
the developers agree that this is of interest I will port my current perl
code to Java and submit it. Note that at present I am not committing to
integrate it with the rest of the project or even implement the GUI
interface, but at least it will get a common code base in place and be
easy to extend to other renderers. Everything is vector based so it is
scalable to any size or resolution. This message will contain the
definition of what goes into a tile, and later messages will include the
object factoring for the code to manipulate and draw tiles.
Currently, my tile data is kept in an Informix database and is derived
from the original TileDesigner database as well as PS18XX data. The tile
data has been modified to get print-ready output and to allow layout
tweaks at database import time rather than strictly when it is rendered,
so manual changes can be made (especially needed for very crowded tiles)
while simple tiles require little intervention.
I propose to create an XML DTD for tile information that represents all
information required for a tile, including everything required to draw the
tile as well as any data necessary for gameplay. This is intended to be
an interchange format rather than a storage format, although it could be
used that way until a proper database is created. I know there is an XML
format that is currently in place that does part of this, but it needs to
include much more.
Here is the current database schema for the tile database. Note that
there is some derived data in here, such as connectivity information --
the derived data is treated as a cache and would not be present in the
exchange format, rather it would be generated on import. All positions
are defined in polar coordinates -- (ang,dist) is the angle and distance
from the center of the tile, with distance being scaled by the radius of
the tile. So, (0,1) is the right-most point on a flat-bottom tile.
tiles
=====
tile_id serial unique identifier
tile_code char(16) code of tile, not necessarily unique
tile_shape char(4) hex etc
printed_number char(4) number actually printed on tile
color varchar(20,6)
label char(20) TileDesigner calls it category
label_ang smallfloat Coordinates of label
label_dist smallfloat
label_rotate smallfloat rotation of label relative to tile
label_font char(1) choice of which font to draw (limited set)
label_justify char(2) justification of label
long_name char(32) full descriptive name of tile
origin varchar(32,0) original game using tile
edge_conn integer bitmap of inter-edge connections
d0-d4=AB-AF, d5-d9=BC-BA, ...
relatively easy to rotate with tile
junc_edge_conn integer bitmap of connections from junctions to edges
d30-d31: two-bit type field
00: normal; d0-d5=J0/A - J0/F, d6=J1/A...
01: 6-way; always connected to nearest
edge, d0-d4=J0/J1 - J0/J5, ...
1x: reserved
interjunc_conn integer bitmap of connections between junctions
d0-d4=J0/J1 - J0/J5, ...
tile_junctions
==============
tile_id integer foreign key into tiles
junction_num smallint tile_id,junction_num is primary key
junction_type char(4) type of junction, including number of tokens
junction_ang smallfloat polar coordinates of junction
junction_dist smallfloat
junction_rotate smallfloat rotation of junction relative to tile
null for whistlestops means draw it
with a dot rather than a bar
junction_revenue char(4) revenue (can mean other things for some
junction types such as refueling junctions)
revenue_ang smallfloat polar coordinates of revenue label
revenue_dist smallfloat null means don't draw it
tile_jun_annot (typically home tokens or reserved slots)
==============
tile_id integer tile_id,junction_num foreign key to
tile_junctions
token_slot smallint index from 1 into token slots in junction
annotation_id integer foreign key into annotations
tile_connections
================
tile_id integer foreign key into tiles
pos1_ang smallfloat polar coordinates of 1st end
pos1_dist smallfloat
pos2_ang smallfloat polar coordinates of 2nd end
pos2_dist smallfloat rules for canonical choice of 1st/2nd ends
conn_type char(8) connection type (includes gauge, ferries,..)
conn_level smallint drawing order for overlapped connections
basic rule - if two connections meet at
some point, their levels must be within 1.
If they cross, their levels must be at
least 2 apart.
conn_radius smallfloat radius to draw connection. negative means
it curves away from the center, positive
curves toward the center of the tile. A
typical 7 tile would be -.5, while #8
would be -1.5. A 0 radius results in a
straight line.
tile_annotations
================
tile_id integer foreign key into tiles
tile_annot_num smallint tile_id,tile_annot_num is primary key
annotation_id integer foreign key into annotations
annot_ang smallfloat polar coordinations of annotation
annot_dist smallfloat
annot_scale smallfloat scale to draw annotation
annot_rotate smallfloat orientation of annotation
base_level boolean true if drawn as part of tile background
annotations
===========
annotation_id serial unique key
annot_desc char(40) text description of annotation
annot_text varchar(255) Postscript code to draw annotation
tile_upgrades
=============
base_tile integer foreign key into tiles
upgrade_tile integer foreign key into tiles
base_tile,upgrade_tile is primary key
game_tiles
==========
game_id integer foreign key into games
tile_id integer foreign key into tiles
orientation smallint rotation relative to canonical orientation
quantity smallint number of tiles present, 0 indicates it
is a tile on the map, a negative number
indicates the given number are supplied
but are treated as infinite.
tile_number char(4) number printed on tile in this game
game_upgrades boolean use game-specific upgrades rather than std
spec_upgrades boolean does game require special upgrade info
The annotations table would likely need to be modified to include other
ways of drawing the annotation, as well as gameplay interactions (ie, a
river annotation needs to somehow include the fact that it costs money to
build on that hex).
So, a sample subset of an XML file for a couple of tiles:
<tile id=27 code="7" origin="1829" color="yellow">
<conn pos1="(330,.866025388)" pos2="(270,.866025388)"/>
</tile>
<tile id=32 code="14" origin="1829N" color="green">
<junction type="2" revenue="30"/>
<conn pos1="(270,.866025388)" pos2="(0,0)"/>
<conn pos1="(90,.866025388)" pos2="(0,0)"/>
<conn pos1="(30,.866025388)" pos2="(0,0)"/>
<conn pos1="(330,.866025388)" pos2="(0,0)"/>
</tile>
<tile id=312 orientation="ew" code="1830-PRR" printed="" origin="1830"
color="fixed" label="Philadephia" label_pos="(90,.3)"
label_justify="c" label_font="A">
<junction type="1" revenue="10">
<annotation code="PRR_token">
</junction>
<conn pos1="(0,.866025388)" pos2="(0,0)"/>
<conn pos1="(180,.866025388)" pos2="(0,0)"/>
<conn pos1="(0,.866025388)" pos2="(330,.5)" radius=-.5/>
<conn pos1="(330,.5)" pos2="(270,.5)" radius=.5/>
<conn pos1="(180,.866025388)" pos2="(210,.5)" radius=-.5/>
<conn pos1="(210,.5)" pos2=("270,.5)" radius=.5/>
</tile>
Note that many of the parameters are defaulted when the import code can
figure them out easily. We might also make aliases for the edges for
position codes to avoid the normal value of sqrt(3), such as sideA etc.
Also note that the tile database includes tiles from all games, and
additional tables define which tiles are present in which games, and
game-specific modifications (such as orientation changes, text labels, or
different upgrade paths). If no game-specific upgrades are provided, the
subset of upgrade possibilities that are present in the game are used.
Additional work needs to be done to have location-specific upgrades in
particular games, such as those who take normal tiles in early stages of
the game but have special brown or gray upgrades.
The map object maintains a connectivity graph between junctions, and
incrementally updates it when tiles are laid or upgraded. It provides an
interface to the route calculation code to find the reachable subgraph of
all junctions reachable from a given companies tokens (taking into account
blocking by tokens and special game rules like 1860 allowing one blocked
junction to be run through). This would also be used by the user
interface code for playing tiles and tokens (with some additional work for
tile placement since you have to look at tiles you can lay from the
frontiers of the reachability graph). The route calculation code would be
responsible for figuring out which of those are reachable by a particular
train according to the game's rules and computing the optimal route.
Next I will send the object breakdown for tile rendering.
--
John A. Tamplin ja...@ja...
770/436-5387 HOME 4116 Manson Ave
Smyrna, GA 30082-3723
|