Day 18 [D&D Character Sheet]
Tags: 100daysofcode
Published: 2020-04-03 05:51:00

# Report
Today I did a little refactoring of my Character sheet by moving the Ability/skill blocks to an include. Here's the new include.

```html
<!-- views/characters/includes/skill.ejs -->
<div class="row border">
	<div class="col-md-4 border-right">
		<dt><%= ability.name %></dt>
		<dd>
			<%= ability.value || 0%>
		</dd>
	</div>
	<!-- prettier-ignore -->
	<div class="col-md">
                <% /* Check skills was passed to prevent undefined errors...
                just realizing I should check that it's and array here. %>
		<%(typeof skills == 'undefined' ? [] : skills).forEach(skill => { %>
		<dl class="row">
			<dt class="col-sm-9">
				<%= skill.name || "No Name"%>
			</dt>
			<dd class="col-sm-3">
				<%= skill.value || 0 %>
			</dd>
		</dl>
		<% }) %>
	</div>
</div>
```
And here's a before and after of that section from the character sheet.
```html
<!-- views/characterSheet.ejs before -->
<div class="col-md px-3">
	<div class="row border">
		<div class="col-md-4 border-right">
			<dt>Strength</dt>
			<dd>
				<%=
				data.character.stats.abilities.strength
				%>
			</dd>
		</div>
		<div class="col-md">
			<dl class="row">
				<dt class="col-sm-9">
					Athletics
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.athletics.skill.value
					|| 0 %>
				</dd>
			</dl>
		</div>
	</div>
	<div class="row border">
		<div class="col-md-4 border-right">
			<dt>Dexterity</dt>
			<dd>
				<%=
				data.character.stats.abilities.dexterity
				%>
			</dd>
		</div>
		<div class="col-md">
			<dl class="row">
				<dt class="col-sm-9">
					Acrobatics
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.acrobatics.skill.value
					|| 0 %>
				</dd>
			</dl>
			<dl class="row">
				<dt class="col-sm-9">
					Sleight of Hand
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.sleightOfHand.skill.value
					|| 0 %>
				</dd>
			</dl>
			<dl class="row">
				<dt class="col-sm-9">
					Stealth
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.stealth.skill.value
					|| 0 %>
				</dd>
			</dl>
		</div>
	</div>
	<div class="row border">
		<div class="col-md-4 border-right">
			<dt>Constitution</dt>
			<dd>
				<%=
				data.character.stats.abilities.constitution
				%>
			</dd>
		</div>
		<div class="col-md"></div>
	</div>
	<div class="row border">
		<div class="col-md-4 border-right">
			<dt>Intelligence</dt>
			<dd>
				<%=
				data.character.stats.abilities.intelligence
				%>
			</dd>
		</div>
		<div class="col-md">
			<dl class="row">
				<dt class="col-sm-9">
					Arcana
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.arcana.skill.value
					|| 0 %>
				</dd>
			</dl>
			<dl class="row">
				<dt class="col-sm-9">
					History
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.history.skill.value
					|| 0 %>
				</dd>
			</dl>
			<dl class="row">
				<dt class="col-sm-9">
					Investigation
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.investigation.skill.value
					|| 0 %>
				</dd>
			</dl>
			<dl class="row">
				<dt class="col-sm-9">
					Nature
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.nature.skill.value
					|| 0 %>
				</dd>
			</dl>
			<dl class="row">
				<dt class="col-sm-9">
					Religion
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.religion.skill.value
					|| 0 %>
				</dd>
			</dl>
		</div>
	</div>
	<div class="row border">
		<div class="col-md-4 border-right">
			<dt>Wisdom</dt>
			<dd>
				<%= data.character.stats.abilities.wisdom
				%>
			</dd>
		</div>
		<div class="col-md">
			<dl class="row">
				<dt class="col-sm-9">
					Animal Handling
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.animalHandling.skill.value
					|| 0 %>
				</dd>
			</dl>
			<dl class="row">
				<dt class="col-sm-9">
					Insight
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.insight.skill.value
					|| 0 %>
				</dd>
			</dl>
			<dl class="row">
				<dt class="col-sm-9">
					Medicine
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.medicine.skill.value
					|| 0 %>
				</dd>
			</dl>
			<dl class="row">
				<dt class="col-sm-9">
					Perception
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.perception.skill.value
					|| 0 %>
				</dd>
			</dl>
			<dl class="row">
				<dt class="col-sm-9">
					Survival
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.survival.skill.value
					|| 0 %>
				</dd>
			</dl>
		</div>
	</div>
	<div class="row border">
		<div class="col-md-4 border-right">
			<dt>Charisma</dt>
			<dd>
				<%=
				data.character.stats.abilities.charisma
				%>
			</dd>
		</div>
		<div class="col-md">
			<dl class="row">
				<dt class="col-sm-9">
					Deception
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.deception.skill.value
					|| 0 %>
				</dd>
			</dl>
			<dl class="row">
				<dt class="col-sm-9">
					Intimidation
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.intimidation.skill.value
					|| 0 %>
				</dd>
			</dl>
			<dl class="row">
				<dt class="col-sm-9">
					Performance
				</dt>
				<dd class="col-sm-3">
					<%=
					data.character.stats.skills.performance.skill.value
					|| 0 %>
				</dd>
			</dl>
		</div>
	</div>
</div>
```

```html
<!-- 
views/characterSheet.ejs moved to views/characters/characterSheet.ejs
after
-->
<div class="col-md px-3">
	<% const PATH_TO_SKILL_INCLUDE = "./includes/skill.ejs" %> 
	<%- 
		include(PATH_TO_SKILL_INCLUDE, {
			ability: {
				name: "Strength", 
				value: data.character.stats.abilities.strength 
			},
			skills:[ 
				{ 
					name: "Athletics",
					value:data.character.stats.skills.athletics.skill.value
				}
			]
	}) 
	%> 
	<%- 
		include(PATH_TO_SKILL_INCLUDE, {
			ability: {
				name: "Dexterity",
				value: data.character.stats.abilities.dexterity
			},
			skills: [
				{
					name: "Acrobatics",
					value: data.character.stats.skills.acrobatics.skill.value
				},
				{
					name: "Sleight of Hand",
					value: data.character.stats.skills.sleightOfHand.skill.value
				},
				{
					name: "Stealth",
					value: data.character.stats.skills.stealth.skill.value
				}
			]
		}) 
	%>
	<%- 
		include(PATH_TO_SKILL_INCLUDE, {
			ability: {
				name: "Constitution",
				value: data.character.stats.abilities.constitution
			},
		}) 
	%>
	<%- 
		include(PATH_TO_SKILL_INCLUDE, {
			ability: {
				name: "Intelligence",
				value:data.character.stats.abilities.intelligence
			},
			skills: [
				{
					name: "Arcana",
					value: data.character.stats.skills.arcana.skill.value
				},
				{
					name: "History",
					value: data.character.stats.skills.history.skill.value
				},
				{
					name: "Investigation",
					value: data.character.stats.skills.investigation.skill.value
				},
				{
					name: "Nature",
					value: data.character.stats.skills.nature.skill.value
				},
				{
					name: "Religion",
					value: data.character.stats.skills.religion.skill.value
				}
			]})
	%>
	<%- 
		include(PATH_TO_SKILL_INCLUDE, {
			ability: {
				name: "Wisdom",
				value: data.character.stats.abilities.wisdom
			},
			skills: [
				{
					name: "Animal Handling",
					value: data.character.stats.skills.animalHandling.skill.value
				},
				{
					name: "Insight",
					value: data.character.stats.skills.insight.skill.value
				},
				{
					name: "Medicine",
					value: data.character.stats.skills.medicine.skill.value
				},
				{
					name: "Perception",
					value: data.character.stats.skills.perception.skill.value
				},
				{
					name: "Survival",
					value: data.character.stats.skills.survival.skill.value
				}
			]
		})
	%>
	<%-  
		include(PATH_TO_SKILL_INCLUDE, {
			ability: {
				name: "Charisma",
				value: data.character.stats.abilities.charisma
			},
			skills: [
				{
					name: "Deception",
					value: data.character.stats.skills.deception.skill.value
				},
				{
					name: "Intimidation",
					value: data.character.stats.skills.intimidation.skill.value
				},
				{
					name: "Performance",
					value: data.character.stats.skills.performance.skill.value
				}
			]
		})
	%> 
</div>
```

# Project

{% github ApproachingApathy/100days-dnd-character-sheets %}

The First project will be an app to keep D&D character sheets.

## Stack

I'll be using Node.js and building a full-stack Express app with MongoDB.
### Requirements
#### Minimum Viable 

- [ ] Investigate automating or finding a source of info for the data in the SRD.
- [X] Present a D&D Character Sheet
    - [ ] The sheet should display all the same info as the first page of the 5e Official sheet.
- [ ] Users should be able to log in and create player-characters.
- [ ] Users should be able to edit character sheets.
- [ ] Users should be able to organize character sheets into groups (parties/tables)
- [ ] Sheets should auto calculate basic stats like ability modifiers.
    - [ ] Support Proficiency Bonuses 

### Cake
- [ ] Extend character creation to allow the user to use any of the three common stat gen methods.
    - [ ] Point Buy
    - [ ] Standard Array
    - [ ] Roll
- [ ] Extend the character sheet to all the info in the 5e official sheet.
- [ ] Allow for image uploads for character portraits.
- [ ] Allow for extended descriptions/backstories.
    - [ ] Characters should have nice full page backstories.
    - [ ] Preferably use a markdown editor.