Skip to main content
Cardinal projects are designed to support multiple shards within a single project. While the framework is unopinionated about folder structure, there are some defaults and common patterns.

Minimal Structure

Here is the minimal structure for a Cardinal project:
File / DirectoryDescription
shards/Source code for your game shards.
shards/<shard-id>/main.goThe entry point for the shard.
world.tomlProject configuration.
go.modGo dependency definition.

Registering Shards

To include a shard in your project, you must define it in the world.toml file. The World CLI only builds and runs shards that are explicitly listed in this configuration. By default, the framework looks for a shard’s source code in shards/<shard-id>. You can override this location by specifying the path key (relative to the project root).
world.toml
TODO: Fix the link below.
For a complete reference of available configuration options, see the Configuration Reference.

Examples

Organization by Concept

In this structure, code within a shard is organized by Cardinal concepts: components, systems, events, etc.
This approach groups code by its architectural role (e.g., all components in one place). It is the recommended starting point for most projects as it provides a clear separation between data and logic.

Organization by Domain

For larger, more complex projects, you may prefer a domain-driven approach where code is grouped by feature (e.g., combat, movement).
In this layout:
  • internal/: Contains the domain logic and definitions. The special internal directory name prevents these packages from being imported by other shards, as enforced by Go’s internal packages rule.
  • types/: Contains type aliases to the definitions in the internal domain packages. This acts as the public API for the shard.
By exporting only specific types via aliases in types/, you allow other shards to interact with your data without exposing your internal logic or creating direct dependencies on your implementation packages.