Table of Contents
Project Summary
Summarized Bullet Points:
-
Making procedural generation (PG) systems for a non-combat roleplaying(RP) demo.
-
A combat system, for the purposes of this project, is any system that has the player damage an opposing force in order to try and knock out/kill said force.
-
-
Where PG will be used:
-
Character/NPC Generation
-
Quest Generation
-
-
Since there will be no combat, some more focus on dialogue will be necessary.
-
Need a dialogue system with speech choices as well as gifting.
-
Also should probably have a way to look up and review information learned (though this is a wishlist item).
-
-
Skills and Minigames
-
The idea would be to break up a bit of the flow, but also relate back to quests and the social aspect.
-
The minigames would be a bit more about button mashing or timed button presses (at least for the ideas I have now).
-
The minigames might could be used in the social aspect in that could have a cooking skill and minigame, and could be used as part of an event to try convince an NPC to do something or fork over information.
-
The project's express goals is to create procedurally generated content for a roleplaying demo in various ways, while also having the added restriction of no combat systems. For the sake of this project, a combat system is considered to be any system that gives the player the power to knock out or kill enemy forces via depleting "life points" or equivalent stat. Thus any skills, stats or so on that does not move the game towards having a combat system is fair game for being incorporated.
The PG content is through quests, and characters (dialogue by association gets effected by the procedurally generated characters).

Gif was uploaded on 4/5/2017. This primarily shows some changes to the tile definition and map systems. But this image also shows the first half of the "Find my Sibling" quest.

Gif was uploaded on 4/5/2017. This gif shows the second half of the "Find my Sibling" quest, but with a different set of procedurally generated characters. The younger sibling is even generated in a new position.

Gif uploaded as of 1/11/2017. What this is demonstrating is some of the basic necessities of an RPG: Movement, and also OnEnter and OnExit events for tiles (which also can be used as part of setting up for OnInteract events).

Gif was uploaded on 4/5/2017. This primarily shows some changes to the tile definition and map systems. But this image also shows the first half of the "Find my Sibling" quest.
Gallery of Screen Captures During Life of Project
Map and Tiles
-
There are several classes to know: Tiles, Tile Definitions, Tile Events, Maps, and Map Files
-
Tile Definitions:
-
​Uses the Resource paradigm
-
Defines a series of parameters for a given Tile to follow:
-
What sprites to use
-
Whether the tile is solid or not
-
Note: a light bit of procedural generation is used:
-
Can define an alternative sprite and percentage change for an alternative sprite to be used, per layer
-
-
Special Cases (requirements paired with overwriting parameters)
-
Enables having a single tile definition for a whole house or a lake.
-
Giving a list of other tile definitions on a given tile definition enables the requirements to treat the others as the same:
-
example: a house tile would be able to treat a sink house tile as the same as its self (thus preventing the roof from having a hole in it)
-
-
-
-
-
Tiles:
-
Holds a list of tile events, a reference to a tile definition, and a series of current parameters
-
-
Tile Events:
-
Defines what should happen when an Agent touches, enters, exits, or interacts with the given tile.
-
Uses Self-Registration paradigm in order to make different Tile Events accessible from data.
-
-
Map:
-
A group of tiles interpreted from a Map Image File and a Map Data File
-
Map Image file defines how many tiles and what tile definition each tile uses.
-
Map Data file defines tile events, and quests available on the map as well as what NPCs and features to spawn.
-
-
-
Map Files:
-
A Map Image File path and a Map Data File path paired with an associated name
-
Important for being able to switch maps
-
Also can specify a list of map file dependencies (which maps need to be loaded before the present one)
-

This image depicts the lake and house tile definitions in action. The special cases enable the tile definitions to check to the north, east, south, and west directions to determine how many of what tile is in a given direction. From that, it can change whatever information about whatever tiles it wants.

This image depicts the same house and lake tiles as before, but from inside of the house. The tile with the sink on it is it's own tile definition, but it is also listed for the brown house to treat the sink tile as the same as itself. This allows the brown house's roof not to have a hole in it.

This image depicts the lake and house tile definitions in action. The special cases enable the tile definitions to check to the north, east, south, and west directions to determine how many of what tile is in a given direction. From that, it can change whatever information about whatever tiles it wants.
Example simple Tile Definition data
Example Tile Definition data with Special Cases
Example Map data
Example Map Files data
Game Entities and Behaviors
-
Base Game Entity makes up any non-Tile object in the game
-
Entity types: Hair, Features, Items (Clothing), Agents (Non-Player Characters (NPCs), and Player)
-
A feature is a cosmetic or interactable entity in the game
-
An agent is any character or mobile entity in the game
-
Features use Feature Behaviors to determine how to act when placed, on update, or when interacted with
-
Feature examples: Doors (turn the tile they are on to non-solid), Campfires (that can be turned on and off), etc.
-
-
NPCs use NPC Behaviors to determine what to do on update
-
Supported NPC Behaviors:
-
Talking (Look towards Agent talking to)
-
Look Around (Change direction every varying amount of seconds)
-
Wander (Same as look around, but constantly moving forward)
-
-
-
Both NPC Behaviors and Feature Behaviors use the self registration paradigm
-
All entity types use the Factory paradigm in order to generate the appearance, stats, and attributes of said entity

A diagram depicting the Base Game Entity and all classes that inherit from it.

A diagram depicting the Base Game Entity and all classes that inherit from it.
Agent/Character Procedural Generation
-
Agents are spawned through Agent Generators (which use the Factory paradigm)
-
Agents have a variety of content that can be procedurally generated on them:
-
Clothing
-
Hair
-
Names
- Skin Color
-
Agent Stats
-
If NPC:
-
Dialogue Segment/Group Names to open when interacted with
-
NPC Attributes
-
NPC Jobs
-
-
-
Clothing and Hair are essentially a list of animations associated with an integer color choice.
-
Skin Color is the color choice for the entity itself.
-
Names:
-
Are generated from a Name Generator; the Agent Generator calls a name generator by name to do so
-
Name Generators can generate a name with any variable number of parts and in a variable order
-
-
Agent Stats:
-
A general range is defined for a particular Agent Stat in its own dedicated XML file
-
However each Agent generator can define a unique range for procedurally generating that stat
-
This can be such that the player starts with a strength between 10 to 15, but the strength stat has an original range of 0 to 100
-
The player's strength stat can be increased beyond 15 up to 100 after it has been generated.
-
-
-
Dialogue Segment/Group Names:
-
A list of names of either a dialogue group or dialogue segment
-
If it is the name of a dialogue group:
-
the dialogue group will select from a list of dialogue segment names that are presently useable and open that segment when the agent is interacted with
-
-
-
NPC Attributes:
-
Essentially a name for the attribute associated with a vector of string values
-
Agent Generators can whitelist or blacklist particular values as needed when generating
-
Can be used by quests to select a particular Agent instead of having to generate a new one
-
Can be used with Dialogue Requirements (limiting what segments are useable/visible per Agent)
-
Example:
-
Attribute Name: Age
-
Old
-
Adult
-
Teenager
-
Child
-
-
-
-
NPC Jobs:
-
An NPC Job is a job name associated with a list of Agent Stat requirements
-
If no valid NPC Job is available, the NPC will be labeled as Jobless
-
Can be used with Dialogue Requirements (limiting what segments are useable/visible per Agent)
-
Example of Agent Generator data
Example of Agent Generator data Inheriting from another Agent Generator
Example of Agent Stats data
Example of Name Generator data
Example of NPC Attribute data
Example of NPC Job data
Example of Clothing data
Example of Hair data
Dialogue
-
The dialogue system is made up of Dialogue Segments, Groups, Choices, Triggers and Requirements
-
Dialogue Segments:
-
Uses the Resource paradigm
-
Contains a string of text, a speech bubble, and a list of dialogue choices, triggers and requirements
-
The text is parsed into separate words at run time
-
This is as there are variables embed into the text
-
Variables are denoted with '$' on either side of a word
-
Variables can indicate to use text from quests, or mention the npcs job, attributes, etc.
-
-
A speech bubble is a sprite that is stretched horizontally and vertically
-
The Dialogue triggers are run upon the dialogue segment's closing
-
Dialogue requirements in this case are used to determine if a dialogue group can open this particular dialogue segment (a dialogue group can not open a dialogue segment who has a requirement that is not met)
-
If the segment has any dialogue segments, then it will display them after the text has been read by the player
-
Alternatively, segments can also list the name of another dialogue segment/group to open after it closes
-
-
Dialogue Groups:
-
Uses the Resource paradigm
-
Contain a list of Dialogue Segment names in which it can call, as well as a list of Dialogue Triggers
-
The dialogue group, upon being accessed, compiles a list of dialogue segments that can be run and selects one to open.
-
A dialogue group does not require its own data file (if a Dialogue Segment says it is a part of a previously non-existing group, then that group will be created)
-
If a dialogue group is declared in its own data file, then it can declare dialogue triggers
-
Dialogue triggers, in this case, run whenever any dialogue segment from this group closes.
-
-
Dialogue Choices:
-
Contains a name, a dialogue segment to open after the player selects it, as well as a list of triggers and requirements.
-
The dialogue triggers are run upon the player selecting the choice
-
If any dialogue requirements are not met for the choice, then the choice will not be displayed and not select-able by the player.
-
-
Dialogue Triggers:
-
Uses the self-registration paradigm
-
Is a function that changes variables within the game
-
-
Dialogue Requirements:
-
Uses the self-registration paradigm
-
Checks variables within the game to determine if a dialogue segment or choice can be used
-

This is a dialogue segment opened from the "greeting" group.

This is another dialogue segment opened from the "greeting" group

This dialogue segment shows a game of riddles, where in the player can select from multiple choices.

This is a dialogue segment opened from the "greeting" group.
Example of Dialogue Segment data
Example of Dialogue Group data
Quest Procedural Generation
-
Once the rest of the content is set up, its pretty straight forward to procedurally generate quest and quest content
-
Quests are able to read data both local to themselves and from the global data pool
-
Map data has the power to define a percentage chance for a quest to appear
-
Procedural generation for quests, in its most basic form, can supply replayability:
-
This is such that the player can not assume that a character they are looking for is always in the same location between different games.
-
-
Quests contain instructions for a list of variables, how to generate the needed entities, and a list of events
-
Quest Variables:
-
Supported data types:
-
Floats
-
Booleans
-
Text
-
These variables can be called as dialogue variables
-
Just requires: $QuestName.VariableName$
-
-
NPC
-
Text information can be read off these via: $QuestName.QuestVariableName.NPCVariableName$
-
Note that only certain things can be gotten this way, such as the NPC's name.
-
-
Feature
-
Player
-
This is necessary if the quest needs any access to the player.
-
-
-
-
Related to Quest Entity spawning:
-
Entities a quest can spawn:
-
Agents
-
Features
-
-
Unless otherwise specified, Features will always be spawned as new
-
Unless otherwise specified, Agents will always be selected from pre-existing NPCs that meet the requirements (else it will spawn as new)
-
The instructions will require to have the quest variable name of the entity it is to be plugged into.
-
Agents and Features can also specify to use a global variable (assuming its the correct type) as the intended variable
-
-
Quest Events:
-
Contains a list of Quest requirements, and two lists of quest triggers
-
Quest Requirements:
-
Determines if the owning event can run; note that the quest will search up until the first event that meets all of it's own requirements, then run that one.
-
-
Quest Triggers:
-
Changes data within the quest as well as within the rest of the game.
-
Can be loaded into a list that runs before the entity is interacted with, and a list that runs after the entity is officially interacted with
-
Aka: before and after dialogue is opened, when the player first talks to an NPC.
-
-
-

Start of the "Find my Sibling" quest, but the younger sibling (searching for) is male.

Start of the "Find my Sibling" quest, but the younger sibling (searching for) is female.

The younger sibling location 3 for the Find my Sibling quest

Start of the "Find my Sibling" quest, but the younger sibling (searching for) is male.
Example of Quest data
Paradigms
-
Factory Paradigm:
-
Data is read into a template, and is used later for spawning objects based on the parameters in the data
-
Each object spawn has the potential to be different, thanks to built in procedural generation functionallity
-
Examples: Agent Generators and Agents, Name Generators and Names, Hair Generators and Hair
-
-
Resource Paradigm:
-
Data is read in, and a single copy of the object is maintained throughout the life of the program
-
Reference to that object is passed around when needed
-
Examples: Sprite Resources, Sounds, Dialogue Segments
-
-
Self-Registration Paradigm:
-
This takes advantage of the nature of game side code
-
First, a base class is defined (i.e. NPCBehavior)
-
Second, a registration helper class is defined (only one constructor is created; one which takes a name and between one and two functions that spawn the needed class
-
Whenever the constructor is called; the registration helper will add itself to a list
-
-
Third, a variant of the base class is created; for each variant, a static Registration Helper is defined along with associated functions
-
Finally, at compile time, the static Registration Helpers are pushed into a list, where in it is easy to pull out and spawn the variant class by the associated name
-
Factory Paradigm Example Header Files
Hair Generator HPP file
Hair Template HPP file
Resource Paradigm Example Header Files
Sound Registration HPP file
Self-Registration Paradigm Example Header Files
NPC Behavior HPP file
NPC Behavior Registration Helper HPP file
Look Around (NPC Behavior Variant) HPP file
What Went Well
-
The paradigms made exposing everything to XML easy. This is as it gave me more control over how to interpret the XML while also decreasing the number includes per file.
-
Agent generators were also fairly straight forward to set up; mainly in that most of the content type that could be desired was easy to foresee, thus easy to prepare.
-
Quests were one of the last things I built; as such the majority of past problems I had encountered were easier to avoid, and I was able to create a fairly powerful system out of it.
Challenges
-
Getting text parsing up to the level of quality I wanted took longer than expected. Even still, the file for the text parsing has the potential to become bloated with code as time goes on
-
Separating out the requirements and triggers for various systems (dialogue, quests, etc.) did give me maximum control over which operations I wanted them to be able to perform, but cost me lots of time
-
Did not create debugging tools for the quests at the same time as creating the quests:
-
Lead to difficulty debugging quests, especially with procedural content
-
What I Learned
-
In the future when planning out a system, plan out what sort of debug tools I or a designer would desire at the same time. Then code them up.
-
Limit the number of variants for a paradigm where possible; the trigger and requirement lists could of been shrunken down eminsely
-
When creating a system that reads in data, write an example data file before doing any code for said system.