GithubHelp home page GithubHelp logo

2785 / factory-town-production-line-planner Goto Github PK

View Code? Open in Web Editor NEW
1.0 2.0 0.0 1.57 MB

This repo hosts an express API that takes a desired output to plan for a production line in the game Factory Town

TypeScript 100.00%

factory-town-production-line-planner's Introduction

Factory Town Production Line Planner

This project is a tool for the game Factory Town. It is designed to take a desired product and generated a production line specification with number of each facilities, as well as the number of workers in each facility.

Technology Stack

  1. Google Firebase
  2. GraphQL
  3. Apollo GraphQL
  4. TypeScript
  5. Node.js
  6. GraphQL Code Generator

Quick Start

To Use the Tool

If you are just interested to use the tool to plan your own production line, head to this url hosted on firebase functions. A user interface similar to the following will show up.

GraphQL Playground Demo UI

Make sure the address bar says ....cloudfunctions.net/apolloServer. You may have to add the /apolloServer part yourself. The following is a sample query you can make to the server. (The project now only has a very limited number of recipes, add more recipes to the google sheet if you wish to contribute)

query {
    getProductionLine(requirement: { product: BEEF, count: 1 }) {
        productionSteps {
            product
            facility
            facilityCount
            workerCount {
                facilityNumber
                workerCount
            }
        }
    }
}

Hit ctrl + space for autocompletion hints. The sample query will generate a result that looks like this:

{
  "data": {
    "getProductionLine": {
      "productionSteps": [
        {
          "product": "BEEF",
          "facility": "PASTURE",
          "facilityCount": 1,
          "workerCount": [
            {
              "facilityNumber": 1,
              "workerCount": 1
            }
          ]
        },
        {
          "product": "ANIMALFEED",
          "facility": "GRAINMILL",
          "facilityCount": 1,
          "workerCount": [
            {
              "facilityNumber": 1,
              "workerCount": 1
            }
          ]
        },
        {
          "product": "GRAIN",
          "facility": "FARM",
          "facilityCount": 2,
          "workerCount": [
            {
              "facilityNumber": 1,
              "workerCount": 5
            },
            {
              "facilityNumber": 2,
              "workerCount": 1
            }
          ]
        }
      ]
    }
  }
}

You can customize your world's happiness level and your facility upgrade level by first setting up a profile like so:

mutation {
    createUser(id: "example-id") {
        id
        worldHappiness
        facilityBoosters {
            facility
            booster
        }
    }
}

You can omit the part on worldHappiness and facilityBoosters. When first creating user profile, it will return the default happiness of 1.0 and no facility boosters.

After this step, you can include your user ID by putting it in the HTTP HEADERS segment at the bottom left corner of the UI:

{
    "authtoken": "example-id"
}

This will allow access to the following mutations.

Set the world happiness with the following mutation (for example, for a happiness of 30~39, 30% production speed bonus, input 1.3):

mutation {
    setWorldHappinessBooster(booster: 1.3) {
        id
        worldHappiness
        facilityBoosters {
            facility
            booster
        }
    }
}

Set the facility boosters that get added once you upgrade certain facilities with the following mutation (for example, if you upgrade pastures three times and it displays a 150% bonus speed, input 1.5):

mutation {
    addFacilityBooster(facility: PASTURE, booster: 1.5) {
        id
        worldHappiness
        facilityBoosters {
            facility
            booster
        }
    }
}

The happiness booster and facility boosters configured here will be taken into consideration when computing your production lines. Simply invoke the getProductionLine query with the HTTP header with your user ID and the query result will be optimized for your world.

To Play with the Project

You will first need node.js in your system to do anything with this project. If you intend to deploy the project to your own firebase project, you will need to set up firebase as follows:

  1. Install firebase tools

    npm i -g firebase-tools
  2. Setup and configure your firebase project here. For the project at the moment you will need to enable

    • Firebase Functions
    • Cloud Firestore
    • Cloud Storage
  3. You will not have access to the original firebase project under the name of factory-town-prod-line-planner, you will need to create your own project and point the firebase cli to your own project by running

    firebase use --add

    This command will start a command line dialog to guide you to create an alias for the project that you want it to point to.

  4. The functions part of the project lives under the ./functions folder. cd into the folder and run npm install to install the dependencies

  5. Once you are in the ./functions folder, you can test the functions locally on Firebase Functions Emulator by running npm run firebaseServe or deploy it to your project by running firebase deploy

    • You need to have private key file fbCred.json for google cloud service account in the folder ./functions/src/utilities (excuse my naming scheme, the project will attempt to read the file fbCred.json if it does not detect a production environment. If you wish to change the name of the service account file, you will need to change the file name string in code and update the file name in .gitignore to not commit your credentials to public repository). Follow this instruction to generate the private key file.
  6. The GraphQL Api itself will not produce any sensible results just yet as there would be no data in the database. The project has a function trigger on file being added to the cloud storage bucket. It is set to interpret a file named productRecipe.csv dropped into the root directory of the storage bucket, parse it, and add the product recipe data to the cloud Firestore. The recipe data in the firestore will be overwritten each time the csv file gets overwritten.

  7. Certain facilities in game have higher worker cap than the usual 5. This data should be set up similarly to the product recipes, the logic (function storage trigger and parsing / uploading logic) has not yet been implemented.

Design Considerations

Why GraphQL

Primary reason for using GraphQL is to exploit its ability to expose schema to the client. Included in the schema is two enum types that include all available names in game, for products and facilities. User input for product and facility would be restricted to these two enum types, that makes it possible to avoid string input parsing and frustration caused by unavoidable typos if it was a REST Api.

It also provides an interface, GraphQLPlayground, that people could interact with. It is not extremely intuitive to use for the general public but it's better than nothing (Imagine using postman). I do not intend to create a UI for this project in the near future as css scares me :)

Why Firebase

Firebase provides easy-to-use integrated function triggers and databases, as well as a very generous free tier for usage.

GraphQL Code Generator

The GraphQL code generator is a great tool to avoid the pain of having to write the types in schema and code twice and trying to make them match.

Project Structure

./functions

The functions folder holds the code that gets deployed to Firebase Functions:

  • ./src/apollo: Holds GraphQL schema, resolvers, and directive implementations. Has apollo server in the root directory server.ts. Types generated by code-gen tool is in generated/types.ts

  • ./src/dataSources: Holds classes and interfaces that concern about getting and setting data. For now it has a very basic implementation to use Firebase Firestore as backend database that does not yet support batch read and write or other fancy features.

  • ./src/utilities: Holds some utility code as the folder name may suggest.

  • ./src/index.ts: Exposes api endpoints to Firebase Functions. Could support deploying to a standalone express server without Firebase Functions as well.

factory-town-production-line-planner's People

Contributors

2785 avatar

Stargazers

 avatar

Watchers

 avatar  avatar

factory-town-production-line-planner's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.