Friday, April 27, 2007
During the course of game development, most objects rarely get written once. Often we have to revisit them to fix bugs, add/remove features and for optimization. Thus, this article provides a practical method and an effective schedule to ensure your game is completed or otherwise a not-so-wonderful releasable version.
They keep track how much our game is completed.
They mark the completion of important game features.
They are the sub-goals we have to achieve at given deadlines.
- We must work towards milestones
- Milestones MUST NOT be unrealistic, even if it will benefit alot financially or ease expenses.
It is also important to include visible/audible progress in our milestones. We must be able to see/hear the progress we have made (or at least to show it to the management) although it is usually not the case.
Visiblity and Completeness go together.
It is also essential to build working versions frequently, weekly if not daily. However, it is recommended that we show the previous working versions to management if they ask for it, rather than the current version. It is important to show progress and it is necessary to upgrade or rewrite the current code to give another release with significant improvements. In other words, BE AHEAD OF TIME.
We will require some things before we jump into coding.
1. Create a comprehensive design of the game
- characters (if any)
- storyline (if any)
2. Create a big list of all classes that would be used in the game
Divide the list into 3 main categories:
- Core -> the most fundamental, critical, foundational
- Required -> features that define the game, make it playable Core & Required would make a game releasable with minimal features, but not exactly fun
- Desired -> features that would make a game great but not essential
Object Functionality: 4 Levels
- Null version -> initial version. May be compiled but not doing anything useful
- Base version -> shows some functionality, used to show the object's basic behaviour
- Nominal version -> fully implemented, visually accepted, commercially viable
- Optimal version -> ultimate version, state-of-the-art
An application is defined as of release quality if and only if its required features are at the nominal level.
An application is referred to as complete if and only if its desired features are at the optimal level.
Iterative Delivery: Ordering using priorities and levels
- Create null implementation of each object, starting from core than required than to desired.It then should be able to build and run, just without any features implemented.
- Now go back to the core tasks and start writing nominal implementations, then the required.The game should then be releasable. Subsequently, write the nominal implementations for the desired.
- Repeat the sweep from core to desired, writing the optimal implementations till we're done or stopped by external factors
Basically it means this:
Null Implementation: CORE -> REQUIRED -> DESIRED
Base & Nominal Implementation: CORE -> REQUIRED -> DESIRED
Optimal Implementation: CORE -> REQUIRED -> DESIRED
Firstly, we have to provide a definition of a 'good enough' game in order to measure our progress. With the iterated delivery method, we'll solve several problems that will arise such as miscalculating the amount of time needed till delivery. This method will ensure that time will be allocated for code revision and improvision.
As defined in Gamasutra:
The time scheduled for a task is the sum of the times for the null, base, nominal and optimal levels.
Wednesday, April 25, 2007
The Prince of Persia 3 is the climax of the Sands of Time videogames. We will be covering several aspects of the game, including Artistic Direction, Characters and Storyline, Animation and AI, Speed Kill system and Free Form Fighting, and Sound and Music.
In artistic direction, the developers chose an outdoor environment and wanted to invoke 3 main feelings. The first is immersion, and in order to do so, they used real life references to create the Prince’s homeland in
Characters and Storyline
In the game’s Characters and Storyline, they talked about how the prince was the epic hero, and will be struck by the sands of time to transform into the Dark Prince. The Dark Prince intends to assist the prince in reclaiming his throne. The Prince’s friend, Kaileena, acts as a narrator, while Farah, a popular character from past games, will return in the Prince of Persia 3.
In animation, the Prince of Persia series is known for its great animation quality, and this iteration of it is no exception. For AI, the programmers intended to make the prince’s foes challenging, but rewarding to defeat. They wanted to break away from the generic enemy types of other games, and wanted different personalities for each character. For example, they created the Sandgate system, where enemies could call for reinforcements.
Speed Kill System
Innovations like the Speed Kill System were implemented in The Prince of Persia 3. Using well timed button presses, the prince could sneak up on and kill his foe instantly. They used an acrobatic approach to the system, which required strategy to analyze the situation. They also gave the player a choice between fighting and using speed kills. In the free form fighting system, the dark prince uses the dagger of time and chains to perform finishing moves.
Sound and Music
In sound and music, they wanted to evoke the feeling of a town ravaged by war, to immerse the gamer and to give a true
Tuesday, April 24, 2007
My definition and benefits of abstract classes
An abstract class is used as a guideline and lays down a set of rules that a game engine should constrain itself to. Abstract classes is used to standardize code in a game engine making tasks less complicated and more efficient. In my opinion, I feel that abstract classes are a key role in engines be it game engines or program frameworks. By setting a standard, the programmer saves time by not having the need to recode class structures or overloading function parameters.
My definition and benefits of virtual functions
From my understanding, virtual functions are defined by an inherited class. These functions are declared, but not defined in the base/abstract class, but can be used to access variables in the abstract level, via the inherited class. These functions must also be defined by the inherited class in order for the class to function normally. Additionally, virtual functions can be used without definition in the abstract level, although a definition must be provided in the inherited class for this to function.
Advantages and Application of abstract classes and virtual functions
With the above knowledge of abstract classes and virtual functions, it is relatively easy to see the advantage of applying the abstract structure to a game engine or software framework.
One of the advantages would be decreasing the number of parameters in a function of the inherited class. Say, I have the declaration of the base class as such:
Example abstract class
virtual void Attack(Sentient &Target);
Advantage 1: Less parameters
The first advantage of having an abstract class can be seen from the virtual function: virtual void Attack(Sentient Target); Notice that the function only needs to take in 1 parameter, which is basically an object of type Sentient, itself. Knowing that there are 4 standard parameters defined in the base class, (hp, mp, attack_power and damage) we can conclude that any class inherited from Sentient can be specified in this parameter, because they already have the basic requirements of the base class, having inherited from it after all, this in turn reduces the number of parameters required in a class, and makes programming more efficient and time-saving.
Advantage 2: 1 definition for each function
Another advantage of abstract classes is that any class inherited from an abstract class can be specified in the Attack class, giving us no need to overload the Attack function. If we had NOT used abstract classes and instead defined 2 different classes, human and demon, we would have to overload the Attack function to take in different parameters, after all humans can attack demons and can sometimes attack other humans too, right? These may not be a problem if we only have 2 different classes, but imagine a world with over 100 different kinds of monsters and enermies. We would have to overload the Attack function once for every imaginable creature.
By using abstract classes, all we need to do is write the Attack function once, and any class inherited from the base class can be fitted into the parameter specified in the base class's function.
Advantage 3: Different definitions for virtual functions
Finally, note that Attack is a virtual functions. As different monsters attack in different ways, using a virtual function will surely furfill our needs. For example, a human class inheriting from a Sentient class could use the factor damage but not the factor attack_power when attacking, but a monster class could use both the attack_power factor and the damage factor. This gives us a wide range of options, and makes our game more intuitive.
The joys of abstract classes are limitless and to summarize this article, I feel that the use of abstract classes will benefit game engine design and is highly useful to large-scaled games where many entities can exist.
Here is the assignment that was requested from the lesson, it can be downloaded from: http://simian.brankenonline.com/uploads/gdev_abstract_classes.zip.