I would have modified each variables OP to stop using the voodoo peek / poke code I wrote1 and use a normal function with the added “variable updated” function call. But your solution with shadowed variables is better.
How about losing the magic ordering required to make vp work and instead:
int16_insert_correct_no_of_stars vp[8] = { &scene_state.variables.a, &scene_state.variables.b, .... };
(and at least one const, at least.)
Oh boy, I really dislike C. Alternatively, add a severe warning in state.h about changing the order of the first 8 members.
1 I did feel very chuffed with myself when I figured out how to do that in C.