 I hope you've had a wonderful first day of sessions here at DrupalCon and thank you all for making your last session of the day here where we are going to talk about Dungeons & Dragons and Drupal 8th edition. So allowing me to introduce myself, my name is Toby Hagler. I am Director of Engineering of our Product Delivery Group at Phase 2 Technology. For the quarter century or so, at least I've been playing Dungeons & Dragons pretty avidly. So needless to say, it's a topic that I really enjoy and I wanted to be able to talk about two of my favorite things here at DrupalCon. So why is a D&D character creator the perfect example of a Drupal project? So I've played D&D as long as I can remember. I used to be able to quote rules and page numbers from the player's handbook. I could create a character without looking up the rules. The point is, it's a thing that I really, truly understood, something that I've been involved with for a long time, so I know the problem space really well. So learning a new language or a framework, a CMS, or even a new version of something, let me focus on solving problems that are endemic to that language without also having to figure out how to solve the problems of the problem space that I'm trying to build something for. So when I stumble, I don't have to figure out is it the technology? Is it my approach? Is it the content domain, you know, like whatever it is? I know it's going to be related to the actual technology that I'm trying to learn. So building a D&D character generator, it helps with a lot of things, you know, learning a new framework, learning a new CMS, a new API, like field API, I'll talk about that a little bit later, or even something a little bit more abstract like data or content modeling. If you want to get really meta, D&D can even help you learn how to create a meaningful presentation by creating a presentation about a subject you really know and love. So in what I kind of refer to as my college days, I learned a lot about C and C++ by building a command line generator, a lot more about C than I learned from actual class. I learned Perl, I learned Perl, I dabbled with Python in much the same way. So it's also how I learned PHP and how to use my SQL to store records. I wanted to learn JavaScript so that I could create a better UI for a D&D character. So let's say you want to learn how to build a site on Drupal 8, or you want to tackle something that's new to you in Drupal 8, like field API, or the new versions of web form. So let's use a D&D character creation as a project to help us figure out the most common tools of Drupal and content management. So since we already understand what goes into D&D character creation, we know if enough about the problem space to get started. So also I want to point out this is not going to be just about learning Drupal. So don't fret if you're already a high-level Drupal adventurer. There's still going to be a lot of treasure to find. Thank you, yeah, context is everything. So every adventure begins with you're sitting in a tavern when you hear rumors about trouble brewing in a nearby village, or something like that, right? It doesn't have to be necessarily you're in a tavern, but every campaign begins with a story hook, something that pulls you in. You don't just jump right into the game and start fighting goblins or uncovering treasure, right? You need a plan and you need to know where you're going first. So it's not really any different with a Drupal project. You need to kind of break it down, plan things out before you start downloading modules and installing things or writing any custom code. So we're going to examine what goes into building a character and how we would do these things in Drupal. So first of all, you need to figure out what you're building and what you're not. So identify your scope. Here we're going to be building something that's going to let us build and track a character. That's all. We're not going to focus on running an entire campaign. We're not going to build our own local version of DnD Beyond. Although interestingly enough, I did that in Drupal 5 when the SRD35 database was released. It was pretty slick. But DnD, let's face it, DnD Beyond is just a lot better. So we're going to concern ourselves with the data points involved in DnD character generation, capturing just the minimum input you need to be able to create a character, all the things, all the entry points that belong to a character. And to do that, we're going to try to maximize the number of things that we have to calculate in order to display the right totals for everything. An interesting concept to think about, especially when we're talking about the capturing the data that we're going to input and then being able to output that later, if you look at the character's record sheet, it's a wireframe, right? That's all it is. So we're going to use this as a wireframe. The character sheet is something that displays the functional elements of our DnD character page and hopefully it's going to illuminate the path for planning our overall functionality. So a DnD character in a nutshell, what is it? So I kind of like to work backwards when I'm planning things out. I want to know what it is that I'm trying to create. So I use the character sheet, sorry, or wireframe here, to know what a DnD character node page should look like and how I can figure out what data elements I'm going to need to display later. So given that our character is just a content type, really, you're going to have to have a node to display all the fields of our character's attributes. And this is perfectly fine when you're viewing your character on a tablet or on your phone. But what happens if you want to print that sucker out, right? So let's say you want to be able to put down the computer and game like it's 1979 with just pencils and dice and paper and tons of Dr. Pepper. What are your options for building a printable character sheet? So we're going to want to talk about the two different types of media that we want to consider a little bit later on in the session, output towards the end. But because now we need to know what our players are going to enter first in order to kind of get the desired output later. So the input of a DnD character, there's a number of ways to approach the input for your builder. You may just want a simple interface for entering content so that anyone could just manage their character with the same ease as managing it on paper. You're filling in the blanks. Or you may want to have a character wizard, not a wizard character, but a character wizard. Something that's going to take input and conditionally change the remaining available options as you go along. So if you choose to play a paladin, you can only choose lawful good or lawful stupid as an alignment. So if you're choosing a druid or a cleric, it's going to limit you to just divine magic. And even then that's going to limit the number of spells that are available to your character, right? So knowing our content entry model may actually change the rest of what we do. So we need to identify the order of things in which players will input their data. So let's look at option one for just a second. It's just going to be a straight node edit form. So all fields are entered sequentially. They're all entered at once. One just great, big, long, huge form. We all know and love node edit forms in Drupal, right? Like the prettiest thing in the world. No? I spend a lot of time thinking of node edit forms. So you can do a couple of things. Like you use JavaScript to help update some of the fields based on choices. But in the end, you're just simply entering the content attributes directly into the character sheet, right? You're just filling out the form. So I'm probably going to spend too little time actually talking about the importance of this approach. But it's the most basic option, so there's not really a whole lot to enumerate on. So even if you want to use web form later, defining the node now is going to let us have all of the data points that we need to capture later. And then in that way, if you do use web form or something to fill it out, you can actually come along and edit it later whenever you've taken a level drain or you need to make an update because you've leveled up finally. So we're not exactly done with what you've created the content type in the fields. So here's what you have another chance to learn in Drupal. There are things like config management, the use of the features module to capture all of your configuration and be able to store that in code. So as a perfect corollary to this, when the weekend that Drupal 7 was released, I sat down on my back porch and actually just created the D&D character module in order to learn field API, to learn features. I wanted to learn some of these new D7 concepts. And yeah, so over the course of the weekend I just kind of packed out a D&D character module that lets me store compound complex fields in a single field widget. And I'll kind of show that off a little bit here in a second. But yeah, I mean, using features in CMI for something like this, you learn how to export content types in related fields so that you can actually reuse the content types you declare on one project and be able to take it over to another project and reuse code, hopefully. The other option gets a little bit more involved pretty quickly. So let's say you want to use the new version of webform. So if we go with option two, for instance, and we want to have a multi-step form process. It's going to be more like a form wizard. You want to figure out how to break things out into the main steps, which will be the form pages. And then for each individual form page, a list of all the input items that we need for the user. So webform for Drupal 8 is kind of a newly reimagined version of webform, which uses a YAML structure underneath internally for managing the form. So you can actually edit the form directly from code. You don't have to use the UI. It's pretty cool. Another cool thing is that it includes a lot of features like multi-step forms and wizard style input out of the box. So also every field has conditional logic that can be associated with it. So you can choose to show or hide fields based on previous selections. And sure, you could do all of this programmatically yourself. But if a module lets you do it through a UI and save you a couple of hours of banging your head against form validations, then cool. So the multi-step webform begins with the basic input of your character's abilities, the race, other basic descriptions. And so here, you capture the total effective level of the character, his alignment. And knowing things like that are going to affect choices later. So next, we're going to ask for the class or classes, if you're going to multi-class, by level. It's very useful for multi-classing. Also, you're going to want to be able to restrict classes based on a subset of classes that are allowed by a particular race or alignment. So after that, you want to capture maybe other things. Like if you're higher than level four, you get additional ability scores that you can assign. And as you advance in level, you might want to be able to change additional things. If you're creating a 10th level character from scratch, because your 11th level character died in the campaign because your DM is merciless, then you can do all of this through the wizard and be able to start from there. So step four would be identifying the class specific abilities. They start to vary widely. Some classes have magical abilities. And every magic using class does vary a lot. You have divine spells, and arcane, and all this other stuff. So now that you have all of that captured, then you can refine the final details. Now that you have your constitution score, your race, your class, you can calculate things like hit die and hit points. And that's all multiplied out by level, perhaps. And so then as a final step in our web form, you figure out what your character's wealth is. You buy your equipment. And even those things affect things like your armor class, your attack bonuses, and that sort of thing. So all of these things are all interconnected, which is really useful to know when you start talking about content models and computational models. So regardless of which input methodology we choose to go down, you want to be able to focus on managing as little user input as possible and calculating the rest in order to display a fully developed D&D character. So now that we know what content we need from the user and what content we need to be able to print out, we need to do some gap analysis between input and output and identify what's going to be calculated or computed from user input. So if you look at a character's stats, you can determine what's computed, what's entered, and then we can build the content model for the character. So what do you have? You have race, you have class and level, you have your ability scores, alignment. All of these things matter in terms of your character's stats, but they also matter to the game itself. So you input those things, but all of those things get modified. You have racial modifiers and traits. You pick a dwarf so you suddenly know three other new languages that you wouldn't have before. That's going to matter later in the game. Class skills and hit-dye, based on what class you pick, you're going to have more or fewer hit points. Ability scores, skills, saving throws, all of these things start to matter. All of these things might limit the class options that you have available. Choosing your equipment is going to modify your armor class or your THACO, if you're still second edition. So all of this, and even outside of the data model, the computational model within Drupal, all of these things affect how the DM creates a story hook, something that's going to appeal to your character and create adventure ideas, and how NPCs react to your character, because honestly, it's all about the content of your character and how that's going to go into the story. So again, determining your relational model, how different points of data relate to each other, how they're going to affect each other, that's all key and vital before you even begin writing a first line of code. So taking a quick look at the actual character content model, not the computational model, but just the basic things that you want to capture from users. At first glance, a D&D character is just a standard node, right? So we create a custom content type called D&D character. You have ability scores, that's just an array of numbers that range from three to 18. You have hit points, hit dial, these are all just integers, integer values. You can very easily slap a field on a node and capture these things. Class, race, and alignment, they're just items from a select list. So things all look pretty basic until you start doing a deeper dive into the content model. You realize that ability scores are not just an array of numbers. It's an array of numbers that are modified by other things, and sometimes you care about the modifications to those numbers. So you have the 46 drop one score that you get as your base score. You have a racial modifier because you're a dwarf, so you gain a little bit of extra constitution or something. You have racial bonuses. You have level up bonuses. Those are all important to capture because if you have a level drain, because you run into a vampire later, you're going to have to readjust some of these things. So you can't just merge these down into the computer fields. Race and class. They limit the options and add additional skills to your character. So especially selecting a class, it changes everything else from that point on in terms of what you have to input down the road. So even though the choice to create your character using a content type might be questionable, maybe we want to consider creating a node plugin to help handle some of the calculations and override values during form validation or submission. So there's a little ounce on the scope of a site building session, but I want to make sure that all the DMs that are out there that are going to be building this when you get back home are going to be aware that a node plugin might be extremely useful for being able to handle a lot of the computations. Last thing I want to talk about data design. Specifically, I want to talk a little bit about atomic design because that's going to go a lot deeper into some of the ability scores that we're going to talk about later. So you're going to hear a lot about atomic design and a more traditional design in front end discussions, but it's also very applicable to data modeling. So if you're interested in atomic design, there's actually a Pinterest component design session tomorrow at the same time that does a much deeper dive into things like pattern lab and atomic design. So it gives you a lot more of the concepts that I'm going to talk about here. But in fact, front end tools like pattern lab are more successful when your data model and the user interface designs are in sync. If they're both following the same data model, things just kind of magically work together. So understanding atomic design is really useful when implementing all the fields and data points for a D&D character, which we're going to discuss next. So if you think about an ability base score, that thing you rolled for earlier, that's just an atom. An ability score, the actual score is made up of the base score, your racial bonus, and including that modifier, that's a molecule. So you start building up all these atomic components. So the collection of all six abilities on your character record sheet, that's an organism. The organism of ability scores, all of your feats, skills, and spells, those are also organisms. Those start to constitute your template. Finally, you can theme up your template into something beautiful and printable and then you have your page. So that's just kind of an introduction to some of the atomic design concepts, but those things are really helpful when breaking apart some of the constituent components of a D&D character field, for instance. So I do want to talk a little bit about fields, entities, and relationships, how everything can kind of work together and come together. So now that we have our data in computational models, and we have a project plan, you can start looking forward to Drupal implementation. So for this particular project, we're gonna create a D&D character. We're gonna be mainly concerned with the fields and the data values of a character content type. Specifically, we're gonna figure out how we're gonna turn basic content entry into complex relational data model and be able to talk about a complete and accurate character sheet that then you can throw the computer away and actually play your game. So I wanna talk a little bit about fields in general. You know, how you can turn very simple atomic fields into something a little bit more usable and transmuted into something that we want for our character sheets. So just like the fourth level transmutation spell, polymorph, field API, and working with complex compound fields kind of seems almost impossible to attain at first. But I do wanna talk about, this is something that does exist outside of D&D and you face this all the time, you may not even realize it, but when you're importing statistical data, collected over time and other factors, that's compound values. When you have financial terms and rates in managing a ledger, you're dealing with compound values. When you're building a recipe book, compound fields are not all that uncommon. You have the name of the ingredient, the amount of it, the metric that you use, maybe even some little note about it. So all of these things are sort of compound field values that become the organism of our field later. So once again, building a D&D character generator lets you solve all the same sorts of problems that you may have to face in real world projects. Another good example that I wanted to point out is the address field. It's a really good microcosm of compound values. If you think about it, if you add an address field to any content type, it's just a field, visually. That's all you're adding is you're adding the address field, but the address field is made up of all sorts of constituent components. The street one, street two, city, province, state, zip, postcode, and some of these things don't necessarily always apply based on the country that you're in. And that's one of the nice things about the address field is that actually depending on the country you pick, it'll change zip code to postal code. It'll change state to province. And so it does kind of do some interesting things based on conditional logic. So again, somebody had to solve the same problem that you're having to solve when you create a D&D character. So let's take a look at what this may look like. So with an ability score, they're always listed in a fixed order, so that makes it kind of advantageous for us. This means we don't have to have a separate field for every ability roll, right? You don't have to have a strength field and an intelligence field or a charisma field. You can just kind of have one field with a cardinality of six. But what about all the modifiers, right? Your thief has a dexterity of 18, so he gets a plus four to dodge or to a saving throw to escape a dragon's breath weapon. So how do you calculate all that? So there's actually some pretty easy ways to calculate the things that are not obvious in D&D. For instance, I like to give this example when I talk about calculating modifiers. All you do is you take the base score that you rolled, divide it by two, subtract five from it and round down. And suddenly you don't have to do this lookup table that's on page 34 of the player's handbook every single time. You could just do simple math in your head, right? Everybody prefers that to a lookup table. I'm gonna take a quick aside here because talking about ability scores reminds me of something I always like to do as a DM. So when players are starting out, especially when they don't have a lot of gold yet, I always like to let them run into a back alley sage who offers discount potions. Really cheap. Like bull strength or eagle splendor. Now they're cheap, so they don't give you the plus one of the 1D4 plus one strength bonus. And you're like, well, that's fine. It's a third of the price of the gold. But the problem is these particular potions are cheap. They're also habit forming. So you can actually have them roll a saving throw every time they take one of these potions as soon as it wears off. So not only do they not get the plus one bonus, they can also lose an ability point until their addiction is taken over. And you just treat that like a magical disease so it could be cured. But every time I talk about abilities, I like to think about ways to take those away from players. Yeah, first potions, always free. Tell your friends. So some other compound fields have kind of alluded to already, but class and level, they go hand in hand. You don't really have a level on a character sheet. You don't think about it this way, but you don't actually have a level. You have a level of a particular class because you could multi-class. You're a 10th level fighter and a third level sorcerer, which means that you're effectively a 13th level magically enhanced fighter. So that's something to think about that class is actually a compound value. It's not just a select item. Skills are the same way, just like I described the recipes. You might actually have the name of the skill, how many ranks you've purchased in that skill, a Boolean to determine whether or not it's a class skill. Based on the class that you picked earlier, or one of the classes you picked earlier, the ability modifier, if you're looking at dodge, for instance, it's modified by dexterity versus arcane knowledge, which is modified by intelligence. So you have different things that you have to account for, even in something as simple as a list of skills. Just another set of potential compound fields, feet. Feets are pretty simple as far as the data is concerned, not so much in the actual role-playing event, but you have a name, a description, and maybe a list of the effects. So one last thing I wanna note about compound fields, going back to the concept of using D&D as a known problem, we can now look at the different options for what we need to help manage some of these compound fields. So here's a couple of different ways that you can go about it. The current D&D character module that I generated, that I made for Drupal 7 years ago, it creates a custom field API set of fields. So there is a D&D skills, a D&D abilities, a D&D feats set of fields. And they take the compound form elements and they do all this kind of other stuff to keep track of everything. And so then you're just adding that field to your character sheet. But let's assume, for instance, the D&D character module doesn't exist. So how do you handle compound fields in a site building way? So paragraphs in web form are two really good ways to do this. Paragraphs is actually a really great module for this. I mean paragraphs, essentially what it is, it's a field that is a collection of other fields. So you can basically pick the individual atomic field items that you want. Say an integer for your skill points, a text field for a description, and a select list for choosing the skill that modifies it. And then that becomes, say, your skill field. Web form is a little bit different spin on it, but you can also create custom fields as needed as well. And of course, I did talk a little bit about Field API. I can't really talk about solving compound fields without at least mentioning that Field API does give you the ability to create new custom fields with multiple input elements. And saying that it is possible. There's a lot of really good documentation on Drupal.org if you wanna go find out about it, or we can talk about it in a separate session later. So how do all these different input options look in practice once you have now created the compound fields and the content types and talked about the different approaches to input for your characters? So let's say you wanted to do something simple with paragraphs. So collecting the compound values of each field can be a little bit tough, but paragraphs will make it really easy through a UI. So this screenshot, it's a paragraph field that manages the ability scores for your character. It's just a single field on the node as far as the node's concerned, but with all the atomic fields contained within, and then you can just limit it to exactly six instances of that field and then you have your ability scores. Since we're assuming kind of a simple content entry system, nothing here is really calculated. Everything is just kind of open for the user to come in and fill it out. But there's nothing to stop you from using JavaScript or hook form alter to make some of the fields read only if you don't trust your players, because they're all liars, let's face it. No, I swear I rolled 18, six times in a row. It happens all the time, every campaign. If you're going with a web form input approach, it's just gonna use stock form API fields, but you can still do a lot with those. And since you can break the form into multiple pages, you can kind of take advantage of a lot of form validation to limit the ability or the availability of some of the remaining form steps. This is actually a screenshot of the D7 version that I did a while back. So here you can actually see the content type. There's about 30 or 40 some odd fields. Some of them are just very basic fields and some of them are compound fields, like the insets there. So you have class and level, you have armor, for instance. The name of the armor, the things that it modifies. Even though it's just a collection of integers and text fields, it's still a compound field. So yeah, so if you're interested in talking about field API, those are the main three steps for creating a custom field element. That's actually much harder than it looks there. So just a couple of brief examples based on our computational model. So yeah, skills, spells, and equipment are really vital things. There's a lot of computation that changes a lot of things about your character. So your character may or may not even have spells based on class and level and everything else. Even then, the subset of spells are gonna change within class specifics. Similarly, thieves are gonna have more skills than everyone else, which is super fair. And so the number of ranks and the skills that are available will vary a lot based on your class and your intelligence modifiers and all these other things. So race also makes a difference in the number of languages known, which is gonna affect a lot of the outcomes for other role-playing situations. So again, even though we're not dealing with data directly anymore, you can think about the game as content and so this is affecting the content of your project. Also, the equipment that you buy is gonna affect your armor class and it may influence actually the way you fight or don't fight depending on what you could afford or what your class allows you to wear. Inevitably, you may have to write some code. But you wanna determine how much you're gonna wanna spend doing form validation versus just trusting your players to enter good, honest data. And that's a problem that you face a lot of time on projects where you're not really sure, do I wanna spend three days doing form validation or do I just wanna say, hey, editors, make sure you don't enter stupid values into that field and they're like, okay, got it, yeah. No stupid data, sure. So there's always that kind of give and take of figuring out how much time you wanna spend on something versus how much value it provides. So on top of that, if you're using something like web forms, you can use conditional logic that's built into every single form element that changes the flow of your content entry. So for instance, only a warlock or a cleric should be required to specify a patron. It's available for everybody else, but for them it's required. So it's just a little thing that's required in fifth edition. So yeah, so those are also some additional things to think about. So pulling on all together, how are your players gonna see this final computed data from the thing that they input earlier? Well obviously, you can view this on just a standard node page. You can create a node template just like you've done on every other project. You can create a node-dndcharacterhtml.twig file. It's gonna go on your theme. And you can make it look really good and make it something that's tablet friendly so that you can have it there on the table so you can look things up. You might add CSS as a library and I would actually suggest creating this as two separate libraries because kind of following the idea of a separation of concerns, you might have one CSS file that manages the output of your compound fields, right? And then you have one that manages the layout and the style of the node page itself. So, but going back to considering the, how users will consume your data, how users will consume your content, think about are they gonna be looking at this on desktop? Are they gonna be looking at this in mobile? And this comes up a lot of times when you have discussions about responsive design. Do I wanna create a mobile app? What about smart devices? What about other things? Well, come on people, what about printing it out? And sitting around the table with something tangible in your hand that you can scribble on with a pencil and do a doodle of your character and all sorts of stick figures fighting. That's what the back of the character sheets for. So, if you have a really good node template and you use, don't forget, there is the media attribute in CSS that you can say, for print, here's a separate set of CSS. People forget about that, but it's nice to be able to point that out here. And you do see this on a lot of really good recipe websites. They'll have a printable CSS because they've considered how users are gonna consume this. You're gonna print this out, put it in your recipe book that you keep on the counter or something. Likewise, you may wanna do that here. But what if you want something that's a little bit more closely resembling the official character sheets? Like, some people are brand nerds and they really want that character sheet to look just like the one that comes out of the back of the player's handbook. So, PDF might be a really good option for you here. There's a lot of modules that actually help this. Some that are kind of in questionable states, but things like entity print, which uses a really widely used WK HTML2 PDF library. It's really easy to remember. To take essentially the HTML output of your node, so if you have a really well-defined node page, it'll actually convert that using WebKit internally, turn that into PDF, and be able to print that out in a really good, character sheet. One of the things that that helps overcome is if you've ever tried printing out something that looks beautiful on a screen, but suddenly you don't get backgrounds or colors or some of your font choices, it handles that for you really well. So, here we have the final project for our D&D character creator. And so, hopefully, you've learned a little bit about things like how to determine what fields the D&D character is gonna need, how to figure out how to calculate the additional values that you need to be able to output, how you might handle some of the intricacies of your complex data. And then, if you need to do some custom UI work, output is the thing that you're most concerned about in the end. Any questions? That is... There's actually a microphone right here in the center of the room. That way the recording can capture your question. Yeah, I'll mention first that the WKHTML to PDF library works with DisplaySuite. And if you grab its CSS, you can actually do your layouts and play with it. Ah, I did not know that. So, it actually integrates really well with DisplaySuite then. Yeah, you can do a Views to HTML. You can grab the HTML from a View and be displaying a set of nodes with DisplaySuite and pull it in. So, you can create a Display Mode that is PDF. Oh, yes. Oh, so yeah, I'm learning things now. And then on save, you can have a rule that says on save when the status is signed, then it goes ahead and produces the PDF and stores it as a private file. And yeah, oh, that's, yeah, it's fun. And the other thing that's kind of a fun way to do the assembly is with views bulk operations. If you go ahead and assign like a session specific kind of variable to your user account so that as you select entities, it can store them off. You could have them, for example, select all their skills and it will, when you hit next step, it'll have saved them and show you everything you have and then if you treated your skills as entities, you can be using that to assemble a node with the correct entity references and normalize your data. So. Yeah, also, that's a great approach. It's fun. You could probably use something like rules too to trigger things like if, Yeah. You know, like, especially if you need to use, like, you know, skills synergy for instance, you can set a couple of rules for that too. Yeah, and I'll use rules link and then put a, you know, just make the display for the link and X and so you can actually remove the skills that you want to take off and on and then. Oh, nice. So it's a fun one. Fun combo. Yeah, I'll check that out. Thank you. I have a question. Early in your presentation, you mentioned lookup tables. I'm wondering if, you know, if you, then being replaced by a formula, you can use to calculate on your data. Do you know of any Drupal modules or way of approaching actually computing lookup tables themselves? Hmm. I don't know of any modules off the top of my head that would let you do that. I know, I know in previous versions, there were things like, you know, I think it was a table module that would let you essentially just create and modify a table in SQL that you can then make available to views and so you would be able to have maybe views do something like that. I don't know that that necessarily helps in the context of a D&D character node per se, but you could probably do something like that. You may also be able to use something like the rules module to do, you know, a little bit more like, you know, stepping through like, you know, traditionally, you know, like if this, then that, you know, that may affect some of the computations as well. Thanks. If I understood you correctly, you stored all of your stats as a single text field. Is that right? You said you stored them as an array? Yeah, so to clarify, what appears on the node for abilities, for instance, is a single field called, you know, D&D character abilities. But that field, of course, in the definition of the field, you set it to a cardinality of six. So you have, you know, all six of those. Okay. And then that field itself is actually a paragraph, which then each instance of that field then has the base score, the racial modifier, the, you know, all these other fields. And so it's, the single field instance is maybe potentially created from six different fields, you know, energy values, and then the cardinality then lets you have six sets of those. One more thing, you mentioned this as a node plugin. Can you speak, I know you said, hey, you know, it might be a little bit over this, but speaking of that of being a, when we view the node, you do these calculations real-time on view or what would you do with the node plugin there? So it gets a little involved pretty quickly. But yeah, you can, you know, so like there is, you know, the node class that does a lot of manipulation of loading fields and things like this. So if you say, for instance, you know, when you're loading a field as part of your node and you're getting those values, you can do a lot of those calculations on the fly. Of course that gets, you know, cached optionally, hopefully. And so you can say, you know, you store like just the very basic fields and then recalculate these things whenever the node is loaded, you know, using that node plugin. Cool, thanks. So in using D7, I got really fond of field collections and you're using paragraphs and I know that this is kind of an, actually a relevant issue right now. Can you tell me why you prefer using paragraphs over field collections? Like I must put this in a sort of vacuum and not just because the community decided that paragraphs is better. Yeah, they do very similar things on the surface. Ultimately what they're doing is they're kind of, you know, collecting a lot of individual fields and putting them in a bag for you that you can kind of then carry along as a single field. One of the things that I like about fields, about paragraphs as fields, is that it's very tightly integrated with entity API. So you get a lot of the benefit of entity caching and paragraphs are themselves entities that you can then use very easily in views. So you can search for, you know, if you wanted to create a view, list all of the characters that have skills above, you know, whatever value. So that's one of the reasons that I would choose paragraphs over that. Partly to just historically, like especially in Drupal 7, I found that paragraphs does perform a lot better because of some of the inherent caching that it takes advantage of within entities, so. Because of its unfortunate name, I just stuck with what I knew, so. Yeah, yeah, and field collections, the name, right, those sounds like exactly what you need. Yeah, it does, it does. But I mean, I've grown really comfortable with the use of paragraphs over the years. I find that the paragraph templates, for instance. So if you, you know, something that I did mention when we were talking about creating a node level template for your character, you can also have a paragraph level template for each one of the skills. So if you wanna have, you know, say depending on the display mode, you can have like a single one line, very minimal version of your ability scores, or you can have that big block that appears on the side of your character sheet. So some of the theming with paragraphs is pretty easy to use too. Templating a field collection is definitely not the funnest thing in the world. And getting it to play nice with views doesn't always work, either. Been there? Been there. Thank you. All right, thank you. I want to see your views. All right, any other questions? So one final question. You mentioned polymorphing your data. If you have chosen transmutation as your restricted school, do you have an alternate method? Wow, thank you. Thank you for, yes, sorry, that was a joke. Peace out. Thank you very much. Mic drop.