Inspiration

Both our name and idea come from Nintendo's game Super Mario Brothers. Nguyentendo is a play on the word Nguyen and our platformer has some Mario-based physics ideas.

What it does

Nguyentendo is a platformer game that takes place at OU, which has you traverse through several unique environments and numerous enemies.

How we built it

Nguyentendo was developed in python with the pygame library, integrated with numerous other libraries and frameworks. For instance, it utilizes Twilio, OAuth0, and MongoDB Atlas.

Movement

The Player's movement can vary, but it is bounded by our collision mechanic. Each character has a rectangular box that has unique interactions with each one of the game's entities. For example, if the Player hits a wall from the right side, we ensure that the right side of the player box is always touching the left side of the wall to sure that we don’t clip through the walls. We use the same algorithm to prevent passing through the floor, as well.

The Player's movement is dynamically determined by a movement vector, which can be manipulated by a variety of factors. For instance, we have implemented gravity as a constant downward force in the y-direction, as well as semi-omnidirectional movement (whether through horizontal or vertical motion).

Another unique movement technique that we include is a Dash mechanic. This allows the Player to have a higher skill ceiling, by allowing them a finite number of short instantaneous bursts of motion.

Environment

The level environment is based on the floors of the Devon Energy Hall. Each one of the five levels of the game represents a different floor of the Devon Energy Hall.

Photography

We used photographs of the Devon Energy Hall as some of the backgrounds in our levels. We took pictures of the four accessible floors to use as environments. We also pixellated these photos to correspond with the 8-bit theme.

World One

World Two

World Three

World Four

World Five

Level Design

Since this game is meant for demo purposes, the first two level were aimed to demonstrate a more complex testing of the controls. The last few levels are meant for coding testing purpose to see if our code was working. For future reference, we will be turning all the levels into more complex levels with increasing difficulty as you progress through each.

Tiles

The Tiles are an integral and foundational piece in order to make our game come to life. Each character, powerup, and wall/floor are all made from Tiles. Each tile has a fixed size to ensure symmetry within the game.

Stairs

The Stairs represent the transition to the next level. When a Player collides with Stairs a cutscene begins and finishes before moving on to the next Level.

Stairs

Stair Cutscene

Characters

Sam

Sam (also known as the Player) is the protagonist of the game, which the user will control.

Sam Sprite

Because we would spend the most time with Sam in-game, we created individualized animations for all four character states: IDLE, RUN, JUMP, and FALL.

Sam Animations

Sam has an initial “life” resource of 5. Whenever Sam would take damage from any given source, one “life” point is used, and the level is restarted.

Sam Taking Damage

Anthony

Anthony is the primary antagonist of the game, which the user will battle in the last level

Anthony Sprite

Because Anthony is constantly moving on the x-axis on a solely-horizontal level, we created an individualized “RUN” animation.

Anthony Animations

Because Anthony is the final boss, we needed a way to implement combat. In order for Anthony to damage Sam, Anthony must horizontally collide with Sam. To increase the difficulty, Anthony’s running speed is randomly regenerated within the bounds of 6 and 12, in contrast to the fixed speed of 4 for the Professor enemy.

For Sam to deal damage to Anthony, Sam must jump upon Anthony. Anthony has a “life” total of 3, so Sam must bounce on Anthony 3 times. In order to prevent one instance of contact from counting as multiple points of damage, Sam will automatically jump afterward.

Anthony Damage

When Anthony is defeated, the following cutscene will play.

Anthony Defeated

Josh

After Sam defeats Anthony, Josh will spawn in the center of the stage of the final level.

Josh Sprite

Because Josh does not move, only an individualized “IDLE” animation was created. This serves as the “final” point in the game, with the time being recorded and the game closing upon player contact.

Josh Appearance

Professors

One of the common enemies is the Professor.

Professor Sprite

The Professor only moves horizontally (with its own “RUN” animation), with a speed value of 4. Additionally, they are able to collide with terrain, causing them to turn around and continue moving in the opposite direction.

Professor Movement

The Professor inflicts damage by horizontally colliding with Sam, causing one point of damage as a result.

Professor Damage

To defeat a Professor, Sam must vertically collide with them, causing him to automatically jump again afterwards.

Defeat Professor

Parking Services Officers

The other common enemy is the Parking Service Officer (PSO).

Parking Service Officer

Parking Ticket

The PSO does not move but utilizes Parking Tickets as a ranged weapon to compensate. These tickets have a speed of 6, have their own “THROWN” animation, and they will destroy themselves upon contact with terrain. They have a 1 in 100 chance of being fired from the PSO for any given tick (one millisecond).

Throwing Parking Tickets

Tickets cannot be destroyed by Sam. They will cause one point of damage in the case of any collision with Sam.

Parking Tickets and Terrain

Power Ups

Celsius

One collectable power-up is Celsius. When acquired (through collision), Sam’s speed with be double for the next 3 seconds.

Celsius Power-Up

ChatGPT

The other collectable power-up is ChatGPT. When acquired (through collision), Sam will gain 1 additional usage of his Dash ability.

[ChatGPT Power-Up)(https://youtu.be/rH9vzoBw0xM)

Website

Nguyentendo includes a companion website, which can be found here. Players may create an account, which allows them to keep track of their high score and compete against other players on the leaderboard.

Website

Authentication Flow with Auth0

Authentication was provided by Auth0, which made it very easy to handle users because Auth0’s middleware already handles authentication and statefulness. However, the application needed to determine whether or not a local user account existed in the MongoDB database, as if one does not exist it must be created to store high scores, phone numbers, and so on. This is accomplished by querying the database when attempting to access the user profile. If the user does not have an account, they will be prompted to complete onboarding by entering their phone number.

Authentication

Database with MongoDB

The database was a MongoDB Community Edition database running on Ubuntu 18.02 LTS. As the website is made in Node.js, we used a JavaScript driver called ‘Mongoose’ to interface with MongoDB. We had just one model, User, which consisted of an email, phone number, score, and API key – everything you see in the user profile.

Database

Scores with Twilio

Nguyentendo prompts the user for an API key before play begins. After the game ends, it sends an HTTP POST request to the website with the given key and the number of ticks since the game started. This serves as our score, and lower is better. Every time a score is submitted, a check is performed to see if the submitted score is a new high score for a player. Only high scores are saved to the website. Additionally, a check is performed to see if this score is the new overall high score. If it is, and the previous high score wasn’t set by the same player, the beaten player is sent a text message using the Twilio API to notify them – encouraging them to have another go at Nguyentendo.

Twilio

The API key can be reset on the website. They are generated through node:crypto’s randomUUID function.

Music

For each world, we found five 8-bit/16-bit songs, that we believed to show the game's progressive increase in difficulty - as well as the game's tone.

World One World Two World Three World Four World Five

We do not own rights to these music tracks. They were utilized for a proof of concept.

Additionally, we implemented sound effects for the Dash, Jump, and Damage Infliction events.

Challenges we ran into

Programming the tickets that the Parking Services Officer shoots toward the left proved harder than it look. First off we needed to create 2 separate sprites and have the tickets spawn in front of the Parking Services Officer. The first issue we ran into was that the coordinates were fixed on the screen and not the layout of the map. So the tickets would always spawn on a part of the screen and not in front of the Parking Services Officer which we fixed by changing the parameters for the tickets to always be one tile left to the Parking Services Officer instead of dynamically choosing the coordinates. We also had to make sure that the tickets scrolled along with the screen whenever the Player moved.

Accomplishments that we're proud of

All the character assets that were made were all hand drawn and animated by Sam with the templates provided by Pixalart.com. We are also proud of creating an innovative and new game. The cutscenes were funny and enjoyable to produce as well.

What we learned

We have familiarized ourselves with the pygames library from Python. We also spent a good amount of time tinkering with MongoDB to store our best time, Twilio to send text notification whenever someone would beat your highest score, and Auth0 to ensure user authentication and security.

What's next for Nguyentendo

For future plans, we will create more extensive map designs with different variable difficulties, such as easy, medium, and hard. We’ll also have customizable character custimization. Another idea could be procedural-level generation in real-time.

Share this project:

Updates