Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a43084c
Add CameraState and CameraProjection utilities
Mosch0512 Mar 28, 2026
1d3d771
Add CameraConfig, CameraMode, and ICamera interface
Mosch0512 Mar 28, 2026
032f758
Add frustum culling system
Mosch0512 Mar 28, 2026
58fc27e
Add DefaultCamera implementation
Mosch0512 Mar 28, 2026
3e81ae9
Add OrbitalCamera with spherical orbit controls
Mosch0512 Mar 28, 2026
0d1e800
Add LegacyCamera for A/B performance baseline
Mosch0512 Mar 28, 2026
3fd0cc6
Add FreeFlyCamera for editor spectator mode
Mosch0512 Mar 28, 2026
1d80537
Add CameraManager mode-switching singleton
Mosch0512 Mar 28, 2026
9cead0b
Migrate camera globals to CameraState and refactor projection calls
Mosch0512 Mar 28, 2026
3e66f67
Integrate frustum culling into terrain and object rendering
Mosch0512 Mar 28, 2026
4be206a
Update scene rendering and fix scene transitions
Mosch0512 Mar 28, 2026
c142a84
Add window resize and resolution handling
Mosch0512 Mar 28, 2026
e2f104e
Add DevEditor UI panel for camera and graphics debugging
Mosch0512 Mar 28, 2026
d3b6339
Apply DevEditor render toggles to game code
Mosch0512 Mar 28, 2026
3434c63
Add percentage-based fog system with per-world fog colors
Mosch0512 Mar 28, 2026
2cfce03
Improve character pick detection and fix viewport ray calculation
Mosch0512 Mar 29, 2026
8455976
Increase login scene render distance for touring camera
Mosch0512 Mar 29, 2026
d89251c
Reorganize DevEditor UI into scene-based layout
Mosch0512 Mar 29, 2026
7ba4c4d
Add login scene render distance sliders and scene-isolate DevEditor s…
Mosch0512 Mar 29, 2026
b775d71
Remove LegacyCamera — no longer needed
Mosch0512 Apr 2, 2026
04a6807
Persist orbital camera zoom level in config.ini
Mosch0512 Apr 2, 2026
79914f5
Clean up DevEditor: remove unused culling debug, fix DefaultCamera fl…
Mosch0512 Apr 2, 2026
8f10b53
Fix PR #29 review issues and window resize
Mosch0512 Apr 2, 2026
0875eb6
Unify ESC menu handling and add option window to login/character scenes
Mosch0512 Apr 10, 2026
324afdd
Split volume config into SoundVolume/MusicVolume and always init audio
Mosch0512 Apr 10, 2026
9ab2d48
Add music volume slider and resolution selector to option window
Mosch0512 Apr 10, 2026
8794c69
Refactor camera system to satisfy coding rules
Mosch0512 Apr 10, 2026
f6573ad
Replace resolution arrows with a scrollable combo box
Mosch0512 Apr 11, 2026
d2f2d0b
Re-layout scene UI on runtime resolution change
Mosch0512 Apr 12, 2026
a8b8e79
Add smooth mount camera offset for all mount types
Mosch0512 Apr 12, 2026
9f77896
Fix item rendering and NPC dialog text after camera refactor
Mosch0512 Apr 12, 2026
43867f5
Fix item rendering and NPC dialog text after camera refactor
Mosch0512 Apr 13, 2026
7bf6f2a
+++wt Remove custom OBBs, add windowed toggle, clean up DevEditor gra…
Mosch0512 Apr 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions docs/CODING_RULES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Coding Rules

These rules apply to all code changes in this project. Read before you commit.

---

## 1. Keep Functions Short and Focused — Break Apart Monoliths

- A function does **one thing**. If you can describe it with "and", split it.
- When touching a large function, **extract at least one** logical block into its own function before you're done. You don't have to refactor everything — just leave it better than you found it.
- If the extracted code doesn't belong in the current file, **move it to a new file** in an appropriate folder. Over time this breaks apart monolithic files naturally.
- Aim for functions that fit on one screen (~40 lines). Logic-heavy functions get shorter limits.

## 2. Exit Early

- Handle error cases and edge conditions **at the top** of a function.
- Avoid deep nesting. Prefer `if (bad) return;` over wrapping the entire body in `if (good) { ... }`.
- Each early exit should have a clear reason — don't silently swallow errors.

## 3. No Hard-Coded Values

- Numbers, strings, paths, sizes, timers, colors — if it's not self-evident, **give it a name**.
- Use constants, enums, or config values. A magic number buried in logic is a bug waiting to happen.
- `0` and `1` in boolean/trivial contexts are fine. `3.14f`, `1000`, `0xFF00FF` are not.

## 4. Write Reusable Code

- Before writing new logic, check if something similar already exists. Don't duplicate.
- Extract shared logic into utility functions or helpers when two or more callers need it.
- Design parameters to be general where it costs nothing, but don't over-abstract for hypothetical future use.

## 5. Separate Concerns by Layer

- **Rendering**, **game logic**, **UI**, **data**, **networking**, and **input** are distinct layers. Don't cross these boundaries.
- UI must not contain game logic. Rendering must not parse network packets. Keep each layer self-contained.
- When touching existing code that mixes concerns, extract toward the correct layer.
- New systems should be composable, self-contained components with clear ownership hierarchies.
- Group related data and behavior together. Don't scatter related logic across unrelated files.
- Name things precisely — if a name needs a comment to explain it, pick a better name.

## 6. One Class Per File

- Each new class or significant struct gets its **own file**, named after the class.
- Header and implementation separated (`.h` / `.cpp`).
- Small helper structs tightly coupled to a single class may stay in that class's header.

## 7. Consistent Style

- Follow the style of the surrounding code. Don't introduce a new convention in one file.
- Use the existing naming conventions for the module you're working in.
- Keep includes minimal — only what the file actually uses.

## 8. Guard Against Leaks and Dangling State

- Every allocation has a clear owner and a clear cleanup path.
- Prefer RAII and smart pointers over manual memory management when possible.
- Don't leave resources (handles, connections, textures) open on early-exit paths.

## 9. Readable Over Clever

- Write code that is obvious to read, even if a "clever" version is shorter.
- Complex expressions get broken into named intermediate variables.
- If a block of code needs a comment to explain *what* it does, refactor it so it doesn't.

## 10. Think Before You Add

- Every new dependency, abstraction, or pattern has a maintenance cost. Justify it.
- Smaller diffs are easier to review. Keep changes focused on one concern per commit.
- If you're unsure about a structural decision, ask before building on top of it.
313 changes: 313 additions & 0 deletions docs/reviews/review-3d-camera-rework.md

Large diffs are not rendered by default.

18 changes: 15 additions & 3 deletions src/MuEditor/Core/MuEditorCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "../MuEditor/UI/Common/MuEditorCenterPaneUI.h"
#include "../MuEditor/UI/ItemEditor/MuItemEditorUI.h"
#include "../MuEditor/UI/SkillEditor/MuSkillEditorUI.h"
#include "../MuEditor/UI/DevEditor/DevEditorUI.h"
#include "../UI/Common/MuEditorUI.h"
#include "../UI/Console/MuEditorConsoleUI.h"
#include "Translation/i18n.h"
Expand All @@ -33,6 +34,8 @@ CMuEditorCore::CMuEditorCore()
, m_bFrameStarted(false)
, m_bShowItemEditor(false)
, m_bShowSkillEditor(false)
, m_bShowDevEditor(false)
, m_bShowConsole(true)
, m_bHoveringUI(false)
, m_bPreviousFrameHoveringUI(false)
{
Expand Down Expand Up @@ -403,15 +406,24 @@ void CMuEditorCore::Render()
m_bHoveringUI = false;

// Render toolbar (handles both open and closed states)
g_MuEditorUI.RenderToolbar(m_bEditorMode, m_bShowItemEditor, m_bShowSkillEditor);
g_MuEditorUI.RenderToolbar(m_bEditorMode, m_bShowItemEditor, m_bShowSkillEditor, m_bShowDevEditor, m_bShowConsole);

if (m_bEditorMode)
{
// Render center pane (handles all editor windows and input blocking)
g_MuEditorCenterPaneUI.Render(m_bShowItemEditor, m_bShowSkillEditor);

// Render console
g_MuEditorConsoleUI.Render();
// Render Dev Editor
if (m_bShowDevEditor)
{
g_DevEditorUI.Render(&m_bShowDevEditor);
}

// Render console (if enabled)
if (m_bShowConsole)
{
g_MuEditorConsoleUI.Render();
}
}

// Store current hover state for next frame's input blocking
Expand Down
4 changes: 4 additions & 0 deletions src/MuEditor/Core/MuEditorCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class CMuEditorCore

bool IsShowingItemEditor() const { return m_bShowItemEditor; }
bool IsShowingSkillEditor() const { return m_bShowSkillEditor; }
bool IsShowingDevEditor() const { return m_bShowDevEditor; }
bool IsShowingConsole() const { return m_bShowConsole; }
bool IsHoveringUI() const { return m_bHoveringUI; }
void SetHoveringUI(bool hovering) { m_bHoveringUI = hovering; }

Expand All @@ -32,6 +34,8 @@ class CMuEditorCore
bool m_bFrameStarted;
bool m_bShowItemEditor;
bool m_bShowSkillEditor;
bool m_bShowDevEditor;
bool m_bShowConsole;
bool m_bHoveringUI;
bool m_bPreviousFrameHoveringUI; // Store previous frame's hover state for input blocking
};
Expand Down
2 changes: 2 additions & 0 deletions src/MuEditor/Core/MuInputBlockerCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ void CMuInputBlockerCore::ProcessInputBlocking()
extern bool MouseLButton, MouseLButtonPop, MouseLButtonPush, MouseLButtonDBClick;
extern bool MouseRButton, MouseRButtonPop, MouseRButtonPush;
extern bool MouseMButton;
extern int MouseWheel;

MouseLButton = false;
MouseLButtonPop = false;
Expand All @@ -37,6 +38,7 @@ void CMuInputBlockerCore::ProcessInputBlocking()
MouseRButtonPop = false;
MouseRButtonPush = false;
MouseMButton = false;
MouseWheel = 0; // Block mouse wheel when ImGui wants mouse input

// Block Enter key when hovering UI or when keyboard input is wanted
// This prevents chat from opening when pressing Enter in input fields
Expand Down
19 changes: 16 additions & 3 deletions src/MuEditor/UI/Common/MuEditorUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ CMuEditorUI& CMuEditorUI::GetInstance()
return instance;
}

void CMuEditorUI::RenderToolbar(bool& editorEnabled, bool& showItemEditor, bool& showSkillEditor)
void CMuEditorUI::RenderToolbar(bool& editorEnabled, bool& showItemEditor, bool& showSkillEditor, bool& showDevEditor, bool& showConsole)
{
if (editorEnabled)
{
RenderToolbarFull(editorEnabled, showItemEditor, showSkillEditor);
RenderToolbarFull(editorEnabled, showItemEditor, showSkillEditor, showDevEditor, showConsole);
}
else
{
Expand Down Expand Up @@ -109,7 +109,7 @@ void CMuEditorUI::RenderToolbarOpen(bool& editorEnabled)
ImGui::PopStyleColor(2);
}

void CMuEditorUI::RenderToolbarFull(bool& editorEnabled, bool& showItemEditor, bool& showSkillEditor)
void CMuEditorUI::RenderToolbarFull(bool& editorEnabled, bool& showItemEditor, bool& showSkillEditor, bool& showDevEditor, bool& showConsole)
{
ImGui::SetNextWindowSize(ImVec2(ImGui::GetIO().DisplaySize.x, TOOLBAR_HEIGHT), ImGuiCond_Always);
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
Expand Down Expand Up @@ -144,6 +144,19 @@ void CMuEditorUI::RenderToolbarFull(bool& editorEnabled, bool& showItemEditor, b
showSkillEditor = !showSkillEditor;
}

ImGui::SameLine();
if (ImGui::Button("Dev Editor"))
{
showDevEditor = !showDevEditor;
}

// Console toggle
ImGui::SameLine();
if (ImGui::Checkbox("Console", &showConsole))
{
// Toggle is handled by reference
}

// Language selector
ImGui::SameLine();
ImGui::SetNextItemWidth(100.0f);
Expand Down
4 changes: 2 additions & 2 deletions src/MuEditor/UI/Common/MuEditorUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ class CMuEditorUI
public:
static CMuEditorUI& GetInstance();

void RenderToolbar(bool& editorEnabled, bool& showItemEditor, bool& showSkillEditor);
void RenderToolbar(bool& editorEnabled, bool& showItemEditor, bool& showSkillEditor, bool& showDevEditor, bool& showConsole);
void RenderCenterViewport();

private:
CMuEditorUI() = default;
~CMuEditorUI() = default;

void RenderToolbarOpen(bool& editorEnabled);
void RenderToolbarFull(bool& editorEnabled, bool& showItemEditor, bool& showSkillEditor);
void RenderToolbarFull(bool& editorEnabled, bool& showItemEditor, bool& showSkillEditor, bool& showDevEditor, bool& showConsole);
};

#define g_MuEditorUI CMuEditorUI::GetInstance()
Expand Down
Loading
Loading