Say for instance I have a puzzle with 3 switches that need to be in some configuration (say all on) in one room, that opens a door in another, with a load screen separating, so I can't link the switches directly to the door. My first thought was to create a singleton that stored the state of each "solution element" which in this case is the switches, but could be a correctly turned knob, ect. then a given "Puzzle Gate" like a locked door would check the required solution elements to decide it's own state, but I'm hesitant to use singletons for all of the commonly given reasons.

What alternatives do I have to singletons that would give me the same or similar control?

  • 1
    \$\begingroup\$ Any static memory allocation can satisfy this requirement. singleton is one of possible implementations. \$\endgroup\$ – Emadpres Oct 19 '14 at 17:54
  • 1
    \$\begingroup\$ possible duplicate of Best way to store game-wide variables \$\endgroup\$ – Seth Battin Oct 20 '14 at 4:41

I don't think that you should go with static class members (you didn't mention language but I assume some kind of OOP) because that just hides "singleton" in a different place.

Switch things around so your Game holds a bunch (map, set, list, array, whatever) of these across-room global puzzles. Make it so your rooms can ask the game about a puzzle it's interested in using some kind of identifier.

So instead of the linear setup of EXE->singletonpuzzles->Game->Map->Rooms you end up with a broader game layer EXE->Game->[bunchofpuzzles+Map]->Rooms

Pro: you can have multiple instances of the same puzzle class with different parameters Con: a little extra writing to create each puzzle and way to look them up by identifier

You'll notice that this "bunch of puzzles" could very well be a singleton at global scope instead of buried inside of Game but, like you noted, there are common reasons why this wouldn't be an ideal design.

| improve this answer | |
  • \$\begingroup\$ I'm doing this in unity, so I don't have access to the "Game" class, but would having an object that persisted between levels be functionally equivalent? \$\endgroup\$ – Somkun Oct 19 '14 at 21:43
  • 3
    \$\begingroup\$ If you have a specific environment like Unity and/or language like C# to script you really should phrase your question and add tags to mention that. You'll get way better, Unity specific answers than with a generic software design question. \$\endgroup\$ – Patrick Hughes Oct 20 '14 at 2:20

I think you should keep things simple in this case. The three switch system is a challenge with a solution and this Puzzle has two states, currently solved correctly and currently unsolved (or solved and then reverted to unsolved for some reason [timer?]). So you have a Boolean value and you need to store it somewhere in your game so the door could get it and behave accordingly.

One generic solution would be to make the Door an observer of the Puzzle. So the Door listens to the Puzzle and knows when to open up or close. This could be problematic however since that Door does not exist at all during the puzzle phase. This means the state of the Puzzle resolution needs to be stored somewhere and passed back to the Door somehow.

This is why I would suggest a "delayed Event" system where you store a Hash aka Associative array and send a "message" through that Hash, for instance:

//In the Puzzle class,
    String threeSwitchPuzzle = "The puzzle with three switches";

// After completion

delayedEvent(threeSwitchPuzzle, success);

// Which translates to

Hash[threeSwitchPuzzle] = true;

// Construct the Door with the appropriate puzzle String as a member

// Then when the `Door` is created

if (getDelayedEvent(door.puzzle)) // behave accordingly

I know this is similar to the obvious solution but if you design it in a way that is legible and maintainable it should work for you and save you the trouble of overthinking this. You simply need the state stored somwhere and retrieved from that place later.

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.