Import System
The import system allows you to organize DataSheetLang projects into reusable packages with namespaced exports.
Workspace Configuration
Section titled “Workspace Configuration”A workspace defines the packages available to your project. Create a datasheetlang.yml file (or .datasheetlang.yml for hidden) in your project root.
Schema
Section titled “Schema”workspace: packages: <name>: <path> schemaAliases: <alias>: <schema> defaultImports: - <package>Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
packages | map[string, string] | Maps package names to their folder paths (relative to workspace file) |
schemaAliases | map[string, string] | Maps short schema names to full schema identifiers |
defaultImports | list[string] | Packages to import automatically in all specs |
Example
Section titled “Example”workspace: packages: core: ./packages/core shared: ./packages/shared vendor: ../external/vendor-lib
schemaAliases: items: items.v1 equipment: equipment.v2
defaultImports: - coreFile Discovery
Section titled “File Discovery”The workspace file is discovered by walking up the directory tree from the spec file location. The first datasheetlang.yml or .datasheetlang.yml found becomes the workspace root.
If both visible and hidden files exist in the same directory, the visible file takes precedence.
Package Registry
Section titled “Package Registry”Package Names
Section titled “Package Names”Package names are identifiers used in imports and script references:
- Must be defined in
workspace.packages - Case-sensitive
- Used as namespace prefix for exports (e.g.,
core.weapon.base)
Entry Points
Section titled “Entry Points”Each package must have an index.yml file in its root folder. This is the package entry point that gets loaded when the package is imported.
packages/core/ # Package folder└── index.yml # Entry point (required)Path Resolution
Section titled “Path Resolution”Package paths in the workspace config are resolved relative to the workspace file:
workspace: packages: core: ./packages/core # Relative path vendor: ../external/vendor # Parent directoryImport Syntax
Section titled “Import Syntax”Package Imports
Section titled “Package Imports”Import a registered package by name:
imports: - from: core - from: sharedThis loads the package’s index.yml and makes all exported definitions available. Variables require explicit opt-in — see Selective variable imports.
Relative Imports
Section titled “Relative Imports”Import a specific file using a relative path:
imports: - from: ./scripts/common.yml - from: ../shared/utils.ymlRelative imports are resolved from the importing file’s directory.
Selective Variable Imports
Section titled “Selective Variable Imports”Variables require explicit opt-in via use.variables. An import without use.variables does not import any variables, even if the source module exports them:
imports: - from: shared use: variables: - BASE_HP - BASE_MPOnly the listed variable names are imported. Requesting a variable not in the source module’s exports.variables triggers E536.
Local variables shadow imported variables of the same name. See Variables for full documentation.
Transitive Imports
Section titled “Transitive Imports”Packages can import other packages. When you import a package, its dependencies are also resolved.
When you import a package that imports another package, its dependencies are also loaded automatically.
Export Syntax
Section titled “Export Syntax”Exporting Definitions
Section titled “Exporting Definitions”Export definitions for use in other modules:
exports: definitions: - baseCondition - rareConditionExported names must exist in the module’s definitions: section (E512 if not). See Definitions for usage with $extends.
Exporting Variables
Section titled “Exporting Variables”Export variables for use in other modules:
exports: variables: - BASE_HP - BASE_MPExported names must exist in the module’s variables: section or its effective imported scope — variables explicitly imported via use.variables (E535 if not). This enables variable re-export: a module can import a variable and make it available to its own consumers. See Variables for full syntax and examples.
Exporting Scripts
Section titled “Exporting Scripts”Scripts are reusable operation blocks:
exports: scripts: starter.gear: items: create: - id: 100 name: training_sword
equipment: create: - equipmentId: 100 level: 1 part: WeaponScripts can contain operations for multiple entity types (items, equipment).
Scripts and Use Directive
Section titled “Scripts and Use Directive”Using Scripts
Section titled “Using Scripts”The use directive injects script operations into your spec:
imports: - from: core
use: - core.starter.gear - core.event.itemsExecution Order
Section titled “Execution Order”Operations are merged in this order:
- Script operations (in order listed in
use) - Local operations (defined in the spec file)
This allows scripts to create base items while local operations modify them:
use: - core.base.items # Creates items first
items: update: # Then updates are applied - id: 100 changes: buyPrice: 999Module Resolution
Section titled “Module Resolution”Resolution Order
Section titled “Resolution Order”When resolving an import:
- Check if it’s a relative path (starts with
./or../) - If relative, resolve from the importing file’s directory
- If not relative, look up in the package registry
Circular Import Detection
Section titled “Circular Import Detection”The system detects and prevents circular imports:
imports: - from: pkgB # pkgA imports pkgB
# packages/pkgB/index.ymlimports: - from: pkgA # pkgB imports pkgA → ERROR: E403Module Graph
Section titled “Module Graph”All loaded modules are tracked in a dependency graph. Each module is loaded only once, even if imported multiple times.
Error Codes
Section titled “Error Codes”| Code | Error | Cause |
|---|---|---|
| E401 | Unknown package | Package name not found in workspace registry |
| E402 | Module not found | File path does not exist |
| E403 | Circular import | Import chain creates a cycle |
| E405 | Duplicate package path | Two packages resolve to the same directory |
| E410 | Duplicate export | Same export name defined in multiple files |
| E414 | Import escapes package | Relative import resolves outside package root |
| E420 | Script not found | Referenced script does not exist |
| E535 | Exported variable not found | Variable in exports.variables not in local variables: or effective imported scope |
| E536 | Imported variable not exported | Variable in use.variables not in source’s exports.variables |
E401: Unknown Package
Section titled “E401: Unknown Package”imports: - from: nonexistent # E401: Package 'nonexistent' is not registeredFix: Add the package to workspace.packages or check for typos.
E403: Circular Import
Section titled “E403: Circular Import”E403: Circular import detected: pkgA → pkgB → pkgAFix: Restructure packages to eliminate circular dependencies.
E405: Duplicate Package Path
Section titled “E405: Duplicate Package Path”E405: Duplicate package path - packages 'weapons' and 'arms' both resolve to: D:\project\packages\weaponsFix: Ensure each package has a unique directory path in your workspace config.
E410: Duplicate Export
Section titled “E410: Duplicate Export”E410: Duplicate export 'starter.gear' - already defined in core/scripts.ymlFix: Rename one of the conflicting exports or consolidate them.
E414: Import Escapes Package
Section titled “E414: Import Escapes Package”imports: - from: ../../outside.yml # E414: Resolves outside package rootFix: Relative imports within a package must stay within the package directory. Use a package import for external files.
E420: Script Not Found
Section titled “E420: Script Not Found”use: - core.nonexistent.script # E420: Script 'core.nonexistent.script' not foundFix: Check the script name and ensure the package is imported.
Complete Reference Example
Section titled “Complete Reference Example”datasheetlang.yml
workspace: packages: core: ./packages/core shared: ./packages/shared
defaultImports: - corepackages/core/index.yml
imports: - from: ./scripts/common.yml
exports: scripts: common.items: items: create: - id: 1 name: common_item maxStack: 1packages/core/scripts/common.yml
exports: scripts: weapons.starter: items: create: - id: 100 name: training_sword combatItemType: EquipWeapon category: Lancepackages/shared/index.yml
imports: - from: core
exports: scripts: bonus.rewards: items: create: - id: 90001 name: bonus_sword combatItemType: EquipWeapon category: Dualpatches/bonus-items.yml
spec: schema: items
imports: - from: shared
use: - shared.bonus.rewards
items: update: - id: 90001 changes: buyPrice: 0 tradable: "False"