Technical Details 1.1 for Design 1.1
- Version: 1.1
- Date: 2013-03-12
- Author: Kyall Henricksen
- Audience: Programmers, Designers, Artists and Stakeholders
The design of the game creates technological risks for the development as the design creates complexity for which elegant solutions must be found prior to development. The purpose of this document is to outline some simple solutions for intended design features as well as to research the best practices or available knowledge that can be leveraged to achieve the game design while reducing the technological risk. Some features that will be highlighted include random lego blocked levels, narrative driven game play and the rendering issues of the ‘mist’. As of yet this document does not deal with existing architectures or technologies such as which engine or tool set to use, it simply highlights available algorithms or knowledge that can be used to achieve the aspects of the design.
Design Condition: Player Choice
The design requires that the game not be completely linear. The intention is not to avoid linearity, but to allow the player to interact with the environment on their own terms, to provide further immersion. This condition creates problems for the control of game logic. Which will be discussed in the section ‘programming solutions: game logic’.
Design Condition: Lego Block Levels
To meet the design goal of creating re-playability in the game it is desired that the game should have some randomly generated elements in terms of it’s layout and narrative so that when a player replays the game a second time they enjoy a modified experience. As the game play that can have re-playable value added to it is limited to the progression of tasks and challenges, the goal here is to create a series of events when the game is begun that differs with each play through.
As there is an intended narrative and theme to the game, the game does not fit under the heading of Emergent game play, such as a game like Mine craft would. The game would fall under the heading of more scripted game play. Hence the randomisation method that is available is not the procedural generation of a world by set rules, but the design of levels into pieces that can be made to fit together in different orders. When the player creates a new game, the pieces will be fitted together to provide a different challenge to the player. For an example of a randomly generated set. Lets say we have 3 rooms. One room contains a key, the other contains a challenge and the third contains a door. We use this rule as the basis for the generation of a level, and then all we need to do is to swap in and out each room to create a different play through from others. But since the location of the key, the location of the door and the location of the challenge are all scripted items, every player will have a shared experience of the game, this allows us to leverage our narrative and theme into an environment that is randomly generated.
This randomisation however creates problems for programming of the game logic. This problem also arose from the design condition that the player would have some element of free choice in how they progress through the game. The solution to this issue will be dealt in the section ‘programming solutions: game logic’.
Design Condition: Narrative Driven Game Play
The design requires that the mechanics of the game reflect the narrative. This technique has been used in commercial games such as “Spec Ops: The Line”. Critics of the game ‘Spec Ops: The Line’ pointed out it’s clunky controls that seemed outdated compared to more streamlined modern shooters. It was suggested by some critics that this was a deliberate decision by the developers to reflect the games theme. A design goal is to use the same technique but more elegantly. Slightly varying attributes of the mechanics throughout the game to use the mechanics to get the games theme across.
This can be achieved in at least 2 ways. By changing the FOV of the projection matrix (camera) that the game uses. And by modifying the sensitivity of the mouse/gamepad and/or increasing the movement speed tied to the controls of the keyboard/gamepad.
Programming Solution: Projection Matrix FOV
The FOV of the projection matrix, aka camera, is in modern times one of the most commonly varied elements to create more immersion in a game. Many flying and racing games will modify the FOV to communicate to the player the issue of velocity. Some will introduce an element of turbulence to the FOV when a players avatar is moving at terminal velocity or maximum speed, to communicate to the player that they have reached maximum velocity and can go no faster.
Our implementation will not be velocity driven as the game is neither racing nor flying, but we will leverage the same mechanics so that throughout the game the players field of view continues to contract to communicate a height of tension to the player, to communicate a message that ties in with the narrative.
Programming Solution: Mouse Sensitivity
For the purposes of allowing designers to tweak/polish the way the mouse sensitivity is varied throughout the game it is up to the programmers to implement an equation that contains fixed input parameters that the designers can set and have at least one parameter that is varying and is derived from the state of the game.
In order to make it easier for the designers to tweak this mechanic to achieve the effect they want, the mouse sensitivity equation needs to contain a term that eliminates increases in sensitivity caused by the contraction or expansion of the FOV. The contraction and expansion of the FOV will give the player the impression that their input is changing the view point more slowly or more quickly, so this effect needs to be neutralised.
For the neutralising equation: I can’t come up with the equation of the top of my head, but I’m pretty sure it will be derived from visible rads with a given FOV, and rads of rotation with a given input.
Rads rotation = ( base rads rotation ) / ( current FOV / base FOV )
Or something like that.
Design Condition: The ‘Mist’
The mist is an enemy in the game that leaves a trail of darkness behind it and is the constant threat to the player. When the player enters the mist the mechanics of the game change slightly and there are denser areas of the mist that are harder to move through. The changing mechanics as you move through the trail or the mist itself are not main technological challenges. However the rendering of the trail and the mist itself do represent technological challenges.
Programming Solution: The ‘Mist’ Trail
An old technology used by games is the ‘lighting map’ technology. This technology was limited in how dynamic it was, as well as how well it could represent directional lights. It also lacked the ability to cast shadows. This technology is one where an effect of lights was embedded into the vertices of non dynamic elements so that when rendering the lighting would be calculated based off the precomputed lighting values rather than the locations and intensities of the lights themselves.
Taking this technique but with modernisation and with a bit of trickery should allow us to render the mist trail effective. And the resulting method of achieving it is based on how the mist itself behaves. If when we generate the random levels we also generate the path of the mist itself, aka a fixed path mist, then we can embed data into the vertices that tells the rendering pipeline what to do based off a global value ‘mistalpha’ where mistalpha starts at zero and progresses to value 1. We send this ‘mistalpha’ value to the shader, and the shader then uses an equation to determine if an area is in the mist trail or not. This however means that the mist cannot disappear from an area it has consumed, and can not react to player movements.
The other method is if the trail must disappear from an area or if the mist must react to player actions and that is one in which the effect of the mist on different vertices of the environment mesh must be recomputed and the mesh updated according, with each frame. If there are two conditions to being under the influence of the mist, entering mist or leaving mist, then we will only have to update the geometry that is affected by where the mist is moving into and where it is moving out of. We will not need to modify the geometry of the entire level.
The difference between these two techniques is simply pre-processed or computed in real time, and the choice must be selected depending upon the design condition for how the mist is to work.
Programming Solution: The ‘Mist’ Itself
The mist needs to be a visually impressive and foreboding presence. To achieve the kind of quality that will reflect well on the game it will be necessary to render the core of the mist using particle/fluid simulation, particle or volumetric rendering or some combination of these. This represents a great technological risk to the project, as it will most likely require very direct access to the hardware to achieve. Requiring direct access to hardware to achieve a rendering/simulation effect that is specific to our game, may result in the ruling out of many available tools and middle-ware for building the game.
Most fluids used in games are simply 2D surfaces that have a manipulator along a third access to give the impression of a 3D fluid. As we will require a true 3D fluid, the existing rendering techniques in most engines do not apply. When it comes to selecting an engine or set of technology to build the game, we must select one that allows us direct access, using C or C++, to the hardware as well as being able to directly modify shaders and the parameters sent to the shaders.
Thankfully because our visual effect is a mist, we don’t need a particle simulation with millions of particles like you can see here:
A few hundred points on a vector flow graph, driving a volumetric rendering, should be sufficient for the effect we desire.
Programming Solution: Game Logic
It is possible to build the game directly using scripted sequences and standard methods of building game logic but I would not advise it. Given the randomness of the levels it would be impossible to test in all possible scenarios that the game is indeed working without non-progress bugs. It would also be infeasible in managing the logic of the games narrative given the free choices the player has. The options for how the game logic can be programmed are as follows:
- A hierarchy of conditions from the microscopic level up to the macroscopic level that tests the player actions against a game state where each condition handles the progress of the game and this map is generated to match the game map when the world is created.
- An artificial intelligence based approach where a knowledge based agent, otherwise known as a logical agent, is used to handle the games logic.
With the hierarchy set, a class would be created to describe every game condition, and those classes would detect player actions to see if given conditions have been met. When a condition is met, an action will be performed, such as opening a door, so that the player can proceed. The next level up in the hierarchy would determine if the player has completed a set of tasks for a section of the game, and the next level up in the hierarchy would determine if the player has achieved a success state where the final level of the game could commence.
A condition class, other than having unique code for each condition, will also have a set of children, if applicable, as well a sibling, if applicable and a parent, if applicable. When the player has reached a condition success state for one condition, the sibling condition would then be activated. When no sibling condition is met, the parent condition would be activated. And when a condition is entered, the game actually navigates down to the lowest level child condition of that condition, if that condition has not already been met.
The flaw in this design is that this creates a linear pathway through the game in its ( the systems ) most basic state. The game can be made to have multiple pathways through some hard coding, but as the multiple pathways are not compatible with the design in earnest, this limits the number of free paths the player has to progress through the game.
The benefit is that this system matches well against randomly generated levels by blocks, where many levels of multiple pathways are not a requirement.
This system can be seen as a normal, industry standard, based on the thinking behind it, solution to this problem.
The alternative is to use an artificial intelligence to control the game logic.
If we were to create an artificial intelligence to play through the game itself, that artificial intelligence would need to know the goals, such as proceed through a door, the microscopic goals, such as collect a key so that the door can be opened, and would solve the problem of succeeding at the game, in the same way the player would. This means that we can create an artificial intelligence that can be used to control the game logic. The artificial intelligence would know that a door needs a key, it would know that it needs to complete certain sections before it can proceed to the main goal. It would serve as a nice replacement to any other game logic system.
Artificial intelligences are designed to succeed in conditions even when there is an element of randomness or the unknown, building an AI to control the games logic will allow the games logic system to react to the randomness, the players free path through the game, with a great amount of code simplicity.
The benefit is that the AI doesn’t need to be strictly constructed or built. It supports the ability to create randomised levels that do not need to follow a linear chain. The impact this solution has is code simplicity as well as freedom for the designers to create a non-linear game that engages the player more.
Both of these solutions are sufficient for creating the game. I am however in favour of the AI.