worldies / resin

Solana NFT generative artwork program
MIT License
4 stars 3 forks source link

Error when generating metadata #2

Open jorian opened 2 years ago

jorian commented 2 years ago

Found this repo after a search for generating artwork using Rust and it seems what I am looking for. But I can't get it to work after trying a quick test.

Could not create weighted index, are any odds less than 0?

I tried looking in the code to see what made it not work, but I don't understand what your goal is with the different sets of attributes using "_" and "_key" as keys. It seems that when I run the code using the provided config.example.json , that the so-called 'rawkeys' (`""`) don't make it to the part where a WeightedIndex is made, for example:

    "background": {
      "_": {
        "blue.png": 0.04,
        "brown.png": 0.04,
        "flesh.png": 0.05,
        "green.png": 0.02
      }
    },

Then it crashes because it complains there are no values:

[src/metadata.rs:118] &weights = []
thread 'main' panicked at 'Could not create weighted index, are any odds less than 0?: NoItem', src/metadata.rs:121:10

(I added some dbg! statements, the crash happens when WeightedIndex::new() is called)

Could you explain what the idea is behind your code? Why the use of _ and _key and _key:alchemist?

EDIT: I see that the underscores basically preclude the names from the eventual metadata that is generated for the NFT, but it doesn't make much sense in the code for me.

Kalissaac commented 2 years ago

Sorry I've made a lot of changes recently and haven't updated the example config to match it. You shouldn't need to use the _ key any more, you can just include your layers in the top-level key such as below:

    "background": {
      "blue.png": 0.04,
      "brown.png": 0.04,
      "flesh.png": 0.05,
      "green.png": 0.02
    },

(This requires the latest version of resin, so please make you install the latest from git (cargo install --git https://github.com/worldies/resin))

The idea behind the _key and _key:alchemist was to match certain entries based on other layers that were rolled previously. In the context of the example config, this means that if the generator selects a value of alchemist when it calculates the _key property, the only available key when it calculates face property will be alchemist-face.png (since it's inside the _key:alchemist subproperty). You definitely don't need to use it, and it will work perfectly fine if you just have a flat layout (like the one below):

        "background": {
            "blue.png": 0.04,
            "brown.png": 0.04,
            "flesh.png": 0.05,
            "green.png": 0.02
        },
        "face": {
            "cyan-face.png": 0.07,
            "dark-green-face.png": 0.04
        },
        "eyes": {
            "egg-eyes.png": 0.3,
            "heart-eyes.png": 0.12,
            "square-eyes.png": 0.02
        },
        "mouth": {
            "block-mouth.png": 0.23,
            "smile-mouth.png": 0.09
        }

I'm going to work on adding better examples and documentation soon, but please follow up if this was unclear or you have more questions!

jorian commented 2 years ago

It was clear, but still failing! I figured out what was wrong though, the guaranteedAttributeRolls are never stripped of their suffix. So either remove the suffix from the config.json or strip the suffix in metadata::generate.

The idea behind the _key and _key:alchemist was to match certain entries based on other layers that were rolled previously. In the context of the example config, this means that if the generator selects a value of alchemist when it calculates the _key property, the only available key when it calculates face property will be alchemist-face.png (since it's inside the _key:alchemist subproperty).

This is quite useful!

Kalissaac commented 2 years ago

Oh that's a good catch, thank you! Definitely looks like I need to expand the test suite.