# Frostbite2D Agent Guide

This guide helps agentic coding agents work effectively with the Frostbite2D 2D game engine codebase.

## Agent Preferences

- Communicate with the user in Chinese by default unless they explicitly ask for another language.
- Treat UTF-8 as the default encoding for new or edited text and source files; do not introduce ANSI or GBK encoded files.

## Build Commands

### Basic Build
```bash
xmake build
```

### Clean Build
```bash
xmake clean
xmake build
```

### Debug Build
```bash
xmake build -m debug
```

### Release Build
```bash
xmake build -m release
```

### Platform-Specific Build
```bash
xmake build -p windows
xmake build -p linux
xmake build -p switch
```

### Configuration
```bash
xmake f -c          # Show current configuration
xmake f             # Interactive configuration
```

## Testing
Currently no automated test framework is configured. Manual testing is performed by running the built binary.

## Project Structure
```
Frostbite2D/
├── include/frostbite2D/    # Public headers
│   ├── core/               # Core engine classes
│   ├── types/              # Type definitions
│   ├── utils/              # Utility classes
│   └── platform/           # Platform-specific code
└── src/frostbite2D/        # Implementation files
```

## Code Style Guidelines

### Naming Conventions
- **Classes/Structs**: PascalCase (`Application`, `Window`, `Vec2`)
- **Methods/Functions**: camelCase (`readTextFile`, `getFileName`)
- **Member Variables**: camelCase with trailing underscore (`width_`, `height_`, `running_`)
- **Constants**: UPPER_CASE (`PI_F`, `DEG_TO_RAD`) or PascalCase static methods (`Vec2::Zero()`)
- **Namespaces**: lowercase (`frostbite2D`, `math`)
- **Template Parameters**: PascalCase (`T`, `Args`, `Sig`)
- **Type Aliases**: using keyword with PascalCase (`using int8 = std::int8_t;`)

### Imports and Includes
- **Engine headers**: Use path relative to frostbite2D root
  ```cpp
  #include <frostbite2D/core/application.h>
  #include <frostbite2D/utils/asset.h>
  ```
- **Third-party libraries**: Use vendor prefixes
  ```cpp
  #include <SDL2/SDL.h>
  #include <glm/gtc/matrix_transform.hpp>
  #include <glad/glad.h>
  ```
- **Standard library**: Use angle brackets
  ```cpp
  #include <string>
  #include <functional>
  #include <optional>
  ```

### Formatting
- **Indentation**: 2 spaces
- **Brace Style**: K&R (opening brace on same line)
  ```cpp
  void myFunction() {
    // body
  }
  ```
- **Pointer/Reference Style**: Type on left, not centered
  ```cpp
  void func(T* ptr);      // Good
  void func(T *ptr);      // Avoid
  void func(T& ref);      // Good
  ```
- **Const Placement**: After type
  ```cpp
  const std::string& str;  // Good
  std::string const& str;  // Avoid
  ```

### Types
- **Use custom type aliases**: `int8`, `int32`, `uint8`, `uint64`, `Ptr<T>`, `SharedPtr<T>`
- **Smart pointers**: Prefer `Ptr<T>` alias over `std::shared_ptr<T>`
- **constexpr**: Use for compile-time constants
- **Struct vs Class**: 
  - Use `struct` for POD types, configurations, and data-only types
  - Use `class` for objects with methods/encapsulation
- **Default member initialization**: Initialize at declaration
  ```cpp
  bool running_ = false;
  int width_ = 1280;
  ```

### Error Handling
- **Return bool for success/failure operations** (especially I/O)
- **Use SDL_Log/SDL_LogError for logging**
- **Use std::optional for optional returns**
- **Avoid exceptions** (not observed in codebase)
- **Return early on failure**: Check conditions and return false immediately

### Singletons
- Use static instance pattern with private constructor:
  ```cpp
  static Application& get();
  private:
    Application() = default;
  ```

### Const Correctness
- Mark methods `const` if they don't modify state
- Pass by const reference for large types: `const std::string&`
- Return const references to member data when appropriate

### Documentation
- **Doxygen-style comments** with `@brief` tag
- **Use `///` for single-line comments in headers**
- **Section separators** use `// ---------------------------------------------------------------------------`
- **Chinese comments** are present and should be preserved/maintained
  ```cpp
  /**
   * @brief 读取文本文件
   * @param path 文件路径
   * @param outContent 输出文件内容
   * @return 读取成功返回 true
   */
  bool readTextFile(const std::string& path, std::string& outContent);
  ```

### Platform Handling
- Use `#ifdef` guards for platform-specific code:
  ```cpp
  #ifdef __SWITCH__
    switchInit();
  #endif
  ```
- Supported platforms: Windows, Linux, macOS, Switch
- Platform configs in `platform/` directory

### STL Usage
- Prefer STL algorithms over manual loops
- Use `std::filesystem` for file operations (already wrapped in Asset class)
- Use `std::optional` for nullable returns
- Use `std::function` for callbacks
- Use `std::vector` for dynamic arrays
- Use `std::string` for text

### OpenGL/Graphics
- GLM library for math operations
- Glad for OpenGL function loading
- Keep OpenGL-specific code minimal and well-encapsulated

## Dependencies
- **SDL2**: Windowing, input, platform abstraction
- **GLM**: Math library (vectors, matrices)
- **Glad**: OpenGL loader
- **STB**: Image/text utilities (single-header libs)

## Key Patterns

### Configuration Pattern
Use configuration structs with default values:
```cpp
struct WindowConfig {
  uint32_t width = 640;
  uint32_t height = 480;
  std::string title = "Frostbite2D Game";
};
```

### Path Handling
Always use the Asset singleton for file operations - it handles platform-specific path issues:
```cpp
Asset& asset = Asset::get();
asset.setWorkingDirectory("path/to/assets");
std::string content;
if (asset.readTextFile("file.txt", content)) {
  // success
}
```

## Common Issues
- **Path separators**: Use Asset class, it handles platform differences
- **Encoding**: Project uses UTF-8, Asset handles Windows UTF-8 paths
- **Memory leaks**: Use smart pointers, ensure proper cleanup in destructors
- **OpenGL context**: Initialize only after window creation
