Setting Up Packages
Packages let you organize reusable scripts into self-contained modules. This guide walks you through setting up a workspace with packages.
Why Packages?
Section titled “Why Packages?”As your project grows, you’ll want to:
- Namespace exports to avoid naming collisions between teams
- Share scripts that define common item sets or equipment configurations
- Organize by domain (e.g.,
core,shared,extensions)
Project Structure
Section titled “Project Structure”A typical DataSheetLang project with packages looks like this:
my-project/├── datasheetlang.yml # Workspace configuration├── packages/│ ├── core/│ │ └── index.yml # Core package entry point│ └── shared/│ └── index.yml # Shared package entry point└── patches/ └── items.yml # Your spec filesStep 1: Create the Workspace File
Section titled “Step 1: Create the Workspace File”Create datasheetlang.yml in your project root:
workspace: packages: core: ./packages/core shared: ./packages/sharedEach entry maps a package name to its folder path. The path is relative to the workspace file.
Step 2: Create a Package
Section titled “Step 2: Create a Package”Create your first package at packages/core/index.yml:
exports: scripts: weapon.starter: items: create: - id: 51056 name: chain_scythe combatItemType: EquipWeapon category: Lance maxStack: 1 tradable: "False" level: 60The index.yml file is the package entry point. Everything under exports becomes available to other files that import this package.
Step 3: Use the Package
Section titled “Step 3: Use the Package”Create a spec file at patches/items.yml:
spec: schema: items
imports: - from: core
use: - core.weapon.starter
items: update: - id: 51056 changes: buyPrice: 100Key points:
imports: [from: core]loads the core package- Scripts are referenced with the package prefix:
core.weapon.starter
Exporting Scripts
Section titled “Exporting Scripts”Packages export scripts as reusable blocks of operations:
exports: scripts: reaper.weapons: items: create: - id: 51056 name: chain combatItemType: EquipWeapon maxStack: 1 level: 60 - id: 51057 name: scythe combatItemType: EquipWeapon maxStack: 1 level: 60Use scripts with the use directive:
spec: schema: items
imports: - from: core
use: - core.reaper.weapons
items: update: - id: 51056 changes: buyPrice: 445360When compiled, script operations are injected before your local operations. This lets you define base items in a script and apply modifications locally.
Organizing with Relative Imports
Section titled “Organizing with Relative Imports”Packages can split their exports across multiple files:
packages/core/├── index.yml└── scripts/ ├── weapons.yml └── starter-gear.ymlUse relative imports to combine them:
imports: - from: ./scripts/weapons.yml - from: ./scripts/starter-gear.yml
exports: scripts: common.items: items: create: - id: 1 name: general_item maxStack: 1Each imported file can have its own exports section. All exports are collected and namespaced under the package name.
Exporting Variables
Section titled “Exporting Variables”Packages can export named variables (ID constants, shared values) alongside scripts. Variables require explicit opt-in at every step — see Variables: Cross-module variables for full rules.
Single-file package
Section titled “Single-file package”Declare variables and list them in exports.variables:
variables: BASE_HP: 1000 BASE_MP: 500
exports: variables: - BASE_HP - BASE_MPConsumer specs import with use.variables:
imports: - from: constants use: variables: - BASE_HP
creatures: create: - id: 1 hp: $BASE_HPMulti-file package
Section titled “Multi-file package”Variables can be split across sub-files. Each sub-file must declare spec:, define variables, and export them. The index.yml imports with use.variables and re-exports:
packages/crystals/├── index.yml├── weapon.yml└── armor.ymlSub-file (weapon.yml):
spec: version: "1.0"
variables: SWORD_ID: 8100 AXE_ID: 8200
exports: variables: - SWORD_ID - AXE_IDPackage entry (index.yml):
spec: version: "1.0"
imports: - from: ./weapon.yml use: variables: - SWORD_ID - AXE_ID - from: ./armor.yml use: variables: - CHEST_ID
exports: variables: - SWORD_ID - AXE_ID - CHEST_IDConsumer spec:
imports: - from: crystals use: variables: - SWORD_ID
items: upsert: - id: $SWORD_ID level: 60Key points:
- Sub-files need
spec: version: "1.0"to be recognized as modules - Sub-files must list exported variables in
exports.variables index.ymlmust explicitly import each variable viause.variablesbefore re-exporting- An import without
use.variablesimports no variables — definitions auto-import, variables do not
Multiple Packages
Section titled “Multiple Packages”You can import from multiple packages:
imports: - from: core - from: shared
use: - core.weapon.starter - shared.special.weaponsEach package maintains its own namespace, so core.weapon.starter and shared.weapon.starter are distinct scripts.
Complete Example
Section titled “Complete Example”Here’s a complete working setup:
datasheetlang.yml
workspace: packages: core: ./packages/corepackages/core/index.yml
exports: scripts: starter.weapons: items: create: - id: 100 name: training_sword combatItemType: EquipWeapon category: Lance maxStack: 1 level: 1
starter.equipment: equipment: create: - equipmentId: 100 level: 1 part: Weaponpatches/new-player.yml
spec: schema: items
imports: - from: core
use: - core.starter.weapons - core.starter.equipment
items: update: - id: 100 changes: buyPrice: 0 sellPrice: 0Run with:
dsl apply patches/new-player.yml --datasheet ./DataSheet