New to the gosu forums, so I'm hoping this is the right place to post this
I just got into gosu a week ago, and I've been working on porting an old piece of code called the Isometric City GeneratorFirst some links:ICGV2
- Written in C# XNAICGV3
- Also in XNAisometric-city-generator-ruby
- Current version
Some pictures of the old version can be found hereAfter I ported to MonoRotatingRotating a city
Current pictures (of the ruby version)Using perlin gemUsing perlin_noise gem
(Disgustingly slow although I liked the way it looked better)
I'm looking for a little advice on performance enhancement since I can barely use it right now to make anything bigger than a 40^3 render of the blocks but, I'll take any suggestions on anything, I'm really looking to improve anything.
So I'll start with talking about the end goal
My plan is to make a program that generates cities at an isometric perspective. My old versions would use a 3d array. I think this is gross. I wanted to make it dynamically generate it so I could do infinite size cities (or at least close to infinite). The ruby version is going to use perlin noise to generate building heights. Buildings will have features like windows, roofs, billboards, signs, doors. The ground will have plants, grass, roads. There should be special patches, like open stadiums, parks, airports. I'd love to add freeways. There will also be specially generated buildings, either by a single texture or building one out of smaller ones. If I can make that happen I'd really like to add people, cars, helocopters, all with pathing. All of these should be generated with perlin noise and not saved to memory (except for the objects like people, cars, copters, etc)
The Mono version was the most complete by far, adding things like rotation, special buildings like clock towers and radio towers, influence generation (making the city have a heart and suburbs).Issues:
Making buildings with a single texture where x or y (z is height in this case) was greater than one. I made a neat "city hall" sprite that I was going to plop down but, the drawing order would get messed up as a result. To see how I was drawing check IsometricFactory.cs
, go to the DrawBlocks method @ line 466. This draw order issue was specifically frustrating. Now I could solve it by breaking up large buildings into single blocks and rendering them that way, but I figure there should be a better way.
Performance is a huge issue. In C# I was barely scraping by @ 30 FPS with a city size of 30*30*7. In ruby I'm barely getting 10 fps on a 20*20*20 block. I had an ok solution of not drawing blocks where there was a block obstructing it. Basically it would just check if a block was at (x+1, y+1, z+1). The hackish solution was to screenshot the window and start rendering that image instead. This sucks because you can't make a city bigger than the screen size, moving the camera will show an edge where the block fell off the screen. Of course this does boost FPS to 60. If possible I'd like to do all generation and drawing dynamically, so no arrays storing what block is where and what tile is what however, the more I use gosu the more I'm getting discouraged from the idea.
Here's my method_profiler report on isometric_factor.rbQuestions:
I'd like to generate features, colors, roads, etc using perlin noise. My idea was to grab the noise at the current x, y, turn it into a string, then grab some digits after the floating point. Is there any issue with this? Is there a better way?
Roads would be the biggest issue I can see with the pure dynamic method, I'm not sure how to go about making them consistent. How would I figure out where a road should be placed? I want to make them more realistic (before I used straight lines and spaced them out a bit, I feel like there is a better way.
I would love to hear your thoughts on the project, if you have any questions I'd be happy to clarify my post.