Automatically creates & tiles .tmx format maps from a world map interface

Related tags

Utilities autotile
Overview

Autotile

Create tiled maps for an arbitrarily large world space from a simple interface, then add larger objects randomly with simple rules (eg. place trees but only on grass/dirt tiles).

example beach scene

Why

Creating maps by hand is labourious and annoying. Especially if you have a few different tilesets for various biomes that need to be placed the same way. A clear river running through an idyllic valley, a murky river through a swamp, a frozen river in the dead of winter - they all have the same tile pieces; centres, left turns, right turns, corners .. like a great jigsaw .. why place these things by hand when a machine can do it (even if it's just to get you started!).

What

Autotile is intended to place various elements tile by tile on to map(s) from something that implements a simple interface. Including complex things with tiles that dove tail together & can vary in shape; rivers, waterfalls, cliffs, lava, roads / paths. As well as simple land tiles - snow where it is cold, sand on beaches & in deserts, grass, dirt etc. And larger logical objects composed of tiles themselves (eg. trees, rocks, houses & anything really).

For the later, placing larger logical objects, this uses & is designed to be used with my tile library which includes tooling to disect larger images in to smaller layered maps. For more info & a tool to create compatible 'tobs' please check that readme or see some of the examples under tobs. Tl;dr they're essentially tiled TMX maps with some special properties.

How

Base Maps

Firstly we'd like to create the base maps. By 'base' I mean we want to place all of the landscape type tiles - land tiles like grass, snow, dirt, water, cliffs, lava, waterfalls etc.

In order to do this we supply something that satisfies the Outline interface (don't panic, it's pretty short).

// tell me how large the world map is 
Bounds() image.Rectangle

// tell me what the area is like at world co-ords (x, y)
At(x, y int) *Area

An Area just relates some basic info like

  • height at the given location
  • average temperature
  • whether the given point has water (sea, river, swamp), lava, road etc
  • a Land struct that tells us what tile(s) to place at this location
  • optional tags ([]string) to add to tiles sourced from this location

Nb. it's recommended not to re-create a Land struct (or even Area if possible) each time At is called -- we'll be calling this function a lot & having it re-instantiate an object each time is probably more work than we want to do.

Armed with this & some config information we can begin creating maps. Checkout the example.

Placing Objects

To place tile objects (again, see

  ldr := autotile.NewFileLoader("")
  bin := autotile.NewObjectBin(ldr)
  
  bin.Load(
    "trees",  // load a new group called "trees"
    0.4,      // we should place an item from the group "trees" 40% of the time
    []string{"tree.01.tmx", "shrub.01.tmx"}, // here are the trees that the Loader (above) knows how to load
    nil,
    []string{autotile.Dirt, autotile.Grass}, // items from group "trees" can be placed only on Dirt or Grass tiles
  )
  
  bin.Load(
     "",      // empty string represents the nil group; ie the chance we place nothing at all
     0.6,     // %60 chance we don't place any object on a given tile
     nil, 
     nil, 
     nil,
  )
  
  // where `m` is a MapOutline returned from CreateMaps and `at` is an autotiler from NewAutotiler()
  at.AddObjects(m, bin)

Again checkout the example for more details.

Notice a couple of things

  • the Loader here in an interface with one function that loads a TMX map given some string. The most trivial example is FileLoader (where the key is a file path) but of course you can supply your own loader that does whatever
  • we can control what tiles the bottom (lowest z-layer) of the object sits on with the last two args all and any which both take a list of tags ([]string)
  • these tags are added at map creation time & as mentioned before the user can stipulate their own (by setting on an Area struct)

Finally we can save out the resulting maps with a simple

	m.Tilemap.WriteFile("my-map.tmx")

It's uh, recommended to not try to keep thousands of maps in memory at a time & to write the out ASAP.

The World

The intention then is to turn a high level world map (depicting rivers , sea, height information, temperature, rivers, sea etc) into an arbitrarily large number of fully tiled maps, each of them representing some (x,y) offset chunk of the world space with fairly minimal work on our part.

TODO

There's more to come in this space -- I'd like to handle creating interiors, cities & villages, cave systems etc. Feel free to push up PRs, requests, fixes etc.

Credits

The image(s) used here are taken from pokemon gen5 tilesets from deviantart and/or spriters resource. Some have been created from existing tiles where original pieces didn't exist. I've added them as an example & a way to visually test code changes.

Releases(v0.0.1)
💪 Helper Utils For The Go: string, array/slice, map, format, cli, env, filesystem, test and more.

?? Helper Utils For The Go: string, array/slice, map, format, cli, env, filesystem, test and more. Go 的一些工具函数,格式化,特殊处理,常用信息获取等等

Gookit 731 May 18, 2022
A Go package for checking conditions for slices and maps.

check Go package The check package of Go helps one to check various conditions for slices: []int []float64 []string []bool maps: map[string]int map[st

null 4 Feb 3, 2022
Create deep copies (clones) of your maps and slices without using reflection.

DeepCopy DeepCopy helps you create deep copies (clones) of your maps and slices. Create deep copies (clones) of your objects The package is based on t

null 3 Apr 12, 2022
Access and modify property values in deeply nested maps, using dot-separated paths

Dig lets you access and modify property values in deeply nested, unstructured maps, using dot-separated paths: source := make(map[string]interface{})

Preslav Rachev 12 May 7, 2022
Golang: unify nil and empty slices and maps

unifynil, unify nil and empty slices and maps in Golang Empty slices and maps can be nil or not nil in Go. It may become a nightmare in tests and JSON

Boris Nagaev 0 Jan 16, 2022
Creates Prometheus Metrics for PolicyReports and ClusterPolicyReports. It also sends PolicyReportResults to different Targets like Grafana Loki or Slack

PolicyReporter Motivation Kyverno ships with two types of validation. You can either enforce a rule or audit it. If you don't want to block developers

Frank Jogeleit 0 Aug 6, 2021
Cell is a Go package that creates new instances by string in running time.

Cell Cell is a Go package that creates new instances by string in running time. Getting Started Installing To start using CELL, install Go and run go

null 0 Dec 20, 2021
ms - 'my story' creates a secure password string which can be memorized with a technique shared by Max.

On 23.12.21 20:22, Stefan Claas wrote: [...] > > Yes, I am aware of that, but how can one memorize a key when traveling > and not taking any devices

Stefan Claas 0 Dec 24, 2021
Go library to interface with NEAR nodes' JSON-RPC interface

StreamingFast Solana library for Go Go library to interface with NEAR nodes' JSON-RPC interface Contributing Issues and PR in this repo related strict

StreamingFast 1 Nov 9, 2021
Go library for decoding generic map values into native Go structures and vice versa.

mapstructure mapstructure is a Go library for decoding generic map values to structures and vice versa, while providing helpful error handling. This l

Mitchell Hashimoto 5.7k May 12, 2022
a thread-safe concurrent map for go

concurrent map As explained here and here, the map type in Go doesn't support concurrent reads and writes. concurrent-map provides a high-performance

Or Hiltch 2.9k May 15, 2022
Fast integer map for uint32-to-uint32

Uint32-to-Uint32 Map This repository contains an implementation of uint32-to-uint32 map which is ~20-50% faster than Go standard map for the same type

Roman Atachiants 4 Apr 2, 2022
A thread-safe concurrent map for go

concurrent map Original repo didn't support go mod and no any tags,so I forkd this repo add go mod support and patch a tag on this repo. No any code c

Yusan Kurban 0 Dec 7, 2021
read copy update map for golang 1.18+

(R)ead-(C)opy-Update read copy update map for golang 1.18+ How it works This is a simple generic implementation for https://en.wikipedia.org/wiki/Read

Michael Ernst 11 Mar 30, 2022
Experimenting with golang generics to implement functional favorites like filter, map, && reduce.

funcy Experimenting with golang generics to implement functional favorites like filter, map, && reduce. 2021-12 To run the tests, you need to install

null 0 Dec 29, 2021
Map downloader and configurator for KillingFloor 2

kf2-map-config Copy the kf2-map-config.exe and maps.txt into the Killing Floor2

Peter Spiess-Knafl 0 Dec 25, 2021
Q2entities - Parse the entities string from a Quake 2 .bsp map file. Written in Go

Q2Entities A simple command-line utility to extract the entities string from a Quake 2 map file. Entities? Binary Space Partitioning maps (.bsp) conta

null 1 Apr 9, 2022
Goterators - A util library that Supports aggregate & transforms functions Go. Such as filter, map, reduce, find, exist

Goterators Goterators is util library that Supports aggregate & transforms functions Go, including: for-each find exist reduce filter map API and func

Thuc Le 74 May 3, 2022
Slice - provides generic Map, Reduce and Filter functions for Go.

slice slice is a simple Go package to provide generic versions of Map, Reduce and Filter on slices. I mainly wrote it as an exercise to get more famil

Andreas Krennmair 17 May 9, 2022