TannDev/silence-among-us

Endpoint or Command for Pulling Game State Data

Closed this issue · 6 comments

I apologize if there is already a way to do this within the current framework, or if you consider it outside the scope of this project, but figured it couldn't hurt to ask.

I have floated the idea of 3rd party game roles to my server and the concept has received some positive feedback. 3rd party roles could really be anything, but my initial idea would be to emulate roles from other Mafia-style games such as "The Tanner" from ONUW.

Obviously, the ideal implementation would be directly into the game itself, but the game itself is not currently open-source, and modifying game files comes with inherent risk. So, at least as proof of concept what makes the most sense to me so far is leveraging the knowledge of the game states this bot has to assign roles and instructions on what to do via discord private messaging.

I figure adding the full functionality is certainly out of the scope of this project. However, if there was a way to either listen to a data endpoint or ping the bot periodically with a command for in-game states (who is known-dead, unknown-dead, game-phase, who is the imposter, etc.) I would try leveraging that into a secondary bot that piggybacks off the provided data and handles the rest of the concept.

Let me know if you want more details about what I had in mind, and I appreciate how responsive you have been even if this isn't something you are interested in pursuing!

The server absolutely could make all the lobby information available via an API. (In fact, it used to.)

There's a couple factors that need to be weighed in when deciding if/how to implement that again:

  • PII / Privacy: How do you restrict access to player information?
  • Cheating: How do you prevent or discourage people from using the data to cheat?

That said, I don't think I really understand what you mean by "3rd party game roles". What are you trying to achieve? And what kind of information does it require?

I don't think I really understand what you mean by "3rd party game roles". What are you trying to achieve?

Ok so in the game currently you are either an imposter or crew. Now if you have ever played other secret role games you know that the roles tend to be quite expansive beyond that.

So, just one idea to give you a look would be a 10 player game with 1 imposter, 8 crew, and a "Joker". The joker is on the imposter's team and the imposter + joker win with either the normal win condition (imposter kills all the crew - 1 player) or if the joker gets voted off by the crew. Whether you like this specific role idea or not I think it demonstrates the concept of trying to spice up the lobbies with new rule sets.

How it works from an implementation standpoint would be my bot needs to know who the imposter is as to avoid assigning them the additional role. The bot randomly selects one of the other players connected and PMs them that they are the "Joker" and tells them who the Imposter is, and the Imposter is PM'd who the Joker is.

And what kind of information does it require?

For this specific concept you just need to know who the imposter is, but to implement others you may need the current game phase, and who is alive/known-dead/unknown-dead(died this round, but not known to crew yet).

PII / Privacy: How do you restrict access to player information?

Possibly opt-in on if you can be broadcast via the API. A field in the database on if they opt in to be API display.

Cheating: How do you prevent or discourage people from using the data to cheat?

I kind of assumed you would only be running this in good faith with people you know, but maybe when the SAU bot spins up a session in the PM it already sends to the host for connecting the lobby it gives them a password to their endpoint data. If that makes no sense maybe you could give me some basic details on how it looked before and I can brainstorm again if interested.

If anything isn't clear I can flesh out any of it further.

Ah, okay, I see what you're going for. Ideally, you'd be able to register to get a stream of game events. (Websockets, or something.)

That's not necessarily impossible to do, but would definitely need some thinking and some work.

PII / Privacy

If it's a documented feature of the bot, it's probably okay. Especially if you can only access a lobby's data if you're an authenticated member of the same channel. (Would need to figure out how to do that for bot-to-bot communication.)

Cheating

The problem isn't really your use-case. It's what other people can do with that information. If the bot publishes secret information in an easy-to-access way, then somebody is going to use it against a public lobby to cheat. There's not a ton I can do to prevent that, but I don't want to make it easy.

Available data

The biggest blocker is that, currently, the bot doesn't know who the imposter is. This is intentional. While amonguscapture does have access to that information, we've made the choice not to send that data in events. (See: making it easy to cheat.)

We've discussed sending that data at the end of a game, for statistical purposes, but I don't think there's much desire to send it earlier than that. (I'm not a primary dev on that project, so I can't say for sure.)

Here's an example of all the data that we store.

(Details are redacted, of course, but this is a real lobby.)

{
  "_id": "SOME_CHANNEL_ID",
  "_rev": "226-7a86140ba3b8bc593a7f664e63658b40",
  "voiceChannelId": "REDACTED",
  "textChannelId": "REDACTED",
  "phase": "Meeting",
  "connectCode": "REDACTED",
  "room": {
    "code": "REDACTED",
    "region": "North America"
  },
  "players": [
    {
      "status": "Living",
      "discordId": "REDACTED",
      "originalNickname": null,
      "amongUsName": "REDACTED",
      "amongUsColor": "Blue"
    },
    {
      "status": "Dead",
      "discordId": "REDACTED",
      "originalNickname": null,
      "amongUsName": "REDACTED",
      "amongUsColor": "Green"
    },
    {
      "status": "Living",
      "amongUsName": "REDACTED",
      "discordId": "REDACTED",
      "originalNickname": "REDACTED",
      "amongUsColor": "White"
    },
    {
      "status": "Living",
      "discordId": "REDACTED",
      "originalNickname": "REDACTED"
    },
    {
      "status": "Living",
      "amongUsName": "REDACTED",
      "discordId": "REDACTED",
      "originalNickname": "REDACTED"
    },
    {
      "status": "Living",
      "amongUsName": "REDACTED",
      "discordId": "REDACTED",
      "originalNickname": null,
      "amongUsColor": "Yellow"
    },
    {
      "status": "Living",
      "amongUsName": "REDACTED ",
      "discordId": "REDACTED",
      "originalNickname": null,
      "amongUsColor": "Black"
    },
    {
      "status": "Living",
      "amongUsName": "REDACTED",
      "discordId": "REDACTED",
      "originalNickname": "REDACTED",
      "amongUsColor": "Orange"
    },
    {
      "status": "Living",
      "amongUsName": "REDACTED",
      "discordId": "REDACTED",
      "originalNickname": "REDACTED",
      "amongUsColor": "Red"
    }
  ]
}

If the bot publishes secret information in an easy-to-access way, then somebody is going to use it against a public lobby to cheat.

Do you receive information on if the lobby is set to public or private? If you do you can prevent 'private information' (e.g. who is the imposter) from being 'streamed' in games set to public. I suppose someone could switch it to private before launching, but maybe you have to start the session with only the host in it, set to private, and if the lobby setting is switched to public at any point the information will not be streamed.

You could also only stream information on tracked players. I suppose one could just link random players to additional discord accounts, but given how easy it seems to be to cheat in the game as it stands, I imagine people would go other routes than setting up 9 extra discord accounts and linking them every time someone joins.

On an aside, I've noticed you can already "soft" cheat. When someone dies in-game (unknown to the crew) you will actually see the bots session message become the newest message in the channel or flicker if it's already the newest message which allows one to know someone in the lobby has died at that exact moment. Obviously not quite as powerful as actually knowing who the imposter is, but still really powerful info to someone trying to cheat. I'm assuming this occurs because their status is being updated from "Living" to "Dying" in preparation to handle muting them properly when they transition to "Dead" during the meeting phase.

In short, I believe the following occurs:
Someone dies -> Bot updates the player info from Living to Dying -> Causes session message to be updated (resulting in it moving to newest message or flickering)

The biggest blocker is that, currently, the bot doesn't know who the imposter is.

This is surprising to me as when all the imposters are ejected it knows to unmute everyone before the game actually ends. I'm guessing then the capture just gets a signal that the game ended before it's displayed to the players themselves.

At the end of the day, I totally understand if you feel my request opens a bigger can of worms than its worth, I just figured it was worth a shot to ask.

Do you receive information on if the lobby is set to public or private? [...] You could also only stream information on tracked players.

Nope to the first question, but the latter was my thought exactly.

When someone dies in-game (unknown to the crew) [the info post updates]

This shouldn't be the case. The info post is only updated if the contents of it have changed since the previous one. So dying players shouldn't trigger an update. If it does, that's definitely a bug which you should report in a separate issue.

You're right about the chain of events, but there's a final step where it says if text == previous text, don't post.

I'm guessing then the capture just gets a signal that the game ended

Absolutely correct. We get a state change event when the meeting ends. If the crew won, the state goes to intermission instead of lobby. This happens much earlier than you might expect.

I just figured it was worth a shot to ask
Absolutely was worth a shot! These kinds of add-on features are super interesting to me.

Unfortunately, I think the functionality you're looking for simply isn't possible right now. That might change in the future, with updates to the capture app, but I'm not sure.

Ultimately, I do want to expose more data through a website and API, so you might be able to leverage some of those features for something like this. But this particular use-case likely won't be supported in the near future. Keep an eye on any API/data changes, though.