TT9: Saved games from GDEX

When I demoed the game at GDex, at the end of every play session, I saved the current game to disk. I skipped out on saving the data for the people in the game, so those are all missing, so all that remains of the towers is the terrain and rooms. There were a few other bugs that resulted from that.

Every game started with a square of empty floor, an entrance, construction room, and an elevator in place, and a vast majority of the players built within that square. So many of the games came out looking nearly identical to each other. However, there was still enough variety that it was nice to see how people played the game, and what they ended up doing with it.

Isotower at GDEX: Post mortem

This past weekend, I exhibited Isotower at GDEX, a small convention for game developers in Columbus, Ohio. The organizers hoped for 5,000 attendees, and there were approximately 100 exhibitors there, spread out between 3 rooms. I opted for a small ISE table, meant for “Independent, Student, and Experimental” games. The convention ran Saturday and Sunday, with Friday being the day where all the exhibitors needed to show up and set up their booths.

Preperation
Attract mode for Isotower
Attract mode for Isotower

Back in August, I found/read through this article about automating a game to make sure it can exhibit well. I borrowed a lot of the basic ideas mentioned in the article, namely, creating an “attract mode” to the game that would draw people in to play it, or at least learn a bit more about the game. I ended up hardcoding a pre-built tower into the game on Thursday night before set up day. In addition, the camera would pan around the tower, and each time it completed a cycle, it would go up or down a floor, so every 15 or so seconds, it would display a new floor of the pre-built tower. All of the floors had something on them, except for one of the basement floors. So there was a short period of time where the attract mode wasn’t too exciting, but it didn’t last long compared to the more “exciting” floors.

I spent a while getting a computer that could run the game well enough to demo. I had a few old computers, but one couldn’t run the shaders I had written, and the other worked, but had 1GB of RAM available total, which was shared between the OS and the on board video. Fortunately, I was able to borrow a computer from my partner, which ran the game nearly perfect, except it didn’t like fullscreen mode. I created a few builds of the game Saturday morning, and ended up being able to use a borderless window that acted almost exactly like fullscreen mode.

I also printed out mini-business cards and stickers from moo printing. They turned out really well, but I severely over-estimated how many I’d need. I bought about 250 of each, and ended up only handing out about 80 of each, or a bit less. This isn’t a huge problem, since I’ll have stuff to pass out if/when I do other conventions, but it is something to note. I’m not sure how many people showed up for the expo, so it’s hard to judge the ratio of material needed to attendees.

Exhibiting
The table set up on Friday
The table set up on Friday

The ISE tables were small, the picture was above was about the total size of them. They were fairly centrally located in the exhibition hall, though there wasn’t a ton of space to maneuver to get to any of the tables set up in the back. Fortunately, I got there early enough on Friday to set up in one of the front rows, and effectively got a premium spot.

Additionally, there was a scavenger hunt put on by COGG, the Central Ohio Gamedev Group. They had cards with 12 companies that were exhibiting at the expo, and if people collected stickers from 10 of those companies, they would get a prize (a small pokemon figure, I think). I signed up for this fairly early on, and it was a huge benefit. Over half the people who encountered Isotower that weekend noticed it in part because of the scavenger hunt. It was a huge boost to my traffic.

The actual act of demoing the game went incredibly well. One of the last minute additions was a quick button to reset the demo to attract mode, and that was invaluable. Each time that happened, the game would save the current map, and at the end of the each day, I had 32 saves, so 64 save games total. Unfortunately, loading those saved games does not currently work, but I’ll do a full analysis of the resulting saves in a week or two once it does.

I had a range of people who tried out the game. A few kids, a few teens, and a fair number of adults of various ages. Reactions were overall positive. One of my goals was to be able to playtest the game for ideas on how to improve the user experience, so I tried to stay silent for many of the early demos and watch as people worked out what to do. Eventually, I gave them a brief tutorial and pointed people towards a few of the buttons that did the most stuff. Generally, people were able to figure out the basics, depending a bit on how much experience they had with games in general, and tycoon games specifically.

A few other random thoughts

I brought some food to eat (peanut butter crackers), and bottles of water to drink. This meant I could eat and drink something without having to leave my table for very long, other than to refill water. I also had more people show up while I was eating then while I wasn’t. A coincidence, but next time I shall eat constantly to get more people to stop by.

One of the kids who stopped by was super polite, introducing himself, saying thank you, and everything. He was awesome.

I had a few people go completely crazy with building stuff, just sort of clicking everywhere until they ran out of money, or otherwise trying to break the game, or just do something it wasn’t really designed for (one man found the “replace floor/wall” buttons and built a moat around the tower, until the game crashed). In a lot of cases, those people were a ton of fun to watch.

A lot of people brought up Zoo Tycoon and Rollercoaster Tycoon, along with a few other early 2000s tycoon games.

Almost everyone was worried when they built bathrooms with the “entrance” facing out towards the grass/outside of the tower. I’ll be updating the bathroom graphics to make it a bit more clear.

I found a fair bit of bugs in the game, but it only crashed a few times, which mostly seemed to happen for anyone that got to day 2 in-game. That only happened for a few people, and they were all willing to forgive the game. Obviously, fixing that issue is a high priority.

Final thoughts

The whole experience was truly amazing, since prior to this I wasn’t sure how people would react to the game. Watching people playing Isotower and having fun is a huge boost, and now I am more serious then ever to finish the game and get it released. It took a few days to fully recover, but I’m trying to find another expo nearby so I can exhibit Isotower again.

TT8: Thoughts on Difficulty

Difficulty in tycoon/management games is hard to do.

A common method of increasing difficulty in most games is to add more things to do, or more things to keep track of, or simply require the player to learn certain skills or tricks, and use those skills to pull off the next set of tasks. Puzzle games, platformers, or action games can increase the difficulty by adding new mechanics, combining previously used mechanics, or just tossing in more of everything into the mix.

With tycoon games, a common method is to just make everything cost more, while giving the player less money. And this works, but there comes a point in most tycoon games where the player has a constant source of income and then it’s just a matter of waiting around a bit for the next source of income. And income usually increases exponentially. In Transport Tycoon and similar games, adding more train routes costs money, but gives you more money faster. In Sim Tower, adding more rooms means you get more money when rents are due, though it usually costs a bit to add those rooms.

Without something in the game to push against the player when they’re successful, a game will quickly turn boring, or, at least, it’ll turn from struggling with needing just a few more dollars to get the next neat thing to struggling with other problems. Transport Tycoon turns from a game of struggling with being able to afford each route and new train, to being able to spend millions sculpting the landscape, while trying to perfect a large, efficient transportation system. Cities: Skylines turns from struggling with getting a basic city set up, to dealing with traffic problems.

Other games give you more to worry about when it comes to budgets. Optimal play in most of the Sim City games is to build out with low income, lower class zones and then once you establish a base of income, work on upgrading the city to high class, high density, highly educated sims via schools and hospitals and other things.

Still others apply pressure simply by the act of having more of everything. Prison Architect is a perfect example, as more prisoners means overcrowding and greater chances of escapes, riots, or other bad things happening. External forces also matter, in the case of city/base building games like Gnomeria or Rimworld, having a “richer” base leads to more, and more powerful raids on the base.

While thinking about this problem for Isotower, I’ve come up with a few different solutions. One is simply the logistics of moving people through the tower, more people = more need for elevators, escalators, stairs, etc. Adding in stuff like staff only elevators, or being able to limit which social class can use what transportation adds another layer to things. This will apply some pressure, but not really enough.

The other method I’m planning on is simply a matter of a bigger tower will cost more to maintain. Most of this cost will be abstracted, effectively the cost of property taxes, utilities, maintenance. These are all things that could be added to the game individually, but most likely, they’d just be busy work for the player, and not really all that interesting from a gameplay standpoint. The goal with this is to keep the player from amassing a huge fortune, at least at first.

Finally, random events such as fires, floods, or threats from terrorists will be more likely to happen in a larger, famous tower. Especially the last one. There are a few other things I have planned to keep the game interesting past the initial struggles with establishing a basic tower. Those are subjects for later, though.

TT7: Elevator waiting! Requests! Ratings!

Isotower will be at the Ohio Game Developer Expo.

So I’ve been preparing for that, along with getting closer to release. The current plan is to release Isotower in the Spring of 2017, so I’m working on getting the last couple of gameplay systems polished, improved, or balanced, as well as finishing up a variety of other things.  One of those things is an improvement to the requirements system. Previously, rooms had various requirements, types of rooms that needed to be built, otherwise the original room wouldn’t be rented out. I’ve expanded that system so that rooms can now also have “requests”, where if you haven’t built a room type yet, the original room can be rented out, but it’ll have a lower initial rating. The screenshot below shows an example of that.

requirements_and_requests

The presentation of this information is still very crude, essentially just a first step towards presenting this info to the user.

The other aspect I’ve been working on has been improving the visuals for the elevator. This includes getting the elevators to display some of the people inside them when they’re being used, as well as display a portion of the people that are waiting for an elevator car to arrive. There’s currently a bug with the elevator that causes it to not let anyone in at a certain point. For now, I left that in to better show off a busy, crowded wait time for the elevator. It will definitely be fixed quite soon.

TT6: Simplify stat tracking with a std::map

This post is a technical post on how I put together stat tracking for Isotower, for the goals system.

A few days ago, I decided to add goals, or missions, or tasks, or quests to Isotower. I don’t have a name for them in the game, but in the code, they’re goals. Essentially, each goal would track a few stats, like how many people of a certain social class were in the tower, or how many rooms of a certain type were built, or how much money was being made per day, or per week. I was already tracking a lot of these stats, but they were often in their own variables stored in factories, or in the finance code. Writing code to look up this information in an easy way would get complicated if each stat had to have a different function pointer, or if there had to be a giant switch/case statement to know which stat pointed to which factory function. Pointers could have worked, and been fast, but there still would have been a need for a switch/case statement to know what to point to for each part of the goal.

Instead, I created a very simple factory to store a collection of stats, and used a std::map<std::string, double> to store everything. Double because finances and averages would be tracked, as well. This lets me store each stat as a std::string for the goals, and then simply look up the value in the StatTracker data to see if the goal has been reached. The code for the goals is easy to use and understand, I can track stats simply by simply calling StatTracker::INSTANCE().addValue(“new stat to track”); and it all ends up working smoothly. The final code came out to 4 public functions, and a mostly used for debug toString() function. The code is pasted here, because why not.

StatTracker.hpp
#ifndef _STAT_TRACKER_HPP
#define _STAT_TRACKER_HPP

#include <map>
#include <string>

class StatTracker {
private:
 std::map<std::string, double> stats;

 StatTracker();
 StatTracker(StatTracker const&);
 void operator=(StatTracker const&);
public:
 static StatTracker & INSTANCE();

 void addValue(std::string);
 void setValue(std::string, double);
 void changeValue(std::string, double);
 double getValue(std::string);

 std::string toString();
};

#endif
StatTracker.cpp
#include "source/Managers/StatTracker.hpp"

#include <sstream>

void StatTracker::addValue(std::string index)
{
 this->stats.insert(std::pair<std::string, double>(index, 0));
}

void StatTracker::setValue(std::string index, double value)
{
 this->stats[index] = value;
}

void StatTracker::changeValue(std::string index, double value)
{
 this->stats[index] += value;
}

double StatTracker::getValue(std::string index)
{
 return this->stats[index];
}

std::string StatTracker::toString()
{
 std::stringstream temp;

 for (const auto &pair : this->stats)
 {
 temp<<pair.first<<": "<<pair.second<<".\n";
 }

 return temp.str();
}

StatTracker::StatTracker() { }

StatTracker & StatTracker::INSTANCE()
{
 static StatTracker instance;

 return instance;
}

69 lines in total (25+44). Much easier to use and understand.

Sidenote: I use this singleton pattern in almost all the areas of my code. It might not be the “right” way to program things, but it’s easy to use, and at the moment, it does what I need.

TT5: Adding an interface

In the past few weeks, I’ve been working to add more depth to the game, and finished up some of the major systems. The biggest set of changes has been with the rooms, switching up how they worked internally, and solving a few problems along the way.

At the moment, the first thing needed is a construction office. It’ll hire construction workers to build the rest of your rooms. Only one construction worker can be dispatched to a newly built room at a time from each individual construction office, but building more offices can speed up the process of building a new room. Once rooms are built, they’ll have various requirements before people will rent them, or show up to shop at stores or eat at restaurants. Hotel rooms can be rented out, but will get dirty once everyone has left for the day, so they’ll need to be cleaned regularly. Security personal will occasionally need to be dispatched to rooms in case of threats. Rooms have a variety of factors that go into keeping high rating, from surrounding noise and beauty levels to how happy their tenants are, to how much money they’re making per day.

 

The interface for querying a room
The interface for querying a room.

There are still plenty of systems and other things to add and improve upon within the game. However, most of the major functions of the rooms are in place, so today, I’ve begun working out the interface layout that shows up when you query a room (seen above). This is not final (it needs a fair bit of work, obviously), but it contains all of the information about the room that the player will need. the red to green rectangle is the rating indicator, which will provide more detailed information when the player hovers over it. The three buttons will turn into tabs (defaulting to showing the info panel), and the info panel contains details from the income of the day and current rent price to how old the room is and “thoughts” which are more like messages from the room itself (and where you can find out if you’re missing a requirement or similar things).

 

The interface in the wild of the full game window.
The interface in the wild of the full game window.

TT4: From Engine to Game

Now that elevators are working and on the map, all of the major portions of the engine are done. Basic construction, pathfinding, visitor and resident AI and simulation. You can see a short video of the elevators in action below.

Now, the goal is to take the engine and transform it into a game. There’s a lot left to do, from graphics, to user interface, to adding additional systems and features. Plus all sorts of minor, but important areas that need to be polished. And playtesting for balance and bug and ease of use.

The ultimate goal of the game is to let players build a wide variety of buildings, from creating a series of brownstone/brick rowhouses, to gleaming skyscrapers. From creating a tiny shopping mall, to recreating the massive monstrosity of the Kowloon Walled City, and all sorts of buildings in between.

 

TT3: Interfaces

There’s a few famous books out there about designing things for usability. The Design of Everyday Things is all about designing physical objects in a way that removes ambiguity and essentially, makes it impossible to use the object the wrong way. Don’t Make Me Think is all about web design and usability, and is handy for other aspects of interface design for computer programs.

Video game interfaces, meanwhile, have some additional complications. A lot of games strive to be immersive, and have minimal interfaces, often incorporating the elements you interact with directly into the world. Often, the interface can be used to enhance the gameplay when this is done well. Other times, the game is almost entirely interface, and the graphics are mostly to prevent the whole thing from being a giant mess of numbers.

Most tycoon style games go for something in between, with the game world being front and center, but with the ability to pull up all sorts of charts, graphs, and numbers. But the important numbers will be visible at all times, such as Sim City’s RCI indicator always being on screen, or Prison Architect’s temperature meter.

I have a philosophy of “don’t make me click”. Actions in the game should take the least number of clicks, in order of their importance. If something is done a lot, it should only take one click to do. If it’s a bit less common, then it can take a few clicks to do. I’m still working out exactly what the important numbers are for Isotower. Money, population, and overall rating are the current important bits, with time and weather also taking a place of importance. After that are tools to let the player design and build their tower, and finally the various details for individual rooms and visitors and residents of the tower.

Unfortunately, until the majority of the game is done, I don’t have a solid idea of what is going to be important and what isn’t. So the interface is going to be very rough until more pieces of the game are in place.

TT2: Decisions

I’ve been thinking a lot around what makes a good simulation/tycoon game compared to mediocre or bad games. One of the elements that’s important is being able to make meaningful decisions throughout the game. Give the player a goal, and then give them multiple ways to reach that goal. In most tycoon games, the goal is to make a lot of money. But sometimes it can be to successfully run an island nation, or to reach a certain technology level and be able to leave the planet, or to keep prisoners from rioting (while also making money).

For Isotower, one of the everyday decisions is elevator scheduling. Making sure that elevators at on the right floor at the right time to catch the lunch rush will be important. Otherwise, people get mad, and the overall tower rating drops. Building more elevators is an option, but it’s important to consider where the elevator is located.

Room placement is another important factor. Rooms generate noise, dirt, beauty, and shops and other retail rooms generate traffic. While retail rooms want to be near traffic, offices and apartments don’t want loads of shoppers walking by every day, causing disruption. Rooms will effect each other in how they’re placed. I do need to ensure that there’s no single, optimal room placement solution, though. My hope is that having different class levels for the rooms will alleviate that problem.

I’m still working out other elements of Isotower’s design when it comes to decisions. One idea is the ability to place solar panels on the roof of the tower. This would help with the energy bill, but would be affected by things like the weather. On the other hand, you could accept regular payments to build a cell phone tower broadcaster/receiver, but it would detract from the overall beauty of the tower, which affects the rating. Or you could build gardens on the roof. Your residents would like it, but it would provide you no outright benefit.

As I work on the game, these are ideas and thoughts I have in the back of my head. There can’t be a decision without some sort of consequence. Otherwise, the game becomes a lot less interesting.

TT1: Isotower’s History

Welcome to the first Tower Tuesday Blog post. I plan on posting on this blog every Tuesday that I can, mostly to talk about various thoughts on ideas that may or may not make it into the game, or randomly write about tycoon game design. For now, a short history of Isotower.

It’s been a year since I started re-writing the engine for Isotower. In that time, the code has evolved from this, a plain tile renderer:

isotower2

To this, a proper game in development:

rooms

And it continues to grow.

It’s actually been over 6 years since Isotower’s initial development. The code first start life as SimMine, a game with the premise of building a mining town, digging into the earth, and trading those minerals for finished goods. Some day, I’d like to revisit that idea, though there’s been multiple similar games that have comes out since then with many of the same elements. You can see the first few screenshots of Sim Mine below.

Sim Mine Town Ground Floor

Sim Mine Town Below Ground

Eventually, I started work on Isotower instead. The first screenshot I have is shown here, with some definite placeholder artwork. Not much was in place then, outside of building on tiles. There wasn’t much simulation behind it.

Isotower's first screenshot

Most of the original code is gone now, though some of the screen -> world coordinates, and back, code lives on. During those years, I’ve learned a lot about game development, and programming practices, and I’m still learning new things and techniques. Fortunately, the code this time around is fairly easy to work with, so finishing Isotower shouldn’t take as long as it has taken to get to this point.