First question:
According to Epic, put this in GameState.
Then make blueprint Function Library and add “global” functions like this:
Using blueprint interfaces is pointless when you always call same function in object that always is same class and always loaded. So pure cast there is enough.
It also answers your second question: if you always keep that data in same class/actor, interfaces are pointless.
Second question:
I would use dispatchers to tell all interested actors that something changed. Ie. from widgets hook to that dispatcher, and just tell them “hey store state changed!”. Then let them read from Game state what is changed. Ie. each item in shop should know its own merchandise and just read about this one.
Last question:
Yes split buy sell logic from widgets, I generally use widgets only to display stuff, and read state of some variables.
About placing dispatchers. It is tip of iceberg. Unreal is object oriented (DUH), it also loads different actors/widgets in different order. Which means if something is working now, for eg. shop widgets are loaded after data in GameState, and they can get their corresponding items, it does not mean that at some point they will be loaded before GameState data, and as result get null pointers.
ps.
I am creating some game that instead of apples in shop has planets, that are loaded from CSV vile, so they are spawned some time after all is loaded. I assume this also will be case for your shop.
So problem is How widget knows pointer to planet if planet is not yet spawned. Yes chicken and egg all over place. All I am sure from widget perspective, is that GameMode (or gameState) are already there. Easiest solution is to make dispatcher in GameMode that tells everybody “we have real game ready state!”, and another “planets state changed, update self!”.
and last problem: using integer as index to some array that identifies planet, solved problems with accessed none at beginning. But code is much more messy and potentially buggy. So use pointers (references) or map (variable type) for shop items and do error handling when reference is null, or use integers and make -1 error value etc.
pps.
If you ever consider loading inventory for shop from CVS, Json etc. do it as soon as possible, those bugs from loading order will surface. Better fix them at beginning.