Lead Developer, Stardock Entertainment

The Zone of control (ZOC) code has always been a bit odd since it was written for GalCiv2, with weird little bubbles, twists, etc. But it mostly worked in GC2, and I didn't have time to give it a lot of love when porting it to the new engine. The code to update the ZOC is also fairly inefficient, which is why it only updates at the end of a turn. The ZOC expands based on the influence of the city and the player's influence ability.  It works by specifying a source, which has a power and a radius. The power determines how much influence the source is exerting on the tile, so that if there are two sources in the same area with different owners, the player who 'owns' the tile is the one who has the most power in that tile.

This is how the influence looks in 1.09e for a city hub which has a radius of 2: 

Current implementation - radius 2

Looks OK, right?  But wait, city hubs have a radius of 2, and that's only showing ZOC around tiles that are 1 tile away from the hub.  It turns out that the ZOC code was modifying the power of the source (the city hub) by its relative distance from the center using the Euclidean distance forumla  So the closer you were to the center, the higher the power was, and the tiles with distance 2 had a power of 0 because they were at the farthest edge. Also, adding an improvement on the edge of the ZOC didn't bump out the influence because most of them only have a radius of 1, which meant that the only tile that got influence was the one they were actually in, which tended to already have influence from the city hub.  Also, since you can have up to 4 improvements in one tile, each exuding their own influence, they were overwriting each other as sources. 

So first I changed it so that all tiles within the radius got the same power value.  If we cared about pixel distance instead of tile distance, having the influence fade out towards the edge of the range would make sense, but everything uses tile distance for calculations, and the descriptions for how much influence an improvement gives you says 2 tiles.  I also made it so that the influence was calculated from the city tiles instead of the improvements themselves, so that each tile would return the max influence radius and power for all the improvements on the tile.  This is what happened:

 

Per tile influence, constant influence

Well, rats.  The interpolation code is clearly just using the center point of each tile and it looks pretty lame.  The city hub is now starting with a radius of 1 and growing to 2 once it's built up a little more. But it looks lame, even with a radius of 2.  It must need more points.  Hmm, there are some extra points that are commented out in the code that calculates the edges. Maybe just uncommenting those will work?

Uncommented points

Nope.  That obviously isn't going to work. That must be why the points were commented out.  But why weren't they deleted when they clearly don't work? I hate that.  The developer who wrote the original ZOC code hasn't worked here for over 5 years, so there is no target for my crankiness.  

I commented out those lines again in case I needed them for reference and stared at the edge calculation code again.  I decided to simply outline the edges of the tiles, since that would be clear which tiles exactly were under your influence, and the filtering code should take care of adjacent zones.

Outlines

Well, that's better, I guess.  You can tell where your influence is--but wait, why isn't that fire shard in my influence? It's only two tiles away.  Oh, but it's still using the Euclidean distance formula to set the powers.  Well, that's lame, and it makes it look lame too.  No one is going to look at this and say, "Oh, it's calculating the Euclidean distance from the city hub." They're going to count the tiles.

So I made it not check the Euclidean distance and just check everything in the bounding rect with the source at its center and a radius of 2.

Using squares

I think it looks a lot better.  This is a city that has been built up a little, and has two improvements built. The first improvement, the farm, only has a radius of 1, so it was inside the 2 tile radius of the city hub.  It wasn't until I added the next improvement that it bumped out a bit.

I might need to do something with the line interpolation code though, because the leftmost corner of the zone always seems very pointy and we want the rounded squares for aesthetics.  Also, I haven't played very long with this code so I don't know how well it will react with adjacent zones yet. But I think it's headed in the right direction, and the calculations are a lot easier to read now, which is always good.  It's even a bit faster since it doesn't have to calculate the Euclidean distance anymore.  Now, to test and polish...

 


Comments (Page 6)
8 PagesFirst 4 5 6 7 8 
on Nov 09, 2010


It's really just a tweaked feature that exists in game already. I don't think that the AI currently tries to expand its influence by building improvements, but since it will include more tiles, it will get some benefit indirectly.

 

This is something that I think the AI should try to do, and I don't think it would be overly hard to code some simple logic rules (not a coder like you or Brad, so if I'm wrong let me know)

a) When the AI builds an improvement, have the AI try to build the influence towards an unclaimed special resource tile if possible.  Unsure if there should be any exceptions to this.  Second priority should be goodie huts.  Maybe the third priority should be towards chokepoints.  Fourth priority towards other zones of influence.

 

when the player builds somethings, have the same AI logic used to place the player's building if unspecified by the player (I'm sure you do this already)

 

Maybe at lower difficulties it would be more random.

on Nov 09, 2010

random_target

For example, if I have a resource north of my city outside the ZOC (or whatever name you use), building houses and other improvements toward the resource will also help expending the ZOC to that area?

It already does matter, just not as much and not for typical buildings. You can build a line of buildings out towards a resource and then build a missionary/town hall.

CariElf

Grids are still extremely useful for judging relative distances, directions, etc.  Squares aren't so bad since we allow 8 directions of movement rather than just 4 like most games that use square tiles, and more than 6 which hexes give you.  It's also far easier to represent the coordinates mathematically, and easier to store stuff on a per tile basis.  I think that you'd probably have to use some kind of tree instead of a 2x2 array, which adds more overhead.

Hexes can be done as a two demisional array (Age of Wonders: Shadow Magic seems to) if the shape of the map is roughly rectangular/square. It just complicates accessing the 'adjacent' tiles, but the overhead is offset by only having to access 6 rather than 8. The main issue is the logic is harder to work out as the way to do it is not obvious.

Edit:

It would have two cases for accessing the adjacent hexes. In AoWSM, the hexes line up into colums, and the X value offset for a hex in a given colum is the same as a square grid. Accessing the hexes above and below it are the same as a square grid (+/- 1 in the Y offset). Depending on if the colum is even or odd (which one it is depends on how the hexes are placed) will determine how to get the adjacent left/right above/below the target hex. In one case the ones above will have a Y offset that is one less that the current and those below will use the same Y offset. The other case will have those above have the same Y offset and those below have an offset that is 1 greater. Switching between these two cases would only add the overhead of an if statement that checks to see if the colum is even or odd (X % 2). If the hexes are oriented diffrently (like in HoMM 1 through 3 for the tactical combat) then row is interchangable for colum.

on Nov 09, 2010

I like the changes. Nice work!

on Nov 09, 2010

carielf, in several of my games I have had a situation where my influence completely surrounded another faction's city and had actually forced the other factions influence to within it's city, at that point I was more or less expecting the other faction's city to switch to my faction, is this sort of situation going to be added in in future?

harpo

 

on Nov 09, 2010

harpo99999
carielf, in several of my games I have had a situation where my influence completely surrounded another faction's city and had actually forced the other factions influence to within it's city, at that point I was more or less expecting the other faction's city to switch to my faction, is this sort of situation going to be added in in future?

harpo

It's not currently planned, but I personally would like to see that implemented since it was very useful in GalCiv2.

on Nov 09, 2010

carielf, if you could add it to wanted/desired features list it would be appreciated.

thank you

harpo

 

on Nov 09, 2010

Your language of "marking" everything in the bounding rect imply to me that you've bypassed the Euclidean calculations. I'd suggest that for the sake of adjacent borders, you're still going to need a proper "distance" calculation to get things to work right.

Personally I'd rather have a game use Euclidean distance for idealistic reasons, but Elemental already isn't a Euclidean game for units (see: treatment of diagonals) so you should be using the Chebyshev distance. It's still computationally cheaper (no squares or root, just absolute values and a comparison) and, I'd say, will give more intuitive results when borders are contested than some rectangle system.

Edit: And you should be able to use the old Euclidean-based code and simply replace the calculation formula[e]. Alternately, you can use the Euclidean distance only for determining tiebreakers when area is contested (otherwise I see awkward looking tiebreaker scenarios), but allowing cities to extend via Chebyshev distance to empty land.

All that said, how is the new, proper handling of influence going to affect the limits regarding building within 2 tiles of an existing city? It seems that once influence becomes more firm as a mechanic, you could keep track of exactly which map tiles "belong" to which city, avoiding the awkwardness that sometimes arises when attempting to claim a resource between two cities.

on Nov 09, 2010

I feel like influence should bubble a little from sources of prestige when compared to corners that are just workshops or something; if you're going to make it the growth conform to the shape of the city at all.

on Nov 09, 2010

CariElf

Quoting harpo99999, reply 79carielf, in several of my games I have had a situation where my influence completely surrounded another faction's city and had actually forced the other factions influence to within it's city, at that point I was more or less expecting the other faction's city to switch to my faction, is this sort of situation going to be added in in future?

harpo

It's not currently planned, but I personally would like to see that implemented since it was very useful in GalCiv2.

 

Here, I'd suggest making the influence revolts be based on the housing perhaps?

You get a majority of the housing, or the town center if there is no housing- you get the town.

on Nov 09, 2010

my thoughts are based upon the town 'voting' which faction is best for the town, ie stay with the faction they are in and have a tiny influence area OR switch to the surrounding faction and GAIN access to the resources of the influence zone, possibly also factoring in what improvements are in the town, eg pubs,ins,townhalls and their equivelents contributing to the stay, and if the  surrounding faction HAS MORE of the improvements in it's surrounding towns, then switch.

harpo

 

on Nov 09, 2010

Loren1350
Your language of "marking" everything in the bounding rect imply to me that you've bypassed the Euclidean calculations. I'd suggest that for the sake of adjacent borders, you're still going to need a proper "distance" calculation to get things to work right.

Personally I'd rather have a game use Euclidean distance for idealistic reasons, but Elemental already isn't a Euclidean game for units (see: treatment of diagonals) so you should be using the Chebyshev distance. It's still computationally cheaper (no squares or root, just absolute values and a comparison) and, I'd say, will give more intuitive results when borders are contested than some rectangle system.

Edit: And you should be able to use the old Euclidean-based code and simply replace the calculation formula[e]. Alternately, you can use the Euclidean distance only for determining tiebreakers when area is contested (otherwise I see awkward looking tiebreaker scenarios), but allowing cities to extend via Chebyshev distance to empty land.

All that said, how is the new, proper handling of influence going to affect the limits regarding building within 2 tiles of an existing city? It seems that once influence becomes more firm as a mechanic, you could keep track of exactly which map tiles "belong" to which city, avoiding the awkwardness that sometimes arises when attempting to claim a resource between two cities.

It is already using the Chebyshev distance formula just by the way it's coded.  I've also seen this algorithm called the max(dx, dy) algorithm, where dx = change in x and dy = change in y.  

For a city hub at location 0,0 (for convenience, we don't actually use negative coordinates) and radius 2, these are all the points that the code loops through (using 2 for loops, for those of you familiar with programming):

(-2,-2) (-1, -2) (0, -2) (1, -2) (2, -2)

(-2, -1) (-1, -1) (0, -1) (1, -1) (2,-1)

(-2, 0) (-1, 0) (0, 0) (1, 0) (2, 0)

(-2, 1) (-1, 1) (0, 1) (1, 1) (2, 1)

(-2, 2) (-1, 2) (0, 2) (1, 2) (2, 2)

Take the first point, which would fail under the Euclidean method because it would have a distance of 4:

d = max( abs(-2 - 0), abs(-2 - 0) )

d = max (2, 2)

d = 2

Since all points are relative to the center and the radius is 2, the max distance of any point will be less than or equal to 2 already, just because of the way that the loops are setup. 

This does not affect the limitation of how close you can build to another city. While improvements exude influence, the influence is not specific to that city, and with this code, it will be possible to have your own zones of influence overlap, so it wouldn't really help anyway. However, now at least you may be able to get the resource within influence without needing to build another city next to it, and then you could fortify it.  It's not as convenient as having it absorbed into a city, but it will be somewhat improved.

on Nov 09, 2010

CariElf

Since all points are relative to the center and the radius is 2, the max distance of any point will be less than or equal to 2 already, just because of the way that the loops are setup. 

This does not affect the limitation of how close you can build to another city. While improvements exude influence, the influence is not specific to that city, and with this code, it will be possible to have your own zones of influence overlap, so it wouldn't really help anyway. However, now at least you may be able to get the resource within influence without needing to build another city next to it, and then you could fortify it.  It's not as convenient as having it absorbed into a city, but it will be somewhat improved.

Well what I meant (re: gameplay and building placement) was that if influence/territory is a well-defined quality, perhaps the map tiles could be assigned ownership not only to a player but to a specific city. I am assuming that the "at least two tiles away" rule is meant to simplify the management of improvements-to-cities situation. If each city has its own territory influence that competes against other cities (even in the same nation), then ownership is simple. Granted, I don't know how you're representing these things internally but if it's doable, it would make for more natural feeling gameplay. The two tile limit feels very artificial, and the fact that it can in certain (and by no means exceptional) circumstances lock the player out of a resource tile is annoying; I'd rather not metagame my city placement.

In short, I don't like the two-tile limitation, and it seems to me that the influence boundary calculations might allow it to be removed.

But apart from that, I am curious about [player] boundaries: How will you break ties in influence conflicts?

on Nov 09, 2010

Okay I like the underlying concept but don't really like the "square" look in the bottom pic and am wondering if the "corners" in the border area can be softened more, if only for an aesthetic effect.  The spread of influence needs to look like an organic flow, IMHO, which is betrayed by hugging the lines of the grid too closely.

on Nov 09, 2010

This is really looking good! I appreciate all of Stardock's hard work!

on Nov 09, 2010

Although this all looks and sounds pretty nice, why is this being focused on?

I'd much rather you talk to us about the spells and the core changes that are coming to the game. I didn't even know that there was an issue with ZOC's.

But that's just me

Cheers,

V.

8 PagesFirst 4 5 6 7 8