Threads Of Destiny(Eastern Fantasy, Sequel to Forge of Destiny)

Voted best in category in the Users' Choice awards.
We need better methods of cultivation than the Empire's current one to make such a tactic sustainable, else the Empire would be doing it allready.
Why would the Empire already be doing it? This comes uncomfortably close to letting commoners get ideas. Also, why would this be any less sustainable than city wards? Afaik cultivation can't regress.
Vast majority of the population is below talent 1 ya know. Even if talent is not a perfect map to how people other then LQ works all the time.

Also, if bringing up most the population to red was possible (outside extrem spiritblood breeding, until they are mostly spirit like the fish people) and no one is doing it you got to ask yourself why. If the only answer is people are dumb/evil then this is the wrong setting for you.
No? Where did you get the idea that talent 1 (i.e. literally can't cultivate) was normal? The average talent is 3 and 4 and we have WoG that the only way to effectively breed for higher cultivation talents is through spirit blood; that's why having lots of children is so important to nobles. Every child is a roll of the dice talent wise, so need to have more to raise your chances of having some with high enough talent to continue the House. This random spread is also why the Sects go out scouting among commoners for talents :Ü™
 
Why would the Empire already be doing it? This comes uncomfortably close to letting commoners get ideas. Also, why would this be any less sustainable than city wards? Afaik cultivation can't regress.

No? Where did you get the idea that talent 1 (i.e. literally can't cultivate) was normal? The average talent is 3 and 4 and we have WoG that the only way to effectively breed for higher cultivation talents is through spirit blood; that's why having lots of children is so important to nobles. Every child is a roll of the dice talent wise, so need to have more to raise your chances of having some with high enough talent to continue the House. This random spread is also why the Sects go out scouting among commoners for talents :Ü™

The average talent of Nobles is 3-4.

The average talent of the entire population of the Empire is 1.
 
No, the vast majority of the Empire population is talent 1. Talent 3-4 is the average (more a baseline) talent for disciples accepted to a Great Sect.
 
Keep in mind that while Red Stones are common, they aren't so common that using them to mass awaken commoners is going to be anywhere near feasible. They're a consumable, the value spikes when demand spikes, and each Red cultivator would be getting paid in and using up more Red Stones.

The plan self-corrects extremely quickly once the economics catch up to how many red stones you're using up.

Which goes back to the root point: The cultivator economy is nearly completely separate from the mortal economy.

The return on investment for Reds has to manifest as cultivator-value. Simply being more quickly skilled at a mortal craft is not enough, mortal crafts do not generate cultivator value.

Red warriors can defend against lesser spirit beast intrusions, so they prevent loss of value. They also hunt spirits for cores and spiritually charged materials, which can be refined into drugs and talismans. This moves towards diminishing returns as they start to exceed the local carrying capacity for spirits, or need to take up law enforcement duties

Red artisans produce simple talismans, but they only generate cultivator-value so far as their fellow cultivators of their tier desire those talismans sufficiently to pay in the cultivation resources they'd normally use up.

Red cultivators farmers and ranchers produce materials for artisans to refine into more consumables, in essence making spirit stones more efficient. This adds value until the carrying capacity of the spiritual site is reached.

When you put it all together, the only scenario where it'd make economic sense to awaken the entire population is if your population occupies a land with a cultivation carrying capacity in excess of your population. Which means the threats of the environment are also in excess of your population.

Which means you're a nomadic people.
 
The Empire is starving for cultivators, and you can see that backfill is a problem for Emerald Seas. In addition to tying cultivators into the system, they just need more barons to tame and hold land long enough. If they could produce more greens, they would because this is a death world.
 
Why would the Empire already be doing it? This comes uncomfortably close to letting commoners get ideas.

You were already answered, but I also wanted to answer this specifically.

An entire province being red will not lead to commoners getting any funny ideas regardless. Just in the latest chapter Shenua's mild interest brought Ling Qi (a Green cultivator with hellish inner strength) to tears. Minister Rose-Garden's dislike made Ling Qi feel as if she's being strangled by flowers. Hell, I'm pretty sure Ling Qi can fight through an entire province of Red soldiers entirely on her own. Commoners do not stand a chance.

On the other hand, if such thing were possible, armies forged from such place would be incredibly more powerful (seeing as they'll be much more numerous).

The Empire has reasons to do it and very little drawbacks of doing it.
 
Last edited:
The Empire is starving for cultivators, and you can see that backfill is a problem for Emerald Seas. In addition to tying cultivators into the system, they just need more barons to tame and hold land long enough. If they could produce more greens, they would because this is a death world.
Actually, the Empire isnt that starved for cultivators. Its just that cultivators either are too weak to do much good unless in large numbers, or strong enough to be a (usually small) faction unto their own and need incentives to be called to action.

Never forget that the Unnatural Death (anything not old age) of someone of decent cultivation not of your faction/clan is good for you in a minor way, while a loss of a decent cultivator from your side costs you greatly in time, resources, potential, influence and a few more.
 
My understanding from the beginning of Forge was that even Red realm cultivators can learn in weeks what would take mortals months to learn. As in it's at least a 3 times learning speed multiplier.

Mmm, that's not really my intention. I don't want to give high talents (6, like us) the same chance, sure extreme talents (7+, like Ji Rong) will be sent to the sect but that's to exploit them, but no, what I actually want to do is just get our entire population awakened i.e. Early Red realm for the learning speed bump because that increase would lead to a significant boost of the economy which means the profit margins on our taxes increase.

I have only our own gain in mind; this isn't supposed to be charity. Talents will be exploited (not to say this isn't also good for them) and Beasts of Burden (taxpayers) will be strengthened to work more for us :Ü™

you can't just awaken everybody. that's infeasible. you can't really just change the current system too. the feudalistic system makes more sense in the cultivator's world. you need resources to be able to cultivate. spirit stones and such are tough to get. if you want it to be more fair for people with talent to awaken, you need to also tie them to you since they're using your resources. this is basically making them your militia or extended servants or whatever. you can have more 'vague' terminology of people who serve ling qi and are given resources, giving them less duties, but you still need them to work for you.

maybe this gives the option for more potential spies and helpers. so far a good idea. helping the common folk while making deals with them to keep an eye out on their lords is a great idea. notice that in the past, when we didn't have technology, the most important use of a spymaster was to constantly know what's happening inside other kingdoms (not just what's in other people's bedrooms). just having a villager in another kingdom's territory should have been really good for information gathering. something that's probably unnecessary nowdays firstly because of long distance communication and secondly because of the internet. but back then if no one would've sent you a letter about the crops and such, you wouldn't have even known if there was a famine. completely clueless. the cultivation world still has long distance communication, but it's not very common, so nevertheless, it is still a very useful thing to have. under the guise of charity work and spreading of ideals we could steadily build a solid foundation for information gathering, starting with common workers. give those who succeed in cultivation higher ranks, and work to make them into better positions along the different factions of the empire. I wonder if we can make this work. it may be hard to keep it a secret so we shouldn't be too careless.

anyways, we can start with making people under ling qi's village have a more accessible option towards cultivation manuals and such. make it easier for them to join the sect. the manuals and arts are only good for lower level cultivators. so this should help them out. make them into extended servants of the ling name. so far so good. besides, I'm sure cai renxiang will have plenty of ideas of how to help the common folk some more. she wants to build a legacy.

nice to see another supporter of the republic idea. making a slightly more democratic government is a nice goal for the future, when cai already has her eyes on the ducal seat.
 
Last edited:
if you want it to be more fair for people with talent to awaken, you need to also tie them to you since they're using your resources. this is basically making them your militia or extended servants or whatever. you can have more 'vague' terminology of people who serve ling qi and are given resources, giving them less duties, but you still need them to work for you.
Well, that was the idea for the more talented ones but my misconception of the sect entrance average being the Empire average led to my infeasible idea of letting less talented ones simply be more competent commoners.
maybe this gives the option for more potential spies and helpers. so far a good idea. helping the common folk while making deals with them to keep an eye out on their lords is a great idea. notice that in the past, when we didn't have technology, the most important use of a spymaster was to constantly know what's happening inside other kingdoms (not just what's in other people's bedrooms). just having a villager in another kingdom's territory should have been really good for information gathering. something that's probably unnecessary nowdays firstly because of long distance communication and secondly because of the internet. but back then if no one would've sent you a letter about the crops and such, you wouldn't have even known if there was a famine. completely clueless. the cultivation world still has long distance communication, but it's not very common, so nevertheless, it is still a very useful thing to have. under the guise of charity work and spreading of ideals we could steadily build a solid foundation for information gathering, starting with common workers. give those who succeed in cultivation higher ranks, and work to make them into better positions along the different factions of the empire. I wonder if we can make this work. it may be hard to keep it a secret so we shouldn't be too careless.
That wasn't really my idea and I'm not sure many commoner spies are a better investment than a few high ranked spies acquired through bribery.
anyways, we can start with making people under ling qi's village have a more accessible option towards cultivation manuals and such. make it easier for them to join the sect. the manuals and arts are only good for lower level cultivators. so this should help them out. make them into extended servants of the ling name. so far so good.
Sure, we can give the public library a try but I don't think it will really be all that helpful since you need Spirit Stones to be able to cultivate at all (unless you have a cultivation art or site that gives you virtual ones but that's higher level stuff) and the Sect has a tuition fee.
besides, I'm sure cai ranxian will have plenty of ideas of how to help the common folk some more. she wants to build a legacy.
Funny how you consistently misspell Cai Renxiang.
nice to see another supporter of the republic idea. making a slightly more democratic government is a nice goal for the future, when cai already has her eyes on the ducal seat.
I'm not a supporter of the Republic idea. I think the current Feudal system is fairly optimal given the circumstances :Ü™
 

Actually you dont need spirit stones , the spirit stone method is the dragon derived cultivation method popular in the empire for obvious reasons, but worldwide cultivation varies and follows different rules. Allinge has a cultivation art that let's her cultivate by studying spirit beast, the barbs have their own methods, and plenty of ancient humans found ways to cultivate in order to survive the harsh death world that is forge.

That being said , the vast majority of the commoner population does not have the talent to cultivate and the few that do generally will cap out between red-yellow. And that can take years and years to get there. We met a guy barely making green at 200+ years old? The old scout guy in our scout test.

One of the biggest hangups if you have talent is finding a cultivation method that fits. Lq cannot teach the argent method she initially learned, that the sect provided . Though she does have a few in her new clan library that her mother chose from.


The largest obstacle though here with any uplift idea is the MoL.(ministry of integrity) and the vast majority at large , would not approve of handing out free cultivation methods to anyone that asks.

It's why the sects exist, to help tie in people with the ability to cultivate with the already existing power structures.

You do not want random people with super powers let alone people who can level entire villages/towns wandering about causing mayhem or god forbid eating people (spirit blooded/etc) .
 
Actually you dont need spirit stones , the spirit stone method is the dragon derived cultivation method popular in the empire for obvious reasons, but worldwide cultivation varies and follows different rules. Allinge has a cultivation art that let's her cultivate by studying spirit beast, the barbs have their own methods, and plenty of ancient humans found ways to cultivate in order to survive the harsh death world that is forge.
Yeah but we only know the Empire's method
That being said , the vast majority of the commoner population does not have the talent to cultivate and the few that do generally will cap out between red-yellow. And that can take years and years to get there. We met a guy barely making green at 200+ years old? The old scout guy in our scout test.

One of the biggest hangups if you have talent is finding a cultivation method that fits. Lq cannot teach the argent method she initially learned, that the sect provided . Though she does have a few in her new clan library that her mother chose from.


The largest obstacle though here with any uplift idea is the MoL.(ministry of integrity) and the vast majority at large , would not approve of handing out free cultivation methods to anyone that asks.

It's why the sects exist, to help tie in people with the ability to cultivate with the already existing power structures.

You do not want random people with super powers let alone people who can level entire villages/towns wandering about causing mayhem or god forbid eating people (spirit blooded/etc) .
I only wanted to have Early Reds, higher levels of cultivation were not my intent and as stated previously my idea has been thoroughly shot down :Ü™
 
Yeah but we only know the Empire's method

I only wanted to have Early Reds, higher levels of cultivation were not my intent and as stated previously my idea has been thoroughly shot down :Ü™

If it makes you feel better we prob will have a decent chunk of reds and yellows under us. We know that servant clans exist from qi mom coming from one, and handmaidens and favored servants are a thing.

any town, province we have will also have to be filled with guards as well, so well assumingly have to recruit from the population or rent them from other places as well.
 
You can awaken the entire population, the Cloud Barbarians do that. You'll have some infant mortality from Talent 0s trying to cultivate but it can be done. However Imperial cultivation depends on a non-organic cultivation source that can't be reasonably scaled up to deal with increased demand.

The result of mass awakening the population is that they move from food being the population bottleneck to spiritual energy being the limiter. Note that the cloud barbarians appear to be mostly nomads: they almost certainly need much larger amounts of territory to sustain a given person than the Imperials do. Trying to cultivate (not like that) spiritual energy to reduce this need for territory is dangerous because spirits can take advantage of it much better than humans can, so you need to be a fairly high Realm cultivator to make the system not implode.

The extreme case not only would get the MoI on your case but also anger Mother who wants a world safe for mortals. That said I also have no doubt that there's a reason why the seats of power have so much ambient spirit energy and that's only partially because they choose high energy places to start off with.
 
you can't just awaken everybody. that's infeasible. you can't really just change the current system too. the feudalistic system makes more sense in the cultivator's world. you need resources to be able to cultivate. spirit stones and such are tough to get. if you want it to be more fair for people with talent to awaken, you need to also tie them to you since they're using your resources. this is basically making them your militia or extended servants or whatever. you can have more 'vague' terminology of people who serve ling qi and are given resources, giving them less duties, but you still need them to work for you.

maybe this gives the option for more potential spies and helpers. so far a good idea. helping the common folk while making deals with them to keep an eye out on their lords is a great idea. notice that in the past, when we didn't have technology, the most important use of a spymaster was to constantly know what's happening inside other kingdoms (not just what's in other people's bedrooms). just having a villager in another kingdom's territory should have been really good for information gathering. something that's probably unnecessary nowdays firstly because of long distance communication and secondly because of the internet. but back then if no one would've sent you a letter about the crops and such, you wouldn't have even known if there was a famine. completely clueless. the cultivation world still has long distance communication, but it's not very common, so nevertheless, it is still a very useful thing to have. under the guise of charity work and spreading of ideals we could steadily build a solid foundation for information gathering, starting with common workers. give those who succeed in cultivation higher ranks, and work to make them into better positions along the different factions of the empire.

we can start with making people under ling qi's village have a more accessible option towards cultivation manuals and such. make it easier for them to join the sect. the manuals and arts are only good for lower level cultivators. so this should help them out. make them into extended servants of the ling name. so far so good. besides, I'm sure cai ranxian will have plenty of ideas of how to help the common folk some more. she wants to build a legacy.

nice to see another supporter of the republic idea. making a slightly more democratic government is a nice goal for the future, when cai already has her eyes on the ducal seat.
Well, that was the idea for the more talented ones but my misconception of the sect entrance average being the Empire average led to my infeasible idea of letting less talented ones simply be more competent commoners.

That wasn't really my idea and I'm not sure many commoner spies are a better investment than a few high ranked spies acquired through bribery.

Sure, we can give the public library a try but I don't think it will really be all that helpful since you need Spirit Stones to be able to cultivate at all (unless you have a cultivation art or site that gives you virtual ones but that's higher level stuff) and the Sect has a tuition fee.

Funny how you consistently misspell Cai Renxiang.

I'm not a supporter of the Republic idea. I think the current Feudal system is fairly optimal given the circumstances :Ü™
you could bring back old weilu customs maybe. taking in moon and sun qi could replace spirits stones as far as I remember. might be worth a shot for the village at least. together with a small library, it's not entirely infeasible. I wonder how much effort would they actually have to give to get to practice that though. it WOULD give them a chance. those that work for you would make more small spirit stones. it's worthwhile to increase the general amount of cultivators under you wing. capturing all the talent ones to fours. they would live longer and their children and offspring would appreciate you for providing their families. now, in case some of them are like ling qi or ji rong... you may hit the jackpot.

as for the spying thing... yeah it's not a small scale project. and the cultivators would not be all commoners. you'd basically have to aid and bring to your midst people who have plenty of issues and make them your extended servants for start... maybe some small barons? perhaps. whichever we find may be candidates. bribery is fine and all but for a real information gathering system you need more loyalty. just a proposition anyways.
 
Last edited:
Yeah but we only know the Empire's method

I only wanted to have Early Reds, higher levels of cultivation were not my intent and as stated previously my idea has been thoroughly shot down :Ü™
I
If it makes you feel better we prob will have a decent chunk of reds and yellows under us. We know that servant clans exist from qi mom coming from one, and handmaidens and favored servants are a thing.

any town, province we have will also have to be filled with guards as well, so well assumingly have to recruit from the population or rent them from other places as well.
I bet the military and the guards have their own way of allocating resources as well. overall, if we want more guards or more 'extended servant' (spy recruits) just generally depends on the amount of commoners under our wing together with the amount we make. most of it we will have to save of course, but being less stingy with resources if probably a good idea.
 
Diceroller code
I have come to provide the custom diceroller I promised! @yrsillar
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <Unlicense.org » Unlicense Yourself: Set Your Code Free>
v1.0.0: INITIAL RELEASE
  • number of dice
  • targetnumber
  • rolling over or under
  • automatic successes
  • success multipliers
  • Title / flavour name for the roll
  • option to reroll 1s
v1.1.0:
  • added BBcode formatting option (default: on) with:
    • highlights of mechanical data
    • coloring for statistical likelihood
v1.1.1:
  • no changes to the diceroller itself
  • added initialisation for Math.random()
v1.2.0:
  • the statistics are now printed out
    • the showStats parameter controls whether this is done as plain text or invisi-text
v1.2.1:
  • replaced the weak source of randomness Math.random() with the strong (cryptographically even) source of randomness window.crypto.getRandomValues(typedArray)
    • this technically increases the resource consumption of the code significantly but practically remains unnoticable
v1.2.2:
  • fixed a formatting bug that occurred only when using type: "over"
Old versions:
JavaScript:
function diceroller({
    // set standard values
    name,
    type,
    tn,
    dice,
    rerollOnes = false,
    mult = 1,
    autos = 0,
}: {
    // declaration of inputs
    name?: string;
    type: "over" | "under";
    tn: number;
    dice: number;
    rerollOnes?: boolean;
    mult?: number;
    autos?: number;
    // format?: boolean;
}): string {
    let ret = name ? name + " | " : "";
    ret += dice + " Dice\n";

    let sux = 0;
    if (type === "over") {
        // Roll each die
        for (let i = 0; i < dice; i++) {
            let num = Math.floor(Math.random() * 10) + 1; // convert Math.random to a d10

            if (num > tn) sux++;

            ret += num + " ";
        }
        ret += "| " + sux + " Successes"; // summarize the successes
    } else if (type === "under") {
        let ones = 0;
        // Roll each die
        for (let i = 0; i < dice; i++) {
            let num = Math.floor(Math.random() * 10) + 1; // convert Math.random to a d10

            if (num < tn) sux++;
            if (num === 1) ones++;

            ret += num + " ";
        }
        ret += "| " + sux + " Successes"; // summarize the successes

        if (rerollOnes && ones > 0) {
            ret += "\n\nRerolling " + ones + "\n";

            let rerolls = 0;
            for (let i = 0; i < ones; i++) {
                let num = Math.floor(Math.random() * 10) + 1;

                if (num < tn) rerolls++;

                ret += num + " ";
            }

            ret += "| " + rerolls + "x2=" + 2 * rerolls + " Successes"; // summarize the successes
            sux += 2 * rerolls;
        }
    } else return "ERROR: You did not specify whether to roll OVER or UNDER the targetnumber.";
    // Add multipliers and autos if there are any
    if (mult !== 1 || autos !== 0) {
        ret += "\n\n" + sux;

        if (mult !== 1) ret += "x" + mult;
        if (autos !== 0) ret += "+" + autos;

        ret += "=" + (Math.floor(sux * mult) + autos) + " Successes";
    }

    return ret + "\n"; // return the finished statement to the console
}
Code:
function diceroller({name,type,tn,dice,rerollOnes=false,mult=1,autos=0}){let ret=name?name+" | ":"";ret+=dice+" Dice\n";let sux=0;if(type==="over"){for(let i=0;i<dice;i+=1){let num=Math.floor(Math.random()*10)+1;if(num>tn){sux+=1}ret+=num+" "}ret+="| "+sux+" Successes"}else if(type==="under"){let ones=0;for(let i=0;i<dice;i+=1){let num=Math.floor(Math.random()*10)+1;if(num<tn){sux+=1}if(num===1){ones+=1}ret+=num+" "}ret+="| "+sux+" Successes";if(rerollOnes&&ones>0){ret+="\n\nRerolling "+ones+"\n";let rerolls=0;for(let i=0;i<ones;i+=1){let num=Math.floor(Math.random()*10)+1;if(num<tn){rerolls+=1}ret+=num+" "}ret+="| "+rerolls+"x2="+2*rerolls+" Successes";sux+=2*rerolls}}else{return "ERROR: You did not specify whether to roll OVER or UNDER the targetnumber."}if(mult!==1||autos!==0){ret+="\n\n"+sux;if(mult!==1){ret+="x"+mult}if(autos!==0){ret+="+"+autos}ret+="="+(Math.floor(sux*mult)+autos)+" Successes"}return ret+"\n"}
Template:
JavaScript:
diceroller({
    type: "under",
    tn: 6,
    dice: 1000,
    name: "Spiritual Cultivation",
    rerollOnes: true,
    mult: 1.2,
    autos: 0,
})
Among these values you can omit:
  • name to roll without a name
  • rerollOnes to not reroll 1s
  • mult for a default multiplier of 1 which will not be mentioned in the output
  • autos for a default number of 0 autos which will not be mentioned in the output
Note 1: As long as you do not take any action which will empty the Console's cache (such as closing the browser) you don't need to repeat steps 1 and 2.
Note 2: You can enter the parameters in any order you want; you don't need to follow the order of the template.
JavaScript:
function diceroller({
    // set standard values
    name,
    type,
    tn,
    dice,
    rerollOnes = false,
    mult = 1,
    autos = 0,
    format = true,
}: {
    // declaration of inputs
    name?: string;
    type: "over" | "under";
    tn: number;
    dice: number;
    rerollOnes?: boolean;
    mult?: number;
    autos?: number;
    format?: boolean;
}): string {
    let ret = "\n";
    ret += name ? name + " | " : "";
    if (format) ret += "[b]";
    ret += dice + " Dice";
    if (format) ret += "[/b]";
    ret += "\n";

    let sux = 0;
    let stats;
    if (type === "over") {
        // Roll each die
        for (let i = 0; i < dice; i++) {
            let num = Math.floor(Math.random() * 10) + 1; // convert Math.random to a d10

            if (num > tn) sux++;

            ret += num + " ";
        }
        // calculate mean and standard deviation
        stats = statistics(dice, tn, type);

        // summarize the successes
        ret += "| ";
        if (format) gradedFormatting(stats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/color]";
    } else if (type === "under") {
        let ones = 0;
        // Roll each die
        for (let i = 0; i < dice; i++) {
            let num = Math.floor(Math.random() * 10) + 1; // convert Math.random to a d10

            if (num < tn) sux++;
            if (num === 1) ones++;

            ret += num + " ";
        }
        // calculate mean and standard deviation
        let basicStats = statistics(dice, tn, type);

        // summarize the successes
        ret += "| ";
        if (format) gradedFormatting(basicStats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/b][/color]";

        if (rerollOnes && ones > 0) {
            ret += "\n\n";
            ret += "Rerolling ";
            if (format) gradedFormatting(statistics(dice, 2, "under"), ones);
            ret += ones;
            if (format) ret += "[/b][/color]";
            ret += "\n";

            let rerolls = 0;
            // Roll each die
            for (let i = 0; i < ones; i++) {
                let num = Math.floor(Math.random() * 10) + 1;

                if (num < tn) rerolls++;

                ret += num + " ";
            }
            // calculate mean and standard deviation for rerolls
            let rerollStats = statistics(ones, tn, type);

            // calculate mean and standard deviation for total
            stats = statistics(dice, tn, type, true);

            ret += "| " + rerolls + "x2=";
            if (format) gradedFormatting(rerollStats, rerolls);
            ret += 2 * rerolls + " Successes"; // summarize the successes
            if (format) ret += "[/b][/color]";

            sux += 2 * rerolls;
        } else stats = basicStats;
    } else return "ERROR: You did not specify whether to roll OVER or UNDER the targetnumber.";
    // Add multipliers and autos if there are any
    if (mult !== 1 || autos !== 0) {
        ret += "\n\n" + sux;

        if (mult !== 1) ret += "x" + mult;
        if (autos !== 0) ret += "+" + autos;

        ret += "=";
        if (format) gradedFormatting(stats, sux);
        ret += Math.floor(sux * mult) + autos + " Successes";
        if (format) ret += "[/b][/color]";
    } else if (rerollOnes) {
        ret += "\n\n";
        if (format) gradedFormatting(stats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/b][/color]";
    }

    return ret + "\n"; // return the finished statement to the console

    // helper functions
    function gradedFormatting(
        { mean, standardDeviation }: { mean: number; standardDeviation: number },
        successes: number,
    ) {
        ret += "[color=rgb(";
        if (successes < mean - standardDeviation) ret += "223, 31, 31";
        else if (successes < mean) ret += "255, 159, 0";
        else if (successes === mean) ret += "223, 223, 223";
        else if (successes < mean + standardDeviation) ret += "191, 255, 0";
        else ret += "31, 223, 31"; // succusses > mean + standardDeviation
        ret += ")][b]";
    }

    function statistics(
        dice: number,
        targetnumber: number,
        type: "over" | "under",
        includeRerolls: boolean = false,
    ): { mean: number; standardDeviation: number } {
        let mean;
        let standardDeviation;
        let meanPerDie;
        let sdPerDie;

        if (type === "under") {
            let winningFaces = targetnumber - 1;

            if (includeRerolls) meanPerDie = 0.12 * winningFaces;
            else meanPerDie = 0.1 * winningFaces;

            if (includeRerolls) sdPerDie = Math.sqrt(0.18 * winningFaces - 0.0144 * winningFaces * winningFaces);
            else sdPerDie = Math.sqrt(0.1 * winningFaces - 0.01 * winningFaces * winningFaces);
        } else {
            let winningFaces = 10 - targetnumber;

            meanPerDie = 0.1 * winningFaces;
            sdPerDie = Math.sqrt(0.1 * winningFaces - 0.01 * winningFaces * winningFaces);
        }

        mean = dice * meanPerDie;
        standardDeviation = Math.sqrt(dice) * sdPerDie;

        return { mean: mean, standardDeviation: standardDeviation };
    }
}
Code:
function diceroller({name,type,tn,dice,rerollOnes=false,mult=1,autos=0,format=true}){let ret="\n";ret+=name?name+" | ":"";if(format){ret+="[b]"}ret+=dice+" Dice";if(format){ret+="[/b]"}ret+="\n";let sux=0;let stats;if(type==="over"){for(let i=0;i<dice;i+=1){let num=Math.floor(Math.random()*10)+1;if(num>tn){sux+=1}ret+=num+" "}stats=statistics(dice,tn,type);ret+="| ";if(format){gradedFormatting(stats,sux)}ret+=sux+" Successes";if(format){ret+="[/color]"}}else if(type==="under"){let ones=0;for(let i=0;i<dice;i+=1){let num=Math.floor(Math.random()*10)+1;if(num<tn){sux+=1}if(num===1){ones+=1}ret+=num+" "}let basicStats=statistics(dice,tn,type);ret+="| ";if(format){gradedFormatting(basicStats,sux)}ret+=sux+" Successes";if(format){ret+="[/b][/color]"}if(rerollOnes&&ones>0){ret+="\n\n";ret+="Rerolling ";if(format){gradedFormatting(statistics(dice,2,"under"),ones)}ret+=ones;if(format){ret+="[/b][/color]"}ret+="\n";let rerolls=0;for(let i=0;i<ones;i+=1){let num=Math.floor(Math.random()*10)+1;if(num<tn){rerolls+=1}ret+=num+" "}let rerollStats=statistics(ones,tn,type);stats=statistics(dice,tn,type,true);ret+="| "+rerolls+"x2=";if(format){gradedFormatting(rerollStats,rerolls)}ret+=2*rerolls+" Successes";if(format){ret+="[/b][/color]"}sux+=2*rerolls}else{stats=basicStats}}else{return "ERROR: You did not specify whether to roll OVER or UNDER the targetnumber."}if(mult!==1||autos!==0){ret+="\n\n"+sux;if(mult!==1){ret+="x"+mult}if(autos!==0){ret+="+"+autos}ret+="=";if(format){gradedFormatting(stats,sux)}ret+=Math.floor(sux*mult)+autos+" Successes";if(format){ret+="[/b][/color]"}}else if(rerollOnes){ret+="\n\n";if(format){gradedFormatting(stats,sux)}ret+=sux+" Successes";if(format){ret+="[/b][/color]"}}return ret+"\n";function gradedFormatting({mean,standardDeviation},successes){ret+="[color=rgb(";if(successes<mean-standardDeviation){ret+="223, 31, 31"}else if(successes<mean){ret+="255, 159, 0"}else if(successes===mean){ret+="223, 223, 223"}else if(successes<mean+standardDeviation){ret+="191, 255, 0"}else{ret+="31, 223, 31"}ret+=")][b]"}function statistics(dice,targetnumber,type,includeRerolls=false){let mean;let standardDeviation;let meanPerDie;let sdPerDie;if(type==="under"){let winningFaces=targetnumber-1;if(includeRerolls){meanPerDie=0.12*winningFaces}else{meanPerDie=0.1*winningFaces}if(includeRerolls){sdPerDie=Math.sqrt(0.18*winningFaces-0.0144*winningFaces*winningFaces)}else{sdPerDie=Math.sqrt(0.1*winningFaces-0.01*winningFaces*winningFaces)}}else{let winningFaces=10-targetnumber;meanPerDie=0.1*winningFaces;sdPerDie=Math.sqrt(0.1*winningFaces-0.01*winningFaces*winningFaces)}mean=dice*meanPerDie;standardDeviation=Math.sqrt(dice)*sdPerDie;return{mean:mean,standardDeviation:standardDeviation}}}
JavaScript:
diceroller({
    type: "under",
    tn: 6,
    dice: 800,
    name: "Physical Cultivation",
    rerollOnes: true,
    mult: 1.1,
    autos: 0,
    format: true
})
Among these values you can omit:
  • name to roll without a name
  • rerollOnes to not reroll 1s
  • mult for a default multiplier of 1 which will not be mentioned in the output
  • autos for a default number of 0 autos which will not be mentioned in the output
  • format for a default value of true which means formatting will be enabled
Note 1: As long as you do not take any action which will empty the Console's cache (such as closing the browser) you don't need to repeat steps 1 and 2.
Note 2: You can enter the parameters in any order you want; you don't need to follow the order of the template.
JavaScript:
function diceroller({
    // set standard values
    name,
    type,
    tn,
    dice,
    rerollOnes = false,
    mult = 1,
    autos = 0,
    format = true,
}: {
    // declaration of inputs
    name?: string;
    type: "over" | "under";
    tn: number;
    dice: number;
    rerollOnes?: boolean;
    mult?: number;
    autos?: number;
    format?: boolean;
}): string {
    let ret = "\n";
    ret += name ? name + " | " : "";
    if (format) ret += "[b]";
    ret += dice + " Dice";
    if (format) ret += "[/b]";
    ret += "\n";

    let sux = 0;
    let stats;
    if (type === "over") {
        // Roll each die
        for (let i = 0; i < dice; i++) {
            let num = Math.floor(Math.random() * 10) + 1; // convert Math.random to a d10

            if (num > tn) sux++;

            ret += num + " ";
        }
        // calculate mean and standard deviation
        stats = statistics(dice, tn, type);

        // summarize the successes
        ret += "| ";
        if (format) gradedFormatting(stats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/color]";
    } else if (type === "under") {
        let ones = 0;
        // Roll each die
        for (let i = 0; i < dice; i++) {
            let num = Math.floor(Math.random() * 10) + 1; // convert Math.random to a d10

            if (num < tn) sux++;
            if (num === 1) ones++;

            ret += num + " ";
        }
        // calculate mean and standard deviation
        let basicStats = statistics(dice, tn, type);

        // summarize the successes
        ret += "| ";
        if (format) gradedFormatting(basicStats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/b][/color]";

        if (rerollOnes && ones > 0) {
            ret += "\n\n";
            ret += "Rerolling ";
            if (format) gradedFormatting(statistics(dice, 2, "under"), ones);
            ret += ones;
            if (format) ret += "[/b][/color]";
            ret += "\n";

            let rerolls = 0;
            // Roll each die
            for (let i = 0; i < ones; i++) {
                let num = Math.floor(Math.random() * 10) + 1;

                if (num < tn) rerolls++;

                ret += num + " ";
            }
            // calculate mean and standard deviation for rerolls
            let rerollStats = statistics(ones, tn, type);

            // calculate mean and standard deviation for total
            stats = statistics(dice, tn, type, true);

            ret += "| " + rerolls + "x2=";
            if (format) gradedFormatting(rerollStats, rerolls);
            ret += 2 * rerolls + " Successes"; // summarize the successes
            if (format) ret += "[/b][/color]";

            sux += 2 * rerolls;
        } else stats = basicStats;
    } else return "ERROR: You did not specify whether to roll OVER or UNDER the targetnumber.";
    // Add multipliers and autos if there are any
    if (mult !== 1 || autos !== 0) {
        ret += "\n\n" + sux;

        if (mult !== 1) ret += "x" + mult;
        if (autos !== 0) ret += "+" + autos;

        ret += "=";
        if (format) gradedFormatting(stats, sux);
        ret += Math.floor(sux * mult) + autos + " Successes";
        if (format) ret += "[/b][/color]";
    } else if (rerollOnes) {
        ret += "\n\n";
        if (format) gradedFormatting(stats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/b][/color]";
    }

    return ret + "\n"; // return the finished statement to the console

    // helper functions
    function gradedFormatting(
        { mean, standardDeviation }: { mean: number; standardDeviation: number },
        successes: number,
    ) {
        ret += "[color=rgb(";
        if (successes < mean - standardDeviation) ret += "223, 31, 31";
        else if (successes < mean) ret += "255, 159, 0";
        else if (successes === mean) ret += "223, 223, 223";
        else if (successes < mean + standardDeviation) ret += "191, 255, 0";
        else ret += "31, 223, 31"; // succusses > mean + standardDeviation
        ret += ")][b]";
    }

    function statistics(
        dice: number,
        targetnumber: number,
        type: "over" | "under",
        includeRerolls: boolean = false,
    ): { mean: number; standardDeviation: number } {
        let mean;
        let standardDeviation;
        let meanPerDie;
        let sdPerDie;

        if (type === "under") {
            let winningFaces = targetnumber - 1;

            if (includeRerolls) meanPerDie = 0.12 * winningFaces;
            else meanPerDie = 0.1 * winningFaces;

            if (includeRerolls) sdPerDie = Math.sqrt(0.18 * winningFaces - 0.0144 * winningFaces * winningFaces);
            else sdPerDie = Math.sqrt(0.1 * winningFaces - 0.01 * winningFaces * winningFaces);
        } else {
            let winningFaces = 10 - targetnumber;

            meanPerDie = 0.1 * winningFaces;
            sdPerDie = Math.sqrt(0.1 * winningFaces - 0.01 * winningFaces * winningFaces);
        }

        mean = dice * meanPerDie;
        standardDeviation = Math.sqrt(dice) * sdPerDie;

        return { mean: mean, standardDeviation: standardDeviation };
    }
}
// initialize Math.random()
for (let i = 0; i < 1000; i++) i -= Math.random();
Code:
function diceroller({name,type,tn,dice,rerollOnes=false,mult=1,autos=0,format=true}){let ret="\n";ret+=name?name+" | ":"";if(format){ret+="[b]"}ret+=dice+" Dice";if(format){ret+="[/b]"}ret+="\n";let sux=0;let stats;if(type==="over"){for(let i=0;i<dice;i+=1){let num=Math.floor(Math.random()*10)+1;if(num>tn){sux+=1}ret+=num+" "}stats=statistics(dice,tn,type);ret+="| ";if(format){gradedFormatting(stats,sux)}ret+=sux+" Successes";if(format){ret+="[/color]"}}else if(type==="under"){let ones=0;for(let i=0;i<dice;i+=1){let num=Math.floor(Math.random()*10)+1;if(num<tn){sux+=1}if(num===1){ones+=1}ret+=num+" "}let basicStats=statistics(dice,tn,type);ret+="| ";if(format){gradedFormatting(basicStats,sux)}ret+=sux+" Successes";if(format){ret+="[/b][/color]"}if(rerollOnes&&ones>0){ret+="\n\n";ret+="Rerolling ";if(format){gradedFormatting(statistics(dice,2,"under"),ones)}ret+=ones;if(format){ret+="[/b][/color]"}ret+="\n";let rerolls=0;for(let i=0;i<ones;i+=1){let num=Math.floor(Math.random()*10)+1;if(num<tn){rerolls+=1}ret+=num+" "}let rerollStats=statistics(ones,tn,type);stats=statistics(dice,tn,type,true);ret+="| "+rerolls+"x2=";if(format){gradedFormatting(rerollStats,rerolls)}ret+=2*rerolls+" Successes";if(format){ret+="[/b][/color]"}sux+=2*rerolls}else{stats=basicStats}}else{return "ERROR: You did not specify whether to roll OVER or UNDER the targetnumber."}if(mult!==1||autos!==0){ret+="\n\n"+sux;if(mult!==1){ret+="x"+mult}if(autos!==0){ret+="+"+autos}ret+="=";if(format){gradedFormatting(stats,sux)}ret+=Math.floor(sux*mult)+autos+" Successes";if(format){ret+="[/b][/color]"}}else if(rerollOnes){ret+="\n\n";if(format){gradedFormatting(stats,sux)}ret+=sux+" Successes";if(format){ret+="[/b][/color]"}}return ret+"\n";function gradedFormatting({mean,standardDeviation},successes){ret+="[color=rgb(";if(successes<mean-standardDeviation){ret+="223, 31, 31"}else if(successes<mean){ret+="255, 159, 0"}else if(successes===mean){ret+="223, 223, 223"}else if(successes<mean+standardDeviation){ret+="191, 255, 0"}else{ret+="31, 223, 31"}ret+=")][b]"}function statistics(dice,targetnumber,type,includeRerolls=false){let mean;let standardDeviation;let meanPerDie;let sdPerDie;if(type==="under"){let winningFaces=targetnumber-1;if(includeRerolls){meanPerDie=0.12*winningFaces}else{meanPerDie=0.1*winningFaces}if(includeRerolls){sdPerDie=Math.sqrt(0.18*winningFaces-0.0144*winningFaces*winningFaces)}else{sdPerDie=Math.sqrt(0.1*winningFaces-0.01*winningFaces*winningFaces)}}else{let winningFaces=10-targetnumber;meanPerDie=0.1*winningFaces;sdPerDie=Math.sqrt(0.1*winningFaces-0.01*winningFaces*winningFaces)}mean=dice*meanPerDie;standardDeviation=Math.sqrt(dice)*sdPerDie;return{mean:mean,standardDeviation:standardDeviation}}}for(let i=0;i<1000;i+=1){i-=Math.random()}
No template changes.
JavaScript:
function diceroller({
    // set standard values
    name,
    type,
    tn,
    dice,
    rerollOnes = false,
    mult = 1,
    autos = 0,
    format = true,
    showStats = false,
}: {
    // declaration of inputs
    name?: string;
    type: "over" | "under";
    tn: number;
    dice: number;
    rerollOnes?: boolean;
    mult?: number;
    autos?: number;
    format?: boolean;
    showStats?: boolean;
}): string {
    let ret = "\n";
    ret += name ? name + " | " : "";
    if (format) ret += "[b]";
    ret += dice + " Dice";
    if (format) ret += "[/b]";
    ret += "\n";

    let sux = 0;
    let stats;
    if (type === "over") {
        // Roll each die
        for (let i = 0; i < dice; i++) {
            let num = Math.floor(Math.random() * 10) + 1; // convert Math.random to a d10

            if (num > tn) sux++;

            ret += num + " ";
        }
        // calculate mean and standard deviation
        stats = statistics(dice, tn, type);

        // summarize the successes
        ret += "| ";
        if (format) gradedFormatting(stats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/color]";
        printStatistics(stats);
    } else if (type === "under") {
        let ones = 0;
        // Roll each die
        for (let i = 0; i < dice; i++) {
            let num = Math.floor(Math.random() * 10) + 1; // convert Math.random to a d10

            if (num < tn) sux++;
            if (num === 1) ones++;

            ret += num + " ";
        }
        // calculate mean and standard deviation
        let basicStats = statistics(dice, tn, type);

        // summarize the successes
        ret += "| ";
        if (format) gradedFormatting(basicStats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/b][/color]";
        printStatistics(basicStats);

        if (rerollOnes && ones > 0) {
            ret += "\n\n";
            ret += "Rerolling ";
            if (format) gradedFormatting(statistics(dice, 2, "under"), ones);
            ret += ones;
            if (format) ret += "[/b][/color]";
            printStatistics(statistics(dice, 2, "under"));
            ret += "\n";

            let rerolls = 0;
            // Roll each die
            for (let i = 0; i < ones; i++) {
                let num = Math.floor(Math.random() * 10) + 1;

                if (num < tn) rerolls++;

                ret += num + " ";
            }
            // calculate mean and standard deviation for rerolls
            let rerollStats = statistics(ones, tn, type);

            // calculate mean and standard deviation for total
            stats = statistics(dice, tn, type, true);

            ret += "| " + rerolls + "x2=";
            if (format) gradedFormatting(rerollStats, rerolls);
            ret += 2 * rerolls + " Successes"; // summarize the successes
            if (format) ret += "[/b][/color]";
            printStatistics({ mean: rerollStats.mean * 2, standardDeviation: rerollStats.standardDeviation * 2 });

            sux += 2 * rerolls;
        } else stats = basicStats;
    } else return "ERROR: You did not specify whether to roll OVER or UNDER the targetnumber.";
    // Add multipliers and autos if there are any
    if (mult !== 1 || autos !== 0) {
        ret += "\n\n" + sux;

        if (mult !== 1) ret += "x" + mult;
        if (autos !== 0) ret += "+" + autos;

        ret += "=";
        if (format) gradedFormatting(stats, sux);
        ret += Math.floor(sux * mult) + autos + " Successes";
        if (format) ret += "[/b][/color]";
        printStatistics({ mean: stats.mean * mult + autos, standardDeviation: stats.standardDeviation * mult });
    } else if (rerollOnes) {
        ret += "\n\n";
        if (format) gradedFormatting(stats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/b][/color]";
        printStatistics(stats);
    }

    return ret + "\n"; // return the finished statement to the console

    // helper functions
    function printStatistics({ mean, standardDeviation }: { mean: number; standardDeviation: number }) {
        ret += " ";
        if (!showStats) ret += "[color=transparent]";
        ret +=
            "[sup][size=3]mean: [b]" +
            mean +
            "[/b] standard deviation: [b]" +
            Math.round(standardDeviation * 100) / 100 +
            "[/b][/size][/sup]";
        if (!showStats) ret += "[/color]";
    }

    function gradedFormatting(
        { mean, standardDeviation }: { mean: number; standardDeviation: number },
        successes: number,
    ) {
        ret += "[color=rgb(";
        if (successes < mean - standardDeviation) ret += "223, 31, 31";
        else if (successes < mean) ret += "255, 159, 0";
        else if (successes === mean) ret += "223, 223, 223";
        else if (successes < mean + standardDeviation) ret += "191, 255, 0";
        else ret += "31, 223, 31"; // succusses > mean + standardDeviation
        ret += ")][b]";
    }

    function statistics(
        dice: number,
        targetnumber: number,
        type: "over" | "under",
        includeRerolls: boolean = false,
    ): { mean: number; standardDeviation: number } {
        let mean;
        let standardDeviation;
        let meanPerDie;
        let sdPerDie;

        if (type === "under") {
            let winningFaces = targetnumber - 1;

            if (includeRerolls) meanPerDie = 0.12 * winningFaces;
            else meanPerDie = 0.1 * winningFaces;

            if (includeRerolls) sdPerDie = Math.sqrt(0.18 * winningFaces - 0.0144 * winningFaces * winningFaces);
            else sdPerDie = Math.sqrt(0.1 * winningFaces - 0.01 * winningFaces * winningFaces);
        } else {
            let winningFaces = 10 - targetnumber;

            meanPerDie = 0.1 * winningFaces;
            sdPerDie = Math.sqrt(0.1 * winningFaces - 0.01 * winningFaces * winningFaces);
        }

        mean = dice * meanPerDie;
        standardDeviation = Math.sqrt(dice) * sdPerDie;

        return { mean: mean, standardDeviation: standardDeviation };
    }
}
// initialize Math.random()
for (let i = 0; i < 1000; i++) i -= Math.random();
Code:
function diceroller({name,type,tn,dice,rerollOnes=false,mult=1,autos=0,format=true,outputStats:showStats=false}){let ret="\n";ret+=name?name+" | ":"";if(format){ret+="[b]"}ret+=dice+" Dice";if(format){ret+="[/b]"}ret+="\n";let sux=0;let stats;if(type==="over"){for(let i=0;i<dice;i+=1){let num=Math.floor(Math.random()*10)+1;if(num>tn){sux+=1}ret+=num+" "}stats=statistics(dice,tn,type);ret+="| ";if(format){gradedFormatting(stats,sux)}ret+=sux+" Successes";if(format){ret+="[/color]"}printStatistics(stats)}else if(type==="under"){let ones=0;for(let i=0;i<dice;i+=1){let num=Math.floor(Math.random()*10)+1;if(num<tn){sux+=1}if(num===1){ones+=1}ret+=num+" "}let basicStats=statistics(dice,tn,type);ret+="| ";if(format){gradedFormatting(basicStats,sux)}ret+=sux+" Successes";if(format){ret+="[/b][/color]"}printStatistics(basicStats);if(rerollOnes&&ones>0){ret+="\n\n";ret+="Rerolling ";if(format){gradedFormatting(statistics(dice,2,"under"),ones)}ret+=ones;if(format){ret+="[/b][/color]"}printStatistics(statistics(dice,2,"under"));ret+="\n";let rerolls=0;for(let i=0;i<ones;i+=1){let num=Math.floor(Math.random()*10)+1;if(num<tn){rerolls+=1}ret+=num+" "}let rerollStats=statistics(ones,tn,type);stats=statistics(dice,tn,type,true);ret+="| "+rerolls+"x2=";if(format){gradedFormatting(rerollStats,rerolls)}ret+=2*rerolls+" Successes";if(format){ret+="[/b][/color]"}printStatistics({mean:rerollStats.mean*2,standardDeviation:rerollStats.standardDeviation*2});sux+=2*rerolls}else{stats=basicStats}}else{return "ERROR: You did not specify whether to roll OVER or UNDER the targetnumber."}if(mult!==1||autos!==0){ret+="\n\n"+sux;if(mult!==1){ret+="x"+mult}if(autos!==0){ret+="+"+autos}ret+="=";if(format){gradedFormatting(stats,sux)}ret+=Math.floor(sux*mult)+autos+" Successes";if(format){ret+="[/b][/color]"}printStatistics({mean:stats.mean*mult+autos,standardDeviation:stats.standardDeviation*mult})}else if(rerollOnes){ret+="\n\n";if(format){gradedFormatting(stats,sux)}ret+=sux+" Successes";if(format){ret+="[/b][/color]"}printStatistics(stats)}return ret+"\n";function printStatistics({mean,standardDeviation}){ret+=" ";if(!showStats){ret+="[color=transparent]"}ret+="[sup][size=3]mean: [b]"+mean+"[/b] standard deviation: [b]"+Math.round(standardDeviation*100)/100+"[/b][/size][/sup]";if(!showStats){ret+="[/color]"}}function gradedFormatting({mean,standardDeviation},successes){ret+="[color=rgb(";if(successes<mean-standardDeviation){ret+="223, 31, 31"}else if(successes<mean){ret+="255, 159, 0"}else if(successes===mean){ret+="223, 223, 223"}else if(successes<mean+standardDeviation){ret+="191, 255, 0"}else{ret+="31, 223, 31"}ret+=")][b]"}function statistics(dice,targetnumber,type,includeRerolls=false){let mean;let standardDeviation;let meanPerDie;let sdPerDie;if(type==="under"){let winningFaces=targetnumber-1;if(includeRerolls){meanPerDie=0.12*winningFaces}else{meanPerDie=0.1*winningFaces}if(includeRerolls){sdPerDie=Math.sqrt(0.18*winningFaces-0.0144*winningFaces*winningFaces)}else{sdPerDie=Math.sqrt(0.1*winningFaces-0.01*winningFaces*winningFaces)}}else{let winningFaces=10-targetnumber;meanPerDie=0.1*winningFaces;sdPerDie=Math.sqrt(0.1*winningFaces-0.01*winningFaces*winningFaces)}mean=dice*meanPerDie;standardDeviation=Math.sqrt(dice)*sdPerDie;return{mean:mean,standardDeviation:standardDeviation}}}for(let i=0;i<1000;i+=1){i-=Math.random()}
JavaScript:
diceroller({
    type: "under",
    tn: 6,
    dice: 800,
    name: "Physical Cultivation",
    rerollOnes: true,
    mult: 1.1,
})
JavaScript:
diceroller({
    type: "under",
    tn: 6,
    dice: 800,
    name: "Physical Cultivation",
    rerollOnes: true,
    mult: 1.1,
    autos: 0,
    format: true,
    showStats: false,
})
Among these values you can omit:
  • name to roll without a name
  • rerollOnes to not reroll 1s
  • mult for a default multiplier of 1 which will not be mentioned in the output
  • autos for a default number of 0 autos which will not be mentioned in the output
  • format for a default value of true which means formatting will be enabled
  • showStats for a default value of false which means the statistics will be printed as invisi-text (color transparent)
Note 1: As long as you do not take any action which will empty the Console's cache (such as closing the browser) you don't need to repeat steps 1 and 2.
Note 2: You can enter the parameters in any order you want; you don't need to follow the order of the template.
JavaScript:
function diceroller({
    // set standard values
    name,
    type,
    tn,
    dice,
    rerollOnes = false,
    mult = 1,
    autos = 0,
    format = true,
    showStats = false,
}: {
    // declaration of inputs
    name?: string;
    type: "over" | "under";
    tn: number;
    dice: number;
    rerollOnes?: boolean;
    mult?: number;
    autos?: number;
    format?: boolean;
    showStats?: boolean;
}): string {
    let ret = "\n";
    ret += name ? name + " | " : "";
    if (format) ret += "[b]";
    ret += dice + " Dice";
    if (format) ret += "[/b]";
    ret += "\n";
    const crypto: Crypto = window.crypto;
    let sux = 0;
    let stats;
    if (type === "over") {
        // Roll each die
        let nums: Uint8Array = new Uint8Array(dice);
        crypto.getRandomValues(nums);
        nums.forEach((num) => {
            num = (num % 10) + 1;
            if (num > tn) sux++;
            ret += num + " ";
        });
        // calculate mean and standard deviation
        stats = statistics(dice, tn, type);
        // summarize the successes
        ret += "| ";
        if (format) gradedFormatting(stats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/color]";
        printStatistics(stats);
    } else if (type === "under") {
        let ones = 0;
        // Roll each die
        let nums: Uint8Array = new Uint8Array(dice);
        crypto.getRandomValues(nums);
        nums.forEach((num) => {
            num = (num % 10) + 1;
            if (num < tn) sux++;
            if (num === 1) ones++;
            ret += num + " ";
        });
        // calculate mean and standard deviation
        let basicStats = statistics(dice, tn, type);
        // summarize the successes
        ret += "| ";
        if (format) gradedFormatting(basicStats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/b][/color]";
        printStatistics(basicStats);
        if (rerollOnes && ones > 0) {
            ret += "\n\n";
            ret += "Rerolling ";
            if (format) gradedFormatting(statistics(dice, 2, "under"), ones);
            ret += ones;
            if (format) ret += "[/b][/color]";
            printStatistics(statistics(dice, 2, "under"));
            ret += "\n";
            let rerolls = 0;
            // Roll each die
            nums = new Uint8Array(ones);
            crypto.getRandomValues(nums);
            nums.forEach((num) => {
                num = (num % 10) + 1;
                if (num < tn) rerolls++;
                ret += num + " ";
            });
            // calculate mean and standard deviation for rerolls
            let rerollStats = statistics(ones, tn, type);
            // calculate mean and standard deviation for total
            stats = statistics(dice, tn, type, true);
            ret += "| " + rerolls + "x2=";
            if (format) gradedFormatting(rerollStats, rerolls);
            ret += 2 * rerolls + " Successes"; // summarize the successes
            if (format) ret += "[/b][/color]";
            printStatistics({ mean: rerollStats.mean * 2, standardDeviation: rerollStats.standardDeviation * 2 });
            sux += 2 * rerolls;
        } else stats = basicStats;
    } else return "ERROR: You did not specify whether to roll OVER or UNDER the targetnumber.";
    // Add multipliers and autos if there are any
    if (mult !== 1 || autos !== 0) {
        ret += "\n\n" + sux;
        if (mult !== 1) ret += "x" + mult;
        if (autos !== 0) ret += "+" + autos;
        ret += "=";
        if (format) gradedFormatting(stats, sux);
        ret += Math.floor(sux * mult) + autos + " Successes";
        if (format) ret += "[/b][/color]";
        printStatistics({ mean: stats.mean * mult + autos, standardDeviation: stats.standardDeviation * mult });
    } else if (rerollOnes) {
        ret += "\n\n";
        if (format) gradedFormatting(stats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/b][/color]";
        printStatistics(stats);
    }
    return ret + "\n"; // return the finished statement to the console
    // helper functions
    function printStatistics({ mean, standardDeviation }: { mean: number; standardDeviation: number }) {
        ret += " ";
        if (!showStats) ret += "[color=transparent]";
        ret +=
            "[sup][size=3]mean: [b]" +
            mean +
            "[/b] standard deviation: [b]" +
            Math.round(standardDeviation * 100) / 100 +
            "[/b][/size][/sup]";
        if (!showStats) ret += "[/color]";
    }
    function gradedFormatting(
        { mean, standardDeviation }: { mean: number; standardDeviation: number },
        successes: number,
    ) {
        ret += "[color=rgb(";
        if (successes < mean - standardDeviation) ret += "223, 31, 31";
        else if (successes < mean) ret += "255, 159, 0";
        else if (successes === mean) ret += "223, 223, 223";
        else if (successes < mean + standardDeviation) ret += "191, 255, 0";
        else ret += "31, 223, 31"; // succusses > mean + standardDeviation
        ret += ")][b]";
    }
    function statistics(
        dice: number,
        targetnumber: number,
        type: "over" | "under",
        includeRerolls: boolean = false,
    ): { mean: number; standardDeviation: number } {
        let mean;
        let standardDeviation;
        let meanPerDie;
        let sdPerDie;
        if (type === "under") {
            let winningFaces = targetnumber - 1;
            if (includeRerolls) meanPerDie = 0.12 * winningFaces;
            else meanPerDie = 0.1 * winningFaces;
            if (includeRerolls) sdPerDie = Math.sqrt(0.18 * winningFaces - 0.0144 * winningFaces * winningFaces);
            else sdPerDie = Math.sqrt(0.1 * winningFaces - 0.01 * winningFaces * winningFaces);
        } else {
            let winningFaces = 10 - targetnumber;
            meanPerDie = 0.1 * winningFaces;
            sdPerDie = Math.sqrt(0.1 * winningFaces - 0.01 * winningFaces * winningFaces);
        }
        mean = dice * meanPerDie;
        standardDeviation = Math.sqrt(dice) * sdPerDie;
        return { mean: mean, standardDeviation: standardDeviation };
    }
}
Code:
function diceroller({name,type,tn,dice,rerollOnes=false,mult=1,autos=0,format=true,showStats=false}){let ret="\n";ret+=name?name+" | ":"";if(format){ret+="[b]"}ret+=dice+" Dice";if(format){ret+="[/b]"}ret+="\n";const crypto=window.crypto;let sux=0;let stats;if(type==="over"){let nums=new Uint8Array(dice);crypto.getRandomValues(nums);nums.forEach((num)=>{num=(num%10)+1;if(num>tn){sux+=1}ret+=num+" "});stats=statistics(dice,tn,type);ret+="| ";if(format){gradedFormatting(stats,sux)}ret+=sux+" Successes";if(format){ret+="[/color]"}printStatistics(stats)}else if(type==="under"){let ones=0;let nums=new Uint8Array(dice);crypto.getRandomValues(nums);nums.forEach((num)=>{num=(num%10)+1;if(num<tn){sux+=1}if(num===1){ones+=1}ret+=num+" "});let basicStats=statistics(dice,tn,type);ret+="| ";if(format){gradedFormatting(basicStats,sux)}ret+=sux+" Successes";if(format){ret+="[/b][/color]"}printStatistics(basicStats);if(rerollOnes&&ones>0){ret+="\n\n";ret+="Rerolling ";if(format){gradedFormatting(statistics(dice,2,"under"),ones)}ret+=ones;if(format){ret+="[/b][/color]"}printStatistics(statistics(dice,2,"under"));ret+="\n";let rerolls=0;nums=new Uint8Array(ones);crypto.getRandomValues(nums);nums.forEach((num)=>{num=(num%10)+1;if(num<tn){rerolls+=1}ret+=num+" "});let rerollStats=statistics(ones,tn,type);stats=statistics(dice,tn,type,true);ret+="| "+rerolls+"x2=";if(format){gradedFormatting(rerollStats,rerolls)}ret+=2*rerolls+" Successes";if(format){ret+="[/b][/color]"}printStatistics({mean:rerollStats.mean*2,standardDeviation:rerollStats.standardDeviation*2});sux+=2*rerolls}else{stats=basicStats}}else{return "ERROR: You did not specify whether to roll OVER or UNDER the targetnumber."}if(mult!==1||autos!==0){ret+="\n\n"+sux;if(mult!==1){ret+="x"+mult}if(autos!==0){ret+="+"+autos}ret+="=";if(format){gradedFormatting(stats,sux)}ret+=Math.floor(sux*mult)+autos+" Successes";if(format){ret+="[/b][/color]"}printStatistics({mean:stats.mean*mult+autos,standardDeviation:stats.standardDeviation*mult})}else if(rerollOnes){ret+="\n\n";if(format){gradedFormatting(stats,sux)}ret+=sux+" Successes";if(format){ret+="[/b][/color]"}printStatistics(stats)}return ret+"\n";function printStatistics({mean,standardDeviation}){ret+=" ";if(!showStats){ret+="[color=transparent]"}ret+="[sup][size=3]mean: [b]"+mean+"[/b] standard deviation: [b]"+Math.round(standardDeviation*100)/100+"[/b][/size][/sup]";if(!showStats){ret+="[/color]"}}function gradedFormatting({mean,standardDeviation},successes){ret+="[color=rgb(";if(successes<mean-standardDeviation){ret+="223, 31, 31"}else if(successes<mean){ret+="255, 159, 0"}else if(successes===mean){ret+="223, 223, 223"}else if(successes<mean+standardDeviation){ret+="191, 255, 0"}else{ret+="31, 223, 31"}ret+=")][b]"}function statistics(dice,targetnumber,type,includeRerolls=false){let mean;let standardDeviation;let meanPerDie;let sdPerDie;if(type==="under"){let winningFaces=targetnumber-1;if(includeRerolls){meanPerDie=0.12*winningFaces}else{meanPerDie=0.1*winningFaces}if(includeRerolls){sdPerDie=Math.sqrt(0.18*winningFaces-0.0144*winningFaces*winningFaces)}else{sdPerDie=Math.sqrt(0.1*winningFaces-0.01*winningFaces*winningFaces)}}else{let winningFaces=10-targetnumber;meanPerDie=0.1*winningFaces;sdPerDie=Math.sqrt(0.1*winningFaces-0.01*winningFaces*winningFaces)}mean=dice*meanPerDie;standardDeviation=Math.sqrt(dice)*sdPerDie;return{mean:mean,standardDeviation:standardDeviation}}}
No template changes from this version to the prior or next.
Current version: 1.2.2
JavaScript:
function diceroller({
    // set standard values
    name,
    type,
    tn,
    dice,
    rerollOnes = false,
    mult = 1,
    autos = 0,
    format = true,
    showStats = false,
}: {
    // declaration of inputs
    name?: string;
    type: "over" | "under";
    tn: number;
    dice: number;
    rerollOnes?: boolean;
    mult?: number;
    autos?: number;
    format?: boolean;
    showStats?: boolean;
}): string {
    let ret = "\n";
    ret += name ? name + " | " : "";
    if (format) ret += "[b]";
    ret += dice + " Dice";
    if (format) ret += "[/b]";
    ret += "\n";
    const crypto: Crypto = window.crypto;
    let sux = 0;
    let stats;
    if (type === "over") {
        // Roll each die
        let nums: Uint8Array = new Uint8Array(dice);
        crypto.getRandomValues(nums);
        nums.forEach((num) => {
            num = (num % 10) + 1;
            if (num > tn) sux++;
            ret += num + " ";
        });
        // calculate mean and standard deviation
        stats = statistics(dice, tn, type);
        // summarize the successes
        ret += "| ";
        if (format) gradedFormatting(stats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/b][/color]";
        printStatistics(stats);
    } else if (type === "under") {
        let ones = 0;
        // Roll each die
        let nums: Uint8Array = new Uint8Array(dice);
        crypto.getRandomValues(nums);
        nums.forEach((num) => {
            num = (num % 10) + 1;
            if (num < tn) sux++;
            if (num === 1) ones++;
            ret += num + " ";
        });
        // calculate mean and standard deviation
        let basicStats = statistics(dice, tn, type);
        // summarize the successes
        ret += "| ";
        if (format) gradedFormatting(basicStats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/b][/color]";
        printStatistics(basicStats);
        if (rerollOnes && ones > 0) {
            ret += "\n\n";
            ret += "Rerolling ";
            if (format) gradedFormatting(statistics(dice, 2, "under"), ones);
            ret += ones;
            if (format) ret += "[/b][/color]";
            printStatistics(statistics(dice, 2, "under"));
            ret += "\n";
            let rerolls = 0;
            // Roll each die
            nums = new Uint8Array(ones);
            crypto.getRandomValues(nums);
            nums.forEach((num) => {
                num = (num % 10) + 1;
                if (num < tn) rerolls++;
                ret += num + " ";
            });
            // calculate mean and standard deviation for rerolls
            let rerollStats = statistics(ones, tn, type);
            // calculate mean and standard deviation for total
            stats = statistics(dice, tn, type, true);
            ret += "| " + rerolls + "x2=";
            if (format) gradedFormatting(rerollStats, rerolls);
            ret += 2 * rerolls + " Successes"; // summarize the successes
            if (format) ret += "[/b][/color]";
            printStatistics({ mean: rerollStats.mean * 2, standardDeviation: rerollStats.standardDeviation * 2 });
            sux += 2 * rerolls;
        } else stats = basicStats;
    } else return "ERROR: You did not specify whether to roll OVER or UNDER the targetnumber.";
    // Add multipliers and autos if there are any
    if (mult !== 1 || autos !== 0) {
        ret += "\n\n" + sux;
        if (mult !== 1) ret += "x" + mult;
        if (autos !== 0) ret += "+" + autos;
        ret += "=";
        if (format) gradedFormatting(stats, sux);
        ret += Math.floor(sux * mult) + autos + " Successes";
        if (format) ret += "[/b][/color]";
        printStatistics({ mean: stats.mean * mult + autos, standardDeviation: stats.standardDeviation * mult });
    } else if (rerollOnes) {
        ret += "\n\n";
        if (format) gradedFormatting(stats, sux);
        ret += sux + " Successes";
        if (format) ret += "[/b][/color]";
        printStatistics(stats);
    }
    return ret + "\n"; // return the finished statement to the console
    // helper functions
    function printStatistics({ mean, standardDeviation }: { mean: number; standardDeviation: number }) {
        ret += " ";
        if (!showStats) ret += "[color=transparent]";
        ret +=
            "[sup][size=3]mean: [b]" +
            mean +
            "[/b] standard deviation: [b]" +
            Math.round(standardDeviation * 100) / 100 +
            "[/b][/size][/sup]";
        if (!showStats) ret += "[/color]";
    }
    function gradedFormatting(
        { mean, standardDeviation }: { mean: number; standardDeviation: number },
        successes: number,
    ) {
        ret += "[color=rgb(";
        if (successes < mean - standardDeviation) ret += "223, 31, 31";
        else if (successes < mean) ret += "255, 159, 0";
        else if (successes === mean) ret += "223, 223, 223";
        else if (successes < mean + standardDeviation) ret += "191, 255, 0";
        else ret += "31, 223, 31"; // succusses > mean + standardDeviation
        ret += ")][b]";
    }
    function statistics(
        dice: number,
        targetnumber: number,
        type: "over" | "under",
        includeRerolls: boolean = false,
    ): { mean: number; standardDeviation: number } {
        let mean;
        let standardDeviation;
        let meanPerDie;
        let sdPerDie;
        if (type === "under") {
            let winningFaces = targetnumber - 1;
            if (includeRerolls) meanPerDie = 0.12 * winningFaces;
            else meanPerDie = 0.1 * winningFaces;
            if (includeRerolls) sdPerDie = Math.sqrt(0.18 * winningFaces - 0.0144 * winningFaces * winningFaces);
            else sdPerDie = Math.sqrt(0.1 * winningFaces - 0.01 * winningFaces * winningFaces);
        } else {
            let winningFaces = 10 - targetnumber;
            meanPerDie = 0.1 * winningFaces;
            sdPerDie = Math.sqrt(0.1 * winningFaces - 0.01 * winningFaces * winningFaces);
        }
        mean = dice * meanPerDie;
        standardDeviation = Math.sqrt(dice) * sdPerDie;
        return { mean: mean, standardDeviation: standardDeviation };
    }
}
Code:
function diceroller({name,type,tn,dice,rerollOnes=false,mult=1,autos=0,format=true,showStats=false}){let ret="\n";ret+=name?name+" | ":"";if(format){ret+="[b]"}ret+=dice+" Dice";if(format){ret+="[/b]"}ret+="\n";const crypto=window.crypto;let sux=0;let stats;if(type==="over"){let nums=new Uint8Array(dice);crypto.getRandomValues(nums);nums.forEach((num)=>{num=(num%10)+1;if(num>tn){sux+=1}ret+=num+" "});stats=statistics(dice,tn,type);ret+="| ";if(format){gradedFormatting(stats,sux)}ret+=sux+" Successes";if(format){ret+="[/b][/color]"}printStatistics(stats)}else if(type==="under"){let ones=0;let nums=new Uint8Array(dice);crypto.getRandomValues(nums);nums.forEach((num)=>{num=(num%10)+1;if(num<tn){sux+=1}if(num===1){ones+=1}ret+=num+" "});let basicStats=statistics(dice,tn,type);ret+="| ";if(format){gradedFormatting(basicStats,sux)}ret+=sux+" Successes";if(format){ret+="[/b][/color]"}printStatistics(basicStats);if(rerollOnes&&ones>0){ret+="\n\n";ret+="Rerolling ";if(format){gradedFormatting(statistics(dice,2,"under"),ones)}ret+=ones;if(format){ret+="[/b][/color]"}printStatistics(statistics(dice,2,"under"));ret+="\n";let rerolls=0;nums=new Uint8Array(ones);crypto.getRandomValues(nums);nums.forEach((num)=>{num=(num%10)+1;if(num<tn){rerolls+=1}ret+=num+" "});let rerollStats=statistics(ones,tn,type);stats=statistics(dice,tn,type,true);ret+="| "+rerolls+"x2=";if(format){gradedFormatting(rerollStats,rerolls)}ret+=2*rerolls+" Successes";if(format){ret+="[/b][/color]"}printStatistics({mean:rerollStats.mean*2,standardDeviation:rerollStats.standardDeviation*2});sux+=2*rerolls}else{stats=basicStats}}else{return "ERROR: You did not specify whether to roll OVER or UNDER the targetnumber."}if(mult!==1||autos!==0){ret+="\n\n"+sux;if(mult!==1){ret+="x"+mult}if(autos!==0){ret+="+"+autos}ret+="=";if(format){gradedFormatting(stats,sux)}ret+=Math.floor(sux*mult)+autos+" Successes";if(format){ret+="[/b][/color]"}printStatistics({mean:stats.mean*mult+autos,standardDeviation:stats.standardDeviation*mult})}else if(rerollOnes){ret+="\n\n";if(format){gradedFormatting(stats,sux)}ret+=sux+" Successes";if(format){ret+="[/b][/color]"}printStatistics(stats)}return ret+"\n";function printStatistics({mean,standardDeviation}){ret+=" ";if(!showStats){ret+="[color=transparent]"}ret+="[sup][size=3]mean: [b]"+mean+"[/b] standard deviation: [b]"+Math.round(standardDeviation*100)/100+"[/b][/size][/sup]";if(!showStats){ret+="[/color]"}}function gradedFormatting({mean,standardDeviation},successes){ret+="[color=rgb(";if(successes<mean-standardDeviation){ret+="223, 31, 31"}else if(successes<mean){ret+="255, 159, 0"}else if(successes===mean){ret+="223, 223, 223"}else if(successes<mean+standardDeviation){ret+="191, 255, 0"}else{ret+="31, 223, 31"}ret+=")][b]"}function statistics(dice,targetnumber,type,includeRerolls=false){let mean;let standardDeviation;let meanPerDie;let sdPerDie;if(type==="under"){let winningFaces=targetnumber-1;if(includeRerolls){meanPerDie=0.12*winningFaces}else{meanPerDie=0.1*winningFaces}if(includeRerolls){sdPerDie=Math.sqrt(0.18*winningFaces-0.0144*winningFaces*winningFaces)}else{sdPerDie=Math.sqrt(0.1*winningFaces-0.01*winningFaces*winningFaces)}}else{let winningFaces=10-targetnumber;meanPerDie=0.1*winningFaces;sdPerDie=Math.sqrt(0.1*winningFaces-0.01*winningFaces*winningFaces)}mean=dice*meanPerDie;standardDeviation=Math.sqrt(dice)*sdPerDie;return{mean:mean,standardDeviation:standardDeviation}}}
And now to the instructions to actually using it:
Step 1: Open the browser's devTools with Ctrl + Shift + I (that's a large i, not a small L) and then navigate to the Console tab.
Step 2: Copy paste the code in the Compiled code spoiler above into the console and hit enter.
Step 3: Call the diceroller function with the parameters you want. For that matter I have prepared for you a template:
JavaScript:
diceroller({
    type: "under",
    tn: 6,
    dice: 800,
    name: "Physical Cultivation",
    rerollOnes: true,
    mult: 1.1,
})
JavaScript:
diceroller({
    type: "under",
    tn: 6,
    dice: 800,
    name: "Physical Cultivation",
    rerollOnes: true,
    mult: 1.1,
    autos: 0,
    format: true,
    showStats: false,
})
Among these values you can omit:
  • name to roll without a name
  • rerollOnes to not reroll 1s
  • mult for a default multiplier of 1 which will not be mentioned in the output
  • autos for a default number of 0 autos which will not be mentioned in the output
  • format for a default value of true which means formatting will be enabled
  • showStats for a default value of false which means the statistics will be printed as invisi-text (color transparent)
Note 1: As long as you do not take any action which will empty the Console's cache (such as closing the browser) you don't need to repeat steps 1 and 2.
Note 2: You can enter the parameters in any order you want; you don't need to follow the order of the template.

I have listened to the grumbles about the statistical unlikeliness of the diceroller's performance and luckily didn't procrastinate on it for too long (which is… surprising, given that I procrastinated on it for weeks). The problem should now be fixed given that I'm using a cryptographically secure source of randomness now, which is to say the highest class of randomness that exists.
Ok, third version is out. Someone suggested the ability to alternatively enter the dice as YSS, GSS, AP and miscellaneous. Not sure if that would be appreciated. Just to be clear, this would add the alternative of specifying the dice as
JavaScript:
dice: {gss: 8, ap: 4, yss: 8, misc: 20}
i.e. calculating the amount of dice internally with any pills added under misc.

Update on the browser extension side: It doesn't appear to be overly complicated but I'm uncertain whether the extra effort on my and more importantly Yrs' side is worth it. The thing is that transfering the browser extension can't be done via the current exchange of simple text copy-pasting (well, it actually can be done that way but again, extra effort and this time with additional points of failure) because it is mandatory for several documents to exist in the host file system. Furthermore it is unlikely for me to get the extension added to the Chrome Web Store, so the extension has to be installed manually using the developer mode which compromises security if one does not know what they're doing (which applies to Yrs) :Ü™
 
Last edited:
If it makes you feel better we prob will have a decent chunk of reds and yellows under us. We know that servant clans exist from qi mom coming from one, and handmaidens and favored servants are a thing.

any town, province we have will also have to be filled with guards as well, so well assumingly have to recruit from the population or rent them from other places as well.
Its also worth noting that a Green Baron like Ling Qi can support the cultivation of her mother as a rounding error since she no longer really uses red stones. (Quite literally)

It wouldn't be that hard for Ling Qi to support the cultivation of multiples of her servants. But most won't have the Talent to get anywhere.
 
Back
Top