GithubHelp home page GithubHelp logo

zabuzard / discord-plays Goto Github PK

View Code? Open in Web Editor NEW
15.0 3.0 2.0 476 KB

Discord bot to play games together - cause the crowd is just better at it! ๐ŸŸ๐ŸŽฎ

License: MIT License

Kotlin 100.00%
discord discord-bot game kord twitch-plays twitch-plays-pokemon

discord-plays's Introduction

banner

codefactor Kotlin license GitHub release (latest by date)

Discord bot to play games together - cause the crowd is just better at it! ๐ŸŸ๐ŸŽฎ

Inspired by Twitch Plays Pokรฉmon. Feel free to contribute or tell us how you like it ๐Ÿค™

demo

There is a full playthrough of Pokรฉmon Red at https://www.youtube.com/playlist?list=PLuIsDtqkJ0MpAyQ7CmfLjW6awaifDMtuX.

Features

  • supports any Gameboy or Gameboy Color ROM
  • cross-community play and chat
  • local display without lag, direct keyboard input
  • recording and video creation
  • statistics
  • various moderation commands
  • configurable, resilient

Lag

Due to the design, the game has the following lag:

  • 1s - input, from clicking the button to the game playing the action
  • 5s - video, from rendering the footage until it arrives on your machine
  • 10s - reaction, from clicking the button until you see the moment on your screen

Get started

As of today, we are not planning on hosting the bot ourselves, or making global events available to everyone.

We encourage you to download the bot and self-host your own events! ๐Ÿ‘

Nonetheless, if you know someone who hosts the bot already and has an event running, you can easily join their event with your community.

Join existing event

To participate in an ongoing event with your community, you need to add the bot to your server. Ask the owner of the event for an invite-link.

invite

Once the bot is part of your server, use the slash-command /host mirror in the channel you would like to dedicate to the event.

mirror

The bot creates the stream mirror, and a thread for cross-community chat.

For best experience, we recommend the following settings:

  • disallow Send Message, allow Send Messages in Threads (except for the bot)

    message permission

  • set slow mode of 5 seconds for the thread

    slow mode

Host yourself

Discord

Create a bot in Discord. Therefore, visit the Developer Portal. Go to Applications and click New Application. Walk through the dialog and set everything up to your liking.

Go to the Bot section and copy your token (it will only be shown once). Ensure to tick:

  • Server Members Intent and
  • Message Content Intent

intent

Create an invite-link to join the bot to servers by going to the OAuth2/URL Generator section.

Under Scope, check:

  • bot
  • applications.command

Select the following Bot Permissions:

  • Read Messages/View Channels
  • Send Messages
  • Create Public Threads
  • Send Messages in Threads
  • Manage Threads
  • Attach Files
  • Use Slash Commands

permissions

The invite-link is shown in the box below.

Application

Download the latest version from our release section. Run it from console using

# Example: java -jar Discord-Plays-1.0-standalone.jar MzE2OTA4Mzk0OTQ0OTQ2NTgx.XbBkcJ.TpW6sUjEoNGv539Lxi-eqfbCl4R
java -jar <name_of_the_jar> <your_discord_bot_token>

On first startup, it will create a config.json file, which you can freely edit to your needs. At minimum, make sure to configure romPath and owners. Latter will be the ID of your own Discord account.

The bot should be up and running now. Start the game emulation using /owner start. At this point, all participating communities can set up their stream by using /host mirror, which will create the message containing the stream, the interaction buttons and a thread for displaying statistics and chatting.

Initially, input is locked for everyone except you (the owner). To unlock input, run /owner lock-input lock:False.

As owner, it can be helpful to occasionally run the game locally without lag and control the game directly. This can be done using /owner local-display activate:True, optionally even with sound. The controls are:

  • WASD or โ†‘โ†โ†“โ†’
  • A: Q, SPACE
  • B: E, BACKSPACE, ESC
  • Start: R, ENTER
  • Select: T, DEL

get started

Overview

The permission system is divided into 3 roles:

  • Owner - responsible for the event, full access, that's you
  • Host - responsible for streaming the event in their community, moderators
  • User - everyone else

Owner

Owners need at least Admin permission in Discord and are configured manually in the config, or via /owner add-owner. The main commands are /start, /stop and /lock-input.

To notify all users, you can use /global-message (banner in the stream itself) and /chat-message (message in the threads). Troublemakers can be excluded from the event with /ban (undo by editing the config).

Configure the event to your liking using /game-metadata and use /clear-stats when starting a new run.

Recording

The system automatically records the game by saving frames as pictures in the recordingPath specified in the config.

recording

This consumes around 2 GB per 24h of footage.

The images can be turned into a video (.mp4) by running the /owner create-video command, giving it the name of the folder, e.g. 2023-02-27. The video is created in the same folder.

The command requires the system to have ffmpeg installed.

Auto-save

The system lacks a fully automatic save mechanism. Because of that, it is necessary to manually save the game sometimes.

To ease that workflow, the bot automatically reminds all owners once per day (see autoSaveRemindAt in the config) to save the game, and walks you through a semi-automatic save routine specialized for Pokรฉmon.

This routine can also be triggered manually using /owner save.

auto-save

Host

Hosts are, by default, all users with Moderator permission in Discord. This can be configured with Discords built-in integration settings.

integration settings

Hosts can create the actual stream message and thread in a channel of their community using /host mirror. To stop the stream for this community, just delete the bots message or the thread. Afterwards, a stream can be started, for example in a different channel, with the same command again.

The /host community-message command allows to attach a message to the stream, readable only within this community.

community-message

Contributing

Thanks for considering improving this project - we hope you like it ๐Ÿค™

Feel free to post all your ideas as issues. If you want, you can try to implement some of them and propose a Pull Request. As of now, there are no guidelines you have to follow - just try to write readable code ๐Ÿ™‚

Tech Stack

The main technologies being used are

  • Kotlin
  • Gradle
  • JDA as Discord framework
  • Coffee GB as emulator

Architecture

The code base is divided into several main packages:

  • Discord
  • Local
  • Emulation
  • Stream

architecture

The flow starts in Main.kt, starting the bot using the Config.kt and booting up all services, wiring them up.

Game emulation is represented and controlled by Emulator.kt. Almost all flows start with invoking a command in either OwnerCommands or HostCommands, which usually end up triggering a method in the main controller class DiscordBot.

The emulator pushes the graphics to StreamRenderer, which scales the game image, adds overlays and more. From there on, all rendered frames are exposed mainly to DiscordBot, LocalDisplay and FrameRecorder.

discord-plays's People

Contributors

ankitsmt211 avatar zabuzard avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

discord-plays's Issues

Forward logs to Discord via webhook

Log messages should also be forward to Discord via a channel webhook.

That way, owners will notice issues sooner - especially when hosting on a headless machine.

YouTube live stream support

For a better experience with less lag, we should ditch the gif-based approach and replace it with a simple YT livestream.

Which can then be captured manually with OBS, also giving more freedom and flexibility.

The bot could then just post the YT link instead of the gifs and keep all other features (discord chat integration, buttons, ...)

Tray icon to launch local display without command

In certain situations, it can be necessary to launch the local display without using the Discord command.

For example when the bot lost connection to the internet and the owner needs to quickly save the game before restarting it.

To enable this, one could add a system-tray icon that allows launching the window.

Video reminder and conversation

Similar to the auto-save routine, there should be a routine reminding the owners to create a /owners video once per day.

In a similar fashion, there should be a DM-conversation with a dropdown for folder selection.

Stream countdown

There should be a way to announce a stream before it actually starts, and have the bot send some sort of countdown-image instead.

As in, "Stream starts in 3d 10h ..."

Add Democracy mode

Optionally, owners should be able to turn on democracy mode - as opposed to just anarchy mode.

In democracy mode, inputs are not immediately played back, but instead collected. For example for 30 seconds. After collection, the highest voted input will be played back.

This is useful when entering a difficult section in the game (like the Rocket Hideout puzzle).

Discord commands do not work

I've tried solving this but It's over my head.

I'm trying to host locally on my PC. I can invite the bot and the bot's online status directly correlates to if the script is running but the discord commands are not working.

I've tried kicking the bot and reinviting & redoing server permissions. The bot shows up and appears in the discord when I launch the commands in PowerShell.

this is my JSON config -

{
"romPath": "Pokemon_Blue.gb",
"gameTitle": "Pokemon",
"owners": [
217126042752516098
],
"bannedUsers": [
],
"hosts": [
],
"autoSaveRemindAt": "13:00",
"userToInputCount": [
],
"playtimeMs": 0,
"recordingPath": "recording",
"font": "Sans Serif"
}

Previously, I had the romPath set as a folder path where the rom was stored but that was giving be a JSON issue. Setting it straight the .gb files doesn't spit out any issues.

This is what Powershell shoots back to me,

WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance.
20:41:43.920 [main] INFO net.dv8tion.jda.api.JDA - Login Successful!
20:41:44.142 [JDA MainWS-WriteThread] INFO net.dv8tion.jda.internal.requests.WebSocketClient - Connected to WebSocket
20:41:44.317 [JDA MainWS-ReadThread] INFO net.dv8tion.jda.api.JDA - Finished Loading!
20:41:44.419 [main] INFO io.github.zabuzard.discordplays.Main - Bot started, ready

Am I missing something? This seems like a great bot. I just can't get the discord commands to work. Any help would be appreciated. Thanks

Team overlay

Add an overlay that displays the current team and its status, similar to TPP:

team overlay

This could be done via ROM hack or by manually reading the correct locations in the gameboy RAM, via emulator.readAddress(...). But that requires knowledge of the Pokemon memory architecture.

Support VisualBoyAdvance

Currently, the game is emulated with a Java-emulator. This makes integration fairly easy, but it is also quite limitting.

Ideally, the project should be able to support a more advanced and industry-standard emulator, such as VisualBoyAdvance.

The problem is that this emulator does not expose any interface to Java. So we would need to implement arbitrary screen capture and forward input events as actual OS-level input. Doable, but not trivial.

Config hot reload

The config should be reloaded sometimes, e.g. every minute.

That way, owners could do simple config changes without needing to restart the bot.

Todo-Tracker

  • poc
  • basic setup
  • discordkt stuff
  • coffeebg stuff
  • wire up input
  • wire up image
  • gif rendering
  • mute sound
  • proper code architecture
  • permission checks on all commands
  • setup commands
  • admin commands
  • option to lock input for non-owners
  • proper startup and shutdown
  • config
  • limit input per-user to 2 seconds or so (prevent spamming)
  • overlay showing the input queues
  • overlay should be rendered so that its exposed to jframe as well
  • only one stream per guild (or channel?)
  • option for owner to send a message banner in the image
  • option for host to send a message in the control-embed
  • add or remove owners via user-selection command
  • local display
  • retry on exception
  • speed up gif, build it per-frame instead of all at once
  • owner ban input from a specific user
  • individual listeners for acceptFrame/acceptGif have to be executed async to not block each other
  • proper offline image if /stream while currently offline - instead of "will start soon"
  • rediscover messages after restart
  • re-wire buttons after restart
  • send proper offline image on shutdown
  • save-game reminder
  • save-game routine
  • change overlay-buttons with pics
  • reverse overlay order (new inputs at bottom)
  • pause emulation if no input for 5min
  • persist stats
  • tracking of unpaused time
  • dump the images somewhere so that one can create a playthrough video at the end
  • logging
  • command to change log level
  • add date/time to overlay
  • global chat messages
  • pin messages (first and global messages)
  • video command
  • autolock input to owners on startup
  • global banner message whenever input is locked
  • chat in overlay
  • cross-community chat features
  • check user rgb inverted
  • uptime duration formatting
  • readme doc
  • jar
  • release first version
ffmpeg -framerate 20 -r 20 -i "2023-02-23/%d frame.png" -pix_fmt yuv420p -profile:v high -level:v 4.1 -crf:v 20 -movflags +faststart output.mp4

The Slash Commands do not show up!

Hi there! I have an issue where the slash commands won't show up. The bot is up and running, I made myself an owner, and I made sure the slash commands permission was set. Nothing pops up though!
Could that be fixed?
If so, thanks! (:

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.