Search code examples
pythonnoiseperlin-noise

pnoise2() function in noise module produces SegFault python 3.8


I am trying to procedurally generate some maps for a game I am working on, and I am trying to use the perlin noise function from the noise module.

By following some tutorials on the internet, I found out that I had to use it this way:

import random
import noise
from noise import pnoise2

factor = 15 #it doesn't need to be 15, it can be anything different from greater than 1 or lower than -1, otherwise it will return 0.0
oct=1
seed=random.randint(0, 100)


print(pnoise2(x/factor, y/factor, octaves=oct, base=seed))

I can pass it the values x and y but if the factor meets the conditions in the comment, the program will throw a fatal error, segfault, when calling the pnoise2 function. What am I doing wrong?

I am also using pygame for the game, and the exact error I get is the following:

Fatal Python error: (pygame parachute) Segmentation Fault
Python runtime state: initialized

Current thread 0x00007fe3247f2740 (most recent call first):
  File "scripts/world_manager.py", line 78 in generate
  File "main.py", line 153 in reload_chunks
  File "main.py", line 257 in update
  File "main.py", line 207 in run
  File "main.py", line 406 in <module>
Aborted

Here is the generate() function in world_manager.py:

# Generate a chunk at given coordinates using pnoise2 and adding it to the chunk list
    def generate(self, chunkx, chunky):

        # print("Generating chunk at", chunkx, chunky)

        GRASS = "grass"
        MOUNTAIN = "mountain"
        EMPTY = "void"

        floor_void_diff = 0.3
        mountain = floor_void_diff + 0.2

        factor = 3

        floor = {}
        items = {}
        chunk = (chunkx, chunky)

        if chunk not in self.chunks:

            # print("Generating chunk at {}".format(chunk))
            for y in range(chunky * CHUNKSIZE, chunky * CHUNKSIZE + CHUNKSIZE):
                for x in range(chunkx * CHUNKSIZE, chunkx * CHUNKSIZE + CHUNKSIZE):
                    i = pnoise2(x/factor, y/factor, base=int(self.seed))
                    print(i)
                    if i >= floor_void_diff:
                        if i > mountain:
                            floor.update({(x, y): MOUNTAIN})
                        else:
                            floor.update({(x, y): GRASS})
                        spawner = random.randint(-1, ITEM_SPAWN_RATIO)
                        random_item = random.randint(0, len(ITEM_LIST)-1)

                        if spawner == 0:
                            items.update({(x, y): ITEM_LIST[random_item]})

                    elif i < floor_void_diff:
                        floor.update({(x, y): EMPTY})
                    else:
                        floor.update({(x, y): EMPTY})

            self.chunks.update({chunk: {"floor": floor, "items": items}})
            self.unsaved += 1

CHUNKSIZE is defined in a settings.py file, and right now CHUNKSIZE=4


Solution

  • I have not found a way to solve this problem, but an alternative. I turns out that the way I was using the noise module breaks it some how, so I started looking for perlin noise functions and I found a pretty good one at https://rosettacode.org/wiki/Perlin_noise#Python