The bio section is useful background information, like age, history, and background. But you only need this section when describing your character, or when refreshing your memory about details, so it doesn’t need to be visible all the time. To avoid it take up useful space, you can hide all but the title bar. We’ll also introduce a technique we’ll use a lot more – it’s handy to be able to toggle between two values.
It normally looks like this:
But if you click the heading it looks like this:

Click any of the headings there and you get back to
and don’t take up much space on the character sheet.
What is the Bio section for?
It includes some basic biographical information, but als includes some important game information. It is split into three sections: description, portrait, and story.
Description
If you enter a name, this changes the character-name of the journal that contains that character sheet – thats a handy way to quickly change name.
The Rank dropdown lets you pick a starting experience level. Each system based on TurboPulp has its own sectionv for specia powerrs. There’s a place on the sidebar to change what it’s called, and that label will show up here in place of Special. You can also change the starting rank for each.
The default is Poor for both. Once you click the locked button, name and the two starting raks are locked and you cant change them again.
The big description text box is, not surprisingly, for entering your description. Enter anything you want here.
Portrait
When you create a portrait on the Edit tab, you will see it here. The 3 buttons below the portrait allow you to tweak the way the portrait appears – some images look better in different layouts.
Story
Finally you need to enter your lifepaths – which describe different,roughly 10-year, sections of your life. Wherever there’s a down arrow, you can click it to see another box to enter more expansive information.
Other games use Lifepaths, but the number you get is based on a roll (or many rolls), and then that determines your age. Here you simply choose your age, and that sets how many lifepaths you get. Lifepaths have a use in the system (in the Interventions system), they are not just meaningless background. See the game chapter about that.
The Code
There’s a lot of code, and I’m not going to describe everything. There are somethings I will explain, and Ive tried to organise the code for easier understanding – please go through it!
<div class="bio expanded">
<div class="description">
<button type="action" name="act_biotoggle" class="title">
<h3>Description</h3>
</button>
<input type="hidden" name="attr_lock" class="lock-toggle" value="0">
<span class="title">Name</span>
<input type="text" name="attr_character_name" class="fit locked" value="" readonly>
<input type="text" name="attr_character_name" class="fit unlocked" value="">
<div class="starting-ranks">
<span class="title">Rank</span>
<select name="attr_character" class="fit unlocked">
<option selected>Poor</option>
<option >Fair</option>
<option >Good</option>
<option >Great</option>
<option >Superb</option>
<option >Spectacular</option>
<option >Legendary</option>
<option >Mythical</option>
<option >Perfect</option>
</select>
<input type="text" name="attr_character" value="Poor" class="locked fit" readonly />
<button type="action" name="act_lock" class="nod20">
<span name="attr_lock_label">Lock?</span>
</button>
<span class="display title" name="attr_special_label" value="Special">Special</span>
<select name="attr_special" class="fit unlocked">
<option selected>Poor</option>
<option >Fair</option>
<option >Good</option>
<option >Great</option>
<option >Superb</option>
<option >Spectacular</option>
<option >Legendary</option>
<option >Mythical</option>
<option >Perfect</option>
</select>
<input type="text" name="attr_special" value="Poor" class="locked fit" readonly />
</div>
<textarea name="attr_description" class="description" placeholder="DESCRIPTION"></textarea>
</div>
<div class="portrait">
<button type="action" name="act_biotoggle" class="title">
<h3>Portrait</h3>
</button>
<input type="hidden" name="attr_image_type" value="cover" class="radio-image">
<img name="attr_character_avatar">
<div class="image-type" title="Click to change image scaling">
<input type="radio" name="attr_image_type" value="cover" title="cover" checked id="cover">
<input type="radio" name="attr_image_type" value="contain" title="contain" id="contain">
<input type="radio" name="attr_image_type" value="fill" title="fill" id="fill">
</div>
</div>
<div class="story">
<button type="action" name="act_biotoggle" class="title">
<h3>Character Story</h3>
</button>
<details class="concept">
<summary>
<span title="click me for more typing space">Concept:</span>
<input type="text" name="attr_concept" value="">
</summary>
<textarea></textarea>
</details>
<div class="age">
<span>What is your age?</span>
<input type="number" name="attr_age" value="35" class="no-spinner">
</div>
<div class="LPs">
<span>You have</span>
<span name="attr_lifepaths" value="3"></span>
<span>extra Lifepaths</span>
</div>
<input type="hidden" name="attr_lp0_show" class="lp-show" value="0">
<details class="lp">
<summary>
<input type="text" name="attr_lp0" placeholder="LIFEPATH 1" value="">
<span class="header center">↓</span>
</summary>
<textarea name="attr_lp0_details" placeholder="MORE ON EVENT AND OUTCOME"></textarea>
</details>
<input type="hidden" name="attr_lp1_show" class="lp-show" value="0">
<details class="lp">
<summary>
<input type="text" name="attr_lp1" placeholder="LIFEPATH 2" value="">
<span class="header center">↓</span>
</summary>
<textarea name="attr_lp1_details" placeholder="MORE ON EVENT AND OUTCOME"></textarea>
</details>
<input type="hidden" name="attr_lp2_show" class="lp-show" value="0">
<details class="lp">
<summary>
<input type="text" name="attr_lp2" placeholder="LIFEPATH 3" value="">
<span class="header center">↓</span>
</summary>
<textarea name="attr_lp2_details" placeholder="MORE ON EVENT AND OUTCOME"></textarea>
</details>
<input type="hidden" name="attr_lp3_show" class="lp-show" value="0">
<details class="lp">
<summary>
<input type="text" name="attr_lp3" placeholder="LIFEPATH 4" value="">
<span class="header center">↓</span>
</summary>
<textarea name="attr_lp3_details" placeholder="MORE ON EVENT AND OUTCOME"></textarea>
</details>
<input type="hidden" name="attr_lp4_show" class="lp-show" value="0">
<details class="lp">
<summary>
<input type="text" name="attr_lp4" placeholder="LIFEPATH 5" value="">
<span class="header center">↓</span>
</summary>
<textarea name="attr_lp4_details" placeholder="MORE ON EVENT AND OUTCOME"></textarea>
</details>
<input type="hidden" name="attr_lp5_show" class="lp-show" value="0">
<details class="lp">
<summary>
<input type="text" name="attr_lp5" placeholder="LIFEPATH 6" value="">
<span class="header center">↓</span>
</summary>
<textarea name="attr_lp5_details" placeholder="MORE ON EVENT AND OUTCOME"></textarea>
</details>
</div>
</div>
Code language: HTML, XML (xml)
Above is the HTML, below is the CSS.
/* BIO */
.biotoggle[value="0"] ~ .container .bio.expanded,
.biotoggle[value="1"] ~ .container .bio.shrunk {
display: grid;
align-content: start;
}
.container div.bio {
grid-template-columns: 210px 175px 210px;
column-gap: 5px;
}
.container div.bio .description span {
margin-top: 5px;
}
.container div.bio .description {
display: grid;
grid-template-columns: 60px auto;
column-gap: 5px;
align-content: start;
}
.container div.bio .description .starting-ranks {
grid-column: 1 / -1;
display: grid;
grid-template-columns: 60px 105px 50px;
column-gap: 5px;
align-content: start;
}
.container div.bio .description .starting-ranks select {
width: auto;
}
.container div.bio textarea.description {
height: 190px;
width: 205px;
}
.container div.bio .portrait img {
border: 5pt double darkred;
border-radius: 50%;
height: 250px;
width: 175px;
object-fit: cover;
}
.container div.bio div.image-type {
text-align: center;
width: 100%;
}
.container div.bio .portrait input.radio-image[value=contain] ~ img {
object-fit: contain;
}
.container div.bio .portrait input.radio-image[value=fill] ~ img {
object-fit: fill;
}
.container div.bio textarea.story {
height: calc(100% - 37px);
margin-left: 10px;
width: 185px;
}
.container div.bio .story .concept input {
display: inline-block;
width: 144px;
}
.container div.bio .story input[type="number"] {
display: inline-block;
width: 40px;
}
.container div.bio .story {
margin-left: 10px;
}
.container .story summary input[type=text] {
width: calc(100% - 15px);
}
Code language: CSS (css)
The are locked
and unlocked
classes. These each only show up when the other doesn’t. Using the tabs
function, and the locked button we can switch between them.
const tabs = {
toggles: ['biotoggle', 'lock', /* more to come */],
inserts: {
/* action buttons which insert the name in a specific location */
}
};
Code language: JavaScript (javascript)
And to go along with that:
iv.bio.expanded,
div.bio.shrunk,
.container div.bio input.lock-toggle:not([value="1"]) ~ div .locked,
.container div.bio input.lock-toggle:not([value="0"]) ~ div .unlocked,
.container div.bio input.lock-toggle:not([value="1"]) ~ .locked,
.container div.bio input.lock-toggle:not([value="0"]) ~ .unlocked,
div.story .lp-show:not([value="1"]) + .lp {
display:none;
}
Code language: CSS (css)
Since the lock-toggle
input value is being switched between 0 and 1, these properly lock that section of the sheet. You can also see where lifepaths above your current total are being hidden. This is in response to a sheet worker based on your age.
on('change:age sheet:opened', () =>{
getAttrs(['age'], v => {
const age = +v.age || 0;
const lps = age < 50 ? Math.floor(age / 10) : age >= 100 ? 6 : 5;
const output = {};
output.lifepaths = lps;
seq(6).forEach(i => {
output[`lp${i}_show`] = i < lps ? 1 : 0;
if(i >= lps) {
output[`lp${i}`] = '';
output[`lp${i}_details`] = '';
}
});
setAttrs(output);
});
});
on('change:lock sheet:opened', () => {
getAttrs(['lock'], values => {
const lock = +values.lock || 0;
const lock_label = lock ? "Locked" : "Lock?";
setAttrs({lock_label});
});
});
Code language: JavaScript (javascript)
By changing the label on the lock?
and locked
button, players get some visual feedback and can see what has happened.
And there we have it. Remember, everything we do here is just one way to do it – in the world of computer code, there are usually multiple different ways to achieve the same goal. I hope this helps you figure out how to do some things on the sheet.