Skip to content
This repository has been archived by the owner on Dec 4, 2023. It is now read-only.

Latest commit

 

History

History
67 lines (44 loc) · 4.44 KB

README.md

File metadata and controls

67 lines (44 loc) · 4.44 KB

EggBot

A Discord bot for Egg, Inc. co-op communities.

Description

To facilitate teamwork for Egg, Inc. communities this bot creates team rosters out of all registered players for any given active contract, allows checking up on the progress of all teams or a detailed view of an individual team and enables setting goals for individual players. This bot is being used daily by a private community of over 70 people.

It is able to predict whether a team will reach their contract goals by running a simulation on each of the member's latest known game state, taking into account all relevant variables from current amount of chickens and performed research to the time since last backup and the transport and habitat capacity.

Co-op info command output example

How to run

  1. Install the dependencies listed below
  2. Use the supplied eggbot.example.yaml and example.env in the folder you're running the bot from.
  3. Test using e.g. ./gradleW run

Deployment dependencies

  • Java Runtime Environment 11
  • PostgreSQL

Reading guide

A few technically interesting features are highlighted here:

Applied techniques

  • Model View Controller structuring
  • Multithreaded/asynchronous processing of heavy workloads
  • Leverage of Java interoperability to combine Java and Kotlin libraries and frameworks
  • Multi-tenancy using directory based database sharding
  • Deployed on a self-managed VPS
  • Development, testing, acceptance and production (DTAP)

The simulation calculates each passing minute until either the final goal will be reached within the time limit or one year has passed. The calculation is performed recursively and stateless; all relevant information is passed in the form of data classes, increasing reliability and separating concerns. Co-op states use Kotlin's sealed classes in order to simplify the view (i.e. table formatting) while still accounting for all possible states by leveraging Kotlin's ability to use that specific sealed class object’s variables as determined by the when case.

In order to produce consistently formatted tables that can be easily iterated upon a custom DSL was made. The DSL enables concise, readable and flexible HTML-like code for generating tables.

Co-op info command output example

Since fetching the backup for each player can take a while even when performed asynchronously, a progress bar is drawn to indicate progress of the parallel fetching and simulating of player's farm state. The progress bar runs a loop that only edits the message once per second and only when a change has occurred.

Progress bar example

Kotlin offers an incredible flexibility by allowing extension methods for any class. This project uses many of these ‘helper methods’, ordered by which dependency they augment. As an example: to aid a functional programming style when handling data these methods add the ability to map over cartesian products ([a, b, c], [1, 2, 3][a1, b1, c1, a2, b2…]), interleaving lists ([a, b, c], [1, 2, 3][a, 1, b, 2, c, 3]) and mapping over collections asynchronously.