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 |