Therefore, a D that outputs values ~0.5 regardless of the input is supposed to be ‘good’

This isn’t necessarily a flag that your generator and discriminators are amazing. If your Discriminator refuses to adjust itself, then your discriminator fell into a local optimum that it’s unable to escape from.
There’s can be many reasons for this to occur, GANs are notoriously tricky to train. I believe this might be affecting both behaviors you’re noticing.
I would suggest exploring the learning rates you have set, different batch sizes, loss functions, and/or optimizers. I would also suggest logging your losses (both gen and discrim) over time to help provide more insight. You shouldn’t see one model getting better than the other, it should be a consistent switch in the “winner” or a steady chase after the winner. If you see one model slowly winning over time, the training is diverging.