Skip to content
This repository was archived by the owner on Apr 3, 2026. It is now read-only.

Terrain generation#79

Closed
Dmitry273 wants to merge 19 commits into
Metta-AI:mainfrom
Dmitry273:main
Closed

Terrain generation#79
Dmitry273 wants to merge 19 commits into
Metta-AI:mainfrom
Dmitry273:main

Conversation

@Dmitry273

Copy link
Copy Markdown

Terrain generation based on simplex noise and guided by arbitrary sampling functions + 2 scenarios for cognitive evals: maze and haul + small ASCII mazedrawing script

@Dmitry273

Copy link
Copy Markdown
Author

3r symmetry off-center rotation
5r symmetry rotation+
fn4 P from 0 01 to ~23
fn4_2 Pf0 01t23 exp + fn5_2 Mf0t1 lin
rotating parabolas f0t0 5

Examples of various sampling functions with time parameter for terrain generation

@Dmitry273

Copy link
Copy Markdown
Author

1
2
3
4
5
6
7
8
9
10
11
12
13
14

@Dmitry273

Dmitry273 commented Apr 18, 2025

Copy link
Copy Markdown
Author

14 consecutive generations with fn7 calibrated layer integrated through yaml file

@Dmitry273

Copy link
Copy Markdown
Author

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

16 consecutive generations with new calibrated yaml file

Comment thread mettagrid/config/room/cognitive_evals/mazedrawing.py Outdated
Comment thread mettagrid/config/room/cognitive_evals/terraingen.py Outdated
Comment thread mettagrid/map/scenes/terraingen.py Outdated
Comment thread mettagrid/map/scenes/terraingen.py Outdated
Comment thread mettagrid/map/scenes/terraingen.py Outdated
Comment thread mettagrid/map/scenes/terraingen.py Outdated
@Dmitry273 Dmitry273 force-pushed the main branch 3 times, most recently from dbde94d to ac0c6c8 Compare April 22, 2025 17:44
@berekuk berekuk requested a review from sasmith April 22, 2025 18:21

@sasmith sasmith left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started by reviewing mettagrid/map/scenes/simplex_sampler.py, since it seems like it's at the heart of this diff. The code needs to be more understandable before I think I'll be able to provide the review at the level I want to. I've left comments that hopefully point you in the right direction, and I've asked Slava if he can help you here as well.

I'm excited about the noise generators you're using, and the speed of map generation you've achieved, so I hope we'll be able to get this to a place where we'll be able to use it.

Comment thread .gitignore
player/node_modules
/multirun
.coverage
poetry.lock

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you say more? By default, I don't think we want to ignore this -- I don't think we're using poetry.lock, but on principle, we should be.

@Dmitry273 Dmitry273 Apr 24, 2025

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am using poetry

Comment thread .gitignore Outdated
Comment thread mettagrid/map/scenes/simplex_sampler.py Outdated
The functions take in parameters such as x and y coordinates, width and height of the terrain, and various other parameters that control the noise generation process.
'''

def fn0(x,y, width, height,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These functions should be less mysterious. This would include:

  • Giving them more descriptive names
  • Providing some sort of documentation as to what they add to the output, and how their parameters impact this. (e.g., "this makes the noise more 'swirly'. The direction and tightness is controlled by foo. Bar controls how consistent the swirliness is each rotation.")

Generally I'd prefer for defaults to be in configuration rather than function definitions (defaults values like None are typically better in code than values like 0.1, but it's fuzzy). It's hard for me to be sure what makes sense in this case, but if we're going to have constants in code, we should have some documentation around why these are appropriate defaults.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default values sort of represent the least distorted version of a sampling function, I've added them for myself to not forget what parameters generate the "normal" result, I've added description for those reasons in now separate file with all sampling functions

Comment thread mettagrid/map/scenes/simplex_sampler.py Outdated
Comment thread mettagrid/map/scenes/simplex_sampler.py Outdated
import time
'''
This file contains a set of functions that can be used to generate different types of noise patterns for terrain generation.
The functions are designed to be used with the OpenSimplex noise generator, and they can be combined in various ways to create complex terrain features.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(My opinion here may change based on documentation changes elsewhere in the file)

This should come with examples of how the functions can be used / composed. Pointing to example yaml files may suffice.

Comment thread mettagrid/map/scenes/simplex_sampler.py Outdated
Comment thread mettagrid/map/scenes/simplex_sampler.py Outdated
wall_size: int = 1,
seed: MaybeSeed = None,
children: list[Any] = [],
layers: list[Layer] = [], # layers dictate how generated noise is sampled and how the end result will look

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a helpful breadcrumb, but (as per all my other comments), I think this should be expanded. Like, how do they dictate how the noise is generated? How does this interaction with children?

Comment thread mettagrid/map/scenes/simplex_sampler.py Outdated
@sasmith sasmith assigned berekuk and unassigned sasmith Apr 23, 2025

@berekuk berekuk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still figuring out your fix_map algorithm, will comment on it separately.


children:
- scene:
_target_: mettagrid.map.scenes.simplex_sampler.SimplexSampler

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend moving these scenes to separate files. When children[*].scene is a string, it's interpreted as a filename, e.g. ./configs/scenes/simplex/arbitrarily_tiled_lattice.yaml.

Then it would be decoupled from this specific 3x3 RoomGrid layout.

Comment thread configs/game/map_builder/mapgen_simsam_arbitrary_tilted_napkin.yaml Outdated
Comment thread mettagrid/config/room/utils.py
Comment thread mettagrid/map/tests/mapgen_manual_drawing.py
Comment thread mettagrid/map/scenes/simplex_sampler.py
Comment thread mettagrid/map/scenes/simplex_sampler.py Outdated
Comment thread configs/game/map_builder/mapgen_simsam_arbitrary_tilted_lattice.yaml Outdated
Comment thread pyproject.toml
Comment thread mettagrid/map/scenes/simplex_sampler.py Outdated
Comment thread mettagrid/map/scenes/simplex_sampler.py
if out_of_bound(next_pos[0], next_pos[1]):
continue
if terrain[next_pos[0]][next_pos[1]] <= self.cutoff:
current_energy = (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be more readable if you modified energy instead of introducing the new variable.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed them to be more readable, I think you can use one variable, but it will make it less intuitive

Comment thread mettagrid/map/scenes/simplex_sampler.py
Comment thread mettagrid/map/scenes/simplex_sampler.py
Comment thread mettagrid/map/scenes/simplex_sampler.py
Comment thread mettagrid/map/scenes/simplex_sampler.py
distances[current][0] = 0
terrain[int(current[0])][int(current[1])] = 255 # type: ignore I don't know why it shows warnings there, but it works
front.put((current_energy, [next_pos, current]))
front.put((current_energy, [current, previous]))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I very strongly suspect that the previous 3-4 lines are not necessary because you repeat the same thing in the loop below. Can you find how to get rid of the duplicate code?

Comment thread mettagrid/map/scenes/simplex_sampler.py
Comment thread mettagrid/map/scenes/simplex_sampler.py

distances[next_pos] = [current_energy, current] # type: ignore
front.put((current_energy, [next_pos, current]))
seen.add(next_pos)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General thoughts on this algorithm:

  1. The idea is very good, I like it.

  2. The implementation could be clearer, see comments above.


  1. I've been thinking how to adapt it to MakeConnected (which has several issues with it).

I'm pretty sure that the integer terrain could be adapted somehow (and could even be useful - right now MakeConnected treats walls and previously placed objects as having the same weight, and it could be good to prioritize one or another for removal).

But another concern is that MakeConnected has randomness, and that's a nice thing to have.

If want to compare them for yourself, you can check out configs/game/map_builder/mapgen_bsp_plus_connected.yaml as an example, or make your own config that calls RoomGrid with a very fine grid of isolated 1x1 cells, and then call MakeConnected on top of it. MakeConnected works decently on top of BSP; it deletes almost everything from 1x1 RoomGrid because it connects everything to a single area.

OTOH, your algorithm removes the minimal amount of walls, but it turns 1x1 RoomGrid into a boring comb-like shape (I tried it - copy-pasted your code and converted the grid to the terrain and then back). The perfect approach, I think, would produce something very maze-like. Maybe shuffling the directions in your code would be enough, but I'm not sure.

Anyway, this part is not necessary for this PR to go in, just something to keep in mind for the future.

@Dmitry273 Dmitry273 closed this Apr 26, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants