> In the MWE below a custom dynamic is placed under a note; under
> certain circumstances it pushes the next note away while in others
> it doesn't. The spacing is normal if there is no StaffGroup or if
> the note following the one with the custom dynamic is changed. Can
> anyone explain what is going on here?
In such situation I recommend to check whether there are skyline
collisions. Consider the following snippet, which is a slight
modification and extension of your code. Activating
`show-vertical-skylines` for stems doesn't show any additional
information, so I've omitted it here.
```
\version "2.24"
mpleg = \tweak self-alignment-X #-0.8
\tweak show-vertical-skylines ##t
#(make-dynamic-script
#{ \markup { mp \normal-text \italic legato } #})
MIa = { c''4\mpleg b' b' b' }
MIb = { c''4\mpleg c'' b' b' }
MIc = { c''4\tweak Y-offset #-3.2 \mpleg b' b' b' }
MII = { b'4 b' b' b' }
\new StaffGroup <<
\new Staff \MIa
\new Staff \MII >>
\new StaffGroup <<
\new Staff \MIb
\new Staff \MII >>
\new StaffGroup <<
\new Staff \MIc
\new Staff \MII >>
```
As can be seen in the first system, LilyPond vertically positions the
dynamic script object as near as possible to the first note while
maintaining some padding inbetween. As a consequence, it has to move
the next note to the right so that there is no collision.
In the second system you can see that by pure luck the stem for pitch
c'' is short enough to fit into the ragged skyline (while maintaining
the padding). However, the horizontal spacing is still distorted.
The third system moves the dynamic script down to avoid any skyline
collisions; the distortion is gone.
A corollary of the issue at hand is that LilyPond doesn't position a
dynamic script in a second pass (i.e., after all notes, stems, and
beams have been processed). Instead, it does that in the first pass
while walking over the music from left to right, and objects that
would collide are shifted to the right if necessary.
Werner