Message Boards Message Boards

GROUPS:

Tabletop RPG Map Generator

Posted 6 months ago
4032 Views
|
5 Replies
|
16 Total Likes
|

The Backstory

This July I was lucky enough to be a participant of the Wolfram Summer School. My project was to develop a function that would generate tessellations of space and assign a value to each cell- all of this so that I could visualize higher-dimensional CAs. I can proudly say that I was somewhat successful and the end result of my work can be found here. You may be wondering why on earth do I bring this up. Well, on the flight back home I was thinking about how I could further develop my code, and I realized that with only a few minor tweaks I could make something REALLY useful. Something that I'm sure many people who frequent these forums would be happy to use. Something to play tabletop RPGs.

The Big Idea

One of the things my TesselationPlot function could do is generate a hexagonal grid- a tabletop map waiting to happen! I got rid of a lot of unnecessary code, added some quality of life improvements, and came up with the following:

Options[TableTop]:={"CellSize"->100};

TableTop[terrain_,basis_List:{{1,0},{1/2,Sqrt[3]/2}},OptionsPattern[TableTop]]:=
Graphics[
    Module[
       {terrainColors=Association[
                       grass->Import["C:/GitHub/TableTop/Graphics/grass.png"],
                    ocean->Import["C:/GitHub/TableTop/Graphics/ocean.png"],
                    desert->Import["C:/GitHub/TableTop/Graphics/desert.png"],
                    mountains->Import["C:/GitHub/TableTop/Graphics/mountains.png"],
                    volcano->Import["C:/GitHub/TableTop/Graphics/volcano.png"],
                    swamp->Import["C:/GitHub/TableTop/Graphics/swamp.png"],
                    ice->Import["C:/GitHub/TableTop/Graphics/ice.png"],
                    lake->Import["C:/GitHub/TableTop/Graphics/lake.png"],
                    forest->Import["C:/GitHub/TableTop/Graphics/forest.png"]
                    (*"XXX"->Import["https://github.com/JHeimrath/TableTop/blob/master/Graphics/XXX.png","Images"][[2]]*)
                 ],
         d1=Dimensions[terrain][[1]],
         d2=Dimensions[terrain][[2]],
         b1=basis[[1]],
         b2=basis[[2]],
         hexagon={{0,0},basis[[1]],basis[[1]]+basis[[2]],2*basis[[2]],2*basis[[2]]-basis[[1]],basis[[2]]-basis[[1]]}   
         },

          Table[
              {EdgeForm[Black],
              Texture[terrainColors[terrain[[i+1,j+1]]]],
              Translate[
                 Polygon[
                   hexagon,
                   VertexTextureCoordinates->Automatic
                 ],
                 i*(b1-2*b2)+If[EvenQ[j],(3*j/2)*b1,(3*j/2-1/2)*b1+b2]
              ]
              },
          {i,0,d1-1},{j,0,d2-1}]
    ],
    ImageSize->Max[Dimensions[terrain]]*OptionValue["CellSize"]
];

The input is a matrix, where the entry in each cell is the type of land you want in that place on your map. So, for example, running:

smallWorld = {{grass, grass, mountains}, {grass, forest, 
   mountains}, {grass, forest, forest}};
TableTop[smallWorld]

would generate the the following map:

A small map.

The Images

The terrain graphics were hand-painted for this project by my talented fiancée, Maria Czarnecka. Currently there are 9 terrain types: grass, ocean, desert, mountains, volcano, swamp, ice, lake, and forest. We plan to add at least a few more (city, village, road, river, ravine). All of them are available for you to download from my GitHub. You can also make as many new ones as you like yourself- feel free to share ideas and images in the comments! However, you can create some pretty nice maps using just what's available at the moment: enter image description here

Some Final Thoughts

When I have some time this week I plan to add auto-padding to the code, so the input won't have to be a full rectangular array. It might also be a good idea to add a "space" terrain tile to create nice world boundaries. Let me know in the comments if you have any other suggestions or ideas!

5 Replies

enter image description here - Congratulations! This post is now featured in our Staff Pick column as distinguished by a badge on your profile of a Featured Contributor! Thank you, keep it coming, and consider contributing your work to the The Notebook Archive!

One idea might be to make the hexagons about 10% larger than currently, but with the same spacing between their centers, so that they overlap. Then, across each overlap, combine/overlay the images in a gradual transition of x(image 1) + (100-x)(image 2) where 0<x<1 is the fraction of distance across the boundary overlap traversed (with different logic for the region around nodes where 3 images intersect). (Not familiar enough with image combination to know how that would look exactly in code, but hopefully the idea's clear.)

That might keep it easy to visually identify what terrain type is in each hexagon, but reduce the abrupt transitions across hexagon boundaries and make it look more "realistic".

What would the syntax look like to generate a hex grid as opposed to a hex grid with overlaps? The idea of hex grids with overlaps strikes me as cool because it is a way to view a continuous map as in a overlapping digital form while giving up the idea of one-to-one correspondence between some of data locations in the continuous map and the hexes of the overlapping view. It feels like this would allow a natural scaling when increasing detail in the continuous map in a computer visual tool, while still having a digital representation.

Dave Whitten 713-870-3834 whitten@netcom.com

Posted 2 months ago

It would be nice if instead of generating hex content arbitrarily one could use a real map. That would be good for historical games; enter a hex size and then produce the Google Earth image at a specified scale with a hex array on top of it.

If you use a real map, wouldn't it basically be a hex grid placed over the real map? Or do think the overlapping hexagons is related to this?

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract