Developing game using TTRPG elements

I’m developing a game based on content from Chaosium’s Call of Cthulhu TTRPG line of products. I’d like to be able to present a working game to the publisher to see if they’d be interested in either using it themselves or allowing me to produce myself - they are very cool about licensing. My problem is I’m not the best programmer - at all. I have lots of great ideas for how the mechanics of the TTRPG can be translated to the Twine game, but I’m spending a lot of unfruitful time looking for sample code and tutorials. Here’s what I’m trying to accomplish that I haven’t already (Twine 2 and Sugarcube 2):

  • Allocation of characteristics (stats) and other data with form validation
  • a system for the skills and allocation of values to the skills
  • Dice rolling logic is done BUT I feel like it could be a widget rather than cutting and pasting and editing code for dozens of passages.
  • Also dice rolling: it would be so sweet to have an animation of percentile dice actually rolling - no idea how I would do this
  • this is more CSS maybe - but the character sheet needs to be formatted

If anyone knows of similar mechanics that I can learn about, see sample code, etc, please let me know! Most of the content of the game is complete, I just took an existing solo scenario and cut and paste a lot.

TIA and if anyone is into Call of Cthulhu and wants to see what I’m doing, please let me know!


The only example on IFDB of a Twine game based off of a TTRPG I could find was Tale of the Starweavers. The source isn’t included, but the author left an email in the details for inquiries regarding the game. If you reached out to them, they might be willing to share.

Also, welcome to intfiction! The community is good about answering specific questions, so hopefully you’ll keep us in mind when you run into coding snafus. Good luck on your project!


Welcome Shana,

I’m not sure your first two bullets really are different questions. In both cases you need to create story variables and a mean to allow values to those variables.

Here’s a sample of how you can achieve this, with only two characteristics, but you can add coding for another characteristics. Also you can use the same model for skills.


<<set $pcStr to 10>>
<<set $pcDex to 10>>

Passage where you start to create the character

<<set _buypoints to 5>>
<span id="buycarac"><<include "Caracs">></span>

Passage Caracs

You have _buypoints remaining points to spend.

Strength: $pcStr <<if $pcStr lt 18 && _buypoints gt 0>><<link "[+]">><<set $pcStr++>><<set _buypoints-->><<replace "#buycarac">><<include "Caracs">><</replace>><</link>><<elseif $pcStr == 18>>maxed<<else>>Not enough points to buy higher charac<</if>> | <<if $pcStr gt 3>><<link "[-]">><<set $pcStr-->><<set _buypoints++>><<replace "#buycarac">><<include "Caracs">><</replace>><</link>><<else>>floored<</if>>

Dexterity: $pcDex <<if $pcDex lt 18 && _buypoints gt 0>><<link "[+]">><<set $pcDex++>><<set _buypoints-->><<replace "#buycarac">><<include "Caracs">><</replace>><</link>><<elseif $pcDex == 18>>maxed<<else>>Not enough points to buy higher charac<</if>> | <<if $pcDex gt 3>><<link "[-]">><<set $pcDex-->><<set _buypoints++>><<replace "#buycarac">><<include "Caracs">><</replace>><</link>><<else>>floored<</if>>

<<link "Confirm" "To skills">><</link>>

That’s by far not the only way to do it, but I like the <<include>> macro as it allows for not too much coding. Also there’s not too much javascript, as learning javascript alongside sugarcube might be a great deal of strain.

About your third bullet, here’s what you can put in a passage with the ‘widget’ tag:

<<widget "d100">><<set _dicetest to random(1,100)>>You roll a _dicetest.<</widget>>

In any passage you need to roll dice you can call the widget easily:

<<if _dicetest lte $Skill>>whatever happens if the skill check is a success.
<<else>>whatever happens is the skill check fails.

I don’t know how to make dynamic rolls, so nothing for the fourth bullet.
And as for the last bullet, there’s nothing anyone can offer if you don’t tell what you want exactly.


note: The following describes the technical steps used to access the source code of a Twine 1.x based project, it doesn’t cover the legal rights issues relating to doing so or for using someone else’s code.

As with all Twine based projects, the HTML page is the source code.

The project’s Story HTML file (Tale of the Starweavers.html) is being hosted on the site, which means you can use your web-browser’s “Save As” feature to save a local copy of that HTML file.

Based on a comment found within the <head> element of the HTML file it was generated using the abandoned Twine 1.x application and the discontinued Sugarcane (1) story format.

note: The Twine 2.x application doesn’t support the importing of a Twine 1.x based HTML file, nor is there a 2.x compatible version of the discontinued Sugarcane story format.

Now that you know which application (TWEE compiler) and story format was used to create the HTML file you have a couple of methods available to you to access the Passages meta data contained within it.

1: You can download/install the abandoned Twine 1.x application, which includes a copy of the Sugarcane story format, and use that application’s Import Compiled Source feature to re-created your own copy of the original project.

2: Use a TWEE Compiler that includes a decompile option to generated a TWEE Notation based file from the HTML file. One such compiler is TweeGo.

(1) Not to be confused with the active SugaCube story format,


…or you could just do that, I guess. If you decide to actually use/adopt a significant chunk of that code beyond just looking at it, you may still want to reach out to the author to get their blessing. Or not. Your choice, I suppose.

1 Like

Thank you! I do have some specific questions now that I understand how this works a little better :slight_smile: It’s been a really long time since I’ve been in a programming forum. I checked Tale of the Starweavers out and I think what I have working is a bit more advanced in some ways. I don’t show locked or inaccessible options to the player, for instance. I’m going to a much better job with explaining what I’m needing help with. I think I was sort of hoping someone would go “awwwwwww, Call of Cthulhu, what a great idea, let’s work on this together!”. But actually the folks responding here have given me renewed resolve that I can do this.

1 Like

You absolutely can! You got this! :smiley:

Thank you! I’m going to stick to one thing a reply so this stays useful.

I’m not sure if they are different questions either. I think solving the characteristics issue will help me solve the skills issue whether it’s part of the same mechanic or not.

I have a StoryInit with many variables being initialized. Obviously not going to paste the whole thing but here’s how I initialize the characteristics variables:

<<set $STR to 0>>
<<set $CON to 0>>
<<set $SIZ to 0>>
<<set $DEX to 0>>
<<set $APP to 0>>
<<set $EDU to 0>>
<<set $INT to 0>>
<<set $POW to 0>>

The solo adventure (this is an already published TTRPG scenario) then has the player set these attributes using the following values: 40, 50, 50, 50, 60, 60, 70, 80 .

I currently have the player open a pop up window with instructions to the player and then 8 labeled textboxes with no form validation.

<<set $character to true>>

STR: <<textbox "$STR" "">>
CON: <<textbox "$CON" "">>
POW: <<textbox "$POW" "">>
DEX: <<textbox "$DEX" "">>
APP: <<textbox "$APP" "">>
SIZ: <<textbox "$SIZ" "">>
INT: <<textbox "$INT" "">>
EDU: <<textbox "$EDU" "">>

I have some ideas about having buttons that have those numbers on them, and then when you click on one to use it in a characteristic, that particular button disappears and you can either reset the whole process or submit the final choices and go back to the passage you were just on. But at this point I’d just be happy to know how to form validate the textbox stuff for those values. Once you’ve allocated the characteristics, the passage does some math to fill in characteristic dependent stats like HP.

Obviously the buypoints thing isn’t relevant to the mechanic going on in this scenario, but I am taking it wholesale and sticking in a test game so I can figure out how to use it for something else where :slight_smile: I also didn’t know what include and span did, so that was helpful too. I’ll look up how that works.

<<set _buypoints to 5>>
<span id="buycarac"><<include "Caracs">></span>

Passage Caracs

You have _buypoints remaining points to spend.

Strength: $pcStr <<if $pcStr lt 18 && _buypoints gt 0>><<link "[+]">><<set $pcStr++>><<set _buypoints-->><<replace "#buycarac">><<include "Caracs">><</replace>><</link>><<elseif $pcStr == 18>>maxed<<else>>Not enough points to buy higher charac<</if>> | <<if $pcStr gt 3>><<link "[-]">><<set $pcStr-->><<set _buypoints++>><<replace "#buycarac">><<include "Caracs">><</replace>><</link>><<else>>floored<</if>>

Dexterity: $pcDex <<if $pcDex lt 18 && _buypoints gt 0>><<link "[+]">><<set $pcDex++>><<set _buypoints-->><<replace "#buycarac">><<include "Caracs">><</replace>><</link>><<elseif $pcDex == 18>>maxed<<else>>Not enough points to buy higher charac<</if>> | <<if $pcDex gt 3>><<link "[-]">><<set $pcDex-->><<set _buypoints++>><<replace "#buycarac">><<include "Caracs">><</replace>><</link>><<else>>floored<</if>>

<<link "Confirm" "To skills">><</link>>

I am emulating the exact dice rolling mechanics in Call of Cthulhu. Not only is there a tens die and a ones die, but there is the possibility of a bonus or penalty die (the tens place) in which the higher die goes for a penalty and the lower die goes for a bonus. I did the full logic so that later on, when I figured out the dynamic animations, I could just plug that in. I also have spaghetti in here so that it displays correctly. This is all in a popup so when you return to the passage you rolled from, the passage reloads with the appropriate text and links to carry on the story with.

<<SetFlag "Rolled" "yes">><<set _dicerolltens to random (1,10)>><<set _dicerollones to random (1,10)>><<set _dicerollbonuspenalty to random (1,10)>><<if _dicerollbonuspenalty is 10>><<set _dicerollbonuspenalty to 0>><</if>>
<<if _dicerolltens is 10>><<set _dicerolltens to 0>>00<<else>><<print _dicerolltens>>0<</if>><<if Flag("PenaltyDie")>> **** <<print _dicerollbonuspenalty>>0<<if _dicerollbonuspenalty gt _dicerolltens>><<set _dicerolltens to _dicerollbonuspenalty>><</if>><</if>><<if Flag("BonusDie")>> ***** <<print _dicerollbonuspenalty>>0<<if _dicerollbonuspenalty lt _dicerolltens>><<set _dicerolltens to _dicerollbonuspenalty>><</if>>
<<if _dicerollones is 10>><<set _dicerollones to 0>>0
	<<print _dicerollones>>
	<</if>><<set $currentdiceroll to _dicerolltens*10+_dicerollones>><<if $currentdiceroll eq 0>><<set $currentdiceroll to 100>><</if>>
FINAL ROLL: $currentdiceroll<<if Flag("BonusDie")>>
<<SetFlag "BonusDie" false>><</if>><<if Flag("PenaltyDie")>>
<<SetFlag "PenaltyDie" false>><</if>>

The thing that I want to make into a widget is this bit I have to put in every single passage with a skill or stat check (with additional code to indicate a bonus or penalty die in certain passages):

<<link "Make a DEX roll.">>
Dialog.setup("DEX Check");"Dice Rolling").processText());"","134" , "noHistory"));
1 Like

You probably know this, but just in case… Cthulhu Chronicles is a game that promotes itself as the official Call of Cthulhu IF game developed in partnership with Chaosium.

Well, if you want to use numbers, instead of text strings, then you should probably be using the <<numberbox>> macro instead.

Also, just to give you a simple way of having code which detects when the values in those <<numberbox>>es change, you can use this simplified code as a guide. In your character creation passage you can have some code like this:

<span id="stats">\
		<tr><td>''Str:''</td><td><<numberbox "$STR" $STR autofocus>></td></tr>
		<tr><td>''Dex:''</td><td><<numberbox "$DEX" $DEX>></td></tr>

''Total:'' <span id="total">0</span>

	<<run $("#stats input").on("change", function () { $.wiki("<<statUpdate>>"); })>>

Note that the above assumes that $STR and $DEX have already been initialized to some number value and that you’re using SugarCube v2.35.0 or later (since that’s when the <<done>> macro was added). The backslashes (\) at the end of some lines are just to prevent line breaks there so that the code remains readable to you. Also, see the SugarCube $.wiki() method and the jQuery .on() method for details on how that part of the code works.

I also note that “autofocus” should set the focus on the $STR <<numberbox>>, but for some unknown reason that’s not working. :woman_shrugging:

The above code will trigger the <<statUpdate>> widget whenever any of the <<numberbox>>es change if they’re within the element that has the “stats” ID. Thus, you’ll need to create another passage for that widget, give it “widget” and “nobr” tags, and then put some code in it like this:

<<widget "statUpdate">>
	<<replace "#total">>
		<<print $STR + $DEX>>

That will cause the value next to “Total:” in the passage to change to the current total of those two stats whenever the <<statUpdate>> widget is called. (The “nobr” tag means that the passage ignores line breaks, but if you need one, you can use the <br> element to force a line break.)

Now, obviously that isn’t exactly what you’re attempting to do, but it should give you most of the information you need to make <<statUpdate>> into an input validator which works however you want it to.

Enjoy! :slight_smile:


I don’t have information enough to understand how penalty die and bonus die occur, nor what they do, so obviously I’m not able to help you!

I didn’t know that! I asked a friend of mine who works for Chaosium about existing product and she didn’t know. I checked into this game, thanks. Looks like it’s been removed from the apple store and is in early release on android so I wasn’t able to try it out. It does look much better, just from what they show on their website, than what I’ve got so far :sweat_smile:

Oh no, I thought the first paragraph explained it ok. That’s cool though, because I’m gonna try some stuff based on code y’all have provided and come back to this only if it doesn’t work :slight_smile:

You did explain, and it’s a solid explanation. However codewise I need it be be even more precise: I have to understand what triggers a penalty die or a bonus one, and I still don’t know what those dice do.

I’ve done Twine games using Harlowe for D&D 5e. I chose not to incorporate the player’s stats into the game. Instead, the player keeps their own character sheet and the game only rolls for the opponent. Players make their own rolls then indicate if they’ve passed a DC or not (and sometimes by how much). You can see examples of my work at