Getting Started with Project
This guide demonstrates project creation and configuration management.
Creating a New Project
Create a project programmatically:
cpp
#include <astralix/modules/project/project.hpp>
#include <astralix/modules/project/managers/project-manager.hpp>
using namespace astralix;
ProjectConfig config;
config.name = "MyGame";
config.directory = "MyGame/";
config.manifest = "project.json";
// Window configuration
WindowConfig window;
window.id = 0; // WindowID
window.title = "My Game";
window.width = 1920;
window.height = 1080;
window.headless = false;
config.windows.push_back(window);
// Renderer system configuration
SystemConfig renderSystem;
renderSystem.name = "RenderSystem";
renderSystem.type = SystemType::Render;
RenderSystemConfig renderConfig;
renderConfig.backend = "opengl";
renderConfig.headless = false;
renderConfig.window_id = "0";
renderConfig.msaa.samples = 4;
renderConfig.msaa.is_enabled = true;
renderSystem.content = renderConfig;
config.systems.push_back(renderSystem);
// Physics system configuration
SystemConfig physicsSystem;
physicsSystem.name = "PhysicsSystem";
physicsSystem.type = SystemType::Physics;
PhysicsSystemConfig physicsConfig;
physicsConfig.backend = "physx";
physicsConfig.gravity = glm::vec3(0, -9.81f, 0);
physicsConfig.pvd_host = "127.0.0.1";
physicsConfig.pvd_port = 5425;
physicsConfig.pvd_timeout = 5;
physicsSystem.content = physicsConfig;
config.systems.push_back(physicsSystem);
// Resource directory configuration
config.resources.directory = "assets/";
// Serialization format
config.serialization.format = SerializationFormat::Json;
// Create project and set as active
Ref<Project> project = Project::create(config);
project_manager()->add_project(project); // Automatically sets as activeLoading an Existing Project
WARNING
The Project::load() method is currently not implemented (commented out in source). Project loading is done through the serializer directly.
Load a project from file:
cpp
#include <astralix/modules/project/project.hpp>
#include <astralix/modules/project/managers/project-manager.hpp>
#include <astralix/modules/project/serializers/project-serializer.hpp>
#include <astralix/modules/streams/adapters/file/file-stream-reader.hpp>
#include <astralix/modules/streams/adapters/json/json-serialization-context.hpp>
using namespace astralix;
// Create empty project with directory path
ProjectConfig config;
config.directory = "MyGame/";
config.manifest = "project.json";
Ref<Project> project = Project::create(config);
// Deserialize from file
StreamBuffer buffer;
FileStreamReader reader("MyGame/project.json");
reader.read(buffer);
Ref<SerializationContext> ctx = std::make_shared<JsonSerializationContext>(buffer);
ProjectSerializer serializer(project, ctx);
serializer.deserialize();
// Set as active
project_manager()->add_project(project);
// Access project data
std::string name = project->get_config().name;
std::string directory = project->get_config().directory;
std::string resourcesDir = project->get_config().resources.directory;Resolving Asset Paths
Use the Path class and PathManager to resolve project-relative paths:
cpp
#include <astralix/modules/project/path.hpp>
#include <astralix/modules/project/managers/path-manager.hpp>
using namespace astralix;
// Create a project-relative path
Ref<Path> texturePath = Path::create("textures/wall.png", BaseDirectory::Project);
// Resolve to absolute filesystem path
std::filesystem::path absolutePath = path_manager()->resolve(texturePath);
// Or use user-defined literals for convenience
auto scenePath = "scenes/MainMenu.ascene"_project;
auto shaderPath = "shaders/default.axsl"_engine;
// Resolve paths
std::filesystem::path sceneAbsolute = path_manager()->resolve(scenePath);
std::filesystem::path shaderAbsolute = path_manager()->resolve(shaderPath);
// Project paths resolve relative to: project_directory + resources_directory
// Engine paths resolve relative to: ASTRALIX_ASSETS_DIR (compile-time constant)Accessing Configuration
Read and modify project configuration:
cpp
#include <astralix/modules/project/managers/project-manager.hpp>
using namespace astralix;
Ref<Project> project = active_project();
ProjectConfig& config = project->get_config();
// Read window settings
if (!config.windows.empty()) {
int width = config.windows[0].width;
int height = config.windows[0].height;
std::string title = config.windows[0].title;
}
// Read system configurations
for (const auto& system : config.systems) {
if (system.type == SystemType::Physics) {
if (std::holds_alternative<PhysicsSystemConfig>(system.content)) {
const auto& physicsConfig = std::get<PhysicsSystemConfig>(system.content);
glm::vec3 gravity = physicsConfig.gravity;
}
} else if (system.type == SystemType::Render) {
if (std::holds_alternative<RenderSystemConfig>(system.content)) {
const auto& renderConfig = std::get<RenderSystemConfig>(system.content);
int msaaSamples = renderConfig.msaa.samples;
bool msaaEnabled = renderConfig.msaa.is_enabled;
}
}
}
// Modify settings
for (auto& system : config.systems) {
if (system.type == SystemType::Render) {
if (std::holds_alternative<RenderSystemConfig>(system.content)) {
auto& renderConfig = std::get<RenderSystemConfig>(system.content);
renderConfig.msaa.samples = 8;
renderConfig.msaa.is_enabled = true;
}
}
}
// Save changes
ElasticArena arena;
project->save(arena);Application Integration
Initialize application with project:
cpp
#include <astralix/modules/project/project.hpp>
#include <astralix/modules/project/managers/project-manager.hpp>
#include <astralix/modules/project/serializers/project-serializer.hpp>
#include <astralix/modules/streams/adapters/file/file-stream-reader.hpp>
#include <astralix/modules/streams/adapters/json/json-serialization-context.hpp>
using namespace astralix;
int main(int argc, char** argv) {
// Parse project path from command line
std::string projectPath = "MyGame/project.json";
if (argc > 1) {
projectPath = argv[1];
}
// Create and load project
ProjectConfig config;
config.directory = std::filesystem::path(projectPath).parent_path().string() + "/";
config.manifest = std::filesystem::path(projectPath).filename().string();
Ref<Project> project = Project::create(config);
// Deserialize project manifest
StreamBuffer buffer;
FileStreamReader reader(projectPath);
reader.read(buffer);
Ref<SerializationContext> ctx = std::make_shared<JsonSerializationContext>(buffer);
ProjectSerializer serializer(project, ctx);
serializer.deserialize();
// Set as active project
project_manager()->add_project(project);
// Systems can now access project configuration via active_project()
// Engine modules use path_manager() to resolve project-relative paths
return 0;
}Asset Management Helpers
Create helper functions for common operations:
cpp
#include <astralix/modules/project/path.hpp>
#include <astralix/modules/project/managers/path-manager.hpp>
using namespace astralix;
class AssetManager {
public:
static std::filesystem::path GetTexturePath(const std::string& name) {
auto path = Path::create("textures/" + name, BaseDirectory::Project);
return path_manager()->resolve(path);
}
static std::filesystem::path GetModelPath(const std::string& name) {
auto path = Path::create("models/" + name, BaseDirectory::Project);
return path_manager()->resolve(path);
}
static std::filesystem::path GetScenePath(const std::string& name) {
auto path = Path::create("scenes/" + name, BaseDirectory::Project);
return path_manager()->resolve(path);
}
// Example with user-defined literals
static std::filesystem::path GetShaderPath(const std::string& name) {
auto path = ("shaders/" + name)._engine; // Engine-relative shader
return path_manager()->resolve(path);
}
};
// Usage
auto texturePath = AssetManager::GetTexturePath("wall.png");
auto modelPath = AssetManager::GetModelPath("character.gltf");
auto scenePath = AssetManager::GetScenePath("MainMenu.ascene");Project Templates
Create project templates for different game types:
cpp
#include <astralix/modules/project/project.hpp>
#include <astralix/modules/project/managers/project-manager.hpp>
using namespace astralix;
class ProjectTemplate {
public:
static Ref<Project> Create2DProject(const std::string& name, const std::string& directory) {
ProjectConfig config;
config.name = name;
config.directory = directory;
config.manifest = "project.json";
// Window configuration
WindowConfig window;
window.id = 0;
window.title = name;
window.width = 1280;
window.height = 720;
window.headless = false;
config.windows.push_back(window);
// 2D Renderer (no MSAA, simpler config)
SystemConfig renderSystem;
renderSystem.name = "RenderSystem";
renderSystem.type = SystemType::Render;
RenderSystemConfig renderConfig;
renderConfig.backend = "opengl";
renderConfig.msaa.samples = 1;
renderConfig.msaa.is_enabled = false;
renderConfig.window_id = "0";
renderSystem.content = renderConfig;
config.systems.push_back(renderSystem);
// Physics with no gravity for 2D
SystemConfig physicsSystem;
physicsSystem.name = "PhysicsSystem";
physicsSystem.type = SystemType::Physics;
PhysicsSystemConfig physicsConfig;
physicsConfig.backend = "physx";
physicsConfig.gravity = glm::vec3(0);
physicsSystem.content = physicsConfig;
config.systems.push_back(physicsSystem);
config.resources.directory = "assets/";
config.serialization.format = SerializationFormat::Json;
return Project::create(config);
}
static Ref<Project> Create3DProject(const std::string& name, const std::string& directory) {
ProjectConfig config;
config.name = name;
config.directory = directory;
config.manifest = "project.json";
WindowConfig window;
window.id = 0;
window.title = name;
window.width = 1920;
window.height = 1080;
window.headless = false;
config.windows.push_back(window);
// 3D Renderer with MSAA
SystemConfig renderSystem;
renderSystem.name = "RenderSystem";
renderSystem.type = SystemType::Render;
RenderSystemConfig renderConfig;
renderConfig.backend = "opengl";
renderConfig.msaa.samples = 4;
renderConfig.msaa.is_enabled = true;
renderConfig.window_id = "0";
renderSystem.content = renderConfig;
config.systems.push_back(renderSystem);
// Physics with standard gravity
SystemConfig physicsSystem;
physicsSystem.name = "PhysicsSystem";
physicsSystem.type = SystemType::Physics;
PhysicsSystemConfig physicsConfig;
physicsConfig.backend = "physx";
physicsConfig.gravity = glm::vec3(0, -9.81f, 0);
physicsSystem.content = physicsConfig;
config.systems.push_back(physicsSystem);
config.resources.directory = "assets/";
config.serialization.format = SerializationFormat::Json;
return Project::create(config);
}
static Ref<Project> CreateVRProject(const std::string& name, const std::string& directory) {
ProjectConfig config;
config.name = name;
config.directory = directory;
config.manifest = "project.json";
WindowConfig window;
window.id = 0;
window.title = name;
window.width = 1920;
window.height = 1080;
window.headless = false;
config.windows.push_back(window);
// VR Renderer with high MSAA
SystemConfig renderSystem;
renderSystem.name = "RenderSystem";
renderSystem.type = SystemType::Render;
RenderSystemConfig renderConfig;
renderConfig.backend = "opengl";
renderConfig.msaa.samples = 8;
renderConfig.msaa.is_enabled = true;
renderConfig.window_id = "0";
renderSystem.content = renderConfig;
config.systems.push_back(renderSystem);
SystemConfig physicsSystem;
physicsSystem.name = "PhysicsSystem";
physicsSystem.type = SystemType::Physics;
PhysicsSystemConfig physicsConfig;
physicsConfig.backend = "physx";
physicsConfig.gravity = glm::vec3(0, -9.81f, 0);
physicsSystem.content = physicsConfig;
config.systems.push_back(physicsSystem);
config.resources.directory = "assets/";
config.serialization.format = SerializationFormat::Json;
return Project::create(config);
}
};Saving Configuration Changes
Update and persist configuration:
cpp
#include <astralix/modules/project/managers/project-manager.hpp>
using namespace astralix;
struct GraphicsSettings {
int msaaSamples;
bool msaaEnabled;
std::string backend;
};
void UpdateGraphicsSettings(const GraphicsSettings& settings) {
Ref<Project> project = active_project();
ProjectConfig& config = project->get_config();
// Find and update render system config
for (auto& system : config.systems) {
if (system.type == SystemType::Render) {
if (std::holds_alternative<RenderSystemConfig>(system.content)) {
auto& renderConfig = std::get<RenderSystemConfig>(system.content);
renderConfig.msaa.samples = settings.msaaSamples;
renderConfig.msaa.is_enabled = settings.msaaEnabled;
renderConfig.backend = settings.backend;
}
}
}
// Save to file (note: save() requires ElasticArena)
ElasticArena arena;
project->save(arena);
}Next Steps
- Learn about Streams for serialization
- Explore Application for initialization
- Review project file format in the documentation