Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`Choice` structure reform

See original GitHub issue

Issue Description


There are a number of issues with the Choice structure that keep cropping up: nested Choices, arrays of mixed types, no way to easily describe or deserialize the structure… This issue aggregates those problems and proposes a reformed Choice structure that aims to solve them.

The details of the existing problems and proposed solutions are explained below. I’ve also described the final proposed structure in TypeScript syntax for reference (this is not intended to be official documentation), and provided an example of the structure in the form of the Fighter’s starting_equipment_options array. Both can be found in this gist:

With the community’s approval I’ll be more than happy to take up the task of implementing the proposal, as well as producing the user-facing documentation.



The biggest issue being addressed is consistency. A lot of data consumers don’t like arrays with items of mixed types (#274), and there are a variety of structures that can appear in different places without any straightforward way of identifying them.

The proposal uses an inheritance pattern to give all items in an array a common type, for easy deserialization. For example, in the from array of a Choice, there could be nested choices, arrays of items that must each be resolved separately, or a “terminal”, single item. Currently these are given in their raw forms; the from array could contain Choice objects, JSON arrays, or single objects.

To solve this, every item in the array will now be an object with an option_type attribute of either choice, multiple or single, which indicates the structure of the underlying data. The same pattern is used to identify whether the Choice is between an array, as described above, or a ResourceList. See the JSON snippet in the gist for examples.


Another issue with the current Choice structure is that it can be hard to explain to a human user what they’re actually choosing between (#355). While it is easy to list the options available, and the type attribute of a choice provides some information, a consumer has no way of indicating where the choices are coming from, or what they are. For example type may indicate that a "proficiency" is being chosen, so an application could easily render something like “Choose one proficiency:”, but the underlying choice in the SRD is actually “one type of artisan’s tools or one musical instrument”

To solve this, the proposal adds an optional desc string for Choices, so that consumers don’t have to write any funky algorithms to tell a human user what they’re choosing from. The string should include the text from the SRD that describes what needs to be chosen, e.g. “a wooden shield or any simple weapon”, “one type of artisan’s tools or one musical instrument”, “a martial weapon and a shield or two martial weapons”, etc.


  • The type attributes of Option and OptionSet objects have been renamed to option_type and option_set_type respectively, to more easily distinguish the difference between the structures from the programmer’s perspective.
  • The array value of the option_type attribute has been changed to multiple, to help indicate that all of the items in the JSON array come with that option.
  • The resource_list value of the option_set_type has been changed to resource_list_url to better indicate the structure of the data: it is a string holding a URL that resolves to a ResourceList, not an actual ResourceList in its own right.
  • The resource_list OptionSet now holds the ResourceList’s URL under resource_list_url, rather than just url.
  • The EquipmentCategoryOptionSet type has been added to support equipment categories properly (which have a structure distinct from ResourceLists). EquipmentCategories are now linked with an APIReference.
  • The single Option type has been split into reference and action. The reference type is identical to the previous single type, corresponding to a counted APIReference. The action type is intended for use within “Multiattack” actions, referring to actions, by name, within the same Monster document. An example based on the “Captain” has been added to the Gist.
  • The array option_set_type has been renamed to options_array, to make it clear what the array contains.

Final Spec

This section describes the state of the proposal after the discussed amendments, to aid with the implementation:


The Choice structure describes a decision that must be made by a player during character creation or gameplay. It has four attributes:

  • desc (string, optional): A description of the choice to be made in human-friendly and (where possible) SRD text.
  • choose (number): The number of options that must be chosen. The same option can be chosen more than once.
  • type (string): A string indicating the type of object that will be chosen.
  • from (object): An object containing the options to choose from. This may take one of a number of forms as described below.


The OptionSet structure provides the options to be chosen from, or sufficient data to fetch and interpret the options. All OptionSets have an option_set_type attribute that indicates the structure of the object that contains the options. The possible values are options_array, equipment_category and reference_list. Other attributes on the OptionSet depend on the value of this attribute.

  • options_array
    • options (array): An array of Option objects. Each item in the array represents an option that can be chosen.
  • equipment_category
    • equipment_category (APIReference): A reference to an EquipmentCategory. Each item in the EquipmentCategory’s equipment array represents one option that can be chosen.
  • resource_list
    • resource_list_url (string): A reference (by URL) to a collection in the database. The URL may include query parameters. Each item in the resulting ResourceList’s results array represents one option that can be chosen.


When the options are given in an options_array, each item in the array inherits from the Option structure. All Options have an option_type attribute that indicates the structure of the option. The possible values are reference, action, multiple and choice. The value of this attribute indicates how the option should be handled, and each type has different attributes.

  • reference - A terminal option. Contains a reference to a Document that can be added to the list of options chosen.
    • item (APIReference): A reference to the chosen item.
  • action - A terminal option. Contains information describing an action, for use within Multiattack actions.
    • action_name (string): The name of the action, according to its name attribute.
    • count (number): The number of times this action can be repeated if this option is chosen.
    • type (string = "melee" | "ranged", optional): For attack actions that can be either melee or ranged (e.g. for thrown weapons).
  • multiple - When this option is chosen, all of its child options are chosen, and must be resolved the same way as a normal option.
    • items (array): An array of Option objects. All of them must be taken if the option is chosen.
  • choice - A nested choice. If this option is chosen, the Choice structure contained within must be resolved like a normal Choice structure, and the results are the chosen options.
    • choice (Choice): The Choice to resolve.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:2
  • Comments:106 (55 by maintainers)

github_iconTop GitHub Comments

Wyzardscommented, Dec 24, 2021

Very late note, but I’ve been asked to include this finding here.

This structure will have some issues handling the choices for Ideals, Flaws, Bonds and Personality Traits stored within Backgrounds. Two types of single option must be added in order for these to be used as Options. An “ideal” option will be needed in addition to the “reference” and “action” OptionTypes. Additionally a “string” OptionType will be needed to use Personality Traits, Bonds and Flaws since all of these are just strings.

Fairly self explanatory, just other option types. This would leave us with singular option types of action, reference, ideal, and string

For any unaware, Ideals are not just strings. Here’s an example of an Ideal in the Acolyte background.

        "desc": "Power. I hope to one day rise to the top of my faith's religious hierarchy.",
        "alignments": [
            "index": "lawful-good",
            "name": "Lawful Good",
            "url": "api/alignments/lawful-good"
            "index": "lawful-neutral",
            "name": "Lawful Neutral",
            "url": "api/alignments/lawful-neutral"
            "index": "lawful-evil",
            "name": "Lawful Evil",
            "url": "api/alignments/lawful-evil"
fergcbcommented, Aug 21, 2021

I’ve updated the Gist and added a summary of the final state of the proposal to the end of the original comment, as a sort of implementation guide for whoever picks this up.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Comparative Structural Reform - FairVote
Comparative Structural Reform presents an extensive assessment of the potential impact of 37 structural reforms to election laws and ...
Read more >
What are structural reforms? - European Central Bank
They are designed to ensure the economy is fit and better able to realise its growth potential in a balanced way. Aiming for...
Read more >
The International Architecture for Resolving Sovereign Debt ...
There have been significant developments in sovereign debt restructuring involving private-sector creditors since the IMF's last stocktaking ...
Read more >
Public Choice, Structural Design, and Police Reform — Mark Twain ...
In the private sector, constant conversations around proper structure and incentives are essential ... Public Choice, Structural Design, and Police Reform.
Read more >
The “Three Reforms” in China: Progress and Outlook
Structural reform policies were actually adopted, however, at the 1997 Chinese Communist Party (CCP) National Congress. Among the policies introduced were ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Post

No results found

github_iconTop Related Hashnode Post

No results found