Party Penguins — The Generative Process

Party Penguins
4 min readAug 13, 2021
Party Penguins

If you would like to understand the gist of building a generative NFT project, this tweet is the best to understand the process. This article goes slightly in depth on the development process we followed for Party Penguins.

So overall, the steps are as follows

  • Get all the asset files properly segregated and named(coded names)
  • Define and fix a trait distribution config(rarity of traits)
  • Use the trait distribution config to generate 10k dna’s
  • Generate images(combine all assets as given in a dna) for each dna generated in last step

Each step uses a set of input file/s and generates a set of output file/s which helps keep the whole process modular. We also followed strict naming conventions for traits, output files and folders etc. which made it easier to code it all out.

Note: This article only talks about the generative pieces we have, we created some 1/1 unique pieces which have some special traits not found in the generative pool.

Step 1 — Asset files

So it all starts with the asset files. You need the components(png’s) of the art piece properly labelled and segregated.

A Party Penguin has the following traits

  • Background(7 values)
  • Face(8 values)
  • Eyes(30 values)
  • Beak(13 values)
  • Cheeks(14 values)
  • Hat(84 values)
  • Clothes(82 values)

So all the asset files were organized in the following directory structure.

assets directory structure
The assets folder has a folder for each component. Component folder names start with a no.(indicates the z index of the trait) followed by the name of the trait/component.The body component was used as a separate asset for generation, but as there was only 1 value for this, this did not become a final trait of a Party Penguin.

Step 2 — Defining the rarity config

We created a traits_config.yml file to define the probability/rarity of each trait value in a particular format.

Each trait has it’s own section which lists all possible values(including NONE) for that trait along with the probability. The sum of each trait section should be a multiple of hundred(100, 200, 300 etc.).

So, in the above example, probability of bkg04 appearing in the pool is 14/100.

Also, the order of trait sections is the same as the z-indexes. So background comes first, then body, then cheeks etc. Here is the complete config file we used for rarity distribution.

Step 3 — Generating a pool of DNA’s based on a rarity config

The input for this step is the traits_config.yml file generated in the last step, and the output is a dna.csv file containing the dna for the complete pool of penguins.

So, let’s first start with what a dna is. DNA is simply a shorthand for different trait values a penguin is composed of. For example, Penguin #2347 has the following properties and dna.

{  
"Background": "Red",
"Cheeks": "Mole",
"Eyes": "Angry",
"Beak": "Cute",
"Face": "Eye Patch",
"Hat": "Bamboo Hat",
"Clothes": "Ocean"
}
dna:bkg01--body01--cheeks13--Eye02--Beak04--face10--hat47--clothes80

We used coded values for traits in the generative process which were translated to actual readable names for metadata later. So, bgk01 translates to Red for the Background trait.

The dna.csv had the following format

random generation, not actual file used for the project

We used the following ruby script to generate the dna.csv for N items using the rarities described in the config file. The dna.csv file generated formed the basis for the final images, with a few manual tweaks done to the file later.

generate_dna_simple.rb
The script above is a simplistic version which assumes all trait combinations are valid. The actual version also includes avoiding certain geometrical exceptions while combining the traits.For example, hat29 can't go with eye21, eye24 etc.

If you’re generating the dna.csv using any other method, it’s important to follow the conventions given below as these become assumptions for step 4

  • The headers have exact names as the traits(folders in assets directory) , and the trait values follow the exact names as the files in the assets directory.
  • The order of columns is same as the z-index

To run the script, simply run ruby generate_dna_simple.rb in a terminal.

Step 4 — Generating images from the assets and dna.csv

The input for this step is the dna.csv, and the output is the final png files.

We used python3 and the pillow library to generate all the images.

generate_penguin.py

The script uses multi processing to speed up the process and also has an override flag, which if set to False, doesn’t generate the output files which are already present in the output folder. This is useful when the script fails for some reason and you have to start it again, or when some of the asset files are updated and you selectively run the generation.

To run the script, simply run python3 generate_penguin.py in a terminal.

The above code snippets for image generation can be found in our github repository. Do not blindly copy paste the code snippets, these were modified for demonstration purposes, and are not production level code you can use.

Join the penguin party !!
Website: https://partypenguins.club/
Twitter: https://twitter.com/PartyPenguinNFT
Discord: https://discord.gg/PartyPenguins
OpenSea: https://opensea.io/collection/party-penguins

Follow the team !!
Dev: https://twitter.com/pengwin_potter
Designer: https://twitter.com/rozi_525

--

--

Party Penguins

9,999 unique penguins ready to party in the coolest NFT project.