I am currently working on a voxel (Minecraft-like) engine in C++. Almost all of the code (ie. world generation, rendering, user input) needs to access data about the block types. To accomplish this, I created a BlockRegistry class with member functions to register and access BlockType instances. Each BlockType instance has member functions to access all of it's properties (ie. textures, shape). The problem I am having is making sure that all parts of the code have access to this class. Right now, I am passing around a pointer to it, but this increases coupling greatly since, for example, if a class b provides something that class a needs, and class b needs to access the block registry, I need to modify class a and everywhere I am using class a to pass it through.
My first thought was to use the singleton pattern (or a class with all static members), but, from what I understand a singleton pattern should only be used if the singleton does not have any state, which isn't the case because the BlockRegistry stores a modifiable block list. Making this block list immutable isn't an option, because that makes mod support impossible. Additionally, if, somehow, different instances of the game end up running in the same process and require separate BlockRegistries this would be a nightmare to factor out. Should I even be worrying about this?
The other option I am thinking of is to have a single "main" class with members for the BlockRegistry, World (basically an infinite paged array to store all the data in the in-game world), OpenGl engine, and other commonly used features, in which case I can pass a pointer to my main class around. I would then pass a pointer to this class around to all parts of the program, since then adding new commonly used classes is as simple as adding a member to this main class. This also solves the issue of having multiple instances of the voxel engine in the same process.
When I have a class that I need many parts of the program to access, should it be a singleton or passed around with a main class? If it should be a singleton, should I do that in the form of a static class or an actual singleton?