Skip to content

Comments

Melron and Moregano#761

Open
Besjbo7 wants to merge 8 commits intovck3000:masterfrom
Besjbo7:fix/moregano-ui
Open

Melron and Moregano#761
Besjbo7 wants to merge 8 commits intovck3000:masterfrom
Besjbo7:fix/moregano-ui

Conversation

@Besjbo7
Copy link
Contributor

@Besjbo7 Besjbo7 commented Jan 7, 2026

Adding two new roles:

Melron is a Resistance member who thinks that they are Merlin. They see an appropriate number of players as Spies, but their information is random.

Moregano is a Resistance member who thinks that they are Morgana. They see an appropriate number of players as Spymates, but their information is random. They can try to Fail, but it will be logged as a Success.

this.room = thisRoom;
}

private cachedSpyUsernames?: string[];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private cachedSpyUsernames?: string[];
private cachedSpyUsernames: string[] = [];

Something like this? Can just default it to empty list :).

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also let's call the list spiesThatMelronSees or something similar :).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the name of the list - but if the default state is an empty list, it never initializes making a list, since right now it's triggered by there being no list. I can rework if that's a sloppy way to do it but for now this is necessary.

this.room = thisRoom;
}

private cachedSpyUsernames?: string[];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also tabbing is a bit off here haha. Can you use prettier to format this? It's a tool that helps you format files. I have a .prettierrc file in the repo that your tool should pick up automatically.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used prettier!

if (p.alliance === Alliance.Spy) {
realSpyCount++;
if (p.role === Role.Mordred || p.role === Role.MordredAssassin) {
hasMordred = true;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just do realSpyCount-- here instead of tracking hasMordred?
Let's us remove L47 below as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, changed.

const self = this.getSelfUsername();
const pool = this.room.playersInGame
.map((p: any) => p.username)
.filter((u: string) => u !== self);
Copy link
Owner

@vck3000 vck3000 Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you instead filter based on role? So something like

    const pool = this.room.playersInGame
      .map((p: any) => p.role)
      .filter((role: Role) => role !== Melron);

This means we can also remove this.getSelfUsername()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now filtering on role and got rid of getselfusername

Comment on lines +54 to +58
// Shuffle once and cache picks
for (let i = pool.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[pool[i], pool[j]] = [pool[j], pool[i]];
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we pull this logic out to a helper or utils file? I think this logic also existed in game.ts from memory.
Would be great to unify these!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used shuffleArray, thanks!

this.room = thisRoom;
}

private cachedSpyUsernames?: string[]; // includes self username as first element
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename this as well similar to my comment in melron.ts :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, in current architecture having the default state by empty breaks things

for (const p of this.room.playersInGame) {
if (p.alliance === Alliance.Spy) {
realSpyCount++;
if (p.role === Role.Oberon) hasOberon = true;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar to hasMord, let's just realSpyCount--

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


const pool = this.room.playersInGame
.map((p: any) => p.username)
.filter((u: string) => u !== self);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do a similar thing here too :). Filter by role so we can remove getSelfUsername.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, done!

if (!this.room.gameStarted) return { spies: [], roleTags: {} };

const self = this.getSelfUsername();
if (!self) return { spies: [], roleTags: {} };
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we'll need this check. If a Moregano object/role exists in the game, I think it's safe to assume there'll be a username that exists :).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted the check

return this.room.playersInGame[i].username;
}
}
return '';
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we were to keep this function, we'd probably first move it to game.ts and then it'd be a good idea to return a string | null, so that it's clear to the caller that the return value may not be valid.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function is gone anyway :)

[MordredAssassin.role]: MordredAssassin,
[Hitberon.role]: Hitberon,

[Melron.role]: Melron,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indenting a bit funny :(

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

MordredAssassin = 'MordredAssassin',
Hitberon = 'Hitberon',

// ADD THESE TWO
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove the comment :).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed!

Comment on lines +507 to +515
for (let i = 0; i < this.playersInGame.length; i++) {
const p = this.playersInGame[i];
if (p.role === Role.Melron) {
p.displayRole = Role.Merlin; // Melron thinks they are Merlin
} else if (p.role === Role.Moregano) {
p.displayRole = Role.Morgana; // Moregano thinks they are Morgana
(p as any).displayAlliance = Alliance.Spy;
}
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to use a for (const player of this.playersInGame) loop?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, implemented.

p.displayRole = Role.Merlin; // Melron thinks they are Merlin
} else if (p.role === Role.Moregano) {
p.displayRole = Role.Morgana; // Moregano thinks they are Morgana
(p as any).displayAlliance = Alliance.Spy;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove the as any's here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

Comment on lines +1050 to +1053
const effectiveAlliance =
(playerRoles[i] as any).displayAlliance !== undefined
? (playerRoles[i] as any).displayAlliance
: playerRoles[i].alliance;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we simplify this to
const effectiveAlliance = playerRoles[i].displayAlliance ? playerRoles[i].displayAlliance : playerRoles[i].alliance?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplified!

Comment on lines +201 to +204
const effectiveAlliance =
(player as any).displayAlliance !== undefined
? (player as any).displayAlliance
: player.alliance;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also simplify this - see prior comment pls

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't actually able to figure out how to simplify this one - it doesn't compile if I use analogous language to game.ts. If this is a problem I'll try to figure it out...

this.room = thisRoom;
}

private cachedSpyUsernames?: string[];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it'd be nice for the game to announce who was melron and moregano and what team they saw?

Can you also confirm whether the moment the game ends, melron and moregano see the true spy team in the end screen?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice all good, just confirmed the end screen looks good :).

Image

Let's get an announcement in chat to specify who melron and moregano saw.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got that postgame announcement feature working!

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you ask AI to add a unit test to ensure that moregano fail attempts are changed to a success pls?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit test added and succeeds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants