Skip to content

Setting Up Packages

Packages let you organize reusable scripts into self-contained modules. This guide walks you through setting up a workspace with 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)

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 files

Create datasheetlang.yml in your project root:

workspace:
packages:
core: ./packages/core
shared: ./packages/shared

Each entry maps a package name to its folder path. The path is relative to the workspace file.

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: 60

The index.yml file is the package entry point. Everything under exports becomes available to other files that import this 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: 100

Key points:

  • imports: [from: core] loads the core package
  • Scripts are referenced with the package prefix: core.weapon.starter

Packages export scripts as reusable blocks of operations:

packages/core/index.yml
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: 60

Use scripts with the use directive:

patches/reaper-patch.yml
spec:
schema: items
imports:
- from: core
use:
- core.reaper.weapons
items:
update:
- id: 51056
changes:
buyPrice: 445360

When compiled, script operations are injected before your local operations. This lets you define base items in a script and apply modifications locally.

Packages can split their exports across multiple files:

packages/core/
├── index.yml
└── scripts/
├── weapons.yml
└── starter-gear.yml

Use relative imports to combine them:

packages/core/index.yml
imports:
- from: ./scripts/weapons.yml
- from: ./scripts/starter-gear.yml
exports:
scripts:
common.items:
items:
create:
- id: 1
name: general_item
maxStack: 1

Each imported file can have its own exports section. All exports are collected and namespaced under the package name.

You can import from multiple packages:

imports:
- from: core
- from: shared
use:
- core.weapon.starter
- shared.special.weapons

Each package maintains its own namespace, so core.weapon.starter and shared.weapon.starter are distinct scripts.

Here’s a complete working setup:

datasheetlang.yml

workspace:
packages:
core: ./packages/core

packages/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: Weapon

patches/new-player.yml

spec:
schema: items
imports:
- from: core
use:
- core.starter.weapons
- core.starter.equipment
items:
update:
- id: 100
changes:
buyPrice: 0
sellPrice: 0

Run with:

Terminal window
dsl apply patches/new-player.yml --datasheet ./DataSheet