Ultima Castle Map Generator: Day 8

Ok, I think I’m done at least for now… I just can’t get something out of my head once I start, this kind of mini projects hijack my mind and derail me from other things I really should be doing, but I’m ready to give this a rest.

day8

It’s done! You can check it out online at http://slashie.net/ultimacastlegen (images are not preloaded so it may take one or two generated maps for graphics to show up)

You can also check the source code at github (It’s not super beautiful, but it was fun!).

As it stands, it generates a single floor layout of a castle based on the design of the old Ultima games, specially Ultima 5. It goes roughly through 4 phases:

  1. Defining a high level structure of the rooms to be placed.
  2. Splitting the available space into rooms, based on the high level structure.
  3. Assign the rooms a given function.
  4. Fill the rooms with the appropriate furniture and contents, based on its function.

During day 8, I did the following

  • Fill the remaining space after the initial room expansion, to ensure most of the space in the castle is used to place rooms.
  • Build throne room, staff quarters, guest rooms, castle lord quarters, dining rooms, kitchens, libraries and halls, furnishing them with all sort of stuff based on the reference material.
  • Render 14×16 pixels sprites instead of 16×16 (high fidelity)
  • Enhance connection of the central feature with the rest of rooms
  • Clean spaces in front of doors to ensure walk-ability.
  • Add treasure chests with secret doors
  • Remove some room types belonging to other floors (forge, for instance)

There is certain room for improvement, and there’s of course the question of adding the basement and additional floors (and connecting all together!). But from what I see, that would take a bit of time.

Doing this generator was pretty interesting… I learned a couple of new tricks I hope will be useful for other projects in the future.

Have fun!

Ultima Castle Generator: Day 7

Screen Shot 2016-02-01 at 11.47.25 PM

Rooms are now linked together, to do this I explore the rooms recursively, starting from these west and east of the courtyard; I scan the map for nearby rooms on each direction, recording the limit segments and then I pick a random place from the segment to place a door. Then I explore the connected rooms repeating the process, as a result the whole map is connected.

Additionally:

  • Rooms’ minimum size is now bigger, in turn the generator now rejects structures in cascade, in case it’s unable to place or assign the rooms
  • Entrance is now split on an in-castle portion and an outside castle segment.

Next up:

  • Finishing entrances and wall corridors
  • Working on the rest of room builders
  • Add moat and drawbridge
  • Put kitchen next to dining rooms

Ultima Castle Generator, Day 5

castleDay5

There’s not a LOT of advancement today, but I decided to skip some steps and go right into the tile renderer (using just floors and walls, without the room’s contents).

From here I noticed some small inaccuracies to be fixed (Notice for example the differences between the west and east towers in the image above), as well as some stuff to be polished on the rooms generator (like adding a minimum width and height for rooms to prevent 3 tile big rooms from happening).

I also created a simple random terrain generator; that one will have to be completed to add the moat, may be.

Ultima Castle Generator: Day 4

ss2

I’ve implemented the following:

  • Beautiful symmetry, basically allowing the castle to be “almost” symmetrical vertically. I love how it ended up, with small changes on each side.
  • Allow specifying rooms to be placed in the north of the castle
  • Allow specifying mandatory rooms south of a given room
  • Allow specifying preference for “big” rooms

Following is still pending for the Room Generator:

  • Allow specifying rooms to be placed next to each other (i.e. put the kitchen next to the dining rooms)

Then I’ll work on the “third level generator” to create the tile map.

If all goes well get ready for some cute screenshots tomorrow.

Ultima Castle Generator: Day 3

Ok, I must confess I’m a bit obsessed over this. I’m sorry, I can’t help it.

Lots of advancements today, here’s a sample of the current results. You can check it out online here

castle1

Today I created the RoomsGenerator; it takes the high level castle structure as an input from the CastleStructureGenerator and based on it it generates a set of rooms and places them on the map.

I also created the Canvas Renderer in order to be able to visualize the results in a graphic way, this in turn helped me tweak some size parameters on the structure generator.

Placing the towers, walls, entrances and central feature was not very complex, the challenge was filling the remaining space with rooms…

area1

Since the area to be filled is not rectangular (the main hall and the entrances should not be covered), doing recursive subdivision such as the one I made for the Stygian generator was not going to work; I thought as an option I could generate smaller rectangular areas from the big area and apply subdivision to each, but since the scale was so small (32×32 for the full map, about 13×20 or less for the area to be subdivided), I knew subdivision was going to be troublesome.

In the end I thought on doing something I rarely do: placing rooms by brute force. Initial results were not very good with lots of unwanted empty space. I was about to explore other options…

initialBeruteforce

…but then, I figured I could make the rooms grow to fill the empty space! 🙂 As a result architecture looks a bit more “organic” than the one generated by subdivision, with less “long lines”, which is good for small maps like this one.

I’m pretty happy with the current results, following are the next steps:

  • Enhancing the room generator to have in consideration what rooms should be placed next to each other
  • Creating the third level generator which actually renders the rooms into tiles and places all decoration and stuff.
  • Connections between rooms will be added by the third level generator (that should suffice for the scope of the generator).

Ultima Castle Generator – Day 2

Advanced a bit more in the Ultima Castle Generator for the ProceduralGeneration reddit monthly challenge # 2.

The generator now generates a high level structure, based on the rules I derived from observation of the maps.

For now, and hoping to finish in time for the challenge, only the first floor of the castle will be generated.

You can check the source code or play around with the generator online.

Next step is going one level further to subdivide the map into areas based on the generated structure.

Here is an example result:

{
  "general": {
    "size": "big"
  },
  "surroundings": {
    "hasMoat": true
  },
  "towers": {
    "size": 5,
    "crossWindows": false,
    "circle": false,
    "verticalConnections": false,
    "horizontalConnections": "bottom",
    "connectionCorridors": {
      "type": "halls",
      "hallDecoration": {
        "torches": true,
        "plants": true,
        "columns": false,
        "fountains": false
      },
      "hallWidth": 3
    }
  },
  "central": {
    "type": "mainHall",
    "hasSpecialFloor": true,
    "centralFeature": "fountain",
    "hasFireplace": true,
    "width": 15,
    "height": 14,
    "shape": "cross"
  },
  "entrances": {
    "northExit": {
      "hasFloor": false,
      "hasCrossWindows": true,
      "lighting": "torches",
      "hasBanners": false
    },
    "southExit": {
      "hasFloor": true,
      "hasCrossWindows": true,
      "lighting": "torches",
      "hasBanners": false
    }
  },
  "rooms": [
    {
      "type": "throneRoom",
      "hasCarpet": true,
      "linedWithColumns": false,
      "linedWithTorches": true,
      "hasSecondaryThrone": false,
      "hasMagicOrb": true
    },
    {
      "type": "lordQuarters",
      "piano": false,
      "clock": true,
      "bookshelf": false,
      "fireplace": true
    },
    {
      "type": "livingQuarters",
      "freeSpace": 0
    },
    {
      "type": "diningRoom",
      "luxury": 2,
      "fireplace": true
    },
    {
      "type": "kitchen",
      "filled": 4,
      "barrels": 2,
      "boxes": 2,
      "hasOven": true
    }
  ]
}