Sei sulla pagina 1di 11

Programming Risk Document

Introduction This project will be executed in the November 2010 build of Unreal Development Kit. The choice of engine precludes the necessity of discussing low-level systems, as UDK very robustly handles such problems. Instead, this document aims to elucidate how the game's mechanics and features will fit into the larger systems already in place, with implementation details given where appropriate. Design Goals Though many of the features outlined herein can be hacked together in Kismet by leveraging existing systems, were striving to simplify the level design process as much as possible to facilitate quick prototyping and iteration of puzzles. The goal is to engineer a system wherein designers can add common traps and devices to a level with minimal Kismet scripting. To that end, the most commonly used puzzle elements will be implemented in UnrealScript as self-contained objects which can be flexibly configured by adjusting their properties. This approach not only ensures that level designers can add and adjust these elements gracefully and efficiently, it also guarantees a consistency in the way that the player experiences them. However, a balance must be struck to avoid overengineering. In cases where the additional time spent implementing a puzzle element in UnrealScript would not appreciably improve efficiency in the level design process, we reserve the right to take the quick-and-dirty approach. Examples include a trap which is used sparingly, one used as a monumental setpiece, or one added late in development. In such an instance, it would be more practical to implement the trap in Kismet as a prefab, relying on triggers and events specific to this project to include functionality not accounted for by base UDK classes. Inheritance

The three major classes that form the backbone the project, APGame, APPlayerController, and APPawn, will extend the UT versions of these classes. Borrowing in this way from Unreal Tournament code will allow access to useful and familiar functionality. Unwanted UT-specific methods will simply be overridden.

Performance Computation Very little about our design imposes a significant performance challenge. The most computationally expensive addition will likely be tracking the players movement, and that of his decoys, every frame under certain conditions. However, this behavior is confined to small, isolated triggers and will have a minimal impact on performance even when active. Other features can make full use of events and states to ensure that the performance impact from additional UnrealScript execution will be negligible. Finally, the games lack of AI puts us well below the baseline in terms of UnrealScript performance. Graphics UDK very ably handles low-level systems like rendering. Additionally, the creation of materials and post-processing effects is accessible to artists, and level optimization is handled almost entirely procedurally. Building the project upon the solid bedrock of UDK ensures that these already-solved problems are not likely to present serious technical challenges. Our target system specs are similar to those of UDK itself. Our aim to is maintain 60 frames per second on a benchmark configuration of a 2.80 GHz dual core CPU with 4 GB of RAM and a Radeon HD 3000 series or GeForce 9 series video card. The most important framerate goal, however, is consistency. Memory Speaking in rough terms, our aim is to keep net memory usage below 512 MB at all times. The loading of textures and other assets is handled by UDK without being exposed to the content creator. In addition to overall efficiency in the use of meshes and texture space, our biggest impact on the memory footprint comes from how levels are broken up for streaming. Using oneway gate mechanisms to split up discrete sections of the level will ensure that our memory usage at any given time is kept low, and paying heed to the number of unique meshes used in each level will prevent the memory footprint of individual levels from becoming inflated.

Core Mechanics Traps All common traps will be collected under the base class APTrapDevice. Traps take full advantage of UnrealScripts native state support.

While in its default state, a trap device may be activated via a Kismet action, at which point it enters the Activated state. In subclasses of APTrapDevice, the mechanism of the specific trap is defined in the latent code of the Activated state. After this action is completed, the trap sleeps for an amount of time specified by the cooldown property, and then returns to the default state. Additionally, a trap device has a Disabled state to represent being broken or unpowered. In the Disabled state, the trap may not be activated. The trap can be enabled and disabled through Kismet via a Toggle action. Subclasses of APTrapDevice may implement effects or other specific functionality for these transitions by overriding the BeginState and EndState methods of the Disabled state. If the trap is disabled while in the Activated state, it will finish firing before proceeding to the Disabled state.

APTrapDevice is accompanied by a SequenceEvent which is notified when the trap fires, when the traps cooldown finishes, and when the trap is enabled or disabled. Example Trap: Crusher The crusher is a large, heavy plate suspended from the ceiling by an extendable piston. Whenever the player (or a decoy) is detected beneath the plate, the plate quickly drops from the ceiling and crushes whatever lies beneath. After a short

delay, it then slowly rises back to the ceiling. It is placed in the level with its origin at the point of contact with the ceiling, and it is activated externally by the Activate Trap Kismet action.

The APTrap_Crusher class extends APTrapDevice, inheriting the base functionality described above. Additionally, it contains a StaticMeshComponent for the plate, a SkeletalMeshComponent for the telescoping piston, and a Volume to represent the bounding area that the plate crushes (the kill zone).

The Crusher only needs to override the Activated state and define new latent code to describe the mechanical action of the plate. In this state code, the trap interpolates the position of the plate to move it rapidly downward. Its downward motion is based on two properties: the distance the plate has to travel in order to reach the floor, and the rate of descent. This allows the designer to place Crushers at different heights with only a single property to adjust. The kill zone is a short, rectangular volume which is attached directly below the plate. At a certain point in the plates interpolation, as it nears the floor, the kill zone is activated. During this time, any player or decoy colliding with the kill zone will be killed. After the plate has reached the floor, the kill zone is deactivated and the plate is returned to its initial position.

Triggers The basic functionality for triggers exists in the engine. A typical UDK trigger setup involves two components: a TriggerVolume in the level and a SeqEvent_Touch in the levels Kismet sequence. When a player enters the TriggerVolume, its associated sequence events are notified, and if certain conditions defined by the sequence events properties are met, they are fired, allowing the designer to script consequent events (for example, the activation of a trap device). Decoy Tracking

Our base trigger will need to discriminate between the player and the decoy. When both a player and a decoy are touching a trigger, the trigger needs to act upon touch events from the decoy while ignoring those from the player. When multiple decoys are present in a single trigger, it should respond only to the most recently spawned decoy. This behavior requires the trigger to track actors which occupy it, taking note of Touch and UnTouch events to determine the highestpriority actor and notifying its sequence events accordingly. Position-Sensitive Trigger Another type of trigger is the position-sensitive trigger. In addition to the decoy discernment functionality implemented in its parent class, it will also allow the game to respond to gradual changes in the instigating actors position. Along with simply reporting a reference to the instigator, the volumes associated SequenceEvent will output X, Y, and Z values representing the instigators position within the trigger. For example, in a trigger spanning from X:0 to X:768, an instigator at X:512 will result in a reported X value of 0.667.

This event will fire every frame while an instigator occupies the volume, calculating new position values each frame. These values can be used to drive events or animations that are meant to progress gradually in response to the players (or decoys) movement from one part of the level to another. The Decoy The decoy itself is implemented as a subclass of Pawn, allowing it to take damage and die just like the player. Upon being spawned and initialized, the decoy is passed a heading based on the ViewRotation of the player, so that it will always face the direction the player was facing at the time it was deployed. Once spawned, the decoy can be in one of two states. In the first, it stands in place until its destroyed. In the second, it stands, then runs in a straight line until destroyed.

Spawning The decoy is spawned by a projectile which is fired from a weapon, APWeap_DecoyLauncher. The projectile, APProj_DecoySpawner, behaves similarly to the UT3 Translocator disc. It flies fast and low such that at sufficiently short distances it lands exactly where its aimed. It does not bounce, except off of walls. Upon landing, the DecoySpawner will spawn an APDecoy at the proper heading.

Input Input is handled through the DecoyLauncher weapon. Primary fire launches a decoy which will stand still upon spawning. Secondary fire launches a decoy which will run forward upon spawning. Another mouse button or key, mapped to an exec function in APPlayerController, will recall the decoy. Recalling In order to recall a decoy which has been spawned, the player presses the recall key while aiming in the general direction of the decoy he wishes to recall. When the recall key is pressed, the spawned decoy closest to the center of the players field of view will be notified that it has been recalled, at which point it will despawn. Decoys will also be recalled automatically in either of two circumstances: when affected by a trap which would kill the player, or when the player throws a decoy while already at the limit for deployed decoys. Limits The player is subject to a limit on the number of decoys which can be actively deployed at any given time. This limit is initially one, but it may be increased as the game progresses. If the player attempts to throw a decoy while already at the maximum, the oldest extant decoy will be automatically recalled. The player may begin with only the ability to place the decoy at his feet, gaining the ability to throw longer distances later in the game. Placing the decoy follows the same procedure as throwing it, except that the projectile is initialized with a very low initial velocity.

Other SYSTEMS Death and Checkpoints The players progress will be saved using a checkpoint system which operates on simple passwords encoded as strings. The level will maintain a password variable to represent the players progress, and the variable will be updated via a Kismet action whenever the player reaches a checkpoint. When the player is killed, the map will be reloaded, and the password string will be passed as a parameter of the map URL. Whenever the level is initialized, another Kismet action will parse the password parameter, firing a sequence of Kismet events which will perform the necessary setup for the requested checkpoint, including streaming the appropriate levels, teleporting the player to the checkpoint, and activating other events within the streamed levels. Incidental Audio Incidental audio is any sound played outside of cutscenes and scripted sequences, including narration, radio messages, and the player characters own muttering. A special incidental audio trigger volume will be provided as a simple means of adding these sound clips to the level without requiring Kismet scripting. Queueing

One non-standard feature of this implementation is the queueing of sounds, in order to provide a precaution against players who move through audio triggers too quickly, which would ordinarily result in overlapping dialogue. APPlayerController will contain a queue of incidental audio structs, each of which will specify a SoundCue, the Actor from which the sound will emanate (or none for the player), and a flag allowing the sound to bypass the queue and always play immediately upon being triggered. APPlayerController will also include a method which will check the incidental audio queue. If this method finds that no sound is playing and that there is a sound waiting to be played, it will play the

sound, pop it from the queue, and set a timer for the duration of the sound, after which the same method will be called again. The incidental audio trigger volume will be the most common means of adding sounds to the queue. In any given audio trigger, the designer will specify a list of incidental audio structs to be added to the queue of the triggering player, allowing chained dialogue to be initiated from a single trigger. Whenever a struct is added to the queue, APPlayerController will check the queue as a consequence. User Interface The user interface will be created in Flash to take advantage of the Scaleform GFx middleware. None of the existing UDK interface elements will be retained. The UI consists of two separate parts: the frontend menu and the in-game HUD. Frontend Menu

The frontend menu consists of a level, to serve primarily as eye candy, in which is opened a GFx movie. The movie contains a functioning main menu which allows the player to start a new game, continue from a specific checkpoint, and access a basic options menu. Menu navigation is implemented in Flash, and button clicks will trigger FsCommand events, allowing actions like loading a map or changing display resolution to be handled in the frontend maps Kismet sequence.

HUD The HUD is fairly minimal. Very little information needs to be shown to the player, and what does can be integrated into weapon display or shown only when pertinent. The HUD must also include a simple pause menu which will allow the player to return to the menu. The majority of display-related functions will be implemented in Flash, and APHUD will pass information to the SWF objects via wrappers in their associated GFx classes. Cinematics Because the game is played entirely from a first-person perspective and the player has no character model, cinematic sequences will typically need to play out from a first-person perspective. A latent Kismet action will be used to create a seamless transition from the players field of view to the cutscenes camera. The action, placed between a trigger and a Matinee sequence, will be supplied with a reference to the player, as well as the CameraActor used in the proceeding Matinee sequence. When activated, the action will spawn a CameraActor at the players Location (taking current EyeHeight into account) and ViewRotation, look through it, and interpolate its position and rotation to that of the supplied CameraActor. Upon finishing, the action will relinquish camera control.

Level Structure The entirety of the games playable experience will be housed in one persistent level, making use of level streaming to load in chunks of the level as necessary. In effect, the game will only directly open one map: the persistent level, hereby named AP NeoRoma. The persistent level consists of a single PlayerStart in an unlit black box, as well as the skydome, directional light, and fog actors required for any outdoor segments. Its Kismet sequence contains the entry point for the level and handles the loading and unloading of sublevels.

How levels are to be broken up must be decided on a case-by-case basis, but a few general guidelines should be followed:

No single puzzle should be spread over multiple levels. Level transitions should follow gate mechanisms which prevent the player from seeing into or accessing a previous area. Level transitions should occur only during downtime, and never when the players reflexes are being tested. Level chunks should be large enough to make transitions relatively infrequent.

Naming Conventions and Style In general, UnrealScript naming conventions should mirror those already established in UDK. All new classes should be prefixed with the abbreviated form of the package name (AP). Variable names should be descriptive, with minimal abbreviation. Hungarian notation should not be used except in the case of booleans, which are prefixed with b. Indentation should be ANSI style, with braces on separate lines, aligned with associated control statements, and code inside braces indented.

Potrebbero piacerti anche