Archive for December, 2012

Beyond my Ability, Part 3

As I continue to translate Amit’s actionscript to javascript, it is becoming increasingly obvious that I’m missing a crucial part of this codebase- the actual voronoi diagram. Since this is a level of math that is beyond my ability, I’m going to cheat and find another implementation. Raymond Hill has a demo and a nice MIT-licensed library that may be exactly what I need.

After I examine the API, perhaps I can figure out how much the map.js will need to change to use that, if they’re even compatible. I also need to figure out which conceptual primitives I will need. In the meantime I’ve gone through most of the map.js and translated the skeleton of it to javascript. It’s not very useful, but it’s something.

Beyond my Ability, Part 2

So I have two ways to go about implementing this- read through Amit’s actionscript and try to implement it in java, or read though his article and randomly mishmash internet code together to get a working prototype. While it’s tempting to just swipe other people’s code, that won’t help me understand how it works.

So, I guess the first part is to start with a simple HTML5 page with a canvas.

<!DOCTYPE html>
<html>
    <head>
        <script src="map.js">
        </script>
        <script>
            window.onload = function(){
                var canvas = document.getElementById("worldmap");
                var context = canvas.getContext("2d");
            };
        </script>
        <title> CityGenerator's Worldmap</title>
    </head>
    <body>
        <canvas id="worldmap" style="height:600px;width:800px;border:1px solid black;">
        </canvas>
    </body>
</html>

There we go. So pretty. The next step (I think) is to come up with an object to represent the map; While the canvas is pretty, it’s just output. Amit seems to have done exactly this with Map.as. Do I try a full blown reimplementation of his code without understanding it, or do I aim for a skeleton that can output to the canvas, and the build up from there? For now, I think I’ll get more out of the latter. I’ll start with a simple map.js and try to port over the basic functionality. I’m not sure how successful this will actually be seeing as how he uses external libraries, which I will either need to emulate (no chance) or find a similar js version (slim chance).

Adding to the complexity is my lack of js-fu; I feel like someone who kind of knows Spanish trying to translate a Portuguese document to find out where Vasco De Gama hid his gold.

I’m currently in the process of stepping through the actionscript and replacing individual methods with javascript, while at the same time comprehending how they work. It’s a lot of effort; I’ve been at it for well over an hour and I’m only 9% complete. I need to take a break.

Beyond my Ability, Part 1

I’ve been working on my CityGenerator off and on for years; it’s finally reached a point where I’m content with it’s output and I want to move to the next level. I’d like to start generating an entire continent, then populating it with my CityGenerator. So, step 1- figure out how to generate an awesome map. I’ve tried a couple of things, including my last couple of posts on using gimp, but that won’t work for the city generator- I need something that can scale reasonably well.

So there are two parts to this problem; figuring out how to do it, and how to implement it. Fortunately, someone named Amit has already figured out and documented it magnificently. While I think his method isn’t perfect, I completely understand the design decisions he makes and would probably take the same shortcuts he has taken (specifically ensuring that there are no local minima to ease the creation of lakes and rivers).

Amit is a smart guy that makes me feel very dumb. Reading through his full article makes my head spin. The main problem with his awesome code is that it’s written in flash/actionscript, which makes it semi-useless to me (I have no flash development tools nor an inclination to get tied up in a now-dying proprietary pile of poo). This leads directly into my next problem- How do I implement it?

Like Amit’s code, my best bet on this is to refrain from doing this on the server side- the perlin noise algorithm can be fairly hefty, and under load would crush my dinky server- it would be better to have the clients do the heavy lifting if possible. That leaves me with one viable option- javascript. A combination of javascript and html5 canvas should do the trick nicely (this is also what I use to generate my city flags).

So, with the proper tools and directions written in another language, all that’s left is to interpret Amit’s code and method, then implement it. Hopefully this will be the first article of many on my progress, and I won’t just give up in frustration.

 

Next:

Generating a world in Gimp, Part 2: Terrainasaurus wrecks

Ok, so lets come back to the landmasses

  1. Click on the land layer and color select the land
  2. Use Filter->render->cloud->solid noise with the following settings:
    1. random seed 1056316098
    2. detail 15
    3. turbulent
    4. x,y= 4.0,4.0
  3. Select colors->levels and click auto, then OK

world_tut_10

If you want nice, boring land, you can color this with the technique below and be done. Otherwise we should spice it up a bit.

With your landmasses selected

  1. Create a new layer
  2. Click on the land layer and color select the land
  3. Use Filter->render->cloud->solid noise with the following settings:
    1. random seed 2925538520  (note that this is different)
    2. detail 15
    3. turbulent
    4. x,y= 6.0,6.0 (note that this is different)
  4. Select colors->levels and click auto, then OK
  5. Set this new layer’s mode to hard light
  6. Merge down

world_tut_12

Perfect! Now your land still roughly matches the patterns of the original solid noise, but has a flavor of something new as well. Now lets colorize this badboy Here’s a simple gradient that I made called Terrain.ggr. It can be dropped into your gimp-2.8/gradient directory.

GIMP Gradient
Name: Terrain
5
0.000000 0.042056 0.144860 0.909804 0.906572 0.635079 1.000000 0.084619 0.588235 0.032295 1.000000 0 0 0 0
0.144860 0.285047 0.485981 0.084619 0.588235 0.032295 1.000000 0.024864 0.133333 0.013595 1.000000 0 0 0 0
0.485981 0.593458 0.686916 0.024864 0.133333 0.013595 1.000000 0.254902 0.199829 0.031988 1.000000 0 0 0 0
0.686916 0.761682 0.845794 0.254902 0.199829 0.031988 1.000000 0.164706 0.070252 0.018731 1.000000 0 0 0 0
0.845794 0.922897 1.000000 0.164706 0.070252 0.018731 1.000000 1.000000 1.000000 1.000000 1.000000 1 0 0 0

world_tut_8

Once you get that loaded in and gimp restarted, we can continue.

  1. Use the gradient tool and select your new terrain gradient
  2. Color select the empty space around your landmasses
  3. Select Select->Invert
  4. Select Colors->Map->gradient map
  5. Select Select->None
  6. Select Filters->Blur->Blur

And now your map has terrain!

world_tut_13

 

Generating a world in Gimp, Part 1: Land and Shallows

This is a work in progress on how to create a nice, quick worldmap.

  1. Create a new image in gimp, 1200×800
  2. Delete the background layer because it’ll just get in the way.
  3. Create a new layer group
  4. Create a new Transparent layer in the group called “noise”
  5. Use Filter->render->cloud->solid noise with the following settings:
    1. random seed 1056316098
    2. detail 15
    3. turbulent
    4. x,y= 4.0,4.0

You should end up with something like this:

Now, Lets make some land.

  1. Create new layer above that, fill color #a4a3a3, set Mode to addition, then disable it. Name it “Shallows addition”
  2. Create new layer above that, fill color #888888, set Mode to addition. Name it “Land addition”
  3. Clone that layer, set Mode to grain merge
  4. Create new layer above that, fill color #000000, set Mode to burn
  5. This should give you a nice group of islands and the shallows around them.

By switching back and forth between the addition layers, you can create outlines of both the land and the shallows:

  1. Enable the shallows addition and disable land addition
  2. Click on the layer folder grouping
  3. Use select by color and select the black area
  4. Click on the solid noise layer
  5. Press delete. This should make a majority of the background clear
  6. Enable the land addition and disable shallows addition. This should leave you with white land, black shallows and clear ocean.
  7. Click Select->None
  8. Right click on the layer grouping and merge visible layers.

You now have a two-tone map:

Now to split it up.

  1. select by color and click on a white area
  2. create new transparent layer,
  3. fill with #7c674f
  4. click on 2 tone layer
  5. hold shift and click on black section
  6. create new transparent layer,
  7. fill with #aeb0ff
  8. click select->None
  9. On the two tone layer, fill with #202261

You now have a 3 layer image, one of solid oceans, one of shallows, and one of land.

Lets fuzz out the shallows:

  1. switch to shallows layer
  2. color select shallows
  3. filter->render->clouds->difference clouds
    1. seed: 1056316098
    2. turbulent
    3. detail 15
    4. x,y=4,4

And lets add a little texture to the base water:

Select the base ocean layer
filter->render->clouds->fog
Set the color to #050755
turbulence 3.0
opacity 60%
merge newly created fog layer down.

filter->render->clouds->fog
Set the color to #4043a9
turbulence 3.0
opacity 60%
merge newly created fog layer down.

And there we go, the final, fullsize image (click to embiggen):

Go to Top