diff --git a/src/core/camera_node.c b/src/core/camera_node.c
index 40ce8af..8b8b849 100644
--- a/src/core/camera_node.c
+++ b/src/core/camera_node.c
@@ -29,15 +29,27 @@ void DestroyCameraNode(CameraNode *self) {
 }
 
 void CameraNodeEnterTree(CameraNode *self) {
+    // register self as main camera if none are selected yet
     if(self->node->scene->main_camera == NULL)
         self->node->scene->main_camera = self;
+    // get parent transformable object
     self->transform = TC_CAST(self->node->parent->entity, Transformable);
+    ASSERT_RETURN(!tc_is_null(self->transform),, "CameraNodeEnterTree: Camera node HAS TO be the child of a transformable node.");
+}
+
+void CameraNodeExitTree(CameraNode *self) {
+    // if this is the current main camera, set the main camera to null
+    if(self->node->scene->main_camera == self)
+        self->node->scene->main_camera = NULL;
 }
 
 Camera3D CameraNodeGetCamera(CameraNode *self) {
+    // Get the global transform matrix of the parent transformable
     Transform global_transform = self->transform.tc->get_global_transform(self->transform.data);
     Matrix mat = TransformGetMatrix(&global_transform);
-    Vector3 forward = { mat.m8, mat.m9, mat.m10 };
+    // get the forward row from the matrix
+    Vector3 forward = MATRIX_FORWARD(mat);
+    // construct a new camera at the global transform location and facing the forward vector
     return (Camera3D){
         .fovy = 90,
         .position = global_transform.translation,
diff --git a/src/core/camera_node.h b/src/core/camera_node.h
index b31bd25..8837bfd 100644
--- a/src/core/camera_node.h
+++ b/src/core/camera_node.h
@@ -12,11 +12,15 @@ typedef struct CameraNode {
     Transformable transform;
 } CameraNode;
 
+//! Instantiate new camera node
 extern SceneNode *CreateCameraNode();
+//! Free all memory related to the camera node, invalidates all pointers to 'self'
 extern void DestroyCameraNode(CameraNode *self);
-
+//! Enter tree SceneNodeEntity callback for camera nodes
 extern void CameraNodeEnterTree(CameraNode *self);
-
+//! Exit tree SceneNodeEntity callback for camera nodes
+extern void CameraNodeExitTree(CameraNode *self);
+//! Constructs a camera object from the current location and rotation of this node
 extern Camera3D CameraNodeGetCamera(CameraNode *self);
 
 DECL_REFLECT(CameraNode)
diff --git a/src/core/engine_global.h b/src/core/engine_global.h
index bd6e023..4fa1c75 100644
--- a/src/core/engine_global.h
+++ b/src/core/engine_global.h
@@ -3,7 +3,9 @@
 
 #include "scene.h"
 
+//! Returns the current main scene
 extern Scene *GetMainScene();
+//! Sets the main scene and unloads the current main scene
 extern void SwitchScene(Scene *new_scene);
 
 #endif // !ENGINE_GLOBAL_H
diff --git a/src/core/engine_loop.c b/src/core/engine_loop.c
index 8947cac..1a93f94 100644
--- a/src/core/engine_loop.c
+++ b/src/core/engine_loop.c
@@ -6,6 +6,7 @@
 #include "stdlib.h"
 #include "raylib.h"
 
+//! Set up raylib window
 static
 void InitializeRaylibContext() {
     // initialize fullscreen game window
@@ -16,8 +17,10 @@ void InitializeRaylibContext() {
 }
 
 void RunGame(Scene *initial_scene) {
+    // set the main scene
     SwitchScene(initial_scene);
     ASSERT_RETURN(GetMainScene() != NULL,, "RunGame: Initial scene cannot be NULL.");
+    // Main update loop
     while (!WindowShouldClose()) {
         SceneTick(GetMainScene(), 1.0);
         RenderNextFrame();
@@ -35,9 +38,12 @@ void InitializeEngine() {
 }
 
 void ShutDown() {
+    // deallocate the main scene
     if(GetMainScene() != NULL)
         DestroyScene(GetMainScene());
+    // clean up subsystem resources
     CleanResourceSubsystem();
+    CleanupRenderingSubsystem();
     CloseWindow();
     exit(0);
 }
diff --git a/src/core/render.c b/src/core/render.c
index 8e86d06..08f4c7b 100644
--- a/src/core/render.c
+++ b/src/core/render.c
@@ -7,11 +7,11 @@
 static List g_render_objects = {}; //!< List of all registered rendering objects
 
 void InitializeRenderingSubsystem() {
-    g_render_objects = list_from_type(Renderable);
+    g_render_objects = list_from_type(Renderable); // Allocate list of renderable typeclass wrappers
 }
 
 void CleanupRenderingSubsystem() {
-    list_empty(&g_render_objects);
+    list_empty(&g_render_objects); // deallocate renderable list, rendering subsystem is not responsible for freeing underlying memory
 }
 
 void AddRenderable(Renderable renderable) {
@@ -28,15 +28,16 @@ void RemoveRenderable(Renderable renderable) {
 void RenderNextFrame() {
     BeginDrawing();
     ClearBackground(DARKGRAY);
+    // get current camera
     CameraNode *camera = GetMainScene()->main_camera;
-    if(camera != NULL) { // can't draw anything if there is no camera
+    // can't draw anything if there is no camera
+    if(camera != NULL) {
+        // render 3D scene
         BeginMode3D(CameraNodeGetCamera(camera));
         list_foreach(Renderable *,object, &g_render_objects)
             object->tc->draw(object->data);
         DrawGrid(100, 1.f);
         EndMode3D();
-    } else {
-        UNREACHABLE("RenderNextFrame: camera not found.");
     }
     DrawFPS(20, 20);
     EndDrawing();
diff --git a/src/core/resources.h b/src/core/resources.h
index f5848fc..6ff7585 100644
--- a/src/core/resources.h
+++ b/src/core/resources.h
@@ -3,7 +3,9 @@
 
 #include "raylib.h"
 
+//! Allocate and initialize memory required to operate resource subsystem
 extern void InitializeResourceSubsystem();
+//! Clean and shut down resource subsystem, all resource calls are invalid after this
 extern void CleanResourceSubsystem();
 
 //! Load a model resource from disk, path is relative to the resource folder