Generation Rules

Understanding how BeatBlocks generates music

What Are Generation Rules?

Generation rules in BeatBlocks define how your musical composition is created from your stems and template. These rules govern which stems are selected, how they're combined, and how the overall arrangement is structured.

The generation process in BeatBlocks is deterministic, meaning that given the same inputs (stems, template, and seed), it will always produce the same output. This is crucial for creating reproducible musical experiences on the blockchain.

Key Concepts

  • Deterministic generation based on seed values
  • Group and mutex constraints for musical coherence
  • Template-driven arrangement structure
  • Weighted selection for controlling stem frequency
  • Reproducible results for blockchain inscriptions

Generation Configuration

The generation process is controlled by the generationConfig object in your BeatBlock JSON:

"generationConfig": {
  "seed": "0x3f7a912e",
  "groups": ["v1", "v2", "v3", "drums", "bass", "lead", "fx"],
  "mutexes": ["percussion", "basslines", "melodies", "effects"]
}

Seed Values

The seed is the starting point for the random number generator that powers the generation process.

  • Numeric seeds:

    Integer values (e.g., 12345)

  • Hexadecimal seeds:

    Hex strings (e.g., "0x3f7a912e")

  • Text seeds:

    Any string (e.g., "my-awesome-beat")

  • Special values:

    "random" for non-deterministic generation

Groups and Mutexes

These define the organizational structure for your stems:

  • Groups:

    Categories that stems can belong to (e.g., "drums", "bass", "v1")

  • Mutexes:

    Categories where only one stem can be active at a time (e.g., "percussion", "basslines")

Groups and mutexes work together with your template's inclusions and exclusions to create musically coherent arrangements.

The Generation Process

Understanding how BeatBlocks generates music helps you design more effective templates and stem collections. Here's a simplified overview of the generation process:

  1. Initialize the random number generator with the seed

    This ensures deterministic results for the same seed value.

  2. Process the template sections

    For each section in the template, the generator determines which stems to include.

  3. Apply inclusion and exclusion rules

    Filter stems based on the groups specified in the section's inclusions and exclusions.

  4. Enforce mutex constraints

    Ensure that only one stem from each mutex category is selected.

  5. Apply weighted selection

    Select stems based on their weight values, with higher weights being more likely to be chosen.

  6. Generate the final arrangement

    Combine all selected stems into a complete arrangement with precise timing.

How Stems Are Selected

The selection process follows these rules:

  1. First, all stems are filtered based on the section's inclusion and exclusion groups.

    // Section definition
    {
      "length": 8,
      "layerCount": 4,
      "inclusions": ["drums", "bass", "v1"],
      "exclusions": ["v2", "v3", "vocals"]
    }
  2. Next, the generator selects stems up to the specified layerCount, respecting mutex constraints.

  3. If multiple stems from the same mutex category are eligible, only one will be selected.

  4. The selection is deterministic based on the seed value, ensuring reproducibility.

Advanced Generation Techniques

Once you understand the basics, you can use more sophisticated techniques to create complex generative compositions:

Variation Groups

Create consistent variations across your composition:

// In generationConfig
"groups": ["v1", "v2", "v3", "drums", "bass", "lead"],

// In your stems
{
  "id": "kick_pattern_v1",
  "groups": ["drums", "v1"],
  "mutex": ["percussion"]
},
{
  "id": "bass_pattern_v1",
  "groups": ["bass", "v1"],
  "mutex": ["basslines"]
},

// In your template
{
  "length": 8,
  "layerCount": 5,
  "inclusions": ["v1", "drums", "bass"],
  "exclusions": ["v2", "v3"]
}

This ensures that all "v1" stems are selected together, creating a cohesive variation.

Progressive Complexity

Build arrangements that evolve in complexity:

// Template with progressive complexity
[
  {
    "length": 4,
    "layerCount": 2,
    "inclusions": ["drums", "bass"],
    "exclusions": ["lead", "fx", "vocals"]
  },
  {
    "length": 8,
    "layerCount": 4,
    "inclusions": ["drums", "bass"],
    "exclusions": ["vocals"]
  },
  {
    "length": 8,
    "layerCount": 6,
    "inclusions": ["drums", "bass", "lead", "vocals"],
    "exclusions": []
  },
  {
    "length": 4,
    "layerCount": 3,
    "inclusions": ["drums", "fx"],
    "exclusions": ["bass", "lead", "vocals"]
  }
]

This creates a progression from a minimal intro to a full arrangement, then a breakdown.

Complete Generation Example

{
  "details": {
    "title": "Generative Composition",
    "author": "BeatBlocks Creator",
    "bpm": 120
  },
  "generationConfig": {
    "seed": "0x3f7a912e",
    "groups": ["v1", "v2", "drums", "bass", "lead", "fx", "ambient"],
    "mutexes": ["percussion", "basslines", "melodies", "effects"]
  },
  "template": [
    {
      "length": 4,
      "layerCount": 2,
      "inclusions": ["ambient", "fx"],
      "exclusions": ["drums", "bass", "lead"]
    },
    {
      "length": 8,
      "layerCount": 4,
      "inclusions": ["drums", "bass", "v1"],
      "exclusions": ["v2", "lead"]
    },
    {
      "length": 8,
      "layerCount": 6,
      "inclusions": ["drums", "bass", "lead", "v1"],
      "exclusions": ["v2", "ambient"]
    },
    {
      "length": 4,
      "layerCount": 3,
      "inclusions": ["drums", "fx"],
      "exclusions": ["bass", "lead"]
    }
  ],
  "layers": [
    {
      "id": "kick_pattern_1",
      "loopLength": 2,
      "path": "/content/<INSCRIPTION_ID>",
      "volume": 1,
      "loop": true,
      "alignment": "start",
      "groups": ["drums", "v1"],
      "mutex": ["percussion"],
      "weight": 2
    },
    {
      "id": "bass_pattern_1",
      "loopLength": 4,
      "path": "/content/<INSCRIPTION_ID>",
      "volume": 0.9,
      "loop": true,
      "alignment": "start",
      "groups": ["bass", "v1"],
      "mutex": ["basslines"],
      "weight": 1
    }
    // Additional stems would be defined here
  ]
}

This example shows a complete BeatBlock with generation configuration, template, and stem definitions. When processed with the specified seed, it will always produce the same musical arrangement.