0
\$\begingroup\$

I am currently working on a SimCity-style game in C# using SharpDX. I'm having trouble handling the growing and shrinking the game entities that represent zones within a region. For example:

     +-------+-------+-------+-------+
     |       |       |       |       |
     |       |       |       |       |
     |   R   |   R   |   R   |   R   |
     |       |       |       |       |
     +-------+-------+-------+-------+   Residential Zones as initially placed
     |       |       |       |       |   with low populations.
     |       |       |       |       |
     |   R   |   R   |   R   |   R   |
     |       |       |       |       |
     +-------+-------+-------+-------+


     +---------------+-------+-------+
     |               |       |       |
     |               |       |       |
     |       R       |   R   |       |
     |               |       |       |   After time, residential zones merge
     +-------+-------+-------+   R   |   to form larger dwellings.
     |       |       |       |       |
     |       |       |       |       |
     |   R   |   R   |   R   |       |
     |       |       |       |       |
     +-------+-------+-------+-------+

I'm not sure how to represent the simulation and display of this kind of behavior. At the moment, I have the following:

  • Each zone is represented by an individual object of type ResidentialZone.
  • Each ResidentialZone has a GridSpace[] property which can changed when the zone shrinks or expands.
  • OnGrow(): a new ResidentialZone is created combining the properties (population, education, etc.) of the 2+ that it combined.
  • OnShrink(): new ResidentialZones are created and divide the properties of the one they replaced.
  • All Zones (Residential, Commercial, Industrial, Parks, etc.) are stored in a collection of IZone within class ZoneManager which handles simulation, rendering, placement by the user.

In the eyes of more experiences game developers, does this model represent a good practice and what performance impacts may arise? Any improvements or suggestions?

\$\endgroup\$
  • 3
    \$\begingroup\$ There are very few games that do stuff similar to what you're doing, and the few that do so most likely do it in wildly differing ways. Also, unless compared to the rest of how the game is made, there is no way to know whether or not that is a "good" way to do it (whatever "good") means. So how about if you do it in the way it makes the most sense to you, and if you have specific problems, you post them in here? \$\endgroup\$ – Panda Pajama Jan 14 '14 at 0:43
  • 1
    \$\begingroup\$ I really like the heart of this question, but what you have actually asked is "is this a good approach?" and for a broad list of suggestions. Neither of those are good on-topic questions here for various reasons (see help center). I think you should change your question to ask "how can I accomplish this?" and then remove the entire section detailing your own currently implementation from the question and instead post it as an answer. This will let others confirm that your approach is reasonable by voting it, or provide answers for alternative approaches. \$\endgroup\$ – user1430 Jan 15 '14 at 16:53
  • \$\begingroup\$ Sounds like a job for chat! \$\endgroup\$ – SpartanDonut Jan 15 '14 at 17:02
  • \$\begingroup\$ I put up a meta question to get some consensus on this approach for handling these kinds of questions (or an alternative). You can read the question and my rationale here. \$\endgroup\$ – user1430 Jan 15 '14 at 17:13
2
\$\begingroup\$

There is no "best" way to solve a software architecture problem. Only the way which works best for you.

Does your current implementation work the way you want it to work? Do you see no reasons why it wouldn't work with any other features you have planned? When the answer to both questions is yes, you should keep it.

Also, don't worry too much about the performance. In game development, the performance bottleneck is usually the graphic engine (yes, even for 2d games). It's very rare for game mechanics to actually be the main CPU cycle consumers. And when it is the case it is usually impossible to know beforehand. Programmers are notoriously bad at predicting which performance bottlenecks will affect the user experience the most. The only way to reliably find them is to profile the application with a tool.

Donald Knuth once wrote:

"Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%."

First, get an implementation which works and which fits into your software architecture. Then check if it impacts performance too much by using a profiler. When the profiler confirms that the performance is unacceptable, then, and only then, optimize it.

\$\endgroup\$
  • \$\begingroup\$ While this is good advice, it isn't really addressing what was actually asked with any sort of specificity (especially once, as I hope happens, the asker edits his question to ask something that can be reopened). \$\endgroup\$ – user1430 Jan 15 '14 at 16:54
1
\$\begingroup\$

It seems to me that your is like a graphs manipulation problem. So using graphs to model your neighborhood will probably give you more satisfaction both in terms of game dynamics expressivity and performance.

In this modelling scenario, your residential entities are associated to a node in the graph, so the entity does not need to store any topological information. When you merge your zones, you create a new node that take over the ownership of the edge halfs of every node involved into mergin ( you can now merge more than two zones). The edges can be agumented with a cost value so you can specify in which direction is better to merge and so on.

The same considerations apply for splitting nodes, again condition for splitting and for choosing splitting solution has to be met before complete a potential split operation.

In general this approach will add some complexity in your arcitecture -in the sense that the things you are working with become complex things instead simple ones- but probably the challenges you will face will reward you good.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.