Team

The New York Turnip Exchange is the final project for Dr. Abraham's Mobile Computing class. This project was developed by Matthew Jackson, Bryan Lee and Daniel Munoz.


Context

Animal Crossing: New Horizons will be undoubtedly one of the biggest games of 2020. Moreover, with the current pandemic and everyone trying to stay indoors, it quickly became an escape to the boredom of being inside. Because of such facts, we wanted to build something around the idea of Animal Crossing: New Horizons, and around its amazing community of players. With ideas flowing around, we arrived at the conclusion that we had to build something to aid in the following two ways:

  • Make new friends to invite to your island, or visit their island. Especially when your, or their, turnip prices are good.
  • Discover new design customization options for clothing and items by creating a central hub for such.

  • If you do not know what all the fuss around turnips is, I will try to explain the quite complex Stalk Market. In Animal Crossing: New Horizons there is a stock market, much like the real one we have (The New York Stock Exchange). Animal Crossing's version is called The Stalk Market, and different than the real one, it only has one stock: turnips. Turnips are veggies, and they can make you extremely rich. You need money to build your island to your liking, and thus the Stalk Market and selling turnips is the optimal way to get rich quick. Now, turnip prices in your island vary greatly. One day price per turnips can be in the low 60s while other days it can soar to the 600s. The caveat is, that turnips only last one week, meaning that you only have 7 days to sell your turnips. Because of this, and the possibility of not having good prices in your island on a certain week, the best technique to make a huge profit selling turnips is to scout around and sell your turnips in another island. One could do this by asking friends, or perhaps going to https://turnip.exchange/; however, sometimes you really have no time, or maybe you are a newbie to Animal Crossing and have no idea of the complexity you just emerged yourself in (and yes, I am talking about getting in-game mortgages, loans, stock market, etc...). This is why we decided to create a quick island hosting/joining platform as one of the core two features of our application.

    ...
    Daisy Mae's Turnips

    The other core feature, the design share hub, is much much simpler. In Animal Crossing players can share clothing or item designs online, and use those designs to apply them to their own clothing/items. For example, if I created a sick UT Longhorn hoodie, I could share that online so that my fellow Longhorns could download it and wear my sick UT hoodie. As of now, there is really no main way of sharing these designs. A quick Google search could potentially yield hundreds of Twitter posts, and Tumblr sites with designs, but that is far away from a central hub. Because of this reason, we decided to create a design sharing hub so can players could post or get designs easily.

    ...
    Mega Man Suit shared as code customization

    Concept

    The first phase was based on creating the REST API that will eventually hold the islands and the designs of the players, this will eventually become the back end of the web application. The second phase was based around creating the actual iOS application, that would eventually serve as the front-end. For the minimum viable product, we wanted to display the following attributes for each of the core areas of the application:

    Islands
  • Island Name
  • Dodo Code
  • Turnip Price
  • Description

  • Designs
  • Item Name
  • Item Code
  • Item Type
  • Image

  • Low Fidelity Prototype

    High Fidelity Prototype

    Original Logos

    Process

    We started by creating the backend. Because of the small time frame we had, we decided to go with Python and Flask to build the REST API. We also decided to use MySQL as the main database, with Digital Ocean Spaces (alternative to AWS S3) as a CDN for asset access (in our case the design code images). We decided to use a CDN so that our database would not overload (we are using free tier servers so they do not handle good with a lot of traffic). We then designed our schema for the database, this is how the attributes will be organized in the API.

    ...
    Schema

    Update

    We have also added a timestamp for both database tables. This is to filter through the islands, the API only displays the islands open in the last 24 hours.


    After defining our schema, we had to define our application architecture. This was done to be better organized as to what goes where, servers can get really tangled once you start applying firewalls, CDNs, etc... The following image, which represents our architecture, might look confusing, but we will try our best to explain. Also please note, this diagram might not be perfect, remember, we are on a time crunch.

    ...
    Architecture

    So as you can see, the client can now take two routes which work very similar. The first route is to use the web, a normal browser, to use our application. You can actually now go to Post Island Page or Post Design Page and submit something, you can go back to the home page Home after to see your recent submission. You can also click on one of the JSON links to see the response for a GET request, this was mainly to debug, but we have left it for reference (turns out it became quite handy when messing around with URLSession). The API Documentation includes all the endpoints that can be called if someone wishes to use this API. You can access that here: Documentation

    One of the challenges we had, was how to link the database to include a URL to the CDN for image retrieval. The urls for each asset had to be unique in order to get stored in the object storage service. So we ended up implementing a randomizer algorithm to do so, it mainly works in the following way. First, identify if the file uploaded is an image, in our case, .png, .jpg and .jpeg, this is done as to prevent malicious attacks (just imagine if someone who knows your system stores a .bashrc file!). Second, the algorithm separates the image extension from the filename, and then randomizes a long 16 character string with letters, numbers and other characters. We determined that 16 digits would be enough for our purpose, as collisions would pretty-much be non-existent. Finally, join the name and the extension and store.

    Now, for the time you have been waiting for. A demo of our iOS application (or at least what we have so far!). By the way, I know my iPhone is messy, I haven't organized my apps in ages...

    Actual iOS Application

    As you can see, the iOS is fetching data from the API and populating the UITableViewController. This is mainly done with URLSession. We also added a spinner, as a loader, for better user experience.


    Future
    Looking Forward

    We still have plenty to do, in that we need to add functionality to the POST request forms in the iOS application. Once we have added functionality for sending POST requests from the iOS application, as well as integrate with Cocoapods AWS S3 (links up with Digital Ocean Spaces, where we store the images), we will have finished the core functionality of the application. Looking forward we also want to add a favorite feature, so users can favorite certain designs for easier access in the future, as shown in the high fidelity mockups. We will use core storage in the iOS device for this.

    Probable Implementations

    There are a couple things we still have not figured out. One is the Dodo Code issue. As the code makes your island available to anyone, if a substantial amount of people begin using this application, we will have to figure out a way to make it so that the owner of an island has control over who is in their island. https://turnip.exchange/ does it incredibly well in that it has a "waiting room" feature, we might think on implementing something similar. Another thing we have not implemented is a limit to the API calls a user could do. Right now, someone could potentially make a bot that just calls our API continously and (probably) crash the entire thing. For future implementations, having a certain header with the user session and API calls will be a good integration. Another way of solving this problem is making API Keys to access the API, though, that is a little more complicated and will require more database tables, so we will leave it at that for now!