Miskatonic-Investigative-Society / CoC7-FoundryVTT

An unofficial implementation of the Call of Cthulhu 7th Edition game system for Foundry Virtual Tabletop
https://discord.gg/foundryvtt
GNU General Public License v3.0
119 stars 98 forks source link

Roll success levels #74

Closed js-murph closed 4 years ago

js-murph commented 4 years ago

First of all, I discovered this today and I'm so excited to finally be able to move my CoC7 games to foundry. I had actually just finished writing a super trashy implementation with simple world building and a pile of macros, so I'm happy to see that go to an early grave.

One thing I've noticed so far is that using this system when making a roll the player selects the intended success level. However I always thought the intended way was for the player to roll, inform the keeper of what level of success they achieved and let the keeper narrate based on their level of success, it also helps keep a little bit of mystery and danger to pushing rolls when you don't know exactly how hard the task is going to be.

In the hideous macros I created the output I was using was something like this.

image

Thanks for all your hard work so far and really looking forward to my first game using this!

HavlockV commented 4 years ago

Hi js-murph. Thanks for the feedback, always appreciated. As requested before, I'm implementing blind and gm rolls. Actually I'm testing them right now, for regulars checks. If it goes as planned (it rarely does, but I might get lucky once in a while) it will be released with some other minor things tomorrow. It will then be adapted for the melee and the range combat flow. For the checks the user select 'blind GM roll' from the side bar. He still can select the difficulty and bonus/penalties but he will not see any results : Player's view : image

The Keeper on his side will see the result and will have some button to decide of the roll difficulty, to award experience or to force a pass on the check : Keeper's view : image

js-murph commented 4 years ago

This is very cool and gets closer to solving the issue, but there's sort of two remaining issues...

  1. I would have to force all my players to most of the time be making blind rolls which would result in them never see their roll results, which isn't very satisfying for the player.
  2. In my head I'll need to do the math after every roll to work out whether the roll meets the criteria for a level of success above normal.

Correct me if I am making some incorrect assumptions there.

I've also just realized that the example image I gave in my original post may be misleading as well because I depicted only combat rolls, so for clarity normal skill rolls shows the same output just without a damage roll. It might be easier to include a code snippet to get an idea of exactly what I mean:

  let skillValue = actorData.data.attributes[skillName].value;
  let skillHalf = Math.floor(actorData.data.attributes[skillName].value / 2);
  let skillFifth = Math.floor(actorData.data.attributes[skillName].value / 5);

  let rollFormula = "1d100";
  let roll = new Roll(rollFormula);
  roll.roll();

  let resultStatus = "Failure";
  let resultBackgroundColour = "#ffcccc";
  let resultForegroundColour = "#ff0000";
  if (roll.total < skillFifth) {
    resultStatus = "Extreme Success";
    resultBackgroundColour = "#ccff99";
    resultForegroundColour = "#009933";
  } else if (roll.total < skillHalf) {
    resultStatus = "Hard Success";
    resultBackgroundColour = "#ffff99";
    resultForegroundColour = "#cc9900";
  } else if (roll.total < skillValue) {
    resultStatus = "Normal Success";
    resultBackgroundColour = "#ffcc99";
    resultForegroundColour = "#cc6600";
  }

  let message = `
    <div>
      <img src="${actorData.img}" style="width: 50px; height: 50px; vertical-align: middle;"/>
      <span style="vertical-align: middle; font-size: 110%;">${actorData.name}</span>
    </div>

    <br/>

    <p style="font-size: 130%;">${actorData.data.attributes[skillName].label}</p>

    <table style="border:0px;">
      <tr style="border-bottom: solid 1px black;">
        <td style="text-align: center; font-size: 120%;">${roll.formula}</td>
      </tr>
      <tr>
        <td style="text-align: center; font-size: 120%;">${roll.total}</td>
      </tr>
    </table>

    <table style="float: left;">
      <tr>
        <td style="text-align: center; font-size: 150%; width: 20%;">${skillValue}</td>
        <td style="width: 10%;">
          <table style="width: 100%; margin-top: 0px; margin-bottom: 0px; border: 0px;">
            <tr><td style="text-align: center;">${skillHalf}</td></tr>
            <tr><td style="text-align: center;">${skillFifth}</td></tr>
          </table>
        </td>
        <td style="text-align: center; background-color: ${resultBackgroundColour}; color: ${resultForegroundColour}; width: 70%;">${resultStatus}</td>
      </tr>
    </table>
  `;

  game.dice3d.showForRoll(roll).then(displayed => { ChatMessage.create({content: message}) });

Now of course I'm not saying I want exactly that, but I'd like an easy way of knowing the highest level of success post roll.

HavlockV commented 4 years ago

Indeed, during a blind roll the player is never given the option to actually see his results. I understand how having only blind rolls should be unsatisfying. The roll itself displays the level of success achieved in the roll details, not on the button. It did on the early version (and still does on the combat flow) but it was getting messy after spending luck/pushing a roll. The color coding could be a solution, I'll have a look at that (and steal your colors ). What could be done is to have the option to select 'unknown' difficulty on the roll with eventually a system wide setting to select the desired default difficulty. This will allow to keep fast forwarding (holding shift while triggering a check). The players will still have the opportunity to spend luck to increase the success level, without knowing if it's necessary or not. The only 'downside' is that it will create (just a little bit) more work from the keeper side. He will have to decide if the roll does actually select the corresponding skill for development. I'll finish with the blind/private roll and start on this. The modification doesn't seems to long nor complicated.

js-murph commented 4 years ago

That sounds like a reasonable compromise. I can definitely appreciate how some of the optional mechanics like luck complicate things and you need to look for simplicity where you can find it, ranged weapons are also rife with edge cases to consider.

Thanks for considering this feature :)

tadaimatrpg commented 4 years ago

Hello, HavlockV. Thank you for your reply on Discord. And congratulations on the publication. I'll post here as well, since the issue of success level was mentioned. Just as we were talking about in Discord, about the level of success, I'm showing it in an API-based way. I'll leave it up to the individual author to decide how to output directly from the HTML, but here's how I'm judging it There are different ways to fail 100% of skills depending on the supplement, and to accommodate any supplement, I'll force a fumble if the number 100 on the die comes up.

Once you have the basics of dice level determination and can display success, you can then apply it to any system.


 //Define a function to read the value
  let m = 0;

  //Define errors as debugging.
  let res = "<h1>Error</h1>";

  //Normal Dice
  let r = new Roll("1d100");

  m = x/*Enter a skill value in X*/;

//Determination based on rolls and readings
r.roll();
//Put the result of the die into s as a number rather than an object.
s = r.result;
if(s <= 1) res = "<h1>CRITICAL</h1>";
else if(s >= 100) res= "<h1>FUMBLE</h1>";
else if(s <= (m/5)) res= "<h1>EXTREME SUCCESS</h1>";
else if(s <= (m/2)) res= "<h1>HARD SUCCESS</h1>";
else if(s <= m) res= "<h1>REGULAR SUCCESS</h1>";
else if(s >= 96){if(m < 50) res= "<h1>FUMBLE</h1>"; 
else res= "<h1>FAIL</h1>";}
else res= "<h1>FAIL</h1>";

//The resulting output.
res += ("Skill value:" + m);
r.toMessage(
     {speaker: ChatMessage.getSpeaker(),
     flavor: res,
    });
HavlockV commented 4 years ago

Dicebot available in 0.2.8 Unknown difficulty rolls have been implemented. Select ???? from the difficulty/bonus selection window. Default roll mode (used as default in the selection window and for fast-forwarding by holding shift while clicking the skill) can be selected in options. Player can see his roll, choose to spend luck to improve his success. Difficulty to achieve is revealed upon selection by the Keeper. Level of success (above actual difficulty) are displayed on the card. with medals (critical) stars (success), spiders (failure) or skulls (fumble) Experience is automatically awarded upon success. I used your color coding for the success quality. Unknown roll can be combined with blind and private roll. Default mode selection : image Roll windows : image Player view : image image Keeper view and difficulty selection : image Both player and keeper's view when difficulty revealed : 1 level of succes : image 2 levels : image 1 failure : image Fumble: image

js-murph commented 4 years ago

Wow, great work, this looks 🔥

Thank you so much for adding this :D