Overview
Bloody Mary developed by us Team
RoGUE is a 3D first person adventure game developed for the PC using the Ogre3D
Game Engine. Bloody Mary is a game of the horror genre, and is made for players
over 17 years of age. The game will test the player’s ability to solve puzzles
and escape from the dreaded hotel in the mirror universe where a young girl was
once murdered.
In Bloody Mary the players will be
placed within a dark hotel with a limited light source which they must use
wisely in order to navigate to the exit of the hotel. The player’s light source
will help them to see certain areas of the level which will greatly assist in
the solving of puzzles, and also defending themselves from the creatures that
now lurk the halls. The game has currently been developed by us to have three
different level areas.
The player also has a health bar
that represents the amount of times a user can be hit by a ghost. They will be
required to meet certain goals and obtain certain items such as keys to open
different doors. Within the game there are a gone but not forgotten team of
knights who’s spirits now reside in the hotel, these knights will assist and
provide players with valuable information on how to get out.
Game Story
Two daring individuals believed
they were brave enough to recite an old tale, one used to scare children
throughout time. It is said that one who enters a dark room with a mirror and
recites the words “Bloody Mary” three times, will be visited by the ghost of a
young woman who was murdered in a hotel after her eyes were cut out. This
spirit was trapped in a mirror during the Elizabethan time period. This one
mirror was found and brought to a museum where two individuals, believing the
rumours to be fake, recited the words. At first they joked and laughed as
nothing happened in the darkness, but suddenly they heard a shriek of what
sounded like a woman dying, they were then visited, by the demonic girl, who
then dragged them through the mirror to what seemed like a nightmare. They were
brought to the hotel where the girl Mary was killed, given the chance to escape
and test their true bravery. Can they escape?
Artwork
![]() |
Main character concept art |
![]() |
Zombie concept art |
![]() |
Loading screen artwork |
![]() |
Losing screen artwork |
![]() |
Main menu screen artwork |
Team RoGUE Post Mortem Report
We, as a team got together and
discussed how a horror game would be the most interesting idea to make a game
of. Bloody Mary in particular interested us the most, as we were very
fascinated with the folktale of Bloody Mary. We got the idea to make Bloody Mary
after meeting up several times after groups have been formed. We met up at some
of our group members’ house in order to work on the game undisrupted. We
decided to choose this type of game because we thought it would be easier to
program and implement the requirements of a first-person adventure game.
Several of our group members were also very into the horror genre. We met up as
a group every Tuesday and Wednesday in order to create our game.
During
the time working on our horror game, Bloody Mary, there were numerous
challenges and obstacles that were encountered, as well as many things that
fell into place for the team helping the creation process along. A lot of
issues came about because of programming struggles but there were also a few
design challenges with models and the overall feel of the game that needed to
be fixed in order to proceed.
Early
design struggles came with finding a useable theme for the game that was not
only feasible as a horror game, but also realistic in terms of time management
for creating an interesting palette. Since blood and dark tones were a large
part of the theme, the decision to use Elizabethan ornate designs to bring some
eerie elegance into the game was used as a base for the design of Bloody Mary.
There was a blurry line when it came to deciding which era to choose our
reference pictures, from originally causing some overlap of design before the
final theme was implemented. Some of our group members wanted to go with
Elizabethan designs and décor for the level, but others wanted to use something
newer, such as from the Titanic era. This was eventually resolved when we all
decided to go with the Elizabethan décor, especially after a GDW milestone,
where we were recommended to go with the Elizabethan era, as it would suit our
game’s dark and gloomy environment.
A
major design challenge at the beginning for our level was how to create the
level so that the Ogre engine can read it properly. At first our level designer
had created the level using Maya, but it was later scrapped due to how
complicated it was. Every single wall of every room was created using a box,
thus allowing for a large amount of faces, which undoubtly will slow down the
game dramatically. Our second design for the level involved creating a box for
each room, rather than each wall. This reduced the number of faces greatly, but
when we tried to use Ogre to load this level, we found out that Ogre can only
read one texture per object. This proved to be a serious problem, as the room
can only be textured with one texture file, in our case the entire room, even
the walls and ceiling, were textured with a wooden floor texture. In order to
solve this problem, our level designer then created a third and final level to
use, which is similar to the first level he designed, but with slightly less
faces in order to allow for smoother gameplay. This proved to be a success, but
it took a long time for the level designer to texture each cube that made up the
walls, floors, ceiling, and hallways. This method of creating the level worked
well, and pretty soon we were able to see good results with our level being
loaded into the game successfully.
The
next design challenge was to come up with suitable ghosts to use as part of the
horrific feel to the game while working with limited modelling experience and a
simple AI idea behind them. The choice of a ghost and zombie seemed like the
best because of their common scary background and allowed for an effective but
simple gameplay element. Since the models themselves were not too spooky by
modern game standards, the layout of the level was used as an advantage. We implemented
closed quarters to keep the zombies as a main obstacle for the player, while
allowing the ghosts to pass through walls and any other obstacles, surprising
the player when they think that they would be safe. Unfortunately the zombies
were not implemented in this prototype, as we could not get skeletal animation
to work. This is mainly due to the fact that our group did not get a lead
programmer, so our only programmers were our contractor and one of our artists.
The skeletal animations for the zombies and the ghosts would be something to
look forward to for next semester, when we start polishing the features of
Bloody Mary.
After
the levels were modelled and implemented into the game world, simple
first-person movement and controls was introduced. The original design was to
move based on the camera’s direction, giving a simple forward and back control
scheme. This became a problem when it was found that strafing left and right
did not work properly and left the player with having to turn via the mouse of
where they wanted to go. This was fixed by using a Havok vector and velocity to
calculate the player’s position, allowing the player to have proper control
over their movement. The controls for Bloody Mary were mainly derived from
homework questions and sample questions from the Game Engines course. The controls
were one of the first things that our programmers had worked on, and it became
the stepping stone to success for our game Bloody Mary.
Another
problem was that part of the camera collision, when the player had collided
with the wall, would sometimes be able to see through the walls and look into
the next room or outside the level. This occurred because the wall was simply a
thin plane while the camera had clipping if an object was too close. A simple
fix to this error was to make the walls and camera have a larger collision box
so they would not tunnel through each other, preventing them from overlapping. This
was done by increasing the size of the sphere that the camera was attached to. After
many tests, the sphere’s size was finalized, and the player can no longer see
through any walls. We also started off with using a box, but found that it wasn’t
suitable to move around in, so we switched to using a cylinder, which should have
a smaller size, and resulting in better collision and hit detection. After both
the box and cylinder did not work out too well, we decided to go with a sphere,
which worked very well after numerous tests.
When
the particle system was initially being implemented into the world, there was
an error where the code had a duplicate call for updating the Havok world and
crashed the game from running. It took time before the error was caught and
fixed so that there would be no duplicate call. Along with the particle error,
there was also a flaw with the gravity in the Havok world. The particles
initially fell at an accelerated rate since it was imported from an outside
source rather than being created within the Havok world. Reducing the speed for
Havok world worked easily and set the particles at a more realistic rate.
Gravity also affected the player when they collided with objects in the world.
Objects could be pushed around and sometimes were knocked into the air when
colliding with multiple objects. It was noticed that these objects had a reduced
force of gravity applied to them, causing them to float in a supernatural way.
Although this looked eerie and would have added an interesting feature to
observe, it wasn’t correct for the world. After researching the problem, code
was found that would allow proper, functional gravity into the world, fixing
the issue with colliding with objects. It was quite simple; our programmers
added one line of code into the game in order to add gravity to the Havok
world. After adding proper gravity, all objects in the game would fly away properly
when hit and the player would also move properly now.
A
key feature of the game is the lighting system. Since the game focuses on
darkness and using a lantern to create an atmospheric light, it had to be
created exceptionally well to reflect the tone of the game. A major issue
within the world was the use of Maya lighting. It worked well enough until the
light had to be moved and have an updated position; this caused the code to
crash. Instead of using a Maya light source, OpenGL lighting was used. It was
more adaptable and worked better within the code, creating a more realistic
light source for the player while not crashing the code.
When
initially importing texture into the game, since there were several textures,
it was hard to implement them all at once, causing loading errors and for the
game to crash. Trying to load several material texture files at once was the
cause, so to fix this, an add-on for Maya was obtained and used that allowed
all the textures to be saved into one material file and imported as such,
saving processing power and run time speed while it did not crash the game. The
add-on was simple to use, and it took all the textures (lamberts and phongs)
and combined it into one big material file, which can be read by Ogre easily. And
just like that, textures would appear on whichever models in our game corresponded
to each of the textures. Once
When
working with Fmod for implementing sounds into the game, the largest issue was
linking it with Ogre3D. Although there was no huge problem with this, there was
a lot of work figuring out which Fmod files to include (they had different
includes for different computers and different languages), where to place the
files, how to link them and what code to include from the documentation,
including updating the documentation’s code to use the files for our setup. Each
problem was solved in different ways, including reading the Fmod documentation,
observing how Ogre files were included, using the Visual Studio debugger on the
code the documentation provided and looking at Fmod examples provided with the
include files. The next issue with Fmod was working with sound channels. A
problem with coding for Fmod was that a channel didn’t exist if it wasn’t
currently playing a sound. This was a
problem when trying to set a channel’s position to the player’s location every
time through the update, and if the channel was ever told to stop playing, it
would therefore crash the program the next time through the update. This was solved by telling the channel to
“pause” instead of “stop” when it had to stop playing, and only “stop” if it
was immediately given a new sound to play, before it went through update again.
Reading
from files became an issue due to formatting. Formatting the large save file
required for the game was painfully hard and caused crashes when forgetting to
add spaces between numbers read from the file, or tried to insert line breaks
in the file. This problem was avoided, where the programmers decided to not
solve this problem since it didn’t really improve the functionality of the game
in any way. It would merely make it easier for hackers to make hacked save
files. This large issue with reading file names came from comparing strings. The
problem here was essentially that the information read from a file in the form
of a cstring was merely stored as a pointer to a character and a length, not as
an actual string. Therefore, if char This[10] = “Easy” and char That[10] =
“Easy” then This != That; which makes it rather hard to compare the
strings. This was solved by looking
online for C functionality to convert the strings, finding a user written
function that did something similar to what was needed. After being modified, the function did
exactly what was wanted, and implemented it in the game.
AI
became a huge issue since this was a relatively new area to the programmers.
Including the concepts of wander, seek, and safe zones to protect the player
were tricky to implement. The game called for a wander function that was simple,
one that could switch back and forth from seek quickly and definitively, and
kept the ghost somewhat near its level at all times. It was also thought to avoid having the
ghosts to have invisible walls that they would walk into everywhere. To do this the wandering ghosts seek out a
location that was randomly determined and if they got near that location it
would change to a new random location within their patrolling area. For safe zones it was designed to have the
safe zone not completely ghost free, but to have the ghosts not seek the player
if the player was in a safe zone. The
only catch is, if the player gets too close to one of the ghosts inside the
safe zone, the player would still get hurt, which is why they should avoid
going near ghosts at all costs, even if it is inside a safe zone. This, combined
with the wander locations never being placed in a safe zone, would make it
unlikely for ghosts to go farther into safe zones then just the edge every now
and then.
Implementing
the HUD for the game was a task on its own because none of the examples offered
an acceptable example of how to display a HUD, so there needed to be a way to
display an image in 2D coordinates in Ogre.
After searching online for the answer, which pointed towards an “Ogre2D”
engine included in the Ogre3D engine. After reading some example code, the programmers
were able to implement some code to display images in 2D, and by playing around
with the code with the help of intellisense, a way to use sprite sheets with
Ogre2D, allowing for objects like the health bar and lamp to display only one
picture from a sprite sheet at a time. Eventually Ogre2D was used to also draw
the menus.
The game in the later stages of
development took a long time to load, due to the high number of objects inside
our level. To help solve this problem, a loading screen and intro music was
added to make the loading screen seem less boring, and they made the music
change noticeably once the program was loaded, so that if the player/developer
had started doing something else off-screen while they waited for it to load,
they could know when it had loaded just by listening to it.
What we could have done in order to
make Bloody Mary a better game would be to add more levels, had we had more
time to do so. The addition of other levels other than the three default wings
would make Bloody Mary more interesting. The 2D artist could also re-make some
of the textures, such as making the blood on the wall darker, in order to make
the game look more appealing to players. Currently, our textures are fairly
limited, as we didn’t want to complicate the game with so little time on our
hands. The polished version of Bloody Mary was envisioned to have much better décor,
through use of textures, and we are striving to get that done by next semester.
We would also try to add skeletal
animations to the ghosts and zombies, in order to give them a more realistic
look and movement whenever they chase the player or are near the player. We could
be able to make the zombies patrol the hallways in certain areas, in order to
make the game more challenging and yet fun to play. Bloody Mary also has some
basic animations and movement for the ghosts in the level, and it would only be
one step further if we could use the animations that the lead 3D modeller had created
for the ghost model, where she moves her arms up and down and also moves her
spine. All this could have been done had we been able to figure our skeletal
animations, but that will be a task to be handled next year. It would also be a
good idea to make a zombie or ghost boss that the player must beat in order to
proceed with the game. This boss could have minions to support him, but we haven’t
really gotten to this stage yet.
Another thing that Bloody Mary
lacked was having different shaders, which can be used whenever an event
happens during the game, such as a ghost chasing after the player, or during
the boss fight. Our programmers already made it so that whenever the player’s
health gets to one out of three bars, the whole screen will turn a red hue. We could
also have implemented different shaders for different levels in the game, once
we polish the game and have more than one large level.
We had also planned to put a
particle system right inside or under a power-up, in order to let the player
see the item easily. This never got to happen because we never got the Maya
particle system implemented with our game. Instead, the particle systems will
simply show blood dripping constantly from the roof to the floor. These particle
systems are made up of cubes that fall and have a limited lifespan, but are not
as fine as the particle systems in Maya. Also, our programmers did not
understand how to duplicate the particle code, so in the end we only managed to
implement one particle system in the first wing of the level. We will try to
work on getting more particle systems into Bloody Mary once our programmers
figure out the means to create multiple particle systems.
Our sound designer had also wanted
to implement a screaming background sound in order to make the gameplay
atmosphere more dark and scary. There were other sounds that we wanted to put
into the game, but our programmers just didn’t have the time to code them in,
due to the lack of a lead programmer position. Our sound designer also wanted
to improve our sounds by creating our own custom sounds for our game, but that
never happened due to the lack of time and equipment.
Our modellers had also created a
lantern to be carried by the main character, however, it was too hard to do
with the little time they had, so they simply did not code that in. We original
planned to have player’s character carry a lantern in his/her hand. This lantern
can be activated whenever the player uses the light, which can be toggled using
the “F” key. We also wanted to have the player be able to see their hand, and
such animations can be used while opening doors
Another major problem in Bloody
Mary was the movement glitch, where the play will occasionally move even
without pressing any of the movement keys. This usually occurs when the player
presses too many keys at once, and so far our programmers haven’t figured out
how to fix this issue. This issue is definitely on the top of the list after
completing all the requirements for GDW. There is also a similar glitch with
the doors, where if the player presses the “E” key too many times in order to
try to open the door, the door will never close again, and just stay opened for
the rest of the game. These glitches are still a mystery to our programmers,
and we hope that they can be fixed before the game gets polished next year.
Screenshots
![]() |
One of the starting rooms |
![]() |
Blue sword that is required to unlock the final door |
![]() |
Grand room with all the locked doors |
![]() |
NPC in the starting room |
![]() |
Another view of the grand room |
![]() |
Final hallway with zombie corpses |
![]() |
Dead zombies in the second last room (our bottleneck) |
![]() |
Oil power-up |
![]() |
Text written on some of the walls in blood |
![]() |
Health power-up |
![]() |
Ghost AI's that chase the player |
Developer Profiles
Role:
Lead Programmer & Game Designer

Role: 3D Artist, 2D Artist, Texture Artist, Design Documentation

Role:
Level Designer, Character Animation & Design Documentation

Role: Object Modelling, Sound Engineer and Game Trailer Director

Role:
Sound Engineer, Paper Prototype & Object Models

The second contractor of our group,
Robert, volunteered to work on the programming side of the game. Robert’s
skills as a programmer contributed greatly in terms of creating the over
structure of our gameplay. Robert’s skilled can be seen in the active map of
our game that assists the players on where they are located within the level.
He also contributed greatly to programming the AI systems of our NPC enemy
characters. Robert worked alongside Yang constantly to get down the collisions,
gameplay mechanics, HUD implementation and event management programming for our
game.
Game Trailer
Game Download
EXE
EXE