Level Exit Gates - Puzzles
One of the three types of Level Exit Gates which prevent players from exiting a Local Map.
These puzzles are designed to generated pseudo-randomly (a jumbled set of preset elements being placed onto a grid) and will be designed to be simultaneous/turn-based withplayers are forced to work together to solve it.
Inspiration for the puzzles comes in part from Keep Talking and Nobody Explodes and We Were Here Forever.
Essentially: one player can see the controls to the puzzle while the other player can see the actual moving parts of the puzzle.
Shown below is a puzzle in We Were here Forever seen from two different players perspective. The player on the left interacts with controls which will cause components of the door in front of them to move, while the player on the right interacts with a book displaying the order of symbols in each layer of the rings on the door on different pages. Both players must communicate clearly what they are seeing in order for them to solve the puzzle; the player on the right must explain the current position of the symbols they can see and what controls they have access to, while the player on the left must explain what the book is showing them and where to move the symbols in order to match that picture.
Our puzzle format would use basically the same approach but with a third player required. One player would be able to see the solution, another the controls to manipulate the moving parts of the puzzle and the last player the results of the controls being moved.
Where our puzzles would potentially differ would be the ability for players to leave one station and go to another. A puzzle could potentially be solved with only two or three players, but doing so would be less efficient.
Above: simplified concept diagram of the puzzle and the different views that the players can see while interacting with the different PuzzleStations
General Puzzle Explanation:
Player A can see Solution
Has to Communicate to Player C where MovingParts should finish
Player B has access to Controls
Has to tell Player C what buttons they have & what they look like
Player C can see the Moving Parts
Has to tell Player B which buttons to press to get to solution
Potential variation: the solution/sequence to enter for puzzle is discovered through finding things within the map, encouraging explorations.
Another variation: the solutions/sequence is given when resources are donated.
Puzzle Generation & Solving Overview:
For the 'moving parts' of the puzzle which Player C can view from the relevant Puzzlestation a script called GridGenerator would use a logical algorithm to spawn in pseudo-randomly selected prefabs into a scene within a grid arrangement. The grid itself would be 8x8 and the prefabs would be internally consistent CellContainer consisting of 4x4 cells. The interior layout of each CellContainer in the prefab list would vary but when arranged on the grid would always contain a valid path from any starting cell to any other cell.
The pseudo-random generation would consist of spawning in four predetermined CellContainers called EndPoint. These nodes would contain EndPoint script components in what would be the corner Cells, which would be responsible for checking if the correct PuzzlePiece object was present within the Cell. Each time the grid was generated the four EndPoint scripts would randomly be assigned as A, B, C or D by the GameManager script.
The remaining slots in the grid would be filled with randomly selected GridCell prefabs, and four of the Cells within the grid would then be randomly selected as the starting point for the PuzzlePiece.
Once the grid is generated and the CellContainer, EndPoint and PuzzlePiece objects instantiated, the position of each object is broadcast and received by the PuzzleSolution script. This script takes that information and creates the visual representation of the puzzle solution for Player A to view. This process is simpler, as it just takes the locations of all the components generated by the GridGeneration script and instantiates prefabs displaying where the EndPoints are and which PuzzlePiece they require on them.
For Player B's controls there would be a script (PuzzleInput) handling their inputs. They would have access to four arrows (up, down, left, right) for moving the selected puzzle piece and two smaller arrows for switching which puzzle piece they have selected. The PuzzleInput script would be responsible for broadcasting Player B's inputs, which the PuzzlePieces would received and act on if able (for instance, if the player tries to move PuzzlePiece(A) 'up' but that movement is blocked, the PuzzlePiece simply would not move.
A PuzzleManager script would be present on a game object and handle the logic for the entire puzzle solving process.
Script Components Required
The technical implementation of the puzzle system would involve several script components.
GridGenerator
This would be attached to a prefab component able to be placed into a scene which would generate a 2d grid of empty game objects (CellContainers) within the scene at specified coordinates. Size of the grid (height/width) would be adjustable from the editor, as would the spacing between each CellContainer.
CellContainer
This script would attach to a prefab component which the GridGeneration script would instantiate while generating the grid. The CellContainer script would be responsible for instantiating the Cell prefabs, with the CellContainers at each of the four corners of the grid being EndPoint variants (each CellContainer would have an enum variable of Regular and EndPoint.
If a CellContainer is an EndPoint it would utilize code responsible for checking if the correct PuzzlePiece object is in the correct position, sending out an event when the correct piece enters it which toggles a bool on the PuzzleManager to true. If the PuzzlePiece leaves that position then another event is sent out which toggles that bool on the PuzzleManager to false.
PuzzlePiece
This script would be attached to prefab puzzle objects and have an enum variable identifying them as A, B, C or D. They'd contain a public method which returns that enum, a public method for moving a single grid position up, down, left or right and a public method which checks if there is a valid position to move to in the indicated direction.
PuzzleManager
A script which would call methods from all the other scripts in order to handle the puzzle generation and solving process. Would call for the GridGenerator to create the grid and receive the signals from the EndPoint CellContainers toggling the four bools indicating the four puzzle pieces are in the correct spot. Once all four bools are set to true the PuzzleManager would call the LevelGate script's state to 'allowed to leave'.
PuzzleSolution
A simple script which would just contain a method which takes the position of the EndPoints and their identities then instantiate objects for Player A to see the solution.
PuzzleInput
This script handles sending out events instructing the 'selected' PuzzlePiece to move in the indicated direction. It would contain an enum for which PuzzlePiece is currently selected (A, B, C or D) and a method for switching between those enums in either 'direction' to match the UI. There would be a method which also updates the UI according to which enum is currently selected.