Oubliette is a 2D tile-based world exploration game, complete with its very own world exploration engine made from scratch. The world exploration engine will build a world, which the user will be able to explore by walking around and interacting with objects in that world with an overhead perspective. This project has been adapted from my final project for CS61B.
Each world is pseudorandomly generated using a unique seed which can be decided & saved by the user. It should be able to handle any positive seed up to 9,223,372,036,854,775,807. There is no defined behavior for seeds larger than this.
The name Oubliette comes from French & is defined as a secret dungeon with access only through a trapdoor in its ceiling, similar to the context of the game. The task is to to collect sixteen orbs and reach the gate within eighty seconds. It is currently hosted on Itch.io, a game hosting service.
Oubliette.mp4
This section explains the interactivity aspects of Oubliette in greater detail. The reasoning & the purposes of the members of every class are explained in the files itself.
View more information on the Title Screen.
This screen shows the title of the game & the relevant menu options: start a new game, load a previous save or save & quit. If the user chooses to load a new game, the user can input their desired seed. This seed is then used pseudorandomly to generate a world (ie: the same seed will always generate the exact same world each run).
View more information on seed & username inputs.
These screens asks the user for their desired seed & username. The seed can be any integer & the user denotes the end of the seed using an 's'. The username can be any valid keyboard input, '.' denotes the end.
View more information on gameplay & controls.
Using the seed, a world is generated, placing the sacred Orbs & Gate in random positions. The user is then placed on a random FLOOR tile & the countdown timer starts. The user controls the character using the "WASD" keys & picks up the orbs by going towards the tile. Once all the orbs have been collected, the user has to go towards the Gate to win the game within the time limit to view the "Win" screen, where their time & seed is shown. If the user is unable to collect all the orbs & reach the Gate, the "Lose" screen is shown.
This project uses StdDraw to handle user input. This results in a couple of limitations:
- StdDraw does not support key combinations. ":Q" means ":" followed by "Q".
- It can only register key presses that result in a char. This means any unicode character will be fine but keys such as the arrow keys and escape will not work.
View more information on the Heads-up display (HUD).
The HUD provides additional information that is useful to the user. This is split into 4 components. The description of a given tile when the user mouses-over a tile, the username chosen by the user, the time left & the number of orbs collected.
View more information on saving & loading.
Oubliette has the ability to save the state of the world while exploring, as well as to subsequently load the world into the exact state it was in when last saved. When the user restarts Oubliette and presses L, the world loaded is exactly the same state as it was before the world was terminated. The command “:Q” saves the data to world_save.txt which is created in the current working directory and completely terminates the program. The user is shown a "successful save" screen upon saving.
Above is a visual representation of how the the Algorithm works, relying on a simple set principles. The pseudorandomness is created by passing the seed the user chooses to a Random
object which outputs the sequence of random numbers which is then used to generate the World.
Firstly, the World is split into five sectors. Each sector has one room drawn by default by drawRoom()
at a random x-coordinate & a 50% chance for a second room to be drawn, decided by drawSecondRoom()
. Every room's top left coordinates are added to rooms
, a RoomTracker
object. After all the possible rooms for every sector has been drawn, the rooms are connected sequentially using drawLink()
to generate the hallways.
The edge cases caused by these functions are rectified using fixEdgeCases()
before finalising the 2D TETile array in worldFrame
.
Do note that more expansive Worlds can be generated just by tweaking the constants ROOMMAX
& ROOMMIN
, although the stability of this has not been tested.
View some generated Worlds & their respective seeds.
-
Pattern Pixel Pack by Kenny: This pack was adapted to create the 16x16 tile assets.
-
StdDraw by Princeton University: This was used to render the world & used as an interface for user input.
-
The Archon tile from NetHack's Wiki: This 16x16 asset was used to create the character used in Oubliette.
-
Download the game from Oubliette's Itch.io page.
-
Download this repository & run this project using an IDE, such as IntelliJ IDEA.
Oubliette provided a point of growth, as the goal of this project was to teach myself how to handle a larger piece of code with little starter code in the hopes of emulating something like a product development cycle. Since there is no notion of “the correct answer” when it comes to world design and implementation, a great deal of exploration and experimentation was required for such an open-ended project. I learnt that it is okay and expected to go through several iterations before settling on something that I deemed good. That is, this project is about the fundamentals of software engineering.