BDL Core Concepts
Learn the fundamental concepts of the Basilisk Definition Language
Overview
The Basilisk Definition Language (BDL) is a domain-specific language designed to define data structures for your game content. Understanding the core concepts is essential for creating effective definitions.
Entities
Entities are the primary data structures in BDL. They represent a collection of related variables that define a single concept, such as a character, weapon, or quest.
entity Character {
id: string,
name: string,
isHidden: boolean,
baseSpeed: int,
scaleMultiplier: float,
powerMultiplier: double
}Each entity must have at least one primary key variable that uniquely identifies instances of that entity.
Subentities
Subentities allow you to nest data structures within entities, creating complex hierarchical data models. They are useful for grouping related properties together.
subentity Stats {
health: float,
attack: float,
defense: float,
speed: float
}
entity Character {
id: string,
name: string,
stats: Stats
}Subentities help organize related data and create more structured, maintainable definitions.
Enums
Enums define a predefined set of values that a variable can take. They are useful for representing fixed categories, states, or types in your data.
enum WeaponRarity {
COMMON,
RARE,
EPIC,
LEGENDARY
}
entity Weapon {
id: string,
name: string,
rarity: WeaponRarity
}Enum values are typically written in UPPER_SNAKE_CASE and provide type safety and clear constraints on valid values.
Variables
Variables define the properties of an entity. They specify the data type and can have additional properties like optional, default values, or references.
| Variable Name | Description | Types of Examples | Real Examples |
|---|---|---|---|
string | Text data | names, descriptions, IDs | id, name |
boolean | True/false values | isActive, isUnlocked | isActive, isUnlocked |
integer | Whole numbers | level, count, damage | damage |
float | Decimal numbers | health, price, probability | critChance, attackSpeed |
double | High-precision decimal numbers | precise calculations, coordinates | powerMultiplier, coordinates |
enum | Predefined set of values | rarity levels, status types | rarity (WeaponRarity) |
subentity | Nested entity structures for complex data | complex nested structures | stats (WeaponStats) |
array | Collections of values of the same type | lists of items | tags (string[]) |
subentity StatModifier {
stat: string,
value: int
}
enum Rarity {
COMMON,
RARE,
EPIC,
LEGENDARY
}
entity Item {
id: string,
name: string,
price: int,
modifiers: StatModifier[],
rarity: Rarity
}Detailed Variable Declaration Mode
BDL supports a detailed declaration mode for variables that allows you to explicitly specify all properties in a structured format. This mode is useful when you need to declare variables with multiple properties or when you want to make the declaration more explicit and readable.
Simple Declaration Mode
The simple mode uses inline properties within parentheses:
entity Character {
id: string,
name: string,
nickname: {
type: string,
optional
},
rarity: {
type: ItemRarity,
optional,
default: COMMON
},
weaponId: {
type: string,
references: Weapon,
optional
}
}Detailed Declaration Mode
The detailed mode uses a block structure to explicitly declare all properties:
entity Character {
id: string,
name: string,
nickname: {
type: string,
optional
},
rarity: {
type: ItemRarity,
optional,
default: COMMON
},
weaponId: {
type: string,
references: Weapon,
optional
},
stats: {
type: CharacterStats,
optional
}
}Available Parameters
| Parameter | Description | Required | Notes |
|---|---|---|---|
type | Defines the data type of the Variable | Yes | Must be a primitive type, Enum, Subentity or an Array. Determines validation rules at build time. |
column | Overrides the sheet's column name used to read the value | No | Use when sheet columns cannot be renamed, multiple Entities read from the same sheet differently, or implementing localization/variants. |
primary key | Marks a Variable as the primary key of the Entity | No | Each Entity has exactly one primary key. Primary keys must be unique. If not specified, a Variable named `id` is used by convention. |
references | Declares a reference to another Entity | No | Each value must exist in the primary key Variable of the referenced Entity. References are validated at build time. |
optional | Allows the Variable to be missing or empty | No | Variables are mandatory by default. Non-empty optional values must still abide by all other rules. |
default | Defines a default value when the spreadsheet cell is empty or missing | No | Requires the Variable to also be optional. The default value must be of the same type as the declared Variable type. |
unique | Enforces uniqueness across all rows for a Variable | No | All values of the Variable must be unique within the Dataset. Primary keys are implicitly unique. |
bundle | Forces Basilisk to group data around repeated values | No | Only available in Subentity structures. Cannot be used on Variables declared as Array. Only one bundle Variable per Subentity allowed. |
When to Use Detailed Mode
Use detailed declaration mode when:
- You have variables with multiple properties that would make inline syntax hard to read
- You need to specify complex default values (like nested objects or arrays)
- You want to make the variable properties more explicit and self-documenting
- You're working with variables that have many optional properties
Both declaration modes are equivalent and can be mixed within the same entity definition. Choose the style that best fits your use case and team preferences.
Indexes
Indexes define how to look up entities in a dataset. They specify which variable(s) should be used as keys for efficient data retrieval.
index {
characters: {
sheet: "characters",
entity: Character
}
weapons: {
sheet: "weapons",
entity: Weapon
}
}Indexes map spreadsheet sheet names to entities, allowing the system to read data from your Google Spreadsheets.
Data Bundles
Data Bundles group entities into deployable units. They specify which datasets to include and how to organize them for your application.
databundle client {
characters: characters
weapons: weapons
quests: quests
}
databundle server {
gameConfig: gameConfig
economy: economy
}You can create multiple data bundles to separate client-side and server-side content, or organize content by feature.
Primary Keys
Primary keys uniquely identify each instance of an entity. They are marked with the (primary_key) property and must be unique across all instances.
entity Item {
id: string,
name: string,
description: string
}References
References create relationships between entities. They ensure data integrity by linking entities together.
entity Weapon {
id: string,
name: string
}
entity Character {
id: string,
name: string,
weaponId: {
type: string,
references: Weapon
}
}References validate that the referenced entity exists, preventing orphaned data and ensuring referential integrity.
Optional Fields
Optional fields allow variables to be omitted from data. This is useful for fields that may not always be present.
entity Character {
id: string,
name: string,
nickname: {
type: string,
optional
},
bio: {
type: string,
optional
}
}Default Values
Default values provide fallback values when a field is not specified. They work together with optional fields.
entity Item {
id: string,
name: string,
rarity: {
type: ItemRarity,
optional,
default: COMMON
},
stackSize: {
type: int,
optional,
default: 1
}
}
enum ItemRarity {
COMMON,
RARE,
EPIC,
LEGENDARY
}