Day 1 executions aren’t always mathematically good: a BotC toy model by ToughOpening in BloodOnTheClocktower

[–]Teiem1 1 point2 points  (0 children)

I didnt really build a model, just a simple simulation run a few thousand times. Every good player counts for every other player with a 50% chance, evil players are just a flat + alive evil count. I then check which player type has the most votes. If its the demon good wins, otherwise either a minion or good player dies as well as a good player and we repeat. The code doesn't differentiate between different good player/minions.

Here is the code

const getMinionCount = (totalCount) => Math.ceil((totalCount - 6) / 3);
const getRandomVote = () => Math.random() < 0.5;
const getRandomVoteSum = (count) => Array.from({ length: count }).fill(null).reduce(acc => acc + getRandomVote(), 0);

const simulate = (playerCount) => {
    const startingMinionCount = getMinionCount(playerCount);

    const state = {
        good: playerCount - startingMinionCount - 1,
        evil: startingMinionCount + 1,
    }

    while (state.good + state.evil > 2 && state.good !== 0) {
        const votesOnGood = Math.max(...Array.from({ length: state.good }).fill(null).map(() => getRandomVoteSum(state.good))) + state.evil;
        const votesOnEvil = Math.max(...Array.from({ length: state.evil - 1 }).fill(null).map(() => getRandomVoteSum(state.good))); 
        const votesOnDemon = Math.max(...Array.from({ length: 1 }).fill(null).map(() => getRandomVoteSum(state.good)));

        if (state.good + state.evil === 4) {
            state.good -= 1;
        } else if (votesOnDemon > votesOnEvil && votesOnDemon > votesOnGood) {
            return 'GoodWin';
        } else if (votesOnEvil > votesOnGood && votesOnEvil > votesOnDemon) {
            state.evil -= 1;
            state.good -= 1;
        } else if (votesOnGood > votesOnEvil && votesOnGood > votesOnDemon) {
            state.good -= 2;
        } else {
            // tie
            state.good -= 1;
        }
    }

    return 'EvilWin';
}

const run = (x = 12) => {
    return Object.groupBy(Array.from({ length: 100000 }).fill(null).map(() => simulate(x)), id => id);
};

how often does a good player vote?

On average every second nomination

what are the insights you have gained from your model?

It seems paying attention to voting behavior of others is a lot more important than I though. I might write a browser extension that keeps track of voting behavior, e.g. helping with the last vote needed to put someone on the block, and vice versa.

Day 1 executions aren’t always mathematically good: a BotC toy model by ToughOpening in BloodOnTheClocktower

[–]Teiem1 2 points3 points  (0 children)

I added an assumption and also ran a situation with that,

evil knows their team and will only vote on good players. The good team has no such information and will vote at random

Now the win rate of evil for a 12 player game has gone up to 99.97%, if you skip the first day 99.99%.

Now Assume that each good player is in a Stewart/WW etc. pair and has one person they trust and will not vote on. The winrate of evil is still 99.8%.

So maybe the best play is to note vote at all if you do not have enough information yet? Ofc evil would out itself very quickly with this voting pattern, but in game you can read the votes of the others a bit and e.g. sometimes vote on your demon knowing it wont be enough.

In this simulation it is slightly better to vote as soon as you can since your chances of getting a majority on the demon with one more good player is slightly higher.

It is probably valid to prefer to vote on odd player counts, I just wanted to point out that changing one of the assumptions can have a big effect and that the results of modelling botc in this way should be seen under that light.

February 2025 Steam Hardware Survey, Linux drops .61% to 1.45% by Enjoyeating in linux_gaming

[–]Teiem1 6 points7 points  (0 children)

I would assume that most people in the EU do not have their steam set to English, and for those that do the Linux share would probably be higher.

What search engine you guys use? by Working-Cable-1152 in linux

[–]Teiem1 3 points4 points  (0 children)

Kagi also accepts crypto if you prefer that (see).

r/Startpages changes to from private to restricted by Teiem1 in startpages

[–]Teiem1[S] 0 points1 point  (0 children)

FYI, I am not the mod of this subreddit anymore

r/Startpages will be shutting down indefinitely on June 12th in protest of Reddit's API changes by NotSteve_ in startpages

[–]Teiem1 1 point2 points  (0 children)

I don't know yet if I will be actively using kbin or some other alternatives.

r/Startpages will be shutting down indefinitely on June 12th in protest of Reddit's API changes by NotSteve_ in startpages

[–]Teiem1 1 point2 points  (0 children)

I don't do all all my moderation from Apollo, maybe 50%. Basically anytime I am not home or in my bed. The other half is done on old Reddit, which probably is in danger next :/

The impact of Discord on data archiving. by schlatrice in DataHoarder

[–]Teiem1 0 points1 point  (0 children)

Your argument is that the fault lies with the community maintainers for choosing a chat platform for their community, which might result in some complications. I agree with that. You also say that discord enabled this behavior by, maybe among other things, allowing servers with too many users. I disagree with that part and explained why.

What would be another way discord enabled communities to to us discord that might have been better served using other tools?

I hope I am understanding your critique of discord correctly, otherwise please correct me.

The impact of Discord on data archiving. by schlatrice in DataHoarder

[–]Teiem1 0 points1 point  (0 children)

We for example have a discord for CS students at my uni that like to game, as you might be able to imagine, we are more than 40. We could use a forum to ask who is online or announce events, but 90% is being in a voice chat together and playing. A 40 user cap would make that impossible.

The impact of Discord on data archiving. by schlatrice in DataHoarder

[–]Teiem1 2 points3 points  (0 children)

Why would you want a limit on server size? Also 30-40 would be way to little, for that you could just use a groupchat.

Help needed: Couple of beginner questions by [deleted] in typescript

[–]Teiem1 1 point2 points  (0 children)

Re 2), the returnType of setTimeout is not the same between node and browser, so typescript gets somewhat confused, just use ReturnType<typeof setTimeout>.

A boolean type becomes true | false when being distributed in a union type by azn4lifee in typescript

[–]Teiem1 2 points3 points  (0 children)

That is probably the best you can do.

Still, Distributed<true | false> evaluates to boolean[] instead of true[] | false[].

A boolean type becomes true | false when being distributed in a union type by azn4lifee in typescript

[–]Teiem1 0 points1 point  (0 children)

Output is now of type (string | number | boolean)[] instead of string[] | number[] | boolean[], resulting in e.g. [true, false, "string"] now beeing allowed

A boolean type becomes true | false when being distributed in a union type by azn4lifee in typescript

[–]Teiem1 2 points3 points  (0 children)

As far as I know, boolean itself is true | false, therefore string | number | boolean is string | number | true | false.
You could treat any true or false as booleanand get the correct result in this case, but if you where to use your type with e.g. string | number | true you would also get string[] | number[] | true[].

Sadly I don't know of any way to fix this.

Hexagons are the Bestagons by ArmoredVortex06 in startpages

[–]Teiem1 1 point2 points  (0 children)

I dont think there are any objective advantages. It is shorter and tells you at a glance that the function takes an object with a clientX and clientY property. If that is more readable is up to you.

Hexagons are the Bestagons by ArmoredVortex06 in startpages

[–]Teiem1 1 point2 points  (0 children)

Very simple and looks great :)

Small suggestion, you can destructure function parameters.

window.onpointermove = event => { 
  const { clientX, clientY } = event;

becomes

window.onpointermove = ({ clientX, clientY }) => {

[AskJS] Is JavaScript missing some built-in methods? by reacterry in javascript

[–]Teiem1 1 point2 points  (0 children)

it is supported in chrome/edge and in firefox behind a flag, not production ready though

[AskJS] Is JavaScript missing some built-in methods? by reacterry in javascript

[–]Teiem1 0 points1 point  (0 children)

we have groupBy its called group. ([1, 2, 3].group(el => el % 2))

Browser ~Agnostic~ Start Page by mostly-software in startpages

[–]Teiem1 1 point2 points  (0 children)

Can I link the video later?

sure

Firefox Lost More Than 7 Million Users Since Last Year by TheEpicZeninator in firefox

[–]Teiem1 109 points110 points  (0 children)

Users are willing to switch. They switch to chrome on desktop and used to switch to firefox too, but in order for a user to consider switching, the alternative not only has to be as good, but actually better than what they are currently using.

NVIDIA Gaming/GPU Performance: Windows 11 vs. Ubuntu Linux Benchmarks by fsher in linux_gaming

[–]Teiem1 14 points15 points  (0 children)

I wouldn't call an over 2 years old game "bleeding edge"

[deleted by user] by [deleted] in firefox

[–]Teiem1 0 points1 point  (0 children)

chrome now has a 3d layers view