Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics

Neighborhoods within Wards. I need the Older version back.

A topic by Glidias created 24 days ago Views: 423 Replies: 9
Viewing posts 1 to 7
(12 edits) (+1)

BTW,  Is there a way to view  the older version of the city generator. The newer version's SVG output flattens each Ward into a flat array of POlygons and no longer uses multiple <path> nodes per neighborhood within each  ward . I can no longer retrieve each sub Neighborhood's convex hulls within each Ward anymore. Hierachy should support 2 parent levels as before:

Ward -> Neighborhood -> Buildings 

 Now, the new version has all building polygons are flattened into a single Ward level,  Ward g -> polygon*, 
so i can't get back clean convex hulls for each secondary neighborhood 

I actually like the new version that uses <polygons> somewhat instead of <path> instead for the buildings. But ,  a secondary <g> parent node for each neighboorhood within each ward  would be useful  to maintain back hierarchical  information that was available  before, and makes the job of setting up a hierachy of collision volumes a lot more easier already (especially since BSP splitters may also be easily identified from them), further reducing collision tests down to a few buildings and additional props within each neighborhood. This is important because the bsp tree cell subdivion allows one to determiisticaly determine good places to place doors ( facing the roads of a certain level, and thus the actual front of the building). HAving the cell-split information (fo rthe bsp tree formation is important to identify the secondary streets/alleyways, etc. within each Ward itself), allowing me to deterministic-ally place   doors that face the main road or at a side road, etc. It makes it super fast to identify the closest occluding building for raycast tests as well when on the ground.

Above  (as seen from the turuoise marked roads within the ward's roads that are in purple) is an example of what my reader was able to easily do in the older version because all the Ward's buildings within a neighborhood are arranged together in a single <path> node, and I am able to get a quick convex hulls that group all neighborhood's buildings from the old version's SVG output. In the new version's SVG output, my tool can no longer identify buildings within the same neighborhood...and thus can't identify roads for specific neighborhoods. 


You seem to have a really fantastic tool there - would you share it? I'm trying to convert the generator data into GIS data, and it seems that your analysis of roads, etc. is exactly what I would need.


For the convex hulls problem - if you export the "blocks" version of buildings, you actually get exactly the convex hulls. I'm using that instead of calculating them myself.

(22 edits) (+1)

Hmm... okay, so it looks like each <polygon> Block  is actually a sub neighbourhood under the <g> Ward. BUt that would mean I'd need to export out 2 SVGs, i guess. Then, if I do need to determine which buildings in the individual polygon buildings list (in the 2nd detailed SVG) belong to which <polygon> Block , I'd check if their centroids (actually, any corner point would do..) lie within the Block polygon. Since they are chunked-listed together, I need to only check against last matching Block polygon until the candidate building centroid breaks out of it, then scan all Blocks again under that given <g> Ward group of Block polygons to update the current ward polygon region

For the road map analysis, I guess the Block-only SVG has to be used then, moving forward.

But I did wish Watabou would include sub-group neighborhood information within the <g> ward as that was avialable in the previous version and now this version lost it and now  I'd have to refer to 2 svgs (and do point in polygon checks to get back the group the buildings of polygons...bleh).


Regarding how i analyse roads, i'm still doing a WIP tool that actually intends to do a lot more though (note: older version SVG):

Currently, the code is long and messy and I haven't organised everything yet but is mainly testing out various features only so i'm just highlighting parts of the svg for trace . I'm actually using this to further expand the city out into a multi-storey-themed city, by scanning the exported SVG and using it as a procedural base for expansion/sub-generation.  THat is why I differentitate different road hierachies for the purpose fo having certain road types appear at higher altitudes compared to others. But this would also mean in order to access lower level roads at junctions, certain buildings at the corners of those junctions ( or merged buildings  with other Neighbourng  bsp tree cells from sibling nodes ) would need to be converted to stair-ramp-landings, ( to form a basis for like  zig zagging flight of stairs) to provide some form of pedestrian walking  access to lower levels of the city. I'm working on this part atm.

ANyway, there are 3 road hierachies. The highway (thick road spaces in orange), the ward streets (roads around wards spaces in purple), and the inner neighborhood lanes ( narrow grooves within <g> ward due to BSP tree lanes in turquoise). THe highway ramps down just outside the City wall exits (note lighter shade of orange), otherwise, without a CIty Wall, the intention si to have them at the last-outlying wards. I managed to calculate Ward distance costs to City Wall or from Ward region to Ward region, via some navmesh generation + graph navigation routines.

I decided to use node/JS because of some libraries already available in JS, and didn't take the Haxe route here though. 

Basically, to analyse the roads and seperate them out, here's how I do it in summary:

Anyway, here's how i sort of reverse engineer the SVG to get more "information" from it
For ward level roads (main  highways and roads adjacient to Wards..) You simply form a CDT (constrained delaunay triangulation) of the entire set of Wards' convex hulls by defining the Ward's convex hulls as edges of holes (onto the entire square map canvas (also defined as an exteriour edge at first)) from the entire set of vertices of all Ward's convex hulls.  I use cdt2d library for this. The vertices that belong to a Ward's convex hull, is given an integer ID that matches the ward's integer ID.
After applying CDT,  I filter off the polygons that contain vertices at the 4 corners of the map canvas and this leaves behind the road parts (more or less..).s. Then, i form a navmesh out of the CDT set of triangules using Yuka library's navmesh to form a navmesh out of those roads. After that, i scan each navmesh's regions' connecting portal edges to see if the left vertex and right vertex of the portal edge is belonging to 2 different Ward, if it is, then that region will be given an assositated ID assosiating that region with those adjacient/incident Wards. This is done for all portal edges of every navmesh region. (I also do a perpendicular width check along the portal edge to get the opposite edge across, then find perpendicular distance to measure the width of the road and determine if it's a valid road region or not). After that, i combine the set of IDs into an array, sort them, then join them to a consistently ordered string concatenated with "_" to give each raod section a unique ID.  Road sections that are assosiated to to the exact similar set of adjacient Wards, will end up receiving the same ID due to the sorting. (So yes, T junctions or crossroad junctions will have different IDs compared to the main road that only lies between 2 wards, etc. and can therefore be potentially named differently).


That's pretty impressive what you are doing with exported SVGs, but I can't help you, sorry. OK, to be honest it's more like I don't want to, but not in a bad way. I treat SVG as a purely presentational format, any traces of semantics you manage to extract from them are just side-effects. Adding ids, classes, maybe some meaningful grouping  is a way to improve SVG, adding geometry, which is not displayed is a way to make SVG worse. I want exported SVGs to be as compact, simple and human-readable as possible.

Also please note, that if everything goes according to the plan, in the next major update there won't be any wards at all, not only in SVG, but even in the code. Maps will consist of independent blocks (grouped into districts, similarly to current wards). This means that BSP won't be involved in street generation. 

When the desktop version finally arrives, its saved files will contain all the geometry there is. I was going to use JSON for that, something pretty close to GeoJSON. I hope it will be convenient for all who want to process such data themselves.


@watabou - any chance to get access to the JSON before the desktop version? Here's a look at what I'm doing with it (zoom in on the city in the center, Phonas) - -- JSON would be perfect, at this low scale straight-out turning it into GeoJSON is ok because we're talking about a few mm of difference.

I'm happy with the most rough interface. I wrote a GeoJSON export for Azgaar's tool myself (he accepted the PR, so it's now in his codebase). If I understood this Haxe thing, I'd do the same here, but sadly I don't.


There is a good chance of getting JSON soon, but most likely the initial version will be very basic.


Fantastic, thanks.

(3 edits)

So no sub g nodes within g districts it seems...means i'd have to read off 2 svgs instead. I guess what would consider "meaningful" group can be subjective, no doubt.

For the city generator, would it be then advisable to host in a different url, particularly for major change  releases? That way older versions can still be kept/archived.

I think the major update is the one that will involve curved streets?


Yes, the one with curved streets