Getting Started with Selene Bundles
Getting Started with Selene Bundles
This guide walks you through creating your first Selene bundle: what a bundle is, the recommended directory layout, and how to declare your bundle metadata in bundle.json. It draws from the example bundles in this repository under bundles/:
bundles/illarion-gobaith-data/bundles/illarion-gobaith-ui/bundles/moonlight-inventory/
What is a Selene bundle?
A Selene bundle is a self-contained package of logic and/or data that the Selene engine can load. Bundles can provide:
- Data definitions (for tiles, entities, items, etc.)
- Client UI logic and behaviors
- Server-side game logic
- Shared/common Lua modules
Each bundle lives in its own directory and is described by a bundle.json file at its root.
Minimal bundle
The smallest possible bundle needs only a bundle.json with a unique name and description:
{
"name": "moonlight-inventory",
"description": "Basic implementation for slot-based inventories."
}
Place this file in your bundle directory, for example bundles/my-first-bundle/bundle.json.
Directory layout
Bundles commonly organize content into client/, server/, and common/ to clarify runtime ownership and to keep resources discoverable:
client/– Code and data used by the client (e.g., UI, input handling, visuals)server/– Code and data used by the server (e.g., NPCs, quests, spawns)common/– Code and data shared between client and server
Within those, you’ll often see:
lua/– Lua modules and scriptsdata/– Static JSON data files consumed by systems
Examples from this repo:
bundles/illarion-gobaith-ui/client/lua/bundles/illarion-gobaith-data/common/lua/bundles/illarion-gobaith-data/server/data/
You can also include a README.md and LICENSE at the root of your bundle for documentation and licensing.
Declaring entrypoints
If your bundle includes executable logic (Lua modules to load on startup), list them in the entrypoints array in bundle.json.
- Paths are relative to the bundle root
- They are typically Lua files located under
client/lua/orcommon/lua/ - Data-only bundles can omit
entrypoints
Examples:
Data bundle with a single shared entrypoint:
{
"name": "illarion-gobaith-data",
"description": "Data definitions for Illarion as a Selene bundle.",
"entrypoints": [
"common/lua/grid.lua"
]
}
Client UI bundle with multiple entrypoints:
{
"name": "illarion-gobaith-ui",
"description": "Illarion UI based on Gobaith era.",
"entrypoints": [
"client/lua/viewport.lua",
"client/lua/cursor.lua",
"client/lua/input.lua",
"client/lua/ui.lua"
]
}
Data-only bundle without entrypoints:
{
"name": "moonlight-inventory",
"description": "Basic implementation for slot-based inventories."
}
Common file types
- JSON under
data/– Structured data used by Selene systems, e.g.:bundles/illarion-gobaith-data/common/data/tiles.jsonbundles/illarion-gobaith-data/server/data/items.json
- Lua under
lua/– Logic modules and scripts, e.g.:bundles/illarion-gobaith-ui/client/lua/input.luabundles/illarion-gobaith-data/common/lua/grid.lua
Note: The specific shape of JSON files is determined by the systems that consume them (tiles, entities, skills, etc.). Use existing examples as templates and keep paths consistent.
Creating your own bundle
- Create the directory
- Choose a unique, URL-safe name
- Create a folder under
bundles/, e.g.bundles/my-bundle/
- Add
bundle.json
- Start with name and description
- Add
entrypointsonly if you have Lua modules to load
- Add code and data
- Place shared modules under
common/lua/ - Place client-only modules under
client/lua/ - Place server-only modules under
server/lua/ - Put static data under
*/data/next to where it is consumed
- Document and license
- Add a
README.mddescribing what your bundle provides and any external dependencies - Add a
LICENSEif you plan to distribute it
- Validate your layout
- Ensure every path in
entrypointsexists and is correct relative to the bundle root - Keep JSON valid; run a linter/formatter if available
Referencing external assets
Some bundles may rely on external graphics or asset bundles. For example, illarion-gobaith-data notes that it depends on a separate asset bundle for visuals and does not embed restricted assets. If you reference external assets:
- Document the dependency in your
README.md - Avoid redistributing licensed assets unless permitted
Tips and conventions
- Use lowercase, hyphenated bundle names (e.g.,
my-feature-pack) - Keep
entrypointsminimal: load a top-level module that in turn requires other modules - Co-locate data with the runtime that consumes it (
server/data/for server-side systems, etc.) - Prefer deterministic file names and folder structures for discoverability
Troubleshooting
- A module does not load: double-check the
entrypointspath and module syntax - Data not applied: ensure the JSON structure matches what the consuming system expects
- Asset missing: verify the asset bundle or path is available and correctly referenced
Examples to study
- Data-centric bundle:
bundles/illarion-gobaith-data/ - Client UI bundle:
bundles/illarion-gobaith-ui/ - Minimal bundle:
bundles/moonlight-inventory/
Open these bundles to copy patterns for your own. Start small, add a single entrypoint if needed, and grow from there.