Bundle Layout
Minimal server-tested bundle
This is the smallest practical layout for a bundle you want to load through the server runtime:
bundles/
example.bundle/
bundle.json
server/
init.lua
Example manifest:
{
"name": "example.bundle",
"description": "Minimal server bundle",
"entrypoints": [
"server/init.lua"
]
}
Runtime folder conventions
Selene consistently distinguishes three script roots:
common/: shared across runtimesserver/: server-onlyclient/: client-only
Those roots affect more than execution:
- Entrypoint filters decide which files may run in each runtime
- Script hot reload watches
commonplus the active runtime root - Messages are loaded from
client/i18n,common/i18n, andserver/i18n - Bundle data and assets are watched by path under bundle-owned runtime directories
Lua module naming
Selene maps Lua files to module names like this:
init.luabecomes<bundle-name>common/foo.luabecomes<bundle-name>.common.fooserver/world/spawn.luabecomes<bundle-name>.server.world.spawn
That naming matters when you use require(...) and when Selene reloads Lua state.
Dependencies and load order
Declare bundle dependencies explicitly in bundle.json:
{
"name": "example.bundle",
"dependencies": [
"base.bundle",
"ui.bundle"
]
}
Selene resolves dependencies before loading dependent bundles. If a required bundle is missing, the runtime aborts loading rather than partially enabling the bundle set.
Preload layout
Use preloads when you want a stable Lua module name that is available before entrypoints run:
{
"name": "example.bundle",
"preloads": {
"example.shared": "common/shared.lua",
"example.legacy": {
"file": "common/legacy.lua",
"encoding": "UTF-8"
}
}
}
This is useful when your bundle wants to expose modules under names that do not map directly to the default file-to-module convention.
Server and client wiring
Server-side wiring is name-based:
bundles_path=../../bundles
bundles=example.bundle
Client-side wiring is path-based:
java -jar selene-client.jar \
--bundle example.bundle /absolute/path/to/example.bundle
That difference is easy to miss. The same bundle directory can be valid for both runtimes, but the server and client do not discover it the same way.