Nimbin[12]?SDL & Graphics / sdl_runtime_compiler / commits / 0a2f8b7

sdl_runtime_compiler git · main

SDL3 game for running and compiling code at runtime

sdl3 c++ compiler dlopen cmake · first commit 2026-04-19 · last commit 2026-07-03 (3 months ago) · synced 3 days ago · upstream: git.ide3.de/hsnr/sdl-runtime-compiler

C++ 72.3% C 26.2%
git clone https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler.gitwget https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler/archive/sdl_runtime_compiler.tar.gz

Cleanup

Christian Immanuel · 2026-06-05 23:43 · 0a2f8b757e206dcc33fe5fc9ed597108247eb511

 benchmark/bench_ai.cpp            |   1 -
 src/c_token/token_db.cpp          |   6 +-
 src/entities/camera.hpp           |  29 +---------
 src/entities/game_object.hpp      |  30 ++++++----
 src/entities/plate.cpp            |  29 ++++------
 src/entities/plate.hpp            |  17 +++---
 src/entities/player.cpp           |   7 ---
 src/entities/player.hpp           |   1 -
 src/levels/level_check.cpp        |   3 +-
 src/states/game_state.cpp         |  93 +++++++++++++++++------------
 src/states/menu_state.cpp         |  86 +++++++--------------------
 src/states/menu_state.hpp         |   4 +-
 src/systems/carry_system.cpp      |  12 ++--
 src/systems/collision.cpp         |  22 +++----
 src/systems/input_system.cpp      |  17 ++++--
 src/systems/physics_system.cpp    | 116 +++++++++++++++----------------------
 src/systems/pick_system.cpp       |  44 +++++---------
 src/systems/projectile_system.cpp | 104 ++++++++++-----------------------
 src/systems/source_tokens.hpp     |  19 ++----
 src/systems/wall_connection.cpp   |   9 ++-
 src/systems/word_ai_system.cpp    | 119 ++++++++++++++++----------------------
 src/systems/word_ai_system.hpp    |   2 -
 src/systems/word_anim.cpp         |   5 +-
 src/text_3d/text_3d.cpp           |   3 +-
 src/text_3d/text_label.cpp        |  49 ++++------------
 src/text_3d/text_mesh.cpp         |   3 +-
 src/text_3d/vim_buffer.hpp        |  66 ++++++++++-----------
 src/utils/carry_math.cpp          |  14 ++---
 src/utils/carry_math.hpp          |   2 +-
 src/utils/math.hpp                |   4 ++
 src/utils/text_wrap.hpp           |   6 +-
 31 files changed, 369 insertions(+), 553 deletions(-)

diff --git a/benchmark/bench_ai.cpp b/benchmark/bench_ai.cpp
index 9aa68a3..8d8c6fc 100644
--- a/benchmark/bench_ai.cpp
+++ b/benchmark/bench_ai.cpp
@@ -27,7 +27,6 @@ static void BM_WordAiUpdate(benchmark::State& state)
     }
 
     WordAiSystem ai;
-    ai.set_WorldScale(16.0f);
 
     std::vector<Text3dPtr> dropped;
     constexpr double dt = 1.0 / 60.0;
diff --git a/src/c_token/token_db.cpp b/src/c_token/token_db.cpp
index 14446c5..1a0b403 100644
--- a/src/c_token/token_db.cpp
+++ b/src/c_token/token_db.cpp
@@ -307,14 +307,16 @@ synth_number(const std::string& s)
             t = { s, TokenType::Literal, "Hex literal",          "Unsigned hexadecimal constant"        };
         else
             t = { s, TokenType::Literal, "Hex literal",          "Hexadecimal integer constant"         };
-    } else if (is_fp) {
+    }
+    else if (is_fp) {
         if (has_f_suffix)
             t = { s, TokenType::Literal, "Float literal",        "Single-precision floating-point (float)"  };
         else if (is_long)
             t = { s, TokenType::Literal, "Long double literal",  "Extended-precision floating-point (long double)" };
         else
             t = { s, TokenType::Literal, "Double literal",       "Double-precision floating-point (double)" };
-    } else {
+    }
+    else {
         if (is_unsigned && is_long)
             t = { s, TokenType::Literal, "Unsigned long literal","Unsigned long integer constant"       };
         else if (is_unsigned)
diff --git a/src/entities/camera.hpp b/src/entities/camera.hpp
index e32de85..fae6d2d 100644
--- a/src/entities/camera.hpp
+++ b/src/entities/camera.hpp
@@ -15,9 +15,9 @@ struct Camera {
     Vec3 fwd        {};
     Vec3 right      {};
 
-    void syncFromPlayer(const Player& player, double alpha)
+    void syncFromPlayer(const Player& player)
     {
-        pos   = player.interpolated_Pos(alpha);
+        pos   = player.prev_pos;
         yaw   = player.yaw;
         pitch = player.pitch;
 
@@ -35,28 +35,3 @@ struct Camera {
         };
     }
 };
-
-inline void buildViewMatrix(const Camera& cam, double out[9])
-{
-    double bin   = ConfigPhysics::binrad;
-
-    double yaw   = bin * cam.yaw;
-    double pitch = bin * cam.pitch;
-
-    double cy = SDL_cos(yaw);
-    double sy = SDL_sin(yaw);
-    double cp = SDL_cos(pitch);
-    double sp = SDL_sin(pitch);
-
-    out[0] = cy;
-    out[1] = 0;
-    out[2] = -sy;
-
-    out[3] = sy * sp;
-    out[4] = cp;
-    out[5] = cy * sp;
-
-    out[6] = sy * cp;
-    out[7] = -sp;
-    out[8] = cy * cp;
-}
diff --git a/src/entities/game_object.hpp b/src/entities/game_object.hpp
index cfaa17c..8047f80 100644
--- a/src/entities/game_object.hpp
+++ b/src/entities/game_object.hpp
@@ -5,14 +5,16 @@
 #include "utils/light.hpp"
 #include "utils/math.hpp"
 
-class GlRenderer;
 class Camera;
+class GlRenderer;
+
 
 enum class ObjectType : uint8_t {
     Text,
     Prop,
 };
 
+
 enum class PhysicsMode : uint8_t {
     Static,
     Dynamic,
@@ -22,27 +24,29 @@ enum class PhysicsMode : uint8_t {
     Projectile,
 };
 
+
 struct CollisionShape {
     Vec3 half_extents{0.5, 0.5, 0.5};
 };
 
+
 struct RigidBody {
-    Vec3        vel{};
-    Vec3        force{};
-    double      mass{1.0};
+    Vec3        vel        {};
+    Vec3        force      {};
+    double      mass       {1.0};
     double      restitution{0.3};
-    double      friction{0.8};
+    double      friction   {0.8};
 
     PhysicsMode mode{PhysicsMode::Hover};
 
-    double      hover_phase{0.0};
-    double      hover_height{0.0};
+    double      hover_phase    {0.0};
+    double      hover_height   {0.0};
     bool        hover_disturbed{false};
 
-    RigidBody( PhysicsMode m = PhysicsMode::Hover,
-               double      mass_        = 1.0,
-               double      restitution_ = 0.3,
-               double      friction_    = 0.8
+    RigidBody(PhysicsMode m = PhysicsMode::Hover,
+              double      mass_        = 1.0,
+              double      restitution_ = 0.3,
+              double      friction_    = 0.8
             ) : mass(mass_),
                 restitution(restitution_),
                 friction(friction_),
@@ -59,7 +63,8 @@ struct RigidBody {
              mode == PhysicsMode::AiHover) {
             mode = PhysicsMode::Dynamic;
             vel  = impulse;
-        } else if (mode == PhysicsMode::Dynamic) {
+        }
+        else if (mode == PhysicsMode::Dynamic) {
             vel += impulse;
         }
     }
@@ -73,6 +78,7 @@ struct RigidBody {
     }
 };
 
+
 struct GameObject {
     Vec3           pos          {};
     float          yaw          {0.0f};
diff --git a/src/entities/plate.cpp b/src/entities/plate.cpp
index 5af01d6..091fc04 100644
--- a/src/entities/plate.cpp
+++ b/src/entities/plate.cpp
@@ -7,11 +7,9 @@
 void
 Plate::tick(double dt)
 {
-    // Subtle bob — drifts up and down ~5cm with a slow sine
     bob_phase += dt * 2.0;
     pos.y = base_pos.y + SDL_sin(bob_phase) * 0.05;
 
-    // Pulse decays over time (set to 1.0 from outside on activation)
     if (pulse > 0.0) {
         pulse -= dt * 1.5;
         if (pulse < 0.0) pulse = 0.0;
@@ -32,8 +30,6 @@ Plate::draw(GlRenderer& gl, const Camera& cam, const Light& light) const
     Mat4 model = buildModelMat4(pos, yaw);
     Mat4 mvp   = Mat4::mul(proj, Mat4::mul(view, model));
 
-    // Brightness: active plates glow fully, inactive are dimmer.
-    // pulse adds a momentary flare on activation.
     float boost = static_cast<float>(active ? 1.0 : 0.6) +
                   static_cast<float>(pulse) * 0.4f;
     if (boost > 1.0f) boost = 1.0f;
@@ -42,20 +38,17 @@ Plate::draw(GlRenderer& gl, const Camera& cam, const Light& light) const
     const float eg = fill_color.g * boost;
     const float eb = fill_color.b * boost;
 
-    // Use the emissive path so plates self-illuminate regardless of scene
-    // lighting and feed into the bloom pass — no light state mutation needed.
     gl.set_Wireframe(false);
-    gl.set_MVP(model, mvp);
+    gl.set_MVP      (model, mvp);
     gl.set_NormalMat(model);
-    gl.set_Light(light);
-    gl.set_Color(er, eg, eb);
-    gl.set_Emissive(er, eg, eb, boost);
-    gl.draw_Box(hx, hy, hz);
-    gl.set_Emissive(0.0f, 0.0f, 0.0f, 0.0f);
-
-    // Wireframe outline
-    gl.set_Wireframe(true);
-    gl.set_MVP(model, mvp);
-    gl.set_Color(wire_color.r, wire_color.g, wire_color.b);
-    gl.draw_Box(hx, hy, hz);
+    gl.set_Light    (light);
+    gl.set_Color    (er, eg, eb);
+    gl.set_Emissive (er, eg, eb, boost);
+    gl.draw_Box     (hx, hy, hz);
+    gl.set_Emissive (0.0f, 0.0f, 0.0f, 0.0f);
+
+    gl.set_Wireframe(false);
+    gl.set_MVP      (model, mvp);
+    gl.set_Color    (wire_color.r, wire_color.g, wire_color.b);
+    gl.draw_Box     (hx, hy, hz);
 }
diff --git a/src/entities/plate.hpp b/src/entities/plate.hpp
index 1b1b043..445e136 100644
--- a/src/entities/plate.hpp
+++ b/src/entities/plate.hpp
@@ -9,28 +9,25 @@
 class Camera;
 class GlRenderer;
 
-// A floor pad the player stands on. Used by the tutorial / level system as
-// a "step here to advance" cue. Glowing bright color, bobs subtly, pulses
-// when stepped on.
 struct Plate final : public SolidBox
 {
-    static constexpr float _HALF_W   = 0.6f;   // plate is wide and short
+    static constexpr float _HALF_W   = 0.6f;
     static constexpr float _HALF_H   = 0.05f;
     static constexpr float _HALF_D   = 0.6f;
 
-    bool   active    { false };   // player currently standing on it
-    bool   was_active{ false };   // for edge detection
+    bool   active    { false };
+    bool   was_active{ false };
     double bob_phase { 0.0 };
-    double pulse     { 0.0 };     // 0..1 visual pulse from recent activation
-    Vec3   base_pos  {};          // anchor for bob
+    double pulse     { 0.0 };
+    Vec3   base_pos  {};
 
     Plate(Vec3 world_pos)
         : SolidBox(
               world_pos,
               Vec3{ _HALF_W, _HALF_H, _HALF_D },
-              SDL_FColor{ 0.3f, 1.0f, 0.6f, 1.0f },   // bright cyan-green
+              SDL_FColor{ 0.3f, 1.0f, 0.6f, 1.0f },
               SDL_FColor{ 0.6f, 1.0f, 0.8f, 1.0f },
-              false)                                  // not interactable like a pult
+              false)
         , base_pos(world_pos)
     {}
 
diff --git a/src/entities/player.cpp b/src/entities/player.cpp
index 1957af0..1eda670 100644
--- a/src/entities/player.cpp
+++ b/src/entities/player.cpp
@@ -60,10 +60,3 @@ Player::compute_Movement(const FrameInput& input)
         _acc_z = ConfigPhysics::player_move_accel * (-s*dirX + c*dirZ) * inv;
     }
 }
-
-
-Vec3
-Player::interpolated_Pos(double alpha) const
-{
-    return lerp(prev_pos, pos, alpha);
-}
diff --git a/src/entities/player.hpp b/src/entities/player.hpp
index 9ef1ff8..fcadfef 100644
--- a/src/entities/player.hpp
+++ b/src/entities/player.hpp
@@ -37,7 +37,6 @@ public:
     void   compute_Movement(const FrameInput& input);
     void   add_Look        (int dx, int dy);
     void   apply_Collision (const PlayerCollision& col);
-    Vec3   interpolated_Pos(double alpha) const;
     double get_AccX        () const { return _acc_x; }
     double get_AccZ        () const { return _acc_z; }
     void   respawn         (const Vec3& spawn_pos);
diff --git a/src/levels/level_check.cpp b/src/levels/level_check.cpp
index b686036..5ee94a5 100644
--- a/src/levels/level_check.cpp
+++ b/src/levels/level_check.cpp
@@ -16,7 +16,8 @@ normalize(const std::string& s)
                 out += ' ';
                 last_space = true;
             }
-        } else {
+        }
+        else {
             out += c;
             last_space = false;
         }
diff --git a/src/states/game_state.cpp b/src/states/game_state.cpp
index 93dab8d..0a88673 100644
--- a/src/states/game_state.cpp
+++ b/src/states/game_state.cpp
@@ -43,15 +43,12 @@ GameState::GameState(size_t starting_level)
     _particle_sys    = cpputils::make_unique<ParticleSystem>   ();
     _dyn_loader_sys  = cpputils::make_unique<DynLoaderSystem>  ();
     _celebration_sys = cpputils::make_unique<CelebrationSystem>();
+    _wall_labels     = WallLabel::generate_All(World::get_BoxScale());
+    _word_ai_sys     = cpputils::make_unique<WordAiSystem>();
 
     _floor_sys       = cpputils::make_unique<FloorMandelbrot>  ();
     _floor_sys->generate(World::get_BoxScale(), World::get_FloorY());
 
-    _wall_labels     = WallLabel::generate_All(World::get_BoxScale());
-
-    _word_ai_sys     = cpputils::make_unique<WordAiSystem>();
-    _word_ai_sys->set_WorldScale(World::get_BoxScale());
-
     _pult_sys        = cpputils::make_unique<PultSystem>  ();
     _pult_sys->init(_ctx.scenery, _ctx.buttons, World::get_BoxScale());
 
@@ -105,15 +102,13 @@ GameState::carriedline_Update()
 
     const FreelookState& fs = _freelook_sys->state;
 
-    // Frozen: leave every word exactly where it is.
     if (fs.active) return;
 
-    // Live carry frame in front of the camera.
     const Vec3   anchor    = CarryMath::line_Anchor(*_ctx.camera, CarryMath::CARRY_DIST);
     const Vec3   right     = _ctx.camera->right;
     const double glyph_yaw = SDL_atan2(-_ctx.camera->fwd.x, -_ctx.camera->fwd.z);
 
-    DynArray<Vec3> slots = CarryMath::slot_positions(_carried, anchor, right, CarryMath::CARRY_GAP);
+    DynArray<Vec3> slots = CarryMath::slot_Positions(_carried, anchor, right, CarryMath::CARRY_GAP);
     DynArray<CarriedWordNode*> nodes = _carried.reverse_nodes();
 
     // Easing back from the frozen spots: lerp each word from its release
@@ -133,7 +128,8 @@ GameState::carriedline_Update()
             nodes[i]->word->pos = { from.x + (target.x - from.x) * s,
                                     from.y + (target.y - from.y) * s,
                                     from.z + (target.z - from.z) * s };
-        } else {
+        }
+        else {
             nodes[i]->word->pos = target;
         }
         nodes[i]->word->yaw = static_cast<float>(glyph_yaw);
@@ -289,7 +285,7 @@ GameState::on_ShootAll()
     _carried = CarriedLine();
     if (!all_words.empty()) {
         Aim::Result aim = Aim::crosshair_Target(*_ctx.camera, _ctx.words, _ctx.scenery,
-                                                _ctx.wall_texts, World::get_BoxScale());
+                                                 _ctx.wall_texts, World::get_BoxScale());
         _projectiles_sys->launch(_projectiles, std::move(all_words),
                                  _ctx.camera->fwd, _ctx.camera->pos, aim);
     }
@@ -307,12 +303,14 @@ void GameState::on_Compile() {
           _level_runner_sys->dynamic_lib()) {
         const std::string path = sandbox_CanonicalPath();
         std::string stripped;
-        for (char c : src) if (!std::isspace((unsigned char)c)) { stripped = src; break; }
+        for (char c : src) if (!std::isspace((unsigned char)c))
+                                { stripped = src; break; }
         if (!path.empty() && !stripped.empty())
             SourceTokens::write_File(path, src);
 
         _dyn_loader_sys->build(_ctx.wall_texts, src, true);
-    } else {
+    }
+    else {
         _compiler_sys->compile(_ctx.wall_texts, src);
     }
 }
@@ -489,11 +487,10 @@ GameState::projectile_LandOnWall(ProjectileResult& result)
         placed.push_back(std::move(wt));
     }
 
-    // Insert the whole shot line as ONE block at its centroid (the aim point),
-    // so it merges between two existing words instead of scattering.
     if (!editor_group.empty()) {
         Vec3 impact{0, 0, 0};
-        for (Text3d* t : editor_group) { impact.x += t->pos.x; impact.y += t->pos.y; impact.z += t->pos.z; }
+        for (Text3d* t : editor_group)
+            { impact.x += t->pos.x; impact.y += t->pos.y; impact.z += t->pos.z; }
         const double inv = 1.0 / static_cast<double>(editor_group.size());
         impact.x *= inv; impact.y *= inv; impact.z *= inv;
         _editor_wall.on_LinePlaced(editor_group, impact);
@@ -519,7 +516,8 @@ GameState::projectile_LandOnWallText(ProjectileResult& result,
         _editor_wall.bounce(lid);
 
         projectile_LandOnFloor(result);
-    } else {
+    }
+    else {
         walltext_HandleShootDown(result, wall_text_to_erase);
     }
     return;
@@ -594,13 +592,16 @@ GameState::handle_Input(FrameInput& input, double dt) {
             editor_CommitToWall(_wall_connection.lines());
             _wall_connection.end();
             _frame_input.capture_vim = false;
-        } else if (req == WallConnection::Request::EditorWrite) {
+        }
+        else if (req == WallConnection::Request::EditorWrite) {
             editor_CommitToWall(_wall_connection.lines());
             _wall_connection.load_Editor(editor_AbsorbLines(), _ctx.camera->pos.y);
         }
-    } else if (_wall_connection.target() == WallConnection::Target::Program) {
+    }
+    else if (_wall_connection.target() == WallConnection::Target::Program) {
         _wall_connection.set_ProgramBuffer(input.typing_buffer);
-    } else if (input.typing_mode) {
+    }
+    else if (input.typing_mode) {
         input.forward = input.backward = input.left = input.right = false;
         if (input.typing_buffer != _typing_last) { typing_RebuildPreview(input.typing_buffer); _typing_last = input.typing_buffer; }
     }
@@ -622,7 +623,7 @@ GameState::update_PlayerCamera(FrameInput& input, double dt)
 
     _freelook_sys->update(dt);
     _ctx.player->compute_Movement(input);
-    _ctx.camera->syncFromPlayer(*_ctx.player, 0.0);
+    _ctx.camera->syncFromPlayer(*_ctx.player);
 }
 
 void
@@ -824,13 +825,12 @@ GameState::infowall_StepdetailsShow()
     const std::string& details = _level_runner_sys->current().details;
     if (details.empty()) return;
 
-    const float      world_scale    = World::get_BoxScale();
-    Wall::Transform  wall_transform = Wall::get_Transform(Wall::Role::Info, world_scale);
+    Wall::Transform  wall_transform = Wall::get_Transform(Wall::Role::Info, World::get_BoxScale());
 
     constexpr size_t MAX_INFO_LINE_CHARS = 92;
     DynArray<std::string> lines = wrap_Text(details, MAX_INFO_LINE_CHARS);
 
-    const float bottom_y = -world_scale + 1.0f;
+    const float bottom_y = World::get_FloorY() + 1.0f;
     float y = bottom_y + static_cast<float>(lines.size() - 1) * ConfigWall::text_line_spacing;
 
     for (const std::string& line : lines) {
@@ -1136,13 +1136,16 @@ GameState::level_Advance()
             _carried = CarriedLine();
         }
 
-        DynArray<std::string> tokens = _level_runner_sys->grants_for_step();
+        DynArray<std::string>
+            tokens = _level_runner_sys->grants_for_step();
+
         step_Spawn(tokens);
         scene_Setup(_level_runner_sys->current().scene);
         step_SettingsApply();
         infowall_StepdetailsShow();
         _hint_sys->set_Hint(_level_runner_sys->current().hint);
-    } else {
+    }
+    else {
         _hint_sys->clear();
         infowall_StepdetailsShow();
     }
@@ -1155,14 +1158,16 @@ GameState::dyn_Clear()
 {
     if (_dyn_scenery.empty()) { return; }
 
-    std::unordered_set<GameObject*> set(_dyn_scenery.begin(), _dyn_scenery.end());
+    std::unordered_set<GameObject*>
+        set(_dyn_scenery.begin(), _dyn_scenery.end());
+
     _ctx.scenery.erase(
         std::remove_if(_ctx.scenery.begin(), _ctx.scenery.end(),
             [&set](const GameObjectPtr& sp) { return set.count(sp.get()) > 0; }),
         _ctx.scenery.end());
     _ctx.words.erase(
         std::remove_if(_ctx.words.begin(), _ctx.words.end(),
-            [&set](const Text3dPtr& wp) { return set.count(wp.get()) > 0; }),
+            [&set](const Text3dPtr& wp)     { return set.count(wp.get()) > 0; }),
         _ctx.words.end());
     _dyn_scenery.clear();
 }
@@ -1181,13 +1186,16 @@ GameState::dyn_Apply(const DynArray<DynObject>& objs)
                 Vec3{ o.hx, o.hy, o.hz },
                 SDL_FColor{ o.r, o.g, o.b, 1.0f });
             box->body.mode = o.dynamic ? PhysicsMode::Dynamic : PhysicsMode::Static;
+
             _dyn_scenery.push_back(box.get());
             _ctx.scenery.push_back(std::move(box));
-        } else { // DYN_TEXT
+        }
+        else { // DYN_TEXT
             Text3dPtr t = make_Text3d(o.text, Text3d::depth_floor, 0.003f,
                                       Vec3{ o.x, o.y, o.z },
                                       SDL_FColor{ o.r, o.g, o.b, 1.0f });
             t->body.mode = PhysicsMode::Static;   // lib text just sits where placed
+
             _dyn_scenery.push_back(t.get());
             _ctx.words.push_back(std::move(t));
         }
@@ -1222,6 +1230,7 @@ GameState::sandbox_LoadFileToWall()
         for (const std::string& tk : toks) { if (!joined.empty()) joined += ' '; joined += tk; }
         lines.push_back(joined);
     }
+
     editor_PlaceLines(lines);
 }
 
@@ -1240,8 +1249,10 @@ GameState::typing_RebuildPreview(const std::string& s)
 
     const Vec3   anchor    = CarryMath::line_Anchor(*_ctx.camera, CarryMath::CARRY_DIST);
     const double glyph_yaw = SDL_atan2(-_ctx.camera->fwd.x, -_ctx.camera->fwd.z);
+
     std::istringstream in(s);
-    std::string tok;
+    std::string        tok;
+
     while (in >> tok) {
         Text3dPtr t = make_Text3d(tok, Text3d::depth_floor, 0.003f,
                                   anchor, ConfigColor::floor);
@@ -1260,6 +1271,7 @@ GameState::typing_ClearPreview()
         if (_carried.empty()) break;
         _carried.pop_back();
     }
+
     _typing_words.clear();
 }
 
@@ -1292,6 +1304,7 @@ GameState::wallconnect_BeginProgram()
 {
     _frame_input.capture_typing = true;
     _frame_input.typing_buffer.clear();
+
     _wall_connection.begin_Program(_pult_sys->get_ConnectProgramPos());
 }
 
@@ -1302,6 +1315,7 @@ GameState::wallconnect_BeginEditor()
     DynArray<std::string> lines = editor_AbsorbLines();
     _frame_input.capture_vim = true;
     _frame_input.vim_keys.clear();
+
     _wall_connection.begin_Editor(_pult_sys->get_ConnectEditorPos(), lines, _ctx.camera->pos.y);
 }
 
@@ -1321,6 +1335,7 @@ GameState::on_WallConnectSubmit()
             _program_sys->echo_Input(_ctx.wall_texts, h);
         return;
     }
+
     _program_sys->feed_Input(line);
     _program_sys->echo_Input(_ctx.wall_texts, line);
 }
@@ -1330,6 +1345,7 @@ void
 GameState::on_WallConnectExit()
 {
     _wall_connection.end();
+
     _frame_input.capture_typing = false;
     _frame_input.typing_buffer.clear();
 }
@@ -1339,6 +1355,7 @@ void
 GameState::editor_Clear()
 {
     _editor_wall.clear();
+
     _ctx.wall_texts.erase(
         std::remove_if(_ctx.wall_texts.begin(), _ctx.wall_texts.end(),
             [](const TextWallPtr& wt){ return wt->role == Wall::Role::Editor; }),
@@ -1351,6 +1368,7 @@ GameState::editor_AbsorbLines()
 {
     std::string src = TextWall::extract_Text(_ctx.wall_texts, Wall::Role::Editor);
     DynArray<std::string> lines;
+
     std::string cur;
     for (char ch : src) {
         if (ch == '\n') { lines.push_back(cur); cur.clear(); }
@@ -1366,23 +1384,26 @@ GameState::editor_AbsorbLines()
 void
 GameState::editor_PlaceLines(const DynArray<std::string>& lines)
 {
-    const float ws = World::get_BoxScale();
-    const double x_wall = -static_cast<double>(ws) + 0.05;
-    Wall::Transform tf = Wall::get_Transform(Wall::Role::Editor, ws);
+    const float     ws     = World::get_BoxScale();
+    const double    x_wall = -static_cast<double>(ws) + 0.05;
+    Wall::Transform tf     = Wall::get_Transform(Wall::Role::Editor, ws);
 
-    double y = static_cast<double>(ws) - 2.0;
+    double       y       = static_cast<double>(ws) - 2.0;
     const double z_start = static_cast<double>(ws) - 1.0;
 
     for (const std::string& line : lines) {
         double z = z_start;
+
         std::istringstream in(line);
-        std::string tk;
+        std::string        tk;
+
         while (in >> tk) {
             Text3dPtr t = make_Text3d(tk, Text3d::depth_wall, 0.003f,
                                       Vec3{ x_wall, y, z }, ConfigColor::wall);
-            t->yaw = tf.yaw;
+            t->yaw       = tf.yaw;
             Vec3 snapped = _editor_wall.on_WordPlaced(t.get(), Vec3{ x_wall, y, z });
-            t->pos = snapped;
+            t->pos       = snapped;
+
             _ctx.wall_texts.push_back(cpputils::make_unique<TextWall>(TextWall{
                 Wall::Position::NegX, Wall::Role::Editor, std::move(t) }));
             z = snapped.z - 0.5;
diff --git a/src/states/menu_state.cpp b/src/states/menu_state.cpp
index e13f4e8..0bba412 100644
--- a/src/states/menu_state.cpp
+++ b/src/states/menu_state.cpp
@@ -7,16 +7,6 @@
 #include "states/game_state.hpp"
 
 
-// ─────────────────────────────────────────────────────────────────────────
-// Layout: three columns at -90° / 0° / +90°. Left holds "Open File", right
-// holds "Quit", middle holds the level list — Tutorial at eye level, every
-// further level stacked downward. Camera stands at _world origin.
-//
-// W/S scroll the level list (the list moves; the _camera does not). At
-// scroll = 0 the first level sits at eye level. At scroll = N the (N+1)th
-// level does.
-// ─────────────────────────────────────────────────────────────────────────
-
 static constexpr float  TITLE_SCALE    = 0.018f;
 static constexpr float  ITEM_SCALE     = 0.012f;
 static constexpr float  TEXT_DEPTH     = 0.10f;
@@ -24,7 +14,7 @@ static constexpr float  TEXT_DEPTH     = 0.10f;
 static constexpr double EYE_Y          = 0.0;
 static constexpr double TITLE_Y        = 2.0;
 static constexpr double COLUMN_RADIUS  = 8.0;
-static constexpr double LEVEL_SPACING  = 1.6;     // vertical gap between levels
+static constexpr double LEVEL_SPACING  = 1.6;
 
 static constexpr double COLUMN_LEFT_RAD  = -SDL_PI_D * 0.35;
 static constexpr double COLUMN_MID_RAD   =  0.0;
@@ -54,7 +44,6 @@ MenuState::yaw_ToRadians(uint32_t yaw)
 }
 
 
-// Helper: place a single Text3d item at a column angle and a given Y.
 static Vec3
 slot_PosForColumn(double column_angle_rad, double y)
 {
@@ -98,7 +87,6 @@ MenuState::build_Items()
 {
     _items.clear();
 
-    // ── Left column: Open File ───────────────────────────────────────────
     {
         MenuItem mi;
         mi.label    = "Open File";
@@ -107,20 +95,15 @@ MenuState::build_Items()
         _items.push_back(std::move(mi));
     }
 
-    // ── Middle column: levels, stacked top-to-bottom ─────────────────────
-    // We DON'T set slot_pos.y here; vertical position is recomputed each
-    // frame in update() based on _scroll_current. The X/Z components (the
-    // middle column) are fixed.
     for (size_t i = 0; i < Level::level_Count(); ++i) {
         MenuItem mi;
         mi.label       = Level::get_Level(i).name;
         mi.kind        = ItemKind::StartLevel;
         mi.level_index = i;
-        mi.slot_pos    = slot_PosForColumn(COLUMN_MID_RAD, EYE_Y);   // y replaced each frame
+        mi.slot_pos    = slot_PosForColumn(COLUMN_MID_RAD, EYE_Y);
         _items.push_back(std::move(mi));
     }
 
-    // ── Right column: Quit ───────────────────────────────────────────────
     {
         MenuItem mi;
         mi.label    = "Quit";
@@ -129,7 +112,6 @@ MenuState::build_Items()
         _items.push_back(std::move(mi));
     }
 
-    // Build Text3d objects.
     for (size_t i = 0; i < _items.size(); ++i) {
         const auto color = (i == _selected) ? COLOR_SELECTED : COLOR_NORMAL;
         _items[i].text3d = make_Text3d(_items[i].label,
@@ -144,7 +126,6 @@ MenuState::build_Items()
 void
 MenuState::handle_Event(Game& game, const SDL_Event& e)
 {
-    // ── Mouse-look ───────────────────────────────────────────────────────
     if (e.type == SDL_EVENT_MOUSE_MOTION) {
         const double dx_rad = static_cast<double>(e.motion.xrel) * MOUSE_SENSITIVITY;
         const double dy_rad = static_cast<double>(e.motion.yrel) * MOUSE_SENSITIVITY;
@@ -162,7 +143,6 @@ MenuState::handle_Event(Game& game, const SDL_Event& e)
         return;
     }
 
-    // ── Left-click: activate hovered item ────────────────────────────────
     if (e.type == SDL_EVENT_MOUSE_BUTTON_DOWN &&
         e.button.button == SDL_BUTTON_LEFT)
     {
@@ -179,8 +159,6 @@ MenuState::handle_Event(Game& game, const SDL_Event& e)
     switch (e.key.key) {
         case SDLK_W:
         case SDLK_UP:
-            // Only scroll the level list when the player is looking at a
-            // level. Other columns ignore W/S.
             if (is_LevelItem(pick_FromCrosshair())) {
                 if (_scroll_target > 0.0) _scroll_target -= 1.0;
             }
@@ -252,7 +230,6 @@ MenuState::pick_FromCrosshair() const
     const double cy = SDL_cos(yaw),  sy = SDL_sin(yaw);
     const double cp = SDL_cos(pitch), sp = SDL_sin(pitch);
 
-    // World-space forward (negation of view-matrix back axis).
     Vec3 fwd { -sy * cp, sp, -cy * cp };
 
     size_t best   = static_cast<size_t>(-1);
@@ -299,45 +276,30 @@ MenuState::update(double dt)
 {
     _t += dt;
 
-    // ── Scroll lerp ──────────────────────────────────────────────────────
-    {
-        const double k = 1.0 - SDL_exp(-SCROLL_LERP_RATE * dt);
-        _scroll_current += (_scroll_target - _scroll_current) * k;
-    }
+    const double lerp_factor = 1.0 - SDL_exp(-SCROLL_LERP_RATE * dt);
+    _scroll_current += (_scroll_target - _scroll_current) * lerp_factor;
 
-    // ── Reposition level _items based on scroll ───────────────────────────
-    // For each level i: y = EYE_Y - (i - _scroll_current) * SPACING.
-    // At _scroll_current = 0, i=0 sits at EYE_Y, i=1 below it, etc.
-    // As _scroll_current grows, the whole list slides upward, so further
-    // levels reach eye level.
-    {
-        size_t level_n = 0;
-        for (MenuItem& mi : _items) {
-            if (mi.kind != ItemKind::StartLevel) continue;
-            const double y = EYE_Y - (static_cast<double>(level_n) - _scroll_current)
-                                     * LEVEL_SPACING;
-            mi.text3d->pos = { mi.slot_pos.x, y, mi.slot_pos.z };
-            ++level_n;
-        }
+    size_t level_n = 0;
+    for (MenuItem& mi : _items) {
+        if (mi.kind != ItemKind::StartLevel) continue;
+        const double y = EYE_Y - (static_cast<double>(level_n) - _scroll_current)
+                                 * LEVEL_SPACING;
+        mi.text3d->pos = { mi.slot_pos.x, y, mi.slot_pos.z };
+        ++level_n;
     }
 
-    // ── Non-level _items stay at their fixed slot positions ───────────────
     for (MenuItem& mi : _items) {
         if (mi.kind == ItemKind::StartLevel) continue;
         mi.text3d->pos = mi.slot_pos;
     }
 
-    // ── Crosshair-driven selection (mouse hover) ─────────────────────────
-    {
-        const size_t hover = pick_FromCrosshair();
-        if (hover != static_cast<size_t>(-1) && hover != _selected) {
-            _items[_selected].text3d->set_Color(COLOR_NORMAL);
-            _items[hover].text3d->set_Color(COLOR_SELECTED);
-            _selected = hover;
-        }
+    const size_t hover = pick_FromCrosshair();
+    if (hover != static_cast<size_t>(-1) && hover != _selected) {
+        _items[_selected].text3d->set_Color(COLOR_NORMAL);
+        _items[hover].text3d->set_Color(COLOR_SELECTED);
+        _selected = hover;
     }
 
-    // ── Billboard: every item faces the _camera ───────────────────────────
     for (MenuItem& mi : _items) {
         if (!mi.text3d) continue;
         const double dx = _camera->pos.x - mi.text3d->pos.x;
@@ -350,7 +312,6 @@ MenuState::update(double dt)
         _title->yaw = static_cast<float>(SDL_atan2(dx, dz));
     }
 
-    // ── Bob the _selected item ────────────────────────────────────────────
     if (_selected < _items.size() && _items[_selected].text3d) {
         const double bob = SDL_sin(_t * 3.0) * 0.10;
         _items[_selected].text3d->pos.y += bob;
@@ -364,16 +325,13 @@ MenuState::render(SDL_Window& window, GlRenderer& renderer)
     int w, h;
     SDL_GetWindowSizeInPixels(&window, &w, &h);
 
-    // Update flashlight: pos = _camera, dir = where the _camera is looking.
-    {
-        const double yaw_r   = ConfigPhysics::binrad * static_cast<double>(_camera->yaw);
-        const double pitch_r = ConfigPhysics::binrad * static_cast<double>(_camera->pitch);
-        const double cy = SDL_cos(yaw_r),   sy = SDL_sin(yaw_r);
-        const double cp = SDL_cos(pitch_r), sp = SDL_sin(pitch_r);
+    const double yaw_r   = ConfigPhysics::binrad * static_cast<double>(_camera->yaw);
+    const double pitch_r = ConfigPhysics::binrad * static_cast<double>(_camera->pitch);
+    const double cy = SDL_cos(yaw_r),   sy = SDL_sin(yaw_r);
+    const double cp = SDL_cos(pitch_r), sp = SDL_sin(pitch_r);
 
-        _light->flashlight_pos = _camera->pos;
-        _light->flashlight_dir = Vec3{ -sy * cp, sp, -cy * cp };
-    }
+    _light->flashlight_pos = _camera->pos;
+    _light->flashlight_dir = Vec3{ -sy * cp, sp, -cy * cp };
 
     renderer.begin_Frame(w, h);
     renderer.set_Light(*_light);
diff --git a/src/states/menu_state.hpp b/src/states/menu_state.hpp
index f789845..f0a0fe2 100644
--- a/src/states/menu_state.hpp
+++ b/src/states/menu_state.hpp
@@ -22,9 +22,9 @@ class MenuState : public IState
     struct MenuItem {
         std::string label;
         ItemKind    kind;
-        size_t      level_index = 0;   // valid when kind == StartLevel
+        size_t      level_index = 0;
         Text3dPtr   text3d;
-        Vec3        slot_pos {};       // base position in the column (no scroll/bob)
+        Vec3        slot_pos {};
     };
 
     cpputils::unique_ptr<World>  _world;
diff --git a/src/systems/carry_system.cpp b/src/systems/carry_system.cpp
index 827bce3..a564c37 100644
--- a/src/systems/carry_system.cpp
+++ b/src/systems/carry_system.cpp
@@ -16,7 +16,8 @@ CarriedLine::push(Text3dPtr w)
     if (!first) {
         first = std::move(node);
         last = first.get();
-    } else {
+    }
+    else {
         last->next = std::move(node);
         last = last->next.get();
     }
@@ -30,7 +31,8 @@ CarriedLine::pop_back()
         if (last->prev) {
             last = last->prev;
             last->next.reset();
-        } else {
+        }
+        else {
             first.reset();
             last = nullptr;
         }
@@ -43,7 +45,8 @@ CarriedLine::pop_back()
     if (last->prev) {
         last = last->prev;
         last->next.reset();
-    } else {
+    }
+    else {
         first.reset();
         last = nullptr;
     }
@@ -61,7 +64,8 @@ CarriedLine::pop_front()
     if (first->next) {
         first = std::move(first->next);
         first->prev = nullptr;
-    } else {
+    }
+    else {
         first.reset();
         last = nullptr;
     }
diff --git a/src/systems/collision.cpp b/src/systems/collision.cpp
index 4375829..d2b554a 100644
--- a/src/systems/collision.cpp
+++ b/src/systems/collision.cpp
@@ -36,17 +36,19 @@ aabb_Manifold(const GameObject& a, const GameObject& b)
                 std::max(a.aabb_min().z, b.aabb_min().z);
 
     if (ox <= 0.0 || oy <= 0.0 || oz <= 0.0)
-        return m;   // no overlap
+        return m;
 
     m.hit = true;
 
     if (ox < oy && ox < oz) {
         m.overlap  = ox;
         m.normal.x = (a.pos.x < b.pos.x) ? -1.0 : 1.0;
-    } else if (oy < oz) {
+    }
+    else if (oy < oz) {
         m.overlap  = oy;
         m.normal.y = (a.pos.y < b.pos.y) ? -1.0 : 1.0;
-    } else {
+    }
+    else {
         m.overlap  = oz;
         m.normal.z = (a.pos.z < b.pos.z) ? -1.0 : 1.0;
     }
@@ -79,7 +81,7 @@ resolve_Objects(GameObject& a, GameObject& b)
     }
 
     // Impulse resolution
-    double rel_vel = dot(b.body.vel - a.body.vel, m.normal);
+    double rel_vel = Math::dot(b.body.vel - a.body.vel, m.normal);
 
     if (rel_vel >= 0.0) return;  // already separating
 
@@ -93,11 +95,11 @@ resolve_Objects(GameObject& a, GameObject& b)
         a.body.vel.y += j * inv_mass_a * m.normal.y;
         a.body.vel.z += j * inv_mass_a * m.normal.z;
 
-        if (SDL_fabs(j) < FRICTION_IMPULSE_CUTOFF) {   // ← add the same guard
-            double vn  = dot(a.body.vel, m.normal);
+        if (SDL_fabs(j) < FRICTION_IMPULSE_CUTOFF) {
+            double vn  = Math::dot(a.body.vel, m.normal);
             Vec3   v_t = a.body.vel - m.normal * vn;
             v_t = v_t * a.body.friction;
-            if (length(v_t) < 0.02) v_t = Vec3{};
+            if (Math::length(v_t) < 0.02) v_t = Vec3{};
             a.body.vel = m.normal * vn + v_t;
         }
     }
@@ -109,10 +111,10 @@ resolve_Objects(GameObject& a, GameObject& b)
         // Only damp tangential drift for gentle/resting contacts. A strong
         // impulse (fast hit) should transfer freely — don't friction it away.
         if (SDL_fabs(j) < FRICTION_IMPULSE_CUTOFF) {
-            double vn  = dot(b.body.vel, m.normal);
+            double vn  = Math::dot(b.body.vel, m.normal);
             Vec3   v_t = b.body.vel - m.normal * vn;
             v_t = v_t * b.body.friction;
-            if (length(v_t) < 0.02) v_t = Vec3{};
+            if (Math::length(v_t) < 0.02) v_t = Vec3{};
             b.body.vel = m.normal * vn + v_t;
         }
     }
@@ -122,7 +124,7 @@ resolve_Objects(GameObject& a, GameObject& b)
 Vec3
 reflect(const Vec3& vel, const Vec3& normal, double restitution)
 {
-    double d = dot(vel, normal);
+    double d = Math::dot(vel, normal);
     return {
         vel.x - (1.0 + restitution) * d * normal.x,
         vel.y - (1.0 + restitution) * d * normal.y,
diff --git a/src/systems/input_system.cpp b/src/systems/input_system.cpp
index 1c389b4..c80a8d4 100644
--- a/src/systems/input_system.cpp
+++ b/src/systems/input_system.cpp
@@ -38,7 +38,8 @@ InputSystem::handle_Event(Game& game, const SDL_Event& e, FrameInput& input)
                         case SDLK_S: input.backward = true; break;
                         case SDLK_D: input.right    = true; break;
                     }
-                } else if (sym == SDLK_RETURN)    input.vim_keys.push_back(-1);
+                }
+                else if (sym == SDLK_RETURN)    input.vim_keys.push_back(-1);
                 else if   (sym == SDLK_ESCAPE)    input.vim_keys.push_back(-2);
                 else if   (sym == SDLK_BACKSPACE) input.vim_keys.push_back(-3);
                 break;
@@ -52,11 +53,14 @@ InputSystem::handle_Event(Game& game, const SDL_Event& e, FrameInput& input)
                         case SDLK_S: input.backward = true; break;
                         case SDLK_D: input.right    = true; break;
                     }
-                } else if (sym == SDLK_RETURN) {
+                }
+                else if (sym == SDLK_RETURN) {
                     input.commands.push_back(InputCommand::ConnectPultSubmit);
-                } else if (sym == SDLK_ESCAPE) {
+                }
+                else if (sym == SDLK_ESCAPE) {
                     input.commands.push_back(InputCommand::ConnectPultExit);
-                } else if (sym == SDLK_BACKSPACE && !input.typing_buffer.empty()) {
+                }
+                else if (sym == SDLK_BACKSPACE && !input.typing_buffer.empty()) {
                     input.typing_buffer.pop_back();
                 }
                 break;
@@ -69,7 +73,7 @@ InputSystem::handle_Event(Game& game, const SDL_Event& e, FrameInput& input)
                     input.commands.push_back(InputCommand::TypingCancel);
                 else if (sym == SDLK_BACKSPACE && !input.typing_buffer.empty())
                     input.typing_buffer.pop_back();
-                break;   // swallow everything else — no movement while typing
+                break;
             }
 
 
@@ -128,7 +132,8 @@ InputSystem::handle_Event(Game& game, const SDL_Event& e, FrameInput& input)
             if (input.capture_vim) {
                 for (const char* p = e.text.text; *p; ++p)
                     input.vim_keys.push_back((unsigned char)*p);
-            } else if (input.capture_typing || input.typing_mode) {
+            }
+            else if (input.capture_typing || input.typing_mode) {
                 input.typing_buffer += e.text.text;
             }
             break;
diff --git a/src/systems/physics_system.cpp b/src/systems/physics_system.cpp
index 5f7d286..394e6e3 100644
--- a/src/systems/physics_system.cpp
+++ b/src/systems/physics_system.cpp
@@ -74,15 +74,16 @@ PhysicsSystem::resolve_PlayerVsObjects(Player& player, CarriedLine& carried,
             if (ox < oy && ox < oz) {
                 overlap  = ox;
                 normal.x = (player.pos.x < obj->pos.x) ? -1.0 : 1.0;
-            } else if (oy < oz) {
+            }
+            else if (oy < oz) {
                 overlap  = oy;
                 normal.y = (player.pos.y < obj->pos.y) ? -1.0 : 1.0;
-            } else {
+            }
+            else {
                 overlap  = oz;
                 normal.z = (player.pos.z < obj->pos.z) ? -1.0 : 1.0;
             }
 
-            // Resolve the overlap fully.
             if (normal.y > 0.0)
                 player.on_ground = true;
 
@@ -90,7 +91,7 @@ PhysicsSystem::resolve_PlayerVsObjects(Player& player, CarriedLine& carried,
             player.pos.y += normal.y * overlap * 0.1;
             player.pos.z += normal.z * overlap * 0.1;
 
-            double vel_along = dot(player.vel, normal);
+            double vel_along = Math::dot(player.vel, normal);
             if (vel_along < 0.0) {
                 player.vel.x -= vel_along * normal.x * 0.1;
                 player.vel.y -= vel_along * normal.y * 0.1;
@@ -104,25 +105,23 @@ PhysicsSystem::resolve_PlayerVsObjects(Player& player, CarriedLine& carried,
                 obj->body.apply_KickImpulse({ -normal.x * kick, 0.3, -normal.z * kick });
         }
 
-        // Grounded check is INDEPENDENT of overlap resolution.
-        // Feet near the top of this box AND overlap in XZ AND not jumping up.
         {
             constexpr double GROUND_EPS = 0.1;
             const bool xz_overlap = (px_max > omin.x && px_min < omax.x &&
-                    pz_max > omin.z && pz_min < omax.z);
+                                     pz_max > omin.z && pz_min < omax.z);
             const bool feet_on_top = (py_min <= omax.y + GROUND_EPS &&
-                    py_min >= omax.y - GROUND_EPS);
+                                      py_min >= omax.y - GROUND_EPS);
             if (xz_overlap && feet_on_top && player.vel.y <= 0.01)
                 player.on_ground = true;
         }
 
         for (CarriedWordNode* node : nodes) {
-            if (!node || !node->word) continue;
+            if (!node || !node->word)
+                        continue;
 
             GameObject& w = *node->word;
-
             if (!Collision::aabb_Overlap(w, *obj))
-                continue;
+                        continue;
 
             Collision::Manifold m = Collision::aabb_Manifold(w, *obj);
             if (!m.hit) continue;
@@ -135,7 +134,7 @@ PhysicsSystem::resolve_PlayerVsObjects(Player& player, CarriedLine& carried,
             w.pos.z += normal.z * overlap;
 
             double speed = SDL_sqrt(player.vel.x * player.vel.x +
-                           player.vel.z * player.vel.z);
+                                    player.vel.z * player.vel.z);
 
             double kick = SDL_max(speed * 2.0, 4.0);
             if (obj->body.mode != PhysicsMode::AiHover)
@@ -160,28 +159,24 @@ PhysicsSystem::try_Pair(GameObject* a, GameObject* b)
     bool i_static_solid = (mi == PhysicsMode::Static && a->solid);
     bool j_static_solid = (mj == PhysicsMode::Static && b->solid);
 
-    // Need at least one moving body
     if (!i_dyn && !j_dyn && !i_hov && !j_hov) return;
+    if (!Collision::aabb_Overlap(*a, *b))     return;
 
-    if (!Collision::aabb_Overlap(*a, *b)) return;
-
-    // Dynamic body knocks a hovering one off its pedestal
     if (i_dyn && j_hov) {
         b->body.mode = PhysicsMode::Dynamic;
         b->body.vel  = a->body.vel * 0.5;
-    } else if (j_dyn && i_hov) {
+    }
+    else if (j_dyn && i_hov) {
         a->body.mode = PhysicsMode::Dynamic;
         a->body.vel  = b->body.vel * 0.5;
     }
 
-    // Re-read modes after possible mutation above
     bool i_dyn_now = (a->body.mode == PhysicsMode::Dynamic);
     bool j_dyn_now = (b->body.mode == PhysicsMode::Dynamic);
 
-    if ((i_dyn_now && j_dyn_now) ||
-        (i_dyn_now && j_static_solid) ||
-        (j_dyn_now && i_static_solid))
-    {
+    if ( (i_dyn_now && j_dyn_now) ||
+         (i_dyn_now && j_static_solid) ||
+         (j_dyn_now && i_static_solid) ) {
         Collision::resolve_Objects(*a, *b);
     }
 }
@@ -194,7 +189,6 @@ void
 PhysicsSystem::update_Objects(const DynArray<GameObject*>& objects,
                               double dt, double gravity)
 {
-    // Integration pass
     { FP_ZONE("phys.integrate");
         for (GameObject* obj : objects) {
             if (!obj) continue;
@@ -209,7 +203,8 @@ PhysicsSystem::update_Objects(const DynArray<GameObject*>& objects,
                 continue;
             }
 
-            if (obj->body.mode != PhysicsMode::Dynamic) continue;
+            if (obj->body.mode != PhysicsMode::Dynamic)
+                continue;
 
             obj->body.apply_Force({ 0.0, -gravity * obj->body.mass, 0.0 });
             obj->body.integrate(dt);
@@ -219,27 +214,22 @@ PhysicsSystem::update_Objects(const DynArray<GameObject*>& objects,
         }
     }
 
-    // World bounds
     { FP_ZONE("phys.bounds");
         for (GameObject* obj : objects) {
-            if (!obj || obj->body.mode != PhysicsMode::Dynamic) continue;
+            if (!obj || obj->body.mode != PhysicsMode::Dynamic)
+                continue;
             resolve_WorldBounds(*obj);
         }
     }
 
-    // ── Object-vs-object collision ────────────────────────────────────────
-    // Most objects are Static or AiHover and only ever collide as the passive
-    // side of a pair. Partition once so we never enumerate passive×passive,
-    // which is the bulk of the old O(n²) work.
     { FP_ZONE("phys.pairs");
-        // Build grid over ALL objects (passive included — movers must find them).
         _grid.build(objects);
 
-        // Only active bodies initiate collision tests.
         DynArray<GameObject*> active;
         active.reserve(objects.size());
         for (GameObject* o : objects) {
-            if (!o) continue;
+            if (!o)
+                continue;
             const PhysicsMode m = o->body.mode;
             if (m == PhysicsMode::Dynamic || m == PhysicsMode::Hover)
                 active.push_back(o);
@@ -293,11 +283,7 @@ PhysicsSystem::update_Projectiles(DynArray<Projectile>& projectiles, double dt,
         p.step_dt       = dt;
         p.prev_centroid = Text3d::words_centroid(p.words);
 
-        // ── Hard-track: steer straight at the target's live point, no gravity.
         if (p.track_obj) {
-            // Validate the target is still alive (could be picked up, shot
-            // down, consumed, or destroyed on teardown). Never deref a raw
-            // pointer we haven't re-confirmed this frame.
             bool alive = false;
             for (const Text3dPtr& w : words)
                 if (w.get() == p.track_obj) { alive = true; break; }
@@ -305,28 +291,28 @@ PhysicsSystem::update_Projectiles(DynArray<Projectile>& projectiles, double dt,
             if (alive) {
                 Text3d* o  = p.track_obj;
                 const double cy = SDL_cos(o->yaw), sy = SDL_sin(o->yaw);
-                const Vec3 live {                      // pos + R(yaw)*local
+                const Vec3 live {
                     o->pos.x + cy * p.track_local.x + sy * p.track_local.z,
                     o->pos.y + p.track_local.y,
                     o->pos.z - sy * p.track_local.x + cy * p.track_local.z
                 };
                 p.track_last = live;
 
-                const Vec3   c  = p.prev_centroid;
+                const Vec3 c = p.prev_centroid;
                 Vec3 d { live.x - c.x, live.y - c.y, live.z - c.z };
-                const double L = length(d);
+
+                const double L = Math::length(d);
                 if (L > 1e-6) {
                     const double s = ConfigPhysics::proj_throw_speed / L;
                     p.vel = Vec3{ d.x * s, d.y * s, d.z * s };
                 }
-                // No gravity while tracking — fly dead-on to the live point.
-            } else {
-                // Target gone: drop tracking, fall toward last known point
-                // under gravity like a normal thrown word.
+            }
+            else {
                 p.track_obj = nullptr;
                 p.vel.y -= ConfigPhysics::proj_grav * dt;
             }
-        } else {
+        }
+        else {
             p.vel.y -= ConfigPhysics::proj_grav * dt;
         }
 
@@ -412,59 +398,52 @@ PhysicsSystem::resolve_Projectiles(DynArray<Projectile>& projectiles,
             if (w) { word_he = w->shape.half_extents; break; }
         }
 
-        // 1. Resolve against GameObjects
         if (statics) {
             constexpr double RESTITUTION_STATIC = 0.45;
 
             for (GameObject* obj : *statics) {
                 if (!obj || !obj->solid) continue;
 
-                // Text words: kick and pass through, regardless of Hover/Dynamic mode.
                 if (obj->type == ObjectType::Text) {
                     constexpr double RESTITUTION_TEXT = 0.55;
                     Vec3 vel_before = proj.vel;
                     Collision::SweptResult sw;
                     if (resolve_SingleBoxCollision(proj, obj->aabb_min(), obj->aabb_max(),
-                                word_he, RESTITUTION_TEXT,
-                                cur, prev, dir, sw)) {
+                                                   word_he, RESTITUTION_TEXT,
+                                                   cur, prev, dir, sw)) {
                         proj.collided = true;
                         if (obj == proj.track_obj) proj.track_obj = nullptr;
                         obj->body.apply_KickImpulse({
                                 vel_before.x * 0.4,
                                 SDL_fabs(vel_before.y) * 0.1 + 0.3,
                                 vel_before.z * 0.4
-                                });
+                            });
 
-                        // ── emit contact event so consumers (level goals) can react.
                         if (contacts) {
                             contacts->push_back(ProjectileContactEvent{
-                                    .projectile = &proj, .other = obj,
-                                    .point = cur, .normal = sw.normal
-                                    });
-                        }
+                                                    .projectile = &proj, .other = obj,
+                                                    .point = cur, .normal = sw.normal });
+                            }
                     }
                     continue;
                 }
 
-                // Props: reflect projectile, emit contact event
                 Collision::SweptResult sw;
                 if (resolve_SingleBoxCollision(proj, obj->aabb_min(), obj->aabb_max(),
-                               word_he, RESTITUTION_STATIC,
-                               cur, prev, dir, sw)) {
+                                               word_he, RESTITUTION_STATIC,
+                                               cur, prev, dir, sw)) {
                     proj.collided = true;
                     if (contacts) {
                         contacts->push_back(ProjectileContactEvent{
-                                .projectile = &proj, .other = obj,
-                                .point = cur, .normal = sw.normal
-                                });
+                                            .projectile = &proj, .other = obj,
+                                            .point = cur, .normal = sw.normal });
                     }
                 }
             }
         }
 
-        // 2. Resolve against Text Labels
         if (labels) {
-            constexpr double RESTITUTION_LABEL = 0.55; // WTF is that
+            constexpr double RESTITUTION_LABEL = 0.55;
 
             for (TextLabel* label : *labels) {
                 if (!label || label->empty()) continue;
@@ -478,8 +457,8 @@ PhysicsSystem::resolve_Projectiles(DynArray<Projectile>& projectiles,
                     Collision::SweptResult sw;
 
                     if (resolve_SingleBoxCollision(proj, hw->aabb_min(), hw->aabb_max(),
-                               word_he, RESTITUTION_LABEL, cur, prev, dir, sw)) {
-                        // Handle unique Label side-effect
+                                                   word_he, RESTITUTION_LABEL,
+                                                   cur, prev, dir, sw)) {
                         proj.collided = true;
                         label->kick(i, vel_before, sw.normal);
                     }
@@ -494,7 +473,6 @@ PhysicsSystem::resolve_Projectiles(DynArray<Projectile>& projectiles,
 void
 PhysicsSystem::SpatialGrid::build(const DynArray<GameObject*>& objs)
 {
-    // Cell size ~ a couple world units; tune if objects are much larger/smaller.
     cell = 2.0;
     inv  = 1.0 / cell;
     min_x = min_z = -World::get_BoxScale<double>();
@@ -503,7 +481,7 @@ PhysicsSystem::SpatialGrid::build(const DynArray<GameObject*>& objs)
 
     const int total = nx * nz;
     if (static_cast<int>(cells.size()) < total) cells.resize(static_cast<size_t>(total));
-    for (auto& c : cells) c.clear();   // keep capacity, drop contents
+    for (auto& c : cells) c.clear();
 
     for (GameObject* o : objs) {
         if (!o) continue;
@@ -518,7 +496,6 @@ PhysicsSystem::SpatialGrid::build(const DynArray<GameObject*>& objs)
 void
 PhysicsSystem::collide_Grid(const DynArray<GameObject*>& active)
 {
-    // Each active object tests against objects in its own + 8 neighbour cells.
     for (GameObject* a : active) {
         if (!a) continue;
 
@@ -539,11 +516,10 @@ PhysicsSystem::collide_Grid(const DynArray<GameObject*>& active)
                 for (GameObject* b : cell) {
                     if (b == a) continue;
 
-                    // Dedupe only when BOTH are active (both initiate).
                     const PhysicsMode mb = b->body.mode;
                     const bool b_active = (mb == PhysicsMode::Dynamic ||
                                            mb == PhysicsMode::Hover);
-                    if (b_active && b < a) continue;   // active-active: once, from higher ptr
+                    if (b_active && b < a) continue;
 
                     try_Pair(a, b);
                 }
diff --git a/src/systems/pick_system.cpp b/src/systems/pick_system.cpp
index 180d50f..7267415 100644
--- a/src/systems/pick_system.cpp
+++ b/src/systems/pick_system.cpp
@@ -9,10 +9,6 @@ namespace PickSystem
 static constexpr double MAX_REACH_XZ = 3.8;
 static constexpr double MAX_ANGLE    = 0.25;
 
-// ─── ang_score ──────────────────────────────────────────────────────────────
-//
-// Distance + angle test from camera to a text-like object's horizontal line.
-// Unchanged from the original implementation.
 static double
 ang_score(const GameObject& obj, const Vec3& eye, const Vec3& fwd)
 {
@@ -31,11 +27,11 @@ ang_score(const GameObject& obj, const Vec3& eye, const Vec3& fwd)
     Vec3 seg_dir { seg_b.x - seg_a.x, seg_b.y - seg_a.y, seg_b.z - seg_a.z };
     Vec3 w       { seg_a.x - eye.x,   seg_a.y - eye.y,   seg_a.z - eye.z   };
 
-    double a = dot(fwd, fwd);
-    double b = dot(fwd, seg_dir);
-    double c = dot(seg_dir, seg_dir);
-    double d = dot(fwd, w);
-    double e = dot(seg_dir, w);
+    double a = Math::dot(fwd, fwd);
+    double b = Math::dot(fwd, seg_dir);
+    double c = Math::dot(seg_dir, seg_dir);
+    double d = Math::dot(fwd, w);
+    double e = Math::dot(seg_dir, w);
 
     double denom = a*c - b*b;
     double seg_t = (denom > 1e-8) ? SDL_clamp((b*d - a*e) / denom, 0.0, 1.0) : 0.0;
@@ -51,22 +47,15 @@ ang_score(const GameObject& obj, const Vec3& eye, const Vec3& fwd)
     double xz = SDL_sqrt(dv.x*dv.x + dv.z*dv.z);
     if (xz > MAX_REACH_XZ) return -1.0;
 
-    double len = length(dv);
+    double len = Math::length(dv);
     if (len < 0.001) return -1.0;
 
-    double t   = SDL_clamp(dot(fwd, dv) / len, -1.0, 1.0);
+    double t   = SDL_clamp(Math::dot(fwd, dv) / len, -1.0, 1.0);
     double angle = SDL_acos(t);
     return (angle < MAX_ANGLE) ? angle : -1.0;
 }
 
 
-// ─── pick ───────────────────────────────────────────────────────────────────
-//
-// Walks each registry separately, finds the single best (smallest angle) hit
-// across all of them, returns a PickResult identifying which list it came
-// from and where in that list. The picker NEVER mutates a registry — the
-// caller is responsible for moving the picked entity into a carry / anim /
-// etc. based on the PickResult.
 PickResult
 pick(const Camera& camera,
      const DynArray<Text3dPtr>&     words,
@@ -75,20 +64,17 @@ pick(const Camera& camera,
 {
     const Vec3& eye = camera.pos;
 
-    // Floor plane. Words/wall-text scrolled (or fallen) below the floor are
-    // hidden under it but still angle-pickable, so exclude anything whose
-    // centre has dropped beneath the floor surface.
     const double floor_y = World::get_FloorY();
 
     PickResult result;
-    double best_angle = MAX_ANGLE;   // any actual hit must beat this
+    double best_angle = MAX_ANGLE;
 
-    // ── words ───────────────────────────────────────────────────────────
     for (size_t i = 0; i < words.size(); ++i) {
         const Text3dPtr& w = words[i];
         if (!w || !w->interactable) continue;
-        if (w->ai.state != Text3dAI::State::Idle) continue;
-        if (w->pos.y < floor_y) continue;   // below the floor → not pickable
+        if (w->ai.state != Text3dAI::State::Idle)
+                                    continue;
+        if (w->pos.y < floor_y)     continue;
 
         double a = ang_score(*w, eye, camera.fwd);
         if (a >= 0.0 && a < best_angle) {
@@ -98,10 +84,9 @@ pick(const Camera& camera,
         }
     }
 
-    // ── scenery ─────────────────────────────────────────────────────────
     for (const GameObjectPtr& s : scenery) {
         if (!s || !s->interactable) continue;
-        if (s->pos.y < floor_y) continue;   // below the floor → not pickable
+        if (s->pos.y < floor_y)     continue;
         double a = ang_score(*s, eye, camera.fwd);
         if (a >= 0.0 && a < best_angle) {
             best_angle         = a;
@@ -110,11 +95,10 @@ pick(const Camera& camera,
         }
     }
 
-    // ── walls ───────────────────────────────────────────────────────────
     for (size_t i = 0; i < wall_texts.size(); ++i) {
         const TextWallPtr& wt = wall_texts[i];
-        if (!wt || !wt->text3d) continue;
-        if (wt->text3d->pos.y < floor_y) continue;   // scrolled below the floor → not pickable
+        if (!wt || !wt->text3d)          continue;
+        if (wt->text3d->pos.y < floor_y) continue;
         double a = ang_score(*wt->text3d, eye, camera.fwd);
         if (a >= 0.0 && a < best_angle) {
             best_angle       = a;
diff --git a/src/systems/projectile_system.cpp b/src/systems/projectile_system.cpp
index fb73e57..356a364 100644
--- a/src/systems/projectile_system.cpp
+++ b/src/systems/projectile_system.cpp
@@ -60,7 +60,6 @@ wall_reconstruct(Wall::Position p, double plane, double tangent, double y)
 }
 
 
-// ── Helper: emit a Floor landing result and mark the projectile for removal ──
 static void
 emit_FloorLanding(Projectile& p, DynArray<ProjectileResult>& results)
 {
@@ -72,11 +71,6 @@ emit_FloorLanding(Projectile& p, DynArray<ProjectileResult>& results)
 }
 
 
-// ── Helper: advance one sticking projectile's smoothing animation ────────────
-//
-// Words exponentially smooth toward their final wall positions. When stick_t
-// reaches 1 we emit a Wall landing result; GameState transfers the words to
-// TextWall. Returns nothing — completion is detected via emptied p.words.
 static void
 tick_Sticking(Projectile& p, double dt, double ws,
               DynArray<ProjectileResult>& results)
@@ -93,13 +87,12 @@ tick_Sticking(Projectile& p, double dt, double ws,
         if (!w || w->type != ObjectType::Text) continue;
 
         Vec3 target = wall_reconstruct(p.stick_wall, plane,
-                           w->ribbon_local.x,
-                           w->ribbon_local.y);
+                                       w->ribbon_local.x,
+                                       w->ribbon_local.y);
 
-        w->pos = lerp(w->pos, target, k);
-        w->yaw = static_cast<float>(lerp(
-                        static_cast<double>(w->yaw),
-                        static_cast<double>(fy), k));
+        w->pos = Math::lerp(w->pos, target, k);
+        w->yaw = static_cast<float>(Math::lerp(static_cast<double>(w->yaw),
+                                               static_cast<double>(fy), k));
     }
 
     if (p.stick_t >= 1.0) {
@@ -113,12 +106,6 @@ tick_Sticking(Projectile& p, double dt, double ws,
 }
 
 
-// ── Helper: floor / ceiling test for a flying projectile ─────────────────────
-//
-// Floor landing fires only when the word's lowest point reaches the floor
-// plane. Anywhere above the floor — including on top of a pult — the
-// projectile keeps flying / bouncing. Ceiling bounce reflects Y velocity.
-// Returns true if the projectile should be removed (floor landing emitted).
 static bool
 check_FloorCeiling(Projectile& p, const Vec3& centroid, double ws,
                    DynArray<ProjectileResult>& results)
@@ -142,8 +129,6 @@ check_FloorCeiling(Projectile& p, const Vec3& centroid, double ws,
 }
 
 
-// ── Helper: which wall (if any) does the projectile cross this frame? ────────
-// Sets out_pos when it returns true.
 static bool
 detect_WallHit(const Projectile& p, const Vec3& centroid, double dt, double ws,
                Wall::Position& out_pos)
@@ -151,7 +136,7 @@ detect_WallHit(const Projectile& p, const Vec3& centroid, double dt, double ws,
     const double next_x = centroid.x + p.vel.x * dt;
     const double next_z = centroid.z + p.vel.z * dt;
 
-    if ((centroid.x > -ws + ConfigPhysics::stick_dist && next_x <= -ws + ConfigPhysics::stick_dist) ||
+    if ((centroid.x >  -ws + ConfigPhysics::stick_dist && next_x <= -ws + ConfigPhysics::stick_dist) ||
         (centroid.x <= -ws + ConfigPhysics::stick_dist && p.vel.x < 0.0))
         { out_pos = Wall::Position::NegX; return true; }
 
@@ -159,7 +144,7 @@ detect_WallHit(const Projectile& p, const Vec3& centroid, double dt, double ws,
         (centroid.x >= ws - ConfigPhysics::stick_dist && p.vel.x > 0.0))
         { out_pos = Wall::Position::PosX; return true; }
 
-    if ((centroid.z > -ws + ConfigPhysics::stick_dist && next_z <= -ws + ConfigPhysics::stick_dist) ||
+    if ((centroid.z >  -ws + ConfigPhysics::stick_dist && next_z <= -ws + ConfigPhysics::stick_dist) ||
         (centroid.z <= -ws + ConfigPhysics::stick_dist && p.vel.z < 0.0))
         { out_pos = Wall::Position::NegZ; return true; }
 
@@ -171,9 +156,6 @@ detect_WallHit(const Projectile& p, const Vec3& centroid, double dt, double ws,
 }
 
 
-// ── Helper: does the projectile path cross a wall-text this frame? ───────────
-// Expands each wall-text AABB by the projectile's half-extents (Minkowski)
-// and sweeps the centroid ray against it. Sets out_idx on hit.
 static bool
 check_WallTextIntercept(const Projectile& p, const Vec3& centroid, double dt,
                         Wall::Position hit_pos,
@@ -213,7 +195,6 @@ check_WallTextIntercept(const Projectile& p, const Vec3& centroid, double dt,
 }
 
 
-// ── Helper: begin the editor-wall stick animation for a projectile ───────────
 static void
 begin_EditorStick(Projectile& p, Wall::Position hit_pos)
 {
@@ -235,12 +216,6 @@ begin_EditorStick(Projectile& p, Wall::Position hit_pos)
     const double dot  = cr_x * wt_x + cr_z * wt_z;
     const double sign = (dot >= 0.0) ? 1.0 : -1.0;
 
-    // Crosshair aim point on the wall: intersect the CAMERA ray (cam_origin
-    // along dir) with the wall plane. Using the camera ray rather than the
-    // line's centroid means the run merges where the crosshair points — the
-    // carried line is laid out from its anchor, so its centroid sits ~half a
-    // line-width off the aim, which is what dragged the merge sideways. This
-    // also gives the aimed-at height with no gravity soak at any distance.
     const Vec3   c_pos  = Text3d::words_centroid(p.words);
     const double plane  = wall_plane_coord(hit_pos, World::get_BoxScale());
     const bool   x_wall = (hit_pos == Wall::Position::NegX || hit_pos == Wall::Position::PosX);
@@ -250,12 +225,13 @@ begin_EditorStick(Projectile& p, Wall::Position hit_pos)
 
     Vec3 aim;
     if (SDL_fabs(dir_coord) > 1e-6) {
-        const double t = (plane - cam_coord) / dir_coord;   // steps along the aim ray
+        const double t = (plane - cam_coord) / dir_coord;
         aim = Vec3{ p.cam_origin.x + p.dir.x * t,
                     p.cam_origin.y + p.dir.y * t,
                     p.cam_origin.z + p.dir.z * t };
-    } else {
-        aim = c_pos;   // aiming parallel to the wall; fall back to the centroid
+    }
+    else {
+        aim = c_pos;
     }
 
     const double c_tan = wall_tangent(hit_pos, aim.x, aim.z);
@@ -273,10 +249,6 @@ begin_EditorStick(Projectile& p, Wall::Position hit_pos)
 }
 
 
-// ── Helper: begin the program-wall "input echo" stick ────────────────────────
-// Like the editor stick, but aimed at the program wall's output line (centred,
-// at the bottom row where new output appears) regardless of where it was hit —
-// so a consumed input word glides into place like text typed at a terminal.
 static void
 begin_ProgramStick(Projectile& p, double ws)
 {
@@ -288,12 +260,12 @@ begin_ProgramStick(Projectile& p, double ws)
 
     const double cr_x =  SDL_cos(p.yaw);
     const double cr_z = -SDL_sin(p.yaw);
-    const double wt_z = -1.0;                 // PosX wall inward tangent
+    const double wt_z = -1.0;
     const double dot  = cr_x * 0.0 + cr_z * wt_z;
     const double sign = (dot >= 0.0) ? 1.0 : -1.0;
 
-    const double c_tan = 0.0;                 // centred horizontally on the wall
-    const double c_y   = -ws + 1.0;           // matches ProgramSystem::start_y
+    const double c_tan = 0.0;
+    const double c_y   = -ws + 1.0;
 
     for (Text3dPtr& w : p.words) {
         if (!w || w->type != ObjectType::Text) continue;
@@ -306,9 +278,6 @@ begin_ProgramStick(Projectile& p, double ws)
 }
 
 
-// ── Helper: bounce a projectile off a non-editor wall ────────────────────────
-// Returns true if the projectile should be removed (second bounce on this
-// axis → falls to the floor instead of bouncing again).
 static bool
 bounce_OffWall(Projectile& p, Wall::Position hit_pos, double ws,
                DynArray<ProjectileResult>& results)
@@ -323,27 +292,26 @@ bounce_OffWall(Projectile& p, Wall::Position hit_pos, double ws,
     }
 
     p.bounce_state |= axis_bit;
-    p.collided = true;
+    p.collided      = true;
 
     if (x_axis) {
         p.vel.x = bounce_velocity(p.vel.x, 0.70);
         for (Text3dPtr& w : p.words) if (w)
             w->pos.x = (hit_pos == Wall::Position::PosX)
-                ? ( ws - ConfigPhysics::stick_dist - 0.05)
-                : (-ws + ConfigPhysics::stick_dist + 0.05);
-    } else {
+                     ? ( ws - ConfigPhysics::stick_dist - 0.05)
+                     : (-ws + ConfigPhysics::stick_dist + 0.05);
+    }
+    else {
         p.vel.z = bounce_velocity(p.vel.z, 0.70);
         for (Text3dPtr& w : p.words) if (w)
             w->pos.z = (hit_pos == Wall::Position::PosZ)
-                ? ( ws - ConfigPhysics::stick_dist - 0.05)
-                : (-ws + ConfigPhysics::stick_dist + 0.05);
+                     ? ( ws - ConfigPhysics::stick_dist - 0.05)
+                     : (-ws + ConfigPhysics::stick_dist + 0.05);
     }
     return false;
 }
 
 
-// ── Helper: handle a wall hit — intercept, stick, or bounce ──────────────────
-// Returns true if the projectile should be removed.
 static bool
 handle_WallHit(Projectile& p, const Vec3& centroid, Wall::Position hit_pos,
                double dt,double ws,
@@ -351,19 +319,11 @@ handle_WallHit(Projectile& p, const Vec3& centroid, Wall::Position hit_pos,
                DynArray<ProjectileResult>& results,
                bool program_running)
 {
-    // Program wall (+X): a thrown word is terminal INPUT.
-    //   - program running → it will be read: stick and glide to the output
-    //     line (the "soaked" animation); GameState then feeds stdin + echoes it.
-    //   - not running      → nothing to read it: bounce off as normal.
     if (Wall::role_of(hit_pos) == Wall::Role::Program) {
         if (program_running) { begin_ProgramStick(p, ws); return false; }
         return bounce_OffWall(p, hit_pos, ws, results);
     }
 
-    // Wall-text intercept takes priority — but ONLY for a single-word shot,
-    // which is what knocks an existing word down or hits a line number. A whole
-    // shot LINE must never knock a word off; it always sticks (and merges) or
-    // bounces, so skip the intercept when carrying more than one word.
     size_t hit_idx = 0;
     if (p.words.size() == 1 &&
         check_WallTextIntercept(p, centroid, dt, hit_pos, wall_text_hits, hit_idx)) {
@@ -388,10 +348,10 @@ handle_WallHit(Projectile& p, const Vec3& centroid, Wall::Position hit_pos,
 
 void
 ProjectileSystem::launch(DynArray<Projectile>&   out,
-                DynArray<Text3dPtr> words,
-                const Vec3& fwd,
-                const Vec3& eye,
-                const Aim::Result& aim)
+                         DynArray<Text3dPtr> words,
+                         const Vec3& fwd,
+                         const Vec3& eye,
+                         const Aim::Result& aim)
 {
     if (words.empty()) return;
 
@@ -422,10 +382,7 @@ ProjectileSystem::launch(DynArray<Projectile>&   out,
         };
     }
 
-    // ── Ballistic solve (method b): pick a flight time from horizontal
-    // distance, then solve the launch velocity so the centroid passes through
-    // `target` under constant gravity. Always one solution; lands on aim.
-    const Vec3   target = aim.point;
+    const Vec3   target= aim.point;
     const double g     = ConfigPhysics::proj_grav;
     const double dx    = target.x - centroid.x;
     const double dy    = target.y - centroid.y;
@@ -444,7 +401,6 @@ ProjectileSystem::launch(DynArray<Projectile>&   out,
     proj.cam_origin    = eye;
     proj.prev_centroid = centroid;
 
-    // Hard-track a movable word: steer to its live point until contact.
     if (aim.track) {
         proj.track_obj   = aim.track;
         proj.track_local = aim.local;
@@ -463,15 +419,12 @@ ProjectileSystem::update(DynArray<Projectile>&        projectiles,
 {
     const double ws = World::get_BoxScale<double>();
 
-    // ── 1. Advance stick animations ──────────────────────────────────────────
     for (Projectile& p : projectiles)
         tick_Sticking(p, dt, ws, results);
 
-    // ── 2. Flight: floor/ceiling, wall hit, then cleanup ─────────────────────
     for (auto it = projectiles.begin(); it != projectiles.end(); ) {
         Projectile& p = *it;
 
-        // Finished sticking projectiles: erase once words have been cleared.
         if (p.sticking) {
             if (p.words.empty()) it = projectiles.erase(it);
             else                 ++it;
@@ -492,14 +445,15 @@ ProjectileSystem::update(DynArray<Projectile>&        projectiles,
                                         wall_text_hits, results, program_running);
         }
 
-        if (!remove && !p.sticking && length(p.vel) < 1.0) {
+        if (!remove && !p.sticking && Math::length(p.vel) < 1.0) {
             emit_FloorLanding(p, results);
             remove = true;
         }
 
         if (remove) {
             it = projectiles.erase(it);
-        } else {
+        }
+        else {
             p.prev_centroid = centroid;
             ++it;
         }
diff --git a/src/systems/source_tokens.hpp b/src/systems/source_tokens.hpp
index a3642ea..f84ece3 100644
--- a/src/systems/source_tokens.hpp
+++ b/src/systems/source_tokens.hpp
@@ -6,19 +6,6 @@
 
 #include "utils/globals.hpp"
 
-// ─────────────────────────────────────────────────────────────────────────
-// SourceTokens — Option 1 tokenizer + file IO for the dynamic-lib sandbox.
-//
-// Tokenizing rule (matches the editor-wall "one word per token" model):
-//   - identifier/number runs (alnum, '.', '_') stay whole:  fuu  1.0  my_var
-//   - a quoted "..." string is one token (quotes kept, \" respected)
-//   - every other character is its own single-char token:    ( ) , ; # * { }
-//
-// Round-trips to valid C when rejoined with single spaces (verified: even
-// `# include "x.h"` and unary `- 3` compile). The editor wall stores each
-// token as a Text3d word; extract_Text rejoins them with spaces, so the
-// file written back on compile is space-normalized but compilable.
-// ─────────────────────────────────────────────────────────────────────────
 namespace SourceTokens
 {
 
@@ -26,7 +13,8 @@ inline DynArray<std::string>
 tokenize(const std::string& src)
 {
     DynArray<std::string> out;
-    const size_t n = src.size();
+    const
+    size_t n = src.size();
     size_t i = 0;
     while (i < n) {
         const char c = src[i];
@@ -56,7 +44,8 @@ tokenize(const std::string& src)
                 if (std::isalnum(static_cast<unsigned char>(d)) || d == '.' || d == '_') {
                     s += d;
                     ++i;
-                } else {
+                }
+                else {
                     break;
                 }
             }
diff --git a/src/systems/wall_connection.cpp b/src/systems/wall_connection.cpp
index a906076..f719601 100644
--- a/src/systems/wall_connection.cpp
+++ b/src/systems/wall_connection.cpp
@@ -186,7 +186,8 @@ WallConnection::rebuild_Editor()
             rows[i].txt->pos.y = row_y;
             rows[i].txt->pos.z = z_block_left - code_u0 - he;
             _render.push_back(std::move(rows[i].txt));
-        } else {
+        }
+        else {
             _render.push_back(Text3dPtr{});
         }
     }
@@ -228,7 +229,8 @@ WallConnection::render(GlRenderer& gl, const Camera& cam, const Light& light) co
 
         draw_ProgramCursor(gl, cam, light);
         draw_Electric     (gl, cam);
-    } else if (_target == Target::Editor) {
+    }
+    else if (_target == Target::Editor) {
         for (const Text3dPtr& t : _render)   if (t) t->draw(gl, cam, light);
         for (const Text3dPtr& n : _linenums) if (n) n->draw(gl, cam, light);
 
@@ -284,7 +286,8 @@ WallConnection::draw_EditorCursor(GlRenderer& gl, const Camera& cam, const Light
         cw     = (2.0 * static_cast<double>(line->half_extent)) / static_cast<double>(N);
         line_x = line->pos.x;
         he_y   = static_cast<double>(line->half_extent_y);
-    } else {
+    }
+    else {
         cw = 0.18;
     }
 
diff --git a/src/systems/word_ai_system.cpp b/src/systems/word_ai_system.cpp
index ff2d1ea..6ceec1f 100644
--- a/src/systems/word_ai_system.cpp
+++ b/src/systems/word_ai_system.cpp
@@ -1,21 +1,19 @@
-#include "word_ai_system.hpp"
-
 #include <SDL3/SDL.h>
 #include <cstdlib>
 
 #include "c_token/token_color.hpp"
 #include "entities/player.hpp"
+#include "entities/world.hpp"
 #include "systems/carry_system.hpp"
 #include "systems/collision.hpp"
 #include "utils/config.hpp"
+#include "word_ai_system.hpp"
 
 
 
 static Vec3
 perpendicular_horizontal(const Vec3& v)
 {
-    // Horizontal perpendicular (rotated 90° around Y).
-    // Used for wiggle — vertical wiggle would look weird.
     return { -v.z, 0.0, v.x };
 }
 
@@ -29,21 +27,18 @@ WordAiSystem::update(DynArray<Text3dPtr>& words,
 {
     DynArray<Text3dPtr> released;
 
-    // Count AI-active words (Attack/Flee/Stunned all count as "active").
     int active_ai_count = 0;
     for (const Text3dPtr& w : words) {
         if (!w) continue;
         if (w->ai.state != Text3dAI::State::Idle) ++active_ai_count;
     }
 
-    // Index-based loop so reallocation doesn't invalidate.
-    // Capture size before the loop so newly-appended items wait until next frame.
     const size_t n = words.size();
     for (size_t i = 0; i < n; ++i) {
         Text3dPtr& w = words[i];
         if (!w) continue;
 
-        if (w->ai.state != Text3dAI::State::Idle &&
+        if (w->ai.state  != Text3dAI::State::Idle &&
             w->body.mode != PhysicsMode::AiHover &&
             w->body.mode != PhysicsMode::Hover)
         {
@@ -52,7 +47,7 @@ WordAiSystem::update(DynArray<Text3dPtr>& words,
                 s->body.mode = PhysicsMode::Dynamic;
                 s->body.vel  = w->body.vel * 0.5;
                 s->set_Color(s->token_info ? TokenColor::get(s->token_info->type) : ConfigColor::floor);
-                released.push_back(std::move(s));   // deferred — not words.push_back
+                released.push_back(std::move(s));
             }
             w->ai.stolen.clear();
             w->ai.state = Text3dAI::State::Idle;
@@ -63,11 +58,11 @@ WordAiSystem::update(DynArray<Text3dPtr>& words,
         w->ai.state_timer += dt;
 
         switch (w->ai.state) {
-            case Text3dAI::State::Idle:    update_Idle(*w, player, active_ai_count, dt); break;
-            case Text3dAI::State::Attack:  update_Attack(*w, player, carried, words, dropped, released, dt);
-                                                                                    break;
-            case Text3dAI::State::Flee:    update_Flee(*w, player, released, dt);        break;
-            case Text3dAI::State::Stunned: update_Stunned(*w, released, dt);             break;
+            case Text3dAI::State::Idle:    update_Idle   (*w, player, active_ai_count, dt); break;
+            case Text3dAI::State::Attack:  update_Attack (*w, player, carried, words, dropped, released, dt);
+                                                                                            break;
+            case Text3dAI::State::Flee:    update_Flee   (*w, player, released, dt);        break;
+            case Text3dAI::State::Stunned: update_Stunned(*w, released, dt);                break;
         }
 
         update_StolenTrail(*w, dt);
@@ -84,13 +79,12 @@ WordAiSystem::update_Idle(Text3d& w, const Player& p, int active_ai_count, doubl
 {
     if (w.body.mode != PhysicsMode::Hover) return;
 
-    // Hard cap: don't start new AI behavior if we're already at the limit.
     if (active_ai_count >= _max_active_ai) return;
 
     Vec3 to_player = p.pos - w.pos;
     double dist_sq = to_player.x*to_player.x +
-        to_player.y*to_player.y +
-        to_player.z*to_player.z;
+                     to_player.y*to_player.y +
+                     to_player.z*to_player.z;
 
     if (dist_sq > ConfigAi::trigger_range * ConfigAi::trigger_range) return;
 
@@ -113,7 +107,8 @@ void WordAiSystem::update_Attack(Text3d& w, const Player& p, CarriedLine& carrie
     Vec3 target;
     if (has_carry) {
         target = carried.last->word->pos;
-    } else {
+    }
+    else {
         constexpr double ORBIT_RADIUS = 4.5;
         constexpr double ORBIT_SPEED  = 0.6;
         constexpr double ORBIT_HEIGHT = 0.5;
@@ -128,12 +123,11 @@ void WordAiSystem::update_Attack(Text3d& w, const Player& p, CarriedLine& carrie
     }
 
     Vec3 to_target = target - w.pos;
-    double dist = length(to_target);
+    double dist = Math::length(to_target);
 
-    // Pause/dash phase machine (unchanged)
     w.ai.phase_timer -= dt;
     if (w.ai.phase_timer <= 0.0) {
-        w.ai.in_pause = !w.ai.in_pause;
+        w.ai.in_pause    = !w.ai.in_pause;
         w.ai.phase_timer = w.ai.in_pause
                            ? (0.4 + Random::unit() * 0.8)
                            : (1.0 + Random::unit() * 1.5);
@@ -142,24 +136,23 @@ void WordAiSystem::update_Attack(Text3d& w, const Player& p, CarriedLine& carrie
     Vec3 target_vel{};
     if (!w.ai.in_pause && dist > 0.01) {
         double inv = 1.0 / dist;
-        Vec3 dir = { to_target.x * inv, to_target.y * inv, to_target.z * inv };
+        Vec3   dir = { to_target.x * inv, to_target.y * inv, to_target.z * inv };
         target_vel = dir * w.ai.speed;
 
         w.ai.wiggle_phase += w.ai.wiggle_freq * dt;
-        Vec3 perp = perpendicular_horizontal(dir);
-        double wig = SDL_sin(w.ai.wiggle_phase) * ConfigAi::wiggle_amplitude;
-        if (!has_carry) wig *= 0.4;   // gentler wobble while orbiting
+        Vec3   perp = perpendicular_horizontal(dir);
+        double wig  = SDL_sin(w.ai.wiggle_phase) * ConfigAi::wiggle_amplitude;
+        if (!has_carry) wig *= 0.4;
         target_vel.x += perp.x * wig;
         target_vel.z += perp.z * wig;
     }
 
     apply_Locomotion(w, target_vel, dt);
 
-    // ── Contact: attacker touches carried word? ──────────────────────
     if (!carried.empty()) {
         if (w.ai.has_stolen) {
-            // Already stole this session — touching carry does nothing.
-        } else {
+        }
+        else {
             DynArray<CarriedWordNode*> nodes = carried.reverse_nodes();
             for (CarriedWordNode* node : nodes) {
                 if (!node || !node->word) continue;
@@ -170,11 +163,10 @@ void WordAiSystem::update_Attack(Text3d& w, const Player& p, CarriedLine& carrie
                     stolen->body.mode = PhysicsMode::AiHover;
                     stolen->set_Color(ConfigColor::attack);
                     w.ai.stolen.push_back(std::move(stolen));
-                    enter_Flee(w);   // run away with the loot
+                    enter_Flee(w);
                     carried.compact();
                     break;
                 }  else {
-                    // failed steal: knock the word off and flee
                     Text3dPtr knocked = std::move(node->word);
                     knocked->body.mode = PhysicsMode::Dynamic;
                     knocked->body.vel  = { 0.0, 2.0, 0.0 };
@@ -187,30 +179,28 @@ void WordAiSystem::update_Attack(Text3d& w, const Player& p, CarriedLine& carrie
         }
     }
 
-    // ── Bowl over Idle words ─────────────────────────────────────────
-    // (Runs regardless of whether the player is carrying anything.)
     for (Text3dPtr& other : all_words) {
-        if (!other) continue;
-        if (other.get() == &w) continue;
-        if (other->ai.state != Text3dAI::State::Idle)    continue;
-        if (other->body.mode != PhysicsMode::Hover) continue;
-        if (!Collision::aabb_Overlap(w, *other))    continue;
+        if (!other)                                  continue;
+        if (other.get() == &w)                       continue;
+        if (other->ai.state != Text3dAI::State::Idle)continue;
+        if (other->body.mode != PhysicsMode::Hover)  continue;
+        if (!Collision::aabb_Overlap(w, *other))     continue;
+
+        Vec3   push_dir = other->pos - w.pos;
 
-        Vec3 push_dir = other->pos - w.pos;
         double d = SDL_sqrt(push_dir.x*push_dir.x + push_dir.z*push_dir.z);
         if (d < 0.01) { push_dir = { 1.0, 0.0, 0.0 }; d = 1.0; }
         push_dir.x /= d;
         push_dir.z /= d;
 
-        double kick_speed = SDL_max(length(w.body.vel) * 1.5, 3.0);
+        double kick_speed = SDL_max(Math::length(w.body.vel) * 1.5, 3.0);
         other->body.apply_KickImpulse({
-                push_dir.x * kick_speed, 1.5, push_dir.z * kick_speed
+                    push_dir.x * kick_speed, 1.5, push_dir.z * kick_speed
                 });
     }
 
-    // ── Give up if player is too far ─────────────────────────────────
     Vec3 to_player = p.pos - w.pos;
-    if (length(to_player) > ConfigAi::trigger_range * 3.0) {
+    if (Math::length(to_player) > ConfigAi::trigger_range * 3.0) {
         release_StolenWords(w, released);
         enter_Stunned(w);
     }
@@ -221,12 +211,11 @@ void
 WordAiSystem::update_Flee(Text3d& w, const Player& p, DynArray<Text3dPtr>& released, double dt)
 {
     Vec3 away = w.pos - p.pos;
-    double dist = length(away);
+    double dist = Math::length(away);
 
-    // Pause/dash similar to attack
     w.ai.phase_timer -= dt;
     if (w.ai.phase_timer <= 0.0) {
-        w.ai.in_pause = !w.ai.in_pause;
+        w.ai.in_pause    = !w.ai.in_pause;
         w.ai.phase_timer = w.ai.in_pause
                            ? (0.3 + Random::unit() * 0.5)
                            : (1.5 + Random::unit() * 1.5);
@@ -235,7 +224,7 @@ WordAiSystem::update_Flee(Text3d& w, const Player& p, DynArray<Text3dPtr>& relea
     Vec3 target_vel{};
     if (!w.ai.in_pause && dist > 0.01) {
         double inv = 1.0 / dist;
-        Vec3 dir = { away.x * inv, 0.0, away.z * inv };   // horizontal flee
+        Vec3   dir = { away.x * inv, 0.0, away.z * inv };
         target_vel = dir * w.ai.speed * 1.2;
 
         w.ai.wiggle_phase += w.ai.wiggle_freq * dt;
@@ -247,18 +236,15 @@ WordAiSystem::update_Flee(Text3d& w, const Player& p, DynArray<Text3dPtr>& relea
 
     apply_Locomotion(w, target_vel, dt);
 
-    // Escape condition: far enough, for long enough.
     if (dist > ConfigAi::flee_escape_dist) {
         if (w.ai.state_timer > ConfigAi::flee_escape_time) {
-            // Got away. If carrying loot, roll for drop-vs-keep.
             if (!w.ai.stolen.empty()) {
                 if (Random::unit() < ConfigAi::drop_loot_probability) {
                     release_StolenWords(w, released);
                 }
-                // Whether we dropped or kept, come back for another attack.
                 enter_Attack(w);
-            } else {
-                // No loot — flee finished naturally.
+            }
+            else {
                 enter_Idle(w);
             }
         }
@@ -294,16 +280,15 @@ WordAiSystem::release_StolenWords(Text3d& w, DynArray<Text3dPtr>& out)
 void
 WordAiSystem::enter_Attack(Text3d& w)
 {
-    w.ai.state             = Text3dAI::State::Attack;
-    w.ai.state_timer       = 0.0;
-    w.ai.phase_timer       = 0.5 + Random::unit() * 1.5;
-    w.ai.in_pause          = false;
-    w.ai.has_stolen        = false;
-    w.ai.hover_height_saved = w.body.hover_height;
-    w.body.mode            = PhysicsMode::AiHover;
     w.set_Color(ConfigColor::attack);
+    w.body.mode      = PhysicsMode::AiHover;
+    w.ai.state       = Text3dAI::State::Attack;
+    w.ai.state_timer = 0.0;
+    w.ai.phase_timer = 0.5 + Random::unit() * 1.5;
+    w.ai.in_pause    = false;
+    w.ai.has_stolen  = false;
+    w.ai.hover_height_saved = w.body.hover_height;
 
-    // Pick an orbit direction and starting angle for the no-carry wander.
     w.ai.orbit_angle = Random::unit() * SDL_PI_D * 2.0;
     w.ai.orbit_dir   = (Random::unit() < 0.5) ? -1.0 : 1.0;
 }
@@ -312,13 +297,13 @@ WordAiSystem::enter_Attack(Text3d& w)
 void
 WordAiSystem::enter_Flee(Text3d& w)
 {
-    w.ai.state             = Text3dAI::State::Flee;
-    w.ai.state_timer       = 0.0;
-    w.ai.phase_timer       = 0.3 + Random::unit() * 0.7;
-    w.ai.in_pause          = false;
-    w.ai.hover_height_saved = w.body.hover_height;
-    w.body.mode            = PhysicsMode::AiHover;
     w.set_Color(ConfigColor::flee);
+    w.body.mode      = PhysicsMode::AiHover;
+    w.ai.state       = Text3dAI::State::Flee;
+    w.ai.state_timer = 0.0;
+    w.ai.phase_timer = 0.3 + Random::unit() * 0.7;
+    w.ai.in_pause    = false;
+    w.ai.hover_height_saved = w.body.hover_height;
 }
 
 
@@ -355,8 +340,7 @@ WordAiSystem::apply_Locomotion(Text3d& w, const Vec3& target_vel, double dt)
     w.pos.y += w.body.vel.y * dt;
     w.pos.z += w.body.vel.z * dt;
 
-    // Clamp to world bounds
-    const double ws = static_cast<double>(_world_scale);
+    const double ws = World::get_BoxScale<double>();
 
     auto clamp_axis = [](double& p, double& v, double he,
                          double lo, double hi) {
@@ -430,6 +414,5 @@ WordAiSystem::update_StolenTrail(Text3d& w, double dt)
         offset += static_cast<double>(s->half_extent);
     }
 
-    // Tick hover_phase so bob/sway animate even when attacker is paused
     w.body.hover_phase += ConfigText3d::hover_speed * dt;
 }
diff --git a/src/systems/word_ai_system.hpp b/src/systems/word_ai_system.hpp
index 0003aa2..3eed820 100644
--- a/src/systems/word_ai_system.hpp
+++ b/src/systems/word_ai_system.hpp
@@ -8,7 +8,6 @@ struct CarriedLine;
 
 class WordAiSystem {
 
-    float _world_scale;
     int   _max_active_ai = 5;
 
 
@@ -33,7 +32,6 @@ class WordAiSystem {
     void apply_Locomotion(Text3d& w, const Vec3& target_vel, double dt);
 public:
     void set_MaxActiveAi(int n)    { _max_active_ai = n; }
-    void set_WorldScale (float ws) { _world_scale = ws; }
     void update(DynArray<Text3dPtr>& words,
                 const Player& player,
                 CarriedLine& carried,
diff --git a/src/systems/word_anim.cpp b/src/systems/word_anim.cpp
index 07ddd8f..def8a7a 100644
--- a/src/systems/word_anim.cpp
+++ b/src/systems/word_anim.cpp
@@ -34,7 +34,8 @@ WordAnimSystem::update(DynArray<WordAnim_Add>&    anims_add,
             anim.word->yaw = static_cast<float>(anim.yaw_target);
             anim.word->pitch = static_cast<float>(anim.pitch_target);
             carried.push(std::move(anim.word));
-        } else {
+        }
+        else {
             double s       = smoothstep(anim.t);
             anim.word->pos = {
                 lerp_d(anim.start_pos.x, anim.target_pos.x, s),
@@ -55,13 +56,11 @@ WordAnimSystem::update(DynArray<WordAnim_Add>&    anims_add,
     for (WordAnim_Drop& drop : anims_drop) {
         if (drop.complete) continue;
 
-        // Integrate: gravity + position update.
         drop.word->body.vel.y -= ConfigPhysics::proj_grav * dt;
         drop.word->pos.x += drop.word->body.vel.x * dt;
         drop.word->pos.y += drop.word->body.vel.y * dt;
         drop.word->pos.z += drop.word->body.vel.z * dt;
 
-        // Account for the word's own thickness — land when the BOTTOM touches floor.
         const double bottom = drop.word->pos.y - drop.word->shape.half_extents.y;
         if (bottom <= floor_y) {
             drop.complete          = true;
diff --git a/src/text_3d/text_3d.cpp b/src/text_3d/text_3d.cpp
index 5d56dbd..2b26986 100644
--- a/src/text_3d/text_3d.cpp
+++ b/src/text_3d/text_3d.cpp
@@ -261,7 +261,8 @@ Text3d::draw(GlRenderer& gl, const Camera& camera, const Light& light) const
             for (int i = 0; i < SPARKLE_TRAIL; ++i) sparkle_trail[i] = pos;
             sparkle_trail_count = SPARKLE_TRAIL;
             sparkle_last_ms     = now;
-        } else if (now - sparkle_last_ms >= 33) {              // ~30 Hz
+        }
+        else if (now - sparkle_last_ms >= 33) {              // ~30 Hz
             for (int i = SPARKLE_TRAIL - 1; i > 0; --i)
                 sparkle_trail[i] = sparkle_trail[i - 1];
             sparkle_trail[0] = pos;
diff --git a/src/text_3d/text_label.cpp b/src/text_3d/text_label.cpp
index 46aed0b..69f23ef 100644
--- a/src/text_3d/text_label.cpp
+++ b/src/text_3d/text_label.cpp
@@ -38,11 +38,11 @@ TextLabel::set_Text(const std::string& text,
 void
 TextLabel::clear()
 {
-    _words.clear();
-    _offsets.clear();
-    _anchor_pos.clear();
-    _jiggle_off.clear();
-    _jiggle_vel.clear();
+    _words       .clear();
+    _offsets     .clear();
+    _anchor_pos  .clear();
+    _jiggle_off  .clear();
+    _jiggle_vel  .clear();
     _current_text.clear();
 }
 
@@ -160,48 +160,26 @@ TextLabel::update(double dt, const Camera& camera)
 {
     if (_words.empty()) return;
 
-    Vec3 centre = current_Centre();
-
-    // ── Compute orientation ─────────────────────────────────────────────
-    //
-    // Billboard mode: the line of glyphs sits on the horizontal `right`
-    // axis (no positional tilt), and each glyph is rotated to face the
-    // camera with both yaw (around world Y) AND pitch (after yaw, around
-    // the rotated X axis). Because every glyph shares the same yaw+pitch,
-    // the whole line reads as a single rigid plane facing the player.
-    //
-    // Non-billboard: fixed yaw, zero pitch.
-
-    Vec3  right{1, 0, 0};
+    Vec3  centre           = current_Centre();
+    Vec3  right            {1, 0, 0};
     float yaw_for_glyphs   = 0.0f;
     float pitch_for_glyphs = 0.0f;
 
     if (_billboard) {
-        Vec3 forward = camera.pos - centre;
-        double flen = length(forward);
+        Vec3   forward = camera.pos - centre;
+        double flen    = Math::length(forward);
         if (flen < 0.0001) return;
+
         forward = forward / flen;
 
-        // right = normalize(world_up × forward). With world_up = (0,1,0)
-        // this is always horizontal (right.y == 0), so the line of glyphs
-        // is a level horizontal sweep. The vertical "tilt" of the label
-        // comes from each glyph's pitch, not from the line geometry.
-        right = cross(Vec3{0, 1, 0}, forward);
-        double rlen = length(right);
+        right = Math::cross(Vec3{0, 1, 0}, forward);
+        double rlen = Math::length(right);
         if (rlen < 0.0001) return;
         right = right / rlen;
 
-        // Yaw: turn around world Y so the glyph's local -Z (its face
-        // normal) points back toward the camera horizontally.
         yaw_for_glyphs = SDL_atan2f(static_cast<float>(forward.x),
                                     static_cast<float>(forward.z));
 
-        // Pitch: tilt forward/back so the glyph face also points up/down
-        // toward the camera. forward.y > 0 means the camera is above the
-        // label, so the label should tilt its top toward the camera.
-        // Using the 3-arg buildModelMat4 (T · Ry · Rx), positive pitch
-        // tilts the local +Y toward local -Z (i.e. forward), which is
-        // what we want when the camera is above.
         pitch_for_glyphs = -SDL_asinf(static_cast<float>(forward.y));
     } else {
         yaw_for_glyphs   = _face_yaw;
@@ -209,14 +187,12 @@ TextLabel::update(double dt, const Camera& camera)
         right = { SDL_cos(_face_yaw), 0.0, -SDL_sin(_face_yaw) };
     }
 
-    // ── Place each word at anchor + jiggle, apply shared orientation ────
     for (size_t i = 0; i < _words.size(); ++i) {
         Text3d& t = *_words[i];
         if (!t.loaded) continue;
 
         double off = _offsets[i];
 
-        // Line stays on the horizontal `right` axis through centre.
         Vec3 anchor{
             centre.x + right.x * off,
             centre.y + right.y * off,
@@ -224,7 +200,6 @@ TextLabel::update(double dt, const Camera& camera)
         };
         _anchor_pos[i] = anchor;
 
-        // Spring-damp the jiggle
         Vec3& off3 = _jiggle_off[i];
         Vec3& vel3 = _jiggle_vel[i];
 
diff --git a/src/text_3d/text_mesh.cpp b/src/text_3d/text_mesh.cpp
index ec35f5d..a3d8373 100644
--- a/src/text_3d/text_mesh.cpp
+++ b/src/text_3d/text_mesh.cpp
@@ -196,7 +196,8 @@ void computeVertexNormals(TextMesh& mesh)
         double len = SDL_sqrt(n.x*n.x + n.y*n.y + n.z*n.z);
         if (len > 0.000001) {
             n.x /= len; n.y /= len; n.z /= len;
-        } else {
+        }
+        else {
             n = {0, 0, -1}; // fallback: face forward
         }
     }
diff --git a/src/text_3d/vim_buffer.hpp b/src/text_3d/vim_buffer.hpp
index 0b292c8..d8f4d39 100644
--- a/src/text_3d/vim_buffer.hpp
+++ b/src/text_3d/vim_buffer.hpp
@@ -1,13 +1,9 @@
 #pragma once
-// Dependency-free vim editing model: lines of text, a cursor, modes, and the
-// agreed motion/edit subset. No rendering, no game types — GameState drives it
-// and reads `lines()`/`row()`/`col()` to render. `version()` bumps on any change
-// so the caller knows when to re-render. Signals (Exit/Help/Write) surface
-// commands the host must act on.
 
+#include <algorithm>
+#include <cstdint>
 #include <string>
 #include <vector>
-#include <cctype>
 
 class VimBuffer {
 public:
@@ -22,7 +18,6 @@ public:
         _sig = Signal::None; ++_version;
     }
 
-    // ── feed (call in input order) ──────────────────────────────────────────
     void key_char(char c) {
         if      (_mode == Mode::Insert)  { insert_Char(c); }
         else if (_mode == Mode::Command) { _cmd.push_back(c); touch(); }
@@ -45,16 +40,16 @@ public:
         clampCol(); touch();
     }
 
-    // ── host accessors ──────────────────────────────────────────────────────
-    const std::vector<std::string>& lines() const { return _lines; }
-    int          row()      const { return _row; }
-    int          col()      const { return _col; }
-    Mode         mode()     const { return _mode; }
-    unsigned     version()  const { return _version; }
-    bool         is_Empty() const { return _lines.size() == 1 && _lines[0].empty(); }
-    void         start_Insert()   { _mode = Mode::Insert; _col = 0; touch(); }
-    const std::string& cmdline() const { return _cmd; }     // includes leading ':'
-    const std::string& status()  const { return _status; }
+    const std::vector<std::string>&
+                       lines()    const { return _lines; }
+    int                row()      const { return _row; }
+    int                col()      const { return _col; }
+    Mode               mode()     const { return _mode; }
+    unsigned           version()  const { return _version; }
+    bool               is_Empty() const { return _lines.size() == 1 && _lines[0].empty(); }
+    void               start_Insert()   { _mode = Mode::Insert; _col = 0; touch(); }
+    const std::string& cmdline()  const { return _cmd; }
+    const std::string& status()   const { return _status; }
     Signal take_Signal() { Signal s = _sig; _sig = Signal::None; return s; }
 
 private:
@@ -62,8 +57,8 @@ private:
     int      _row = 0, _col = 0;
     Mode     _mode = Mode::Normal;
     int      _count = 0;
-    std::string _pending;          // "d" or "g" awaiting second key
-    std::string _cmd;              // command-line text (":...")
+    std::string _pending; // "d" or "g" awaiting second key
+    std::string _cmd;     // command-line text (":...")
     std::string _status;
     Signal   _sig = Signal::None;
     unsigned _version = 0;
@@ -78,7 +73,6 @@ private:
     }
     int  eff() const { return _count > 0 ? _count : 1; }
 
-    // ── Insert-mode edits ────────────────────────────────────────────────────
     void insert_Char(char c) {
         std::string& L = _lines[(size_t)_row];
         if (_col > (int)L.size()) _col = (int)L.size();
@@ -102,12 +96,12 @@ private:
         touch();
     }
 
-    // ── Normal-mode interpreter ───────────────────────────────────────────────
     void normal_Key(char c) {
         if (c == ':') { _mode = Mode::Command; _cmd = ":"; _status.clear(); touch(); return; }
 
         if (std::isdigit((unsigned char)c)) {
-            if (c == '0' && _count == 0 && _pending.empty()) { _col = 0; touch(); return; } // 0 = motion
+            if (c == '0' && _count == 0 && _pending.empty())
+                    { _col = 0; touch(); return; }
             _count = _count * 10 + (c - '0'); return;
         }
 
@@ -121,21 +115,21 @@ private:
         }
 
         switch (c) {
-            case 'h': _col -= eff(); break;
-            case 'l': _col += eff(); break;
+            case 'h': _col -= eff();                 break;
+            case 'l': _col += eff();                 break;
             case 'j': _row = clampRow(_row + eff()); break;
             case 'k': _row = clampRow(_row - eff()); break;
-            case '0': _col = 0; break;
+            case '0': _col = 0;                      break;
             case '$': _col = lineLen() > 0 ? lineLen() - 1 : 0; break;
-            case 'x': delete_Chars(eff()); break;
-            case 'i': _mode = Mode::Insert; break;
-            case 'a': _col = (lineLen() > 0 ? _col + 1 : 0); _mode = Mode::Insert; break;
-            case 'A': _col = lineLen(); _mode = Mode::Insert; break;
-            case 'o': open_Below(); _mode = Mode::Insert; break;
-            case 'O': open_Above(); _mode = Mode::Insert; break;
-            case 'G': _row = clampRow(_count > 0 ? _count - 1 : (int)_lines.size() - 1); break;
-            case 'd': _pending = "d"; return;
-            case 'g': _pending = "g"; return;
+            case 'x': delete_Chars(eff());           break;
+            case 'i': _mode = Mode::Insert;          break;
+            case 'a': _col = (lineLen() > 0 ? _col + 1 : 0); _mode = Mode::Insert;      break;
+            case 'A': _col = lineLen(); _mode = Mode::Insert;   break;
+            case 'o': open_Below(); _mode = Mode::Insert;       break;
+            case 'O': open_Above(); _mode = Mode::Insert;       break;
+            case 'G': _row = clampRow(_count > 0 ? _count - 1 : (int)_lines.size() - 1);break;
+            case 'd': _pending = "d";                return;
+            case 'g': _pending = "g";                return;
             default: break;
         }
         _count = 0; clampCol(); touch();
@@ -157,7 +151,6 @@ private:
     void open_Below() { _lines.insert(_lines.begin() + _row + 1, ""); ++_row; _col = 0; }
     void open_Above() { _lines.insert(_lines.begin() + _row,     ""); _col = 0; }
 
-    // ── command line ──────────────────────────────────────────────────────────
     void run_Command() {
         std::string c = _cmd.size() ? _cmd.substr(1) : "";   // strip ':'
         _cmd.clear(); _mode = Mode::Normal;
@@ -167,7 +160,8 @@ private:
         else if (!c.empty() && std::all_of(c.begin(), c.end(),
                  [](char ch){ return std::isdigit((unsigned char)ch); })) {
             _row = clampRow(std::stoi(c) - 1); clampCol();
-        } else _status = "not a command: " + c;
+        }
+        else _status = "not a command: " + c;
         touch();
     }
     void cancel_Command() { _cmd.clear(); _mode = Mode::Normal; touch(); }
diff --git a/src/utils/carry_math.cpp b/src/utils/carry_math.cpp
index 234eac6..ddbe43f 100644
--- a/src/utils/carry_math.cpp
+++ b/src/utils/carry_math.cpp
@@ -6,10 +6,8 @@
 Vec3
 CarryMath::line_Anchor(const Camera& camera, double carry_dist)
 {
-    // Right-hand carry pose. Camera has no `up`, so derive it: with `right`
-    // horizontal and `fwd` unit, cross(right, fwd) is the unit up vector.
     const Vec3& right = camera.right;
-    const Vec3  up    = cross(camera.right, camera.fwd);
+    const Vec3  up    = Math::cross(camera.right, camera.fwd);
 
     return {
         camera.pos.x + camera.fwd.x * carry_dist
@@ -23,10 +21,10 @@ CarryMath::line_Anchor(const Camera& camera, double carry_dist)
 
 
 DynArray<Vec3>
-CarryMath::slot_positions(const CarriedLine& carried,
-                                             const Vec3& anchor,
-                                             const Vec3& right,
-                                             double carry_gap)
+CarryMath::slot_Positions(const CarriedLine& carried,
+                          const Vec3& anchor,
+                          const Vec3& right,
+                          double carry_gap)
 {
     DynArray<Vec3> positions;
     DynArray<CarriedWordNode*> nodes = carried.reverse_nodes();
@@ -45,7 +43,7 @@ CarryMath::slot_positions(const CarriedLine& carried,
         });
 
         if (i + 1 < nodes.size() && nodes[i + 1]->word) {
-            double a = 0.5, b = 0.5;  // default fallback
+            double a = 0.5, b = 0.5;
 
             if (nodes[i]->word->type == ObjectType::Text)
                 a = static_cast<const Text3d&>(*nodes[i]->word).half_extent;
diff --git a/src/utils/carry_math.hpp b/src/utils/carry_math.hpp
index 2630ec0..fbeee20 100644
--- a/src/utils/carry_math.hpp
+++ b/src/utils/carry_math.hpp
@@ -22,7 +22,7 @@ namespace CarryMath
 
     Vec3   line_Anchor(const Camera& camera, double carry_dist);
 
-    DynArray<Vec3> slot_positions(const CarriedLine& carried,
+    DynArray<Vec3> slot_Positions(const CarriedLine& carried,
                                      const Vec3& anchor,
                                      const Vec3& right,
                                      double carry_gap);
diff --git a/src/utils/math.hpp b/src/utils/math.hpp
index 1ebe461..0534458 100644
--- a/src/utils/math.hpp
+++ b/src/utils/math.hpp
@@ -37,6 +37,8 @@ inline Vec3 operator-(Vec3 a, const Vec3& b) { return a -= b; }
 inline Vec3 operator*(Vec3 v, double s)      { return v *= s; }
 inline Vec3 operator/(Vec3 v, double s)      { return v /= s; }
 
+namespace Math
+{
 
 inline double
 dot(const Vec3& a, const Vec3& b)
@@ -82,3 +84,5 @@ lerp(double a, double b, double t)
 inline Vec3
 lerp(const Vec3& a, const Vec3& b, double t)
 { return { lerp(a.x, b.x, t), lerp(a.y, b.y, t), lerp(a.z, b.z, t) }; }
+
+} // namespace
diff --git a/src/utils/text_wrap.hpp b/src/utils/text_wrap.hpp
index 93863a1..e75c9d8 100644
--- a/src/utils/text_wrap.hpp
+++ b/src/utils/text_wrap.hpp
@@ -44,9 +44,11 @@ wrap_Text(const std::string& text, size_t max_chars)
         if (c == '\n') {
             flush_word();
             flush_line();
-        } else if (c == ' ' || c == '\t') {
+        }
+        else if (c == ' ' || c == '\t') {
             flush_word();
-        } else {
+        }
+        else {
             word += c;
         }
     }