- Sataponn Phutrakul โ @nropatas
- Ekaterina Shmeleva โ @shmeleva
- Felipe Gonzalez Carceller โ @speedyjr
The goal is to develop an online game store where (1) developers can publish and sell games and view statistics for games and (2) players can search for games, purchase games via an online payment system, launch and play games, leave public comments for developers and other players, and view leaderboards for individual games.
200 points
- Signing in and logging in and out are implemented with the Django authentication system;
- We send a verification link to the email address used to sign up using console backend during development and SendGrid in production. The user must verify the email address before they can access their account.
- We also integrated Google sign-in into the app (see 3.2).
300 points
Players can:
- Search games and filter games by genre and ownership, which is implemented with AJAX so that the user does not have to press the Search button for filtering search results and the page is not reloaded every time the user refines their search results;
- Purchase games via an online payment system;
- Launch and play games;
- View leaderboards for individual games;
- View their own latest and high scores for individual games;
- Leave public Facebook comments and share games on social media (see 3.2).
- Players are only able to play games they have purchased: however, we deliberately do not protect against accessing games through their URL as it is not included in the scope of this project;
- Players are not able to publish games;
- Etc.
200 points
Developers can:
- Publish, remove and manage games, including setting and making changes to its URL, description, categories, image and price;
- View sales statistics including a revenue graph, which is implemented with FusionCharts, and detailed game purchases (pending, canceled, failed, successful).
- Developers can only view, modify and access statistics of their own games and are not be able to impersonate other developers;
- Developers cannot play games;
- Etc.
200 points
- The game runs in the
iframe
. Once it is over, the score is posted from theiframe
that holds the game to its parent with thewindow.postMessage()
. Then, the score is posted to the backend using AJAX. The latest and high personal scores and global high scores are updated accordingly.
90 points
-
We did not comment each and every line because good code should be self-documenting and that is what we were trying to achieve. Yet, we use comments where necessary, e.g. for providing a description for methods.
-
In order to allow better modularity, we use separate applications for different models, e.g.
games
forGame
model,purposes
forPurchase
model, etc. All logic, forms, templates, styles are placed in corresponding applications. Furthermore, we have an additional application for RESTful API. -
In order to achieve better code reusability, we use custom
Manager
s andQuerySet
s for querying games, purchases and results. -
We include and extends templates to achieve better reusability and readability. For example, all the pages contain the same navbar โ we use template inheritance for that; the Game page contains a couple of different logical blocks (description, leaderboards) that are defined in separate files and included in the main template. We also use template tags for the Game action button (Buy, Play, Manage) that can be reused in multiple templates.
-
A substantial part of application logic is located in
QuerySet
s, not in views. This applies, for example, to the Search and Sales Statistics. The same code is reused in different views and RESTful API. -
The UI is mobile-friendly (see 3.2). For the UI, we selected a dark theme and an Anonymous Pro font which seamed appropriated for an online game store. We also used icons provided by Font Awesome. All features are logically organized and easily accessible.
-
We used
w3c-validation
package for Atom text editor for validating HTML and CSS files. -
While testing our responsive design, we used both physical mobile devices and Google Chrome developer tools for emulating a variety of screen sizes.
-
All modules of the application were tested manually. These tests included penetration tests. We did not use automated unit testing.
200 points
We mostly communicated using Telegram and, additionally, we were meeting in person for a discussion at least once week or more often, if it was required. Sometimes we were meeting to work together for the whole day.
We first started working on mandatory features. At each stage, we divided tasks among team members, so that everyone knew what they should work on next. Trello was used to create, define, assign, and track tasks:
100 points
- The service supports saving and loading for games with the simple message protocol described in Game Developer Information.
- The service is able to receive additional style settings which are then applied to the
iframe
.
100 points
- Google sign-in is added as an alternative to the standard email registration using social-auth-app-django.
100 points
- We implemented an API with Django REST framework. The API provides the following methods:
- A public
GET api/v1/games?search=<search>&categories=<category1,category2>
method for searching games by a keyword and categories; - A public
GET api/v1/game/<int:id>
method for retrieving information about a specific game; - A public
GET api/v1/game/<int:id>/scores
method for retrieving high scores for individual games; - A private
GET api/v1/dev/sales
method for retrieving game sale statistics; - A private
GET api/v1/dev/revenue
method for retrieving game sale revenue.
- A public
- Private API can only be accessed with a developer API access token.
100 points
- A simple Breakout game written in JavaScript;
- The game is able to communicate with the service using
postMessage
. The score is saved once the player loses, the current game progress can be saved and the latest saved game state can be loaded from the backend.
50 points
- We use ShareThis for social sharing. The user can share a game, including its title, image, description, and URL, which is achieved by using Open Graph and Twitter Cards meta tags.
50 points
- We build our application using Bootstrap 4 to support a variety of devices, including smartphones, tablets, and desktops. We also use
django-crispy-forms
for displaying forms with Bootstrap.
- We use the Facebook Comments Plugin to let players comment on games.
Overall, we were able to implement all the features that were mentioned in our initial design with some minor changes, e.g. implementing social login with Google, not Facebook.
It was sometimes difficult to figure out where to put a specific piece of code, so at first our project structure did not exactly follow the DRY and SoC principles and we then had to change it and move some code around. In the end, we still have some issues with that. Also, we did not use unit tests even though we probably should have. Some security (see Player Functionalities) and scalability issues exist but these lie outside of the scope of this project.
- Sataponn Phutrakul
- Authentication, including email verification and social login with Google;
- User settings, including password settings;
- Payments;
- Stats, including beautiful graphs.
- Ekaterina Shmeleva
- Search, including filtering search results;
- Personal and global high scores;
- Game publishing, editing and removal;
- Mobile-friendly markup and styles, including theming;
- Social sharing and Facebook comments;
- RESTful API, including token authentication.
- Felipe Gonzalez Carceller
- Prototypes and basic page layout with the Navbar, Sign up and Log in buttons;
- Game interaction, including extended functionalities;
- Breakout โ JavaScript game;
- Testing.
We worked together on the initial design and final document, constantly communicated and helped each other during the project.
We extended the existing User
model using a one-to-one link:
UserProfile
role
verified
user = models.OneToOneField(User, on_delete=models.CASCADE)
Game
title
image
description
price
url
developer = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
categories = models.ManyToManyField(Category)
GameState
game_state
game = models.ForeignKey(Game, on_delete=models.CASCADE)
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
Purchase
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
game = models.ForeignKey(Game, on_delete=models.CASCADE)
price
timestamp
status
Result
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
game = models.ForeignKey(Game, on_delete=models.CASCADE)
score
timestamp
Category
title
We used Marvel to build a simple clickable prototype; it can be found HERE ๐
The thumbnail pictures are taken from MINICLIP and are only used for educational purposes.