SimCity 2000 – A Retrospective Review

While EA scrambles to try to sort out the controversial debacle surrounding the latest entry in the SimCity series, my mind has been cast back to the one previous entry in the series that I’ve played. SimCity 2000 came at a time when Maxis were an independent company, free of influence from EA, and followed a series of relatively unsuccessful titles also bearing the Sim branding. First released in 1994 on DOS, Mac OS and the Commodore Amiga, it spread eventually to a number of other computer and console platforms, including Windows 95, the SNES and the PlayStation.

The premise of the SimCity games has always been simple – keeping within your budget, attempt to build a successful city with a satisfied population, maintaining services and entertainment while trying to avoid disasters such as fires, riots or hurricanes. That is, unless you possess a certain sadistic streak, in which case you can build up a city just to watch it burn to the ground.

In order to build up the city, you must appropriately place zones of residential, industrial and commercial land in line with population demand. Low-population cities will desire industrial property, while higher populations desire more commercial property. There are two grades of each zone, light and dense: Light zones grow more quickly, but cannot hold as much population per tile; dense zones grow less quickly and tend to have a greater amount of crime and pollution per tile, but can support a greater population per tile.

Producing electrical power for the city is another imperative. Electrical demands start at a low level, capable of being satisfied by a single coal or oil power plant, but grow as the city grows and as time progresses further on. The options for power plants start with pollution-producing coal and oil power plants, along with expensive hydroelectric plants with a limited ability for placement, but expand with time to encompass natural gas stations, nuclear power plants and wind turbines, among others. Population zones are connected to power plants using power lines, and while it might be tempting to place a pollution-spewing coal plant far out of the way of your burgeoning city, every additional tile of power lines reduces the output at the business end of the power grid in an attempt to simulate power loss through thermal radiation through the power lines.

All of the population zones must then be connected with an appropriate transport system. Your options begin with basic roads and railways, but later expand to include subways and highways. Zone placement plays a large part in whether a transport system will be considered successful; the closer that a target zone is to the source zone of a denizen of the city, also known as a Sim, the less time and more satisfactory the journey will be for the Sim. However, roads can soon become clogged with too much traffic, making for logjams which make for dissatisfaction and an ultimate decrease in population.

As your city grows beyond a certain population, your Sims will begin to demand other facilities. Some of these are intended to lower the instances of potentially ravaging disasters, such as the police and fire stations, while others are designed to increase various components of your Sims’ satisfaction, including the health-improving hospital, the education-improving schools, colleges, museums and libraries and the recreational parks, zoos and stadiums.

A couple of other building zones exist beyond the residential, industrial and commercial zones, which become more available as your population grows. The seaport and airport both act to improve your city’s fortunes, creating new potential for industry and commerce when they are built. However, seaports can only be placed on bodies of water defined as rivers or coasts, while airport placement requires a certain amount of space devoid of dense buildings in order to prevent crashes which can cause devastating fires. However, the limitations don’t really get too much in the way of what are largely beneficial additions to your city.

The growth in population of your city comes with its own satisfaction, but a number of incentives become available once you reach various population milestones. The first of these, the Mayor’s House, becomes available at a population of 2,000, while other buildings become available at populations of 10,000, 30,000 and so on. One of these incentives, which comes at a population of 60,000, is optional. The military base available at this point can further increase your city’s population and gives you a small number of military units that can be used during disasters to both conquer fires and population uprisings, but leads to an increase in crime around the area that the military base is placed.

One of the major difficulties in building a large city is the limitation which is provided by your budget. You get a certain amount of money to begin with, at most $20,000, and if you pick the hard budgetary option, you end up with a $10,000 bond which accrues interest every year. With this money, you must produce a city that is self-sustainable enough to generate money so that city improvements can continue in the years going by. A property tax takes money from your populated zones, while various services including the police and fire forces, along with education, hospitals and transit cost money. It can be a difficult balance between maintaining satisfaction among your population and keeping within budgetary lines, and that’s before you get to various city ordinances, most of which have minor effects on how the city develops, but which generally cost extra money. If you get stuck, a small bond can be issued to give you a small period of solvency, but at the cost of interest.

A few evolutionary changes distinctively marked SimCity 2000 from its predecessor, including the isometric perspective replacing the top-down graphics of SimCity, and a greater granularity in terms of zone placement which allowed a single tile to be filled with a residential, commercial or industrial zone. Other changes added extra features, such as the inclusion of new transit and power plant options.

SimCity 2000 might seem like a somewhat arcane game with all of the options available to the player, but the beauty of the game is that the game is still easy to pick up while also maintaining its long-term potential. Indeed, SimCity 2000 was one of the first games that I played which I really felt compelled to continue playing. OK, there were some uninspired design decisions on the Windows 95 version that I first played; it took me a couple of weeks when I was playing the demo to realise that you had to hold down the toolbar buttons to get extra options, while the lack of ability to use the mouse wheel to scroll or zoom makes the game feel a little more clunky today than I’d like it to. That doesn’t spoil the core of the game, though – it still feels fun and challenging.

The graphics, as mentioned above, are isometric, so the game is going to look inherently dated compared to modern graphics. That said, there’s a difference between dated graphics and bad graphics and the sprites in SimCity 2000 are still reasonable today. All in all, the graphics suffice for their purpose, although they’re not exactly dazzling.

Similarly, the sound effects in the game serve their purpose, but aren’t going to blow your mind. The “electro-zap” effect of power plant and line placement does get somewhat repetitive, though. The music, on the other hand, is a funky collection of jazz-inspired MIDI tracks. Probably the best thing that can be said about the tracks is that they’re definitely distinctive and, to me at least, memorable; even sixteen years after I first played the game, a few bars of any of the tunes in the game evokes memories of the hours I’ve spent playing the game.

Despite the age of SimCity 2000, there’s very little that I can fault with it, at least on the platforms that could handle it with ease – specifically, the personal computer platforms such as Windows 95 and Mac OS Classic. The interface may feel a bit clunky at times on the DOS and Windows 95 platforms which I have played the most hours on, but this is a small price to pay for a game with such depth. There is, however, a more serious technical issue with the Windows version that betrays the game’s age: The game binary is 16-bit, completely preventing it from being played on a 64-bit version of Windows. Unless you have an older computer lying around with Windows XP or an earlier version, or unless you have a virtual machine on your computer with an earlier version of Windows, you’ll have to resort to using DOSBox in order to run the game, which isn’t as friendly an option.

Bottom Line: SimCity 2000‘s gameplay is still solid, even a couple of decades after its first release. Personal computer versions are preferable – the SNES version, in particular, feels distinctly limited – but beware the 16-bit binary on Windows versions.

Recommendation: It’s going to be difficult to find a working copy of SimCity 2000 for the personal computer platforms; even in 1997, when I bought it, it was in the bargain bin. I’d expect greater difficulty getting it today, especially considering that its sequel, SimCity 3000, has very much displaced it in the bargain bin section. If you can track it down, though, it’s well worth a bash.

Fundamentals of String Manipulation in C: Part 2

Having discussed most of the important functions relating to strings before, there are only a few others of particular note. We saw gets() previously, which acts like scanf(“%s”, string), and while it performs the job it’s asked to do, it is regarded as somewhat dangerous as it is prone to buffer overflow. A function does exist in the C standard library in <stdio.h> which is somewhat safer.

fgets() is an equivalent function to gets() designed to work on file input. Unlike gets(), you can specify a maximum number of characters to be taken in, which mitigates the buffer overflow that can occur with gets(). fgets() is called with three arguments: the string where input will be stored; the maximum number of characters, including the null character and either stdin, the reference of the standard input stream, or a pointer to a variable of the type FILE. File pointers will be discussed later; for now, we are only interested in stdin.

An example of the use of fgets() is illustrated below:

#include <stdio.h>

int main(void)
{
    char string[30];
    printf("Please enter a string: ");
    fgets(string, 30, stdin);
    puts(string);
    return 0;
}

One peculiar difference between fgets() and gets() is that fgets() does not remove newline characters from its input, while gets() does. This is to be noted when trying to concatenate two strings with strcat() which have been entered from the standard input stream with fgets().

Previously, we also saw the strcmp() function for comparing two strings. A similar function, strstr() (for string string) can be used to find an instance of a string of smaller or equal size within another string. It takes two arguments, both of them strings, and returns a pointer to the first instance of the string being searched for in the string being searched. The following program demonstrates strstr() in action.

#include <stdio.h>
#include <string.h>

int main(void)
{
    char string[] = "yellow dinosaurs eat snow reluctantly";
    char *p;
    int index;

    /* Looking for the location of "eat" in string[] */
    p = strstr(string, "eat");
    /* Finding the element within the array where "eat" begins */
    index = p - string;
    printf("The string \"eat\" begins at index %d of string[]\n");

  return 0;
}

This returns the following:

The string "eat" begins at index 16 of string[]

Searching for multiple instances of strings using strstr() requires a slight modification of our program. We can do this by creating an index, or a point in the array where the last instance of the string was found, and call the strstr() function from the next contiguous point in memory (i.e. the pointer string + index + 1). This example will benefit from the following illustration:

#include <stdio.h>
#include <string.h>

int main(void)
{
    char long_string[] = "The C programming language was invented in the \n"
    "early 1970s by the computer scientist, Dennis Ritchie, who was then \n"
    "working at Bell Labs in New Jersey, which had just removed its \n"
    "support from the Multics project.\n";
    int index = -1, count = 0, i;
    char *p;

    printf("%s", long_string);

    for (i = 0; i < strlen(long_string); i += index) {
	p = strstr(long_string + index + 1, "in");
	if ((index = p - long_string) >= strlen(long_string) || p == NULL)
	break;
	++count;
    }
    printf("\nThe string \"in\" has been located in the string %d times\n", count);
    return 0;
}

This example returns the following:

The C programming language was invented in the 
early 1970s by the computer scientist, Dennis Ritchie, who was then 
working at Bell Labs in New Jersey, which had just removed its 
support from the Multics project.

The string "in" has been located in the string 5 times

One thing to notice about this program is that the counter variable is not incremented by 1 on every loop, but instead by the value of index; this ensures that the loop continues only as long as there are still instances of the string being searched for to be counted.

In the last tutorial, We demonstrated atoi(), a function which converts a string consisting of numeral digits into a decimal integer. It was mentioned at the time that other functions of the same type exist. atof(), for instance, converts a string consisting of numeral digits, exponents and at most one radix point into a double; atol() operates like atoi(), except that it returns a long int. On most modern compilers, atol() works exactly like atoi(), but on older compilers with 2-byte ints, the two functions work differently.

The implementation of simple versions of these two functions is discussed in The C Programming Language (Kernighan & Ritchie, 2nd Edition, 1988). Other functions of this type with more flexibility exist, like strtod(), strtol() and strtoul(), the operations of which can be found in any good C reference material.

Hostile Space – A Preliminary Attempt at Tabletop Game Design

Editor’s Note: I’m back after a month’s break – trying among other things to consider an appropriate topic for a new blog post!

A few months back, I was ruminating on a discussion I’d had with my friends regarding game design. Game design is a field which always seems easy when first encountered, but many hidden issues show themselves after a deeper look. Many of these issues concern the concept of game balance, whereby one player has an insurmountable advantage (or at least an advantage that is difficult to surmount) over the opposing player. Occasionally, it’s a fun exercise to try to beat the odds against you, but if the game gives a consistent advantage to certain strategies or choices to the detriment of others, it makes a lot of the game designers’ efforts redundant.

Keeping this in mind, I set myself the task of creating a game that had limited complexity in terms of setting up the game, but with the potential for complex strategies and rules once the game began. As a template, I used a concept that I had conceived of for a computer game that I wish to write; as a result, I could get a twofer where I could test the rules with human players before trying to transfer it to the computer screen. The game uses a quasi-Newtonian concept of movement, similar but probably inferior to the likes of Triplanetary. Nevertheless, if I can figure out how to refine these rules, I will endeavour to do so.

I’m making these rules available under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License; specific details are available in the copyright details underneath the rules themselves. Any suggestions for rules changes or updates would be appreciated.

HOSTILE SPACE – A game for 2 or more players
—–
:Setting Up:

Each player begins with a set number of spacecraft (probably 4-8 in total). Each spacecraft, in turn, starts with a set number of missiles (probably 8) and a set delta-v value (probably 12-24 hexes).

The players throw a die to determine turn precedence. If two or more players receive the same amount on their die roll, these players roll again, and the order of these players is determined by this roll. The player that rolled the highest may pick a hex within the grid and place a marker there. The mark denotes an initial “zone of control” for that player, whereby the player may place their spacecraft anywhere within six hexes of that marker, and no other player may place a marker so that its zone of control would overlap that player’s zone of control. This process continues in descending order of the die rolls.

Once the spacecraft are placed, the players should remove their markers and mark their spacecraft numerically in the order they were placed. All missiles should in turn be marked with the number of the spacecraft which fired them followed by the number identifying the order in which they were fired.

—–
:Game Rules:

Once all spacecraft have been placed and numbered appropriately, the game begins. In the first phase of each turn, the players may adjust the velocities of each of their spacecraft. Each spacecraft has a set beginning delta-v value, which determines how much they may change their velocity.

An increase or decrease in velocity in either the direction that a spacecraft is pointing or the direction opposite to the one in which the spacecraft is pointing (a “linear change” in velocity) can be resolved by subtracting the value of the difference between the number of hexes that the spacecraft would move otherwise and the number of hexes the player wishes the spacecraft to move.

For instance, if the spacecraft is travelling at a velocity of four hexes in a given direction and the player wishes the spacecraft to only travel at a velocity of two hexes in that direction, the player will spend two hexes of delta-v to decelerate the spacecraft. This may be calculated as such:

[current] 4 hexes – [proposed] 2 hexes = [delta-v cost] 2 hexes.

This rule is also applied to linear changes in velocity that would result in the spacecraft travelling in the direction opposite to the one that it is pointing. For instance, if the spacecraft is travelling with a velocity of three hexes in the direction that it is pointing, and the player wishes it to have a velocity of three hexes in the direction opposite to the direction of travel, the player will spend three hexes of delta-v to bring the velocity to zero, then three more hexes to accelerate the spacecraft in the other direction. This may be calculated as such:

[current] 3 hexes – [proposed] (-3 hexes) = [delta-v cost] 6 hexes.

If the velocity of a spacecraft is zero, the player may change the direction in which it is facing for no cost. If, however, the velocity of the spacecraft is non-zero, a change in direction costs one hex for each hex between the place where the spacecraft would end its movement at the current velocity and the proposed target, calculated in a manner of “concentric circles”. [NOTE: I’ll have to put in rules illustrating this better, if not completely rethink this section of the rules.] Calculate velocity change costs for linear velocity change first, then for directional change.

After all players have chosen their changes in velocity, the movement phase begins. Each player in order of turn precedence repositions their spacecraft in accordance with their new velocity. If at the end of movement, two spacecraft or a spacecraft and an object which occupies only a single hex are in the same hex, destroy both entities. If at the end of movement, a spacecraft is in the same hex as an object that occupies more than one hex, destroy the spacecraft. If during movement, a spacecraft would travel outside the borders, place the spacecraft at the corresponding position at the opposite side of the map and continue its movement in the current direction. [NOTE: This leads to a toroidal game area, but short of awkward rules concerning the “halfway point” of a hex grid, this is a necessary expedient.]

After the movement phase, the firing phase begins. Each player in order of turn precedence may choose to fire one missile from each of their spacecraft as long as that spacecraft has at least one missile remaining. The missile is placed in any of the hexes surrounding the spacecraft and will continue in that direction at a fixed velocity at least slightly higher than the maximum velocity of a spacecraft (approximately 15-30 hexes, based on proposed delta-v limits). Once all players have declared which spacecraft, if any, will fire, resolve the movement of each of the missiles, first by order of the players’ turn sequence, then by the order in which they were fired.

If, during movement, a single missile would pass through the hex occupied by a spacecraft or an entity occupying a single hex, destroy that missile and resolve damage if appropriate. An entity occupying a single hex is immediately destroyed, while damage to a spacecraft may be resolved under two systems: the “Brutal” system where a single hit from a missile will destroy a spacecraft, and the “Fortified” system where a spacecraft has three hit points, and on each hit from a missile, a D6 is rolled and the result modulo 3 is taken away from the spacecraft’s hit points.

If a missile would pass through a hex occupied by an entity occupying more than one hex, destroy that missile.

If, during movement, multiple missiles would pass through a hex occupied by a spacecraft or an entity occupying a single hex, determine the missile that was fired first, and on which turn it was fired. That missile, along with any others fired on the same turn, are considered to have hit and may resolve damage as normal. The remainder of the missiles pass through the hex and continue movement as normal.

The winner may be determined by the last remaining player, or by the player with the most spacecraft, or in the case of a tie, most missiles remaining after a number of turns.

—–
:Entity placement rules:

At the beginning of the game, the players may choose to place additional game entities such as asteroids on the game map. If they choose to do so, roll either one or two D6s to determine the number of additional entities to place.

The entities are then placed on the map after the players have positioned their spacecraft. Each entity is placed one at a time on the map by the players in order of turn precedence. An entity may be placed on any hex or series of hexes on the map as long as it does not occupy or overlap a hex that is already occupied and as long as it does not overlap a player’s zone of control established by their marker or base.

—–
:Base Defence – an alternate play style:

In the Base Defence play style, each player begins with a base, a game entity consisting of seven tokens: The central token, which occupies a single hex, and six peripheral tokens which occupy the hexes surrounding the central token. Instead of placing a marker at the start of the game, the players place their bases instead, and the central hex determines the centre of the player’s zone of control.

The objective in Base Defence is to destroy your opponent’s bases by attacking them with missiles and destroying the central token, while simultaneously defending your own. A player whose base is destroyed is considered to be defeated; any remaining base tokens, spacecraft and missiles owned by that player remain in play and all spacecraft and missiles continue at the velocity they were travelling. However, a defeated player may not change the velocity of any of their spacecraft, nor may any of their spacecraft fire any missiles.

A base does not follow the usual Hostile Space rules for entities occupying more than one hex. If a spacecraft or missile would pass through a hex occupied by a base token, both the spacecraft or missile and the base token is considered to be destroyed, and the hex occupied by the base token is then considered to be empty for the purposes of other objects passing through that hex. Once the central token of a base is destroyed, the player owning that base is defeated; see above for the consequences of defeat.

If a spacecraft ends its turn at zero velocity beside a base token owned by either the same player that owns that spacecraft or a player allied to the owner of the spacecraft, that spacecraft regains all of its expended delta-v and up to two of its expended missiles, effective on the next turn.

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.