Skip to content

Preparing for Generator

The Extended Note Block possesses many custom NBT tags that allow for richer musical effects compared to traditional note blocks. This is particularly useful for generating note blocks in bulk via command blocks or external generators.

NBT Structure Overview

The NBT data of the Extended Note Block is primarily divided into Basic Attributes and Advanced Data (AdvancedData).

Basic Attributes (Root)

These attributes are located directly under the root node of the NBT:

Tag NameTypeDescriptionRange/UnitDefault
noteIntMIDI Pitch0-127 (60 is Middle C)60
velocityIntMIDI Velocity (Base Volume)0-127100
sustainTimeIntNote Sustain TimeTicks (20 ticks = 1s)40
delayedPlayingTimeIntDelay TimeMilliseconds (ms)0
fadeInTimeIntFade In TimeTicks0
fadeOutTimeIntFade Out TimeTicks0

Block States

In addition to NBT data, the Extended Note Block uses BlockStates to handle Redstone signals and visual representation.

State NameTypeValuesDescription
pitchEnumc, cs, d, ds, e, f, fs, g, gs, a, as, bCorresponds to the pitch of the current note within an octave (Note % 12). Primarily used for resource packs to change block textures. For example, cs stands for C#.
poweredBooleantrue, falseMarks whether the block is activated by a Redstone signal. Used for detecting signal edges (rising/falling edge).

Note

When placing blocks using setblock, you usually do not need to manually specify pitch. When the block is activated by Redstone, it will automatically calculate and update this state based on the note value in the NBT.

Advanced Data (AdvancedData Compound)

All advanced feature data is stored within a compound tag named AdvancedData. Generators need to construct precise List data structures.

1. Pitch Bend Points (PitchBendPoints)

  • Type: List<Compound>
  • Element Structure: {t: <float>, v: <float>}
    • t (Time): Time point, ranging from 0.0 (start) to 1.0 (end).
    • v (Value): Semitones offset.
      • 0.0: No offset (original pitch).
      • 12.0: One octave up.
      • -12.0: One octave down.
      • Decimals are supported, e.g., 0.5 semitones (50 cents).
  • Interpolation Behavior: The game performs linear interpolation between two key points.

2. Volume Points (VolumePoints)

  • Type: List<Compound>
  • Element Structure: {t: <float>, v: <float>}
    • t (Time): Time point, ranging from 0.0 to 1.0.
    • v (Value): Volume Multiplier.
      • 1.0: Standard volume (determined by velocity).
      • 0.0: Mute.
      • 2.0: Double the standard volume.
  • Interpolation Behavior: The game performs linear interpolation between two key points.
  • Override Rule: Once this list is non-empty, fadeInTime/fadeOutTime in the NBT root node will be ignored.

3. Sound Path (SoundPath)

  • Type: List<Compound>
  • Element Structure: {x: <double>, y: <double>, z: <double>}
    • These coordinates are offsets relative to the center of the note block. For example, {x:0, y:1, z:0} indicates a position 1 block above the note block.
  • Sampling Behavior: Unlike curves, SoundPath does NOT perform linear interpolation.
    • The game calculates the index Index = Progress * (Size - 1) based on the current playback progress and directly takes the position of the corresponding point.
    • Recommendation: If smooth movement is required, the generator should generate sufficiently dense points (e.g., if sustainTime is 40 ticks, it is recommended to generate 40 path points, one per tick).

4. GUI Expression Cache (ExpressionX/Y/Z)

  • Type: String
  • These are merely strings used to echo user-input formulas (like sin(t * pi)) in the GUI.

Important

The game core logic completely ignores these strings. If you are an external generator, you do not need to generate these strings unless you want the player to see specific formulas when opening the GUI. What you need to generate is the SoundPath list above.

Setblock Command Examples

You can use the /setblock command to place an Extended Note Block with preset NBT data.

Basic Example:

mcfunction
setblock ~ ~1 ~ extendednoteblock:extended_note_block{note:64, velocity:120, sustainTime:10}

Advanced Example (including pitch bend):

mcfunction
setblock ~ ~1 ~ extendednoteblock:extended_note_block{note:60, sustainTime:40, AdvancedData:{PitchBendPoints:[{t:0.0f, v:0.0f}, {t:1.0f, v:12.0f}]}}

Important Notes

Relationship between SoundPath and Expression

In AdvancedData, you might find both SoundPath and ExpressionX/Y/Z existing simultaneously.

  • Expr (Expression): Used only for GUI display and editing. The game does not calculate these expressions at runtime.
  • SoundPath: This is the path data actually used by the game when playing sounds.

Key Point: If you are writing a generator, you must generate the SoundPath list data directly. Just writing Expression strings is ineffective; the sound will not move unless the player manually opens the GUI and saves, at which point the client calculates the path points based on the expressions and writes them to SoundPath.

Volume Control Priority

Volume is mainly controlled by the following two attributes:

  1. velocity (Base MIDI Velocity): Determines the base volume of the entire note.
  2. VolumePoints (Advanced Volume Curve): If a non-empty VolumePoints list exists in AdvancedData, it will completely override the effect of the base velocity.

This means if you want to use dynamic volume envelopes (like ADSR), you should use VolumePoints; for simple fixed volume, use velocity.