{"owner":"playcanvas","repo":"engine","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# Agent Guidelines for PlayCanvas Engine\n\nThis document contains rules, conventions, and best practices for AI agents and developers working on the PlayCanvas Engine codebase.\n\n## Project Overview\n\nPlayCanvas is an open-source WebGL/WebGPU game engine written in JavaScript. It's a performance-critical library used by thousands of developers worldwide.\n\n- **Language**: JavaScript (ES2022) with JSDoc for TypeScript type definitions\n- **Module System**: ES Modules\n- **Node Version**: >=18.0.0\n- **Build System**: Rollup\n- **Testing**: Mocha + Chai + Sinon\n- **Linting**: ESLint with @playcanvas/eslint-config\n- **License**: MIT\n\n## General Code Rules\n\n### 1. Code Style and Formatting\n\n- **Follow ESLint rules**: Always run `npm run lint` before committing\n  - **Important**: Only fix lint issues in code you are actively modifying or creating\n  - Do not fix pre-existing lint issues in unrelated code unless specifically asked\n  - Focus on ensuring new and refactored code is lint-free\n- **Use JSDoc comments**: All public APIs must have comprehensive JSDoc documentation\n- **Module imports**: Use ES6 import/export syntax\n- **Naming conventions**:\n  - Classes: PascalCase (e.g., `GraphicsDevice`, `Entity`)\n  - Functions/methods: camelCase (e.g., `createShader`, `setPosition`)\n  - Constants: UPPER_SNAKE_CASE (e.g., `PIXELFORMAT_RGBA8`)\n\n### 2. File Organization\n\n- **Source files**: All engine source code goes in `src/`\n- **Directory structure**:\n  - `src/core/` - Core utilities and data structures\n  - `src/platform/` - Platform-specific code (graphics, audio, input)\n  - `src/scene/` - Scene graph, rendering, materials, shaders\n  - `src/framework/` - High-level components and application framework\n  - `src/extras/` - Optional extras and utilities\n- **Build output**: Generated files go in `build/` (never edit these directly)\n- **Examples**: Live in `examples/src/examples/`\n- **Tests**: Unit tests go in `test/` with `.mjs` extension\n- **File naming**: Module file names should match the main class they contain\n  - Use kebab-case for file names (e.g., `graphics-device.js` for `GraphicsDevice` class)\n  - If a class is renamed, the file should be renamed to match\n  - Multiple related classes can share a file if they're tightly coupled\n\n#### Module Dependency Hierarchy\n\nThe codebase follows a strict hierarchical structure to maintain clean architecture:\n\n```\ncore → platform → scene → framework\n```\n\n**Rules**:\n- Lower-level modules **cannot import** from higher-level modules\n- Lower-level modules **cannot use instances** from higher-level modules\n- Example: `core/` cannot import from `platform/`, `scene/`, or `framework/`\n- Example: `scene/` cannot import from `framework/`\n\n**Known Exception**:\n- `CameraComponent` (from `framework/`) is currently used in multiple places at the `scene/` level\n- **Do not introduce new exceptions** unless explicitly requested and confirmed\n- When in doubt, ask before breaking the hierarchy\n\nThis hierarchy ensures:\n- Clean separation of concerns\n- Prevents circular dependencies\n- Makes the codebase more maintainable and testable\n\n### 3. Documentation Standards\n\n- **JSDoc is mandatory** for all public APIs:\n  ```javascript\n  /**\n   * Brief description of the function.\n   *\n   * @param {string} name - Parameter description.\n   * @param {number} [optional=0] - Optional parameter with default.\n   * @returns {boolean} Return value description.\n   * @example\n   * const result = myFunction('test', 5);\n   */\n  ```\n- **Include examples** for complex APIs\n- **Document side effects**: Mention if a function modifies state\n- **Link related APIs**: Use `@see` tags to cross-reference\n- **Mark deprecations**: Use `@deprecated` with migration instructions\n\n### 4. TypeScript Definitions\n\n- JSDoc comments are used to generate TypeScript definitions\n- Run `npm run build:types` to generate `.d.ts` files\n- Test types with `npm run test:types`\n- Use proper JSDoc type annotations:\n  - `@type {TypeName}` for variables\n  - `@param {TypeName} paramName` for parameters\n  - `@returns {TypeName}` for return values\n  - Support for generics, unions, and complex types\n- **Type-only imports**: Use `@import` for types referenced in JSDoc comments\n  - These imports are only for type information, not runtime code\n  - Place at the top of the file in a JSDoc comment block\n  - Example:\n    ```javascript\n    /**\n     * @import { Texture } from './texture.js'\n     * @import { Shader } from './shader.js'\n     */\n    ```\n  - These help TypeScript understand types without adding runtime dependencies\n\n### 5. Testing\n\n- **Write tests** for all new features and bug fixes if instructed\n- **Test location**: `test/` directory, organized by module\n- **Test naming**: Use descriptive names that explain what is being tested\n- **Run tests**: `npm test` (or `npm run test:coverage` for coverage)\n- **Test structure**:\n  ```javascript\n  describe('ClassName', function () {\n      describe('#methodName', function () {\n          it('should do something specific', function () {\n              // Test implementation\n          });\n      });\n  });\n  ```\n\n### 6. Performance Considerations\n\nThis is a **performance-critical** engine. Always consider:\n\n- **Avoid allocations in hot paths**: Reuse objects, use object pools\n- **Minimize function calls**: Inline critical code when necessary\n- **Cache property access**: Store frequently accessed properties in local variables\n- **Use typed arrays**: For numeric data (Float32Array, Uint8Array, etc.)\n\n### 7. Graphics API Considerations\n\n- **Multi-backend support**: Code must work with both WebGL2 and WebGPU\n- **Use abstraction layers**: Don't call WebGL/WebGPU APIs directly in high-level code\n- **Shader code**: Maintain both GLSL and WGSL versions\n  - GLSL: `src/scene/shader-lib/glsl/`\n  - WGSL: `src/scene/shader-lib/wgsl/`\n- **NullGraphicsDevice**: A dummy graphics device for headless/testing scenarios\n  - When adding public API methods to `GraphicsDevice`, add stub implementations to `NullGraphicsDevice`\n  - Stub methods should be empty or return safe default values to avoid crashes\n  - This ensures the engine can run without a real graphics backend for testing/server-side use\n\n## Project-Specific Rules\n\n### 8. API Stability and Deprecation\n\n- **Backward compatibility matters**: Breaking changes require major version bump\n- **Deprecation process**:\n  1. Mark API as `@deprecated` with alternatives\n  2. Add console warning in development builds\n  3. Keep deprecated code for at least one major version\n  4. Consider removing jsdocs completely\n- **Never remove public APIs** without proper deprecation cycle\n\n### 9. Build System\n\n- **Source is in `src/`**: Never edit files in `build/` directory\n- **Module exports**: Main exports defined in `src/index.js`\n\n### 10. Dependencies\n\n- **Minimal dependencies**: Avoid adding new dependencies unless absolutely necessary\n- **Types only**: `@types/*` and `@webgpu/types` are the main dependencies\n\n### 11. Error Handling\n\n- **Debug class**: Use `Debug` class (`src/core/debug.js`) for logging and assertions\n  - Methods include: `assert()`, `warn()`, `warnOnce()`, `error()`, `deprecated()`, `log()`, `trace()`\n  - **Important**: All Debug methods are stripped out in production builds\n  - Use `*Once()` variants to avoid spam in loops or frequent calls\n  - Don't use Debug in hot paths - even in debug builds, excessive logging impacts performance\n- **DebugHelper class**: Helper methods for debugging (also stripped in production)\n  - `setName()`, `setLabel()`, `setDestroyed()` for marking objects\n\n### 12. Code Comments\n\n- **Explain \"why\" not \"what\"**: Code should be self-documenting, but comments help with quick understanding\n- **Complex algorithms**: Explain the approach and any non-obvious optimizations\n- **TODOs**: Include issue reference or context\n  ```javascript\n  // TODO: Optimize this when texture streaming is implemented (#1234)\n  ```\n- **Avoid very obvious comments**: Don't state what the code clearly does\n\n### 13. Commit and PR Guidelines\n\n- **Clear commit messages**: Use conventional commits format\n  - `feat: Add feature description`\n  - `fix: Bug fix description`\n  - `perf: Performance improvement description`\n  - `docs: Documentation update`\n  - `refactor: Code refactoring`\n  - `test: Test updates`\n- **Reference issues**: Include issue number in commit message in format 'Fixed #1234'\n- **Small, focused commits**: Each commit should be a logical unit\n- **No generated files**: Don't commit files in `build/` directory\n\n### 14. Browser Compatibility\n\n- **Modern browsers only**: ES6+ features are allowed\n- **No polyfills in engine**: Users can add their own if needed (except `src/polyfill/`)\n- **WebGL 2.0 minimum**: WebGL 1.0 is not supported\n- **WebGPU support**: Must maintain compatibility with WebGPU API\n\n## Common Patterns\n\n### 15. Object Creation\n\n```javascript\n// Prefer class syntax with TypeScript-like property declarations\nclass MyClass {\n    /**\n     * @type {GraphicsDevice}\n     */\n    device;\n\n    /**\n     * @type {string}\n     */\n    name;\n\n    constructor(device, options = {}) {\n        this.device = device;\n        this.name = options.name ?? 'default';\n    }\n\n    destroy() {\n        // Clean up resources\n        this.device = null;\n    }\n}\n```\n\n### 16. Resource Management\n\n```javascript\n// Always provide destroy() method for objects holding resources\nclass Resource {\n    constructor() {\n        this._resource = createResource();\n    }\n\n    destroy() {\n        this._resource?.destroy();\n        this._resource = null;\n    }\n}\n```\n\n### 17. Root Cause Analysis\n\nAlways address the root cause of issues rather than implementing workarounds that hide or suppress problems:\n\n- **Identify the root cause**: When you encounter an error or unexpected behavior, investigate why it's happening\n- **Don't mask symptoms**: Avoid solutions that simply hide errors or suppress warnings without fixing the underlying issue\n- **Fix at the source**: When you identify the root cause, fix it where the problem originates, not where it manifests\n\n## Things to Avoid\n\n### 18. Anti-Patterns\n\n- **Don't use `var`**: Use `const` or `let` (except in legacy `scripts/` directory)\n- **Avoid `any` types**: Be specific in JSDoc type annotations\n- **No global state**: Everything should be instance-based\n  - Exception: Module-scope variables for local optimization are allowed (e.g., reusable Mat4 instances)\n  - These must never be exported and should only be used within the module\n- **Don't bypass abstractions**: Use the platform API, not direct WebGL/WebGPU calls\n- **Don't suppress linter warnings**: Fix the underlying issue\n\n### 19. Performance Anti-Patterns\n\n- **No allocations in render loop**: Pre-allocate and reuse if feasible\n- **Don't use `try/catch` in hot paths**: It prevents optimizations\n- **No string concatenation in loops**: Build arrays and join\n- **Don't create functions in loops**: Define functions outside\n\n## AI Agent-Specific Guidelines\n\n### 20. When Making Changes\n\n- **Read existing code first**: Understand the context and patterns\n- **Follow existing style**: Match the style of surrounding code\n- **Lint your changes**: Run `npm run lint`\n- **Update documentation**: Modify JSDoc comments when changing APIs\n- **Consider performance**: This is a real-time engine, every microsecond counts\n- **Check both WebGL and WebGPU**: Changes may affect both backends\n\n### 21. When Creating Examples\n\n- Examples go in `examples/src/examples/`\n- Follow existing example structure (see other `.example.mjs` files)\n- Include descriptive comments\n- Keep examples simple and focused on one feature\n\n### 22. When Writing PR Descriptions\n\n- **Format as a single code block**: Always deliver PR descriptions wrapped in triple backticks for easy copy/paste\n- **Structure**:\n  - Brief title and overview\n  - Bullet points for functionality changes\n  - Technical details section (if relevant)\n  - **Clearly list all public API changes** with before/after code examples\n  - List updated examples (if applicable)\n  - Performance considerations (if relevant)\n- **Focus on user-facing changes**: What developers using the engine will see/use\n- **Be concise but complete**: Include all breaking changes and new APIs\n- **Avoid excessive detail**: Group related changes together, don't list every tiny implementation detail or internal refactoring\n- **Only document public APIs**: Do not list functionality tagged with `@ignore`, `@protected`, or `@private` as these are internal implementation details\n\n## Resources\n\n- **API Reference**: https://api.playcanvas.com/engine/\n- **User Manual**: https://developer.playcanvas.com/user-manual/engine/\n- **Developer Site**: https://github.com/playcanvas/developer-site\n  - For large features, ask to add documentation to the User Manual\n  - Manual pages are Markdown files in the `docs/` directory\n- **Examples**: https://playcanvas.github.io\n- **Forum**: https://forum.playcanvas.com\n- **Discord**: https://discord.gg/RSaMRzg\n- **GitHub Issues**: https://github.com/playcanvas/engine/issues\n\n## Questions?\n\nWhen in doubt:\n1. Look at similar existing code in the codebase\n2. Check the ESLint configuration\n3. Review recent commits for patterns\n4. If unclear or multiple valid approaches exist, ask instead of picking a possibly incorrect solution\n\n---\n\n**Remember**: This is a library used by thousands of developers. Quality, performance, and stability are paramount. When in doubt, prefer conservative, well-tested changes over clever optimizations.\n\n"},"files":{"AGENTS.md":"# Agent Guidelines for PlayCanvas Engine\n\nThis document contains rules, conventions, and best practices for AI agents and developers working on the PlayCanvas Engine codebase.\n\n## Project Overview\n\nPlayCanvas is an open-source WebGL/WebGPU game engine written in JavaScript. It's a performance-critical library used by thousands of developers worldwide.\n\n- **Language**: JavaScript (ES2022) with JSDoc for TypeScript type definitions\n- **Module System**: ES Modules\n- **Node Version**: >=18.0.0\n- **Build System**: Rollup\n- **Testing**: Mocha + Chai + Sinon\n- **Linting**: ESLint with @playcanvas/eslint-config\n- **License**: MIT\n\n## General Code Rules\n\n### 1. Code Style and Formatting\n\n- **Follow ESLint rules**: Always run `npm run lint` before committing\n  - **Important**: Only fix lint issues in code you are actively modifying or creating\n  - Do not fix pre-existing lint issues in unrelated code unless specifically asked\n  - Focus on ensuring new and refactored code is lint-free\n- **Use JSDoc comments**: All public APIs must have comprehensive JSDoc documentation\n- **Module imports**: Use ES6 import/export syntax\n- **Naming conventions**:\n  - Classes: PascalCase (e.g., `GraphicsDevice`, `Entity`)\n  - Functions/methods: camelCase (e.g., `createShader`, `setPosition`)\n  - Constants: UPPER_SNAKE_CASE (e.g., `PIXELFORMAT_RGBA8`)\n\n### 2. File Organization\n\n- **Source files**: All engine source code goes in `src/`\n- **Directory structure**:\n  - `src/core/` - Core utilities and data structures\n  - `src/platform/` - Platform-specific code (graphics, audio, input)\n  - `src/scene/` - Scene graph, rendering, materials, shaders\n  - `src/framework/` - High-level components and application framework\n  - `src/extras/` - Optional extras and utilities\n- **Build output**: Generated files go in `build/` (never edit these directly)\n- **Examples**: Live in `examples/src/examples/`\n- **Tests**: Unit tests go in `test/` with `.mjs` extension\n- **File naming**: Module file names should match the main class they contain\n  - Use kebab-case for file names (e.g., `graphics-device.js` for `GraphicsDevice` class)\n  - If a class is renamed, the file should be renamed to match\n  - Multiple related classes can share a file if they're tightly coupled\n\n#### Module Dependency Hierarchy\n\nThe codebase follows a strict hierarchical structure to maintain clean architecture:\n\n```\ncore → platform → scene → framework\n```\n\n**Rules**:\n- Lower-level modules **cannot import** from higher-level modules\n- Lower-level modules **cannot use instances** from higher-level modules\n- Example: `core/` cannot import from `platform/`, `scene/`, or `framework/`\n- Example: `scene/` cannot import from `framework/`\n\n**Known Exception**:\n- `CameraComponent` (from `framework/`) is currently used in multiple places at the `scene/` level\n- **Do not introduce new exceptions** unless explicitly requested and confirmed\n- When in doubt, ask before breaking the hierarchy\n\nThis hierarchy ensures:\n- Clean separation of concerns\n- Prevents circular dependencies\n- Makes the codebase more maintainable and testable\n\n### 3. Documentation Standards\n\n- **JSDoc is mandatory** for all public APIs:\n  ```javascript\n  /**\n   * Brief description of the function.\n   *\n   * @param {string} name - Parameter description.\n   * @param {number} [optional=0] - Optional parameter with default.\n   * @returns {boolean} Return value description.\n   * @example\n   * const result = myFunction('test', 5);\n   */\n  ```\n- **Include examples** for complex APIs\n- **Document side effects**: Mention if a function modifies state\n- **Link related APIs**: Use `@see` tags to cross-reference\n- **Mark deprecations**: Use `@deprecated` with migration instructions\n\n### 4. TypeScript Definitions\n\n- JSDoc comments are used to generate TypeScript definitions\n- Run `npm run build:types` to generate `.d.ts` files\n- Test types with `npm run test:types`\n- Use proper JSDoc type annotations:\n  - `@type {TypeName}` for variables\n  - `@param {TypeName} paramName` for parameters\n  - `@returns {TypeName}` for return values\n  - Support for generics, unions, and complex types\n- **Type-only imports**: Use `@import` for types referenced in JSDoc comments\n  - These imports are only for type information, not runtime code\n  - Place at the top of the file in a JSDoc comment block\n  - Example:\n    ```javascript\n    /**\n     * @import { Texture } from './texture.js'\n     * @import { Shader } from './shader.js'\n     */\n    ```\n  - These help TypeScript understand types without adding runtime dependencies\n\n### 5. Testing\n\n- **Write tests** for all new features and bug fixes if instructed\n- **Test location**: `test/` directory, organized by module\n- **Test naming**: Use descriptive names that explain what is being tested\n- **Run tests**: `npm test` (or `npm run test:coverage` for coverage)\n- **Test structure**:\n  ```javascript\n  describe('ClassName', function () {\n      describe('#methodName', function () {\n          it('should do something specific', function () {\n              // Test implementation\n          });\n      });\n  });\n  ```\n\n### 6. Performance Considerations\n\nThis is a **performance-critical** engine. Always consider:\n\n- **Avoid allocations in hot paths**: Reuse objects, use object pools\n- **Minimize function calls**: Inline critical code when necessary\n- **Cache property access**: Store frequently accessed properties in local variables\n- **Use typed arrays**: For numeric data (Float32Array, Uint8Array, etc.)\n\n### 7. Graphics API Considerations\n\n- **Multi-backend support**: Code must work with both WebGL2 and WebGPU\n- **Use abstraction layers**: Don't call WebGL/WebGPU APIs directly in high-level code\n- **Shader code**: Maintain both GLSL and WGSL versions\n  - GLSL: `src/scene/shader-lib/glsl/`\n  - WGSL: `src/scene/shader-lib/wgsl/`\n- **NullGraphicsDevice**: A dummy graphics device for headless/testing scenarios\n  - When adding public API methods to `GraphicsDevice`, add stub implementations to `NullGraphicsDevice`\n  - Stub methods should be empty or return safe default values to avoid crashes\n  - This ensures the engine can run without a real graphics backend for testing/server-side use\n\n## Project-Specific Rules\n\n### 8. API Stability and Deprecation\n\n- **Backward compatibility matters**: Breaking changes require major version bump\n- **Deprecation process**:\n  1. Mark API as `@deprecated` with alternatives\n  2. Add console warning in development builds\n  3. Keep deprecated code for at least one major version\n  4. Consider removing jsdocs completely\n- **Never remove public APIs** without proper deprecation cycle\n\n### 9. Build System\n\n- **Source is in `src/`**: Never edit files in `build/` directory\n- **Module exports**: Main exports defined in `src/index.js`\n\n### 10. Dependencies\n\n- **Minimal dependencies**: Avoid adding new dependencies unless absolutely necessary\n- **Types only**: `@types/*` and `@webgpu/types` are the main dependencies\n\n### 11. Error Handling\n\n- **Debug class**: Use `Debug` class (`src/core/debug.js`) for logging and assertions\n  - Methods include: `assert()`, `warn()`, `warnOnce()`, `error()`, `deprecated()`, `log()`, `trace()`\n  - **Important**: All Debug methods are stripped out in production builds\n  - Use `*Once()` variants to avoid spam in loops or frequent calls\n  - Don't use Debug in hot paths - even in debug builds, excessive logging impacts performance\n- **DebugHelper class**: Helper methods for debugging (also stripped in production)\n  - `setName()`, `setLabel()`, `setDestroyed()` for marking objects\n\n### 12. Code Comments\n\n- **Explain \"why\" not \"what\"**: Code should be self-documenting, but comments help with quick understanding\n- **Complex algorithms**: Explain the approach and any non-obvious optimizations\n- **TODOs**: Include issue reference or context\n  ```javascript\n  // TODO: Optimize this when texture streaming is implemented (#1234)\n  ```\n- **Avoid very obvious comments**: Don't state what the code clearly does\n\n### 13. Commit and PR Guidelines\n\n- **Clear commit messages**: Use conventional commits format\n  - `feat: Add feature description`\n  - `fix: Bug fix description`\n  - `perf: Performance improvement description`\n  - `docs: Documentation update`\n  - `refactor: Code refactoring`\n  - `test: Test updates`\n- **Reference issues**: Include issue number in commit message in format 'Fixed #1234'\n- **Small, focused commits**: Each commit should be a logical unit\n- **No generated files**: Don't commit files in `build/` directory\n\n### 14. Browser Compatibility\n\n- **Modern browsers only**: ES6+ features are allowed\n- **No polyfills in engine**: Users can add their own if needed (except `src/polyfill/`)\n- **WebGL 2.0 minimum**: WebGL 1.0 is not supported\n- **WebGPU support**: Must maintain compatibility with WebGPU API\n\n## Common Patterns\n\n### 15. Object Creation\n\n```javascript\n// Prefer class syntax with TypeScript-like property declarations\nclass MyClass {\n    /**\n     * @type {GraphicsDevice}\n     */\n    device;\n\n    /**\n     * @type {string}\n     */\n    name;\n\n    constructor(device, options = {}) {\n        this.device = device;\n        this.name = options.name ?? 'default';\n    }\n\n    destroy() {\n        // Clean up resources\n        this.device = null;\n    }\n}\n```\n\n### 16. Resource Management\n\n```javascript\n// Always provide destroy() method for objects holding resources\nclass Resource {\n    constructor() {\n        this._resource = createResource();\n    }\n\n    destroy() {\n        this._resource?.destroy();\n        this._resource = null;\n    }\n}\n```\n\n### 17. Root Cause Analysis\n\nAlways address the root cause of issues rather than implementing workarounds that hide or suppress problems:\n\n- **Identify the root cause**: When you encounter an error or unexpected behavior, investigate why it's happening\n- **Don't mask symptoms**: Avoid solutions that simply hide errors or suppress warnings without fixing the underlying issue\n- **Fix at the source**: When you identify the root cause, fix it where the problem originates, not where it manifests\n\n## Things to Avoid\n\n### 18. Anti-Patterns\n\n- **Don't use `var`**: Use `const` or `let` (except in legacy `scripts/` directory)\n- **Avoid `any` types**: Be specific in JSDoc type annotations\n- **No global state**: Everything should be instance-based\n  - Exception: Module-scope variables for local optimization are allowed (e.g., reusable Mat4 instances)\n  - These must never be exported and should only be used within the module\n- **Don't bypass abstractions**: Use the platform API, not direct WebGL/WebGPU calls\n- **Don't suppress linter warnings**: Fix the underlying issue\n\n### 19. Performance Anti-Patterns\n\n- **No allocations in render loop**: Pre-allocate and reuse if feasible\n- **Don't use `try/catch` in hot paths**: It prevents optimizations\n- **No string concatenation in loops**: Build arrays and join\n- **Don't create functions in loops**: Define functions outside\n\n## AI Agent-Specific Guidelines\n\n### 20. When Making Changes\n\n- **Read existing code first**: Understand the context and patterns\n- **Follow existing style**: Match the style of surrounding code\n- **Lint your changes**: Run `npm run lint`\n- **Update documentation**: Modify JSDoc comments when changing APIs\n- **Consider performance**: This is a real-time engine, every microsecond counts\n- **Check both WebGL and WebGPU**: Changes may affect both backends\n\n### 21. When Creating Examples\n\n- Examples go in `examples/src/examples/`\n- Follow existing example structure (see other `.example.mjs` files)\n- Include descriptive comments\n- Keep examples simple and focused on one feature\n\n### 22. When Writing PR Descriptions\n\n- **Format as a single code block**: Always deliver PR descriptions wrapped in triple backticks for easy copy/paste\n- **Structure**:\n  - Brief title and overview\n  - Bullet points for functionality changes\n  - Technical details section (if relevant)\n  - **Clearly list all public API changes** with before/after code examples\n  - List updated examples (if applicable)\n  - Performance considerations (if relevant)\n- **Focus on user-facing changes**: What developers using the engine will see/use\n- **Be concise but complete**: Include all breaking changes and new APIs\n- **Avoid excessive detail**: Group related changes together, don't list every tiny implementation detail or internal refactoring\n- **Only document public APIs**: Do not list functionality tagged with `@ignore`, `@protected`, or `@private` as these are internal implementation details\n\n## Resources\n\n- **API Reference**: https://api.playcanvas.com/engine/\n- **User Manual**: https://developer.playcanvas.com/user-manual/engine/\n- **Developer Site**: https://github.com/playcanvas/developer-site\n  - For large features, ask to add documentation to the User Manual\n  - Manual pages are Markdown files in the `docs/` directory\n- **Examples**: https://playcanvas.github.io\n- **Forum**: https://forum.playcanvas.com\n- **Discord**: https://discord.gg/RSaMRzg\n- **GitHub Issues**: https://github.com/playcanvas/engine/issues\n\n## Questions?\n\nWhen in doubt:\n1. Look at similar existing code in the codebase\n2. Check the ESLint configuration\n3. Review recent commits for patterns\n4. If unclear or multiple valid approaches exist, ask instead of picking a possibly incorrect solution\n\n---\n\n**Remember**: This is a library used by thousands of developers. Quality, performance, and stability are paramount. When in doubt, prefer conservative, well-tested changes over clever optimizations.\n\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# Agent Guidelines for PlayCanvas Engine\n\nThis document contains rules, conventions, and best practices for AI agents and developers working on the PlayCanvas Engine codebase.\n\n## Project Overview\n\nPlayCanvas is an open-source WebGL/WebGPU game engine written in JavaScript. It's a performance-critical library used by thousands of developers worldwide.\n\n- **Language**: JavaScript (ES2022) with JSDoc for TypeScript type definitions\n- **Module System**: ES Modules\n- **Node Version**: >=18.0.0\n- **Build System**: Rollup\n- **Testing**: Mocha + Chai + Sinon\n- **Linting**: ESLint with @playcanvas/eslint-config\n- **License**: MIT\n\n## General Code Rules\n\n### 1. Code Style and Formatting\n\n- **Follow ESLint rules**: Always run `npm run lint` before committing\n  - **Important**: Only fix lint issues in code you are actively modifying or creating\n  - Do not fix pre-existing lint issues in unrelated code unless specifically asked\n  - Focus on ensuring new and refactored code is lint-free\n- **Use JSDoc comments**: All public APIs must have comprehensive JSDoc documentation\n- **Module imports**: Use ES6 import/export syntax\n- **Naming conventions**:\n  - Classes: PascalCase (e.g., `GraphicsDevice`, `Entity`)\n  - Functions/methods: camelCase (e.g., `createShader`, `setPosition`)\n  - Constants: UPPER_SNAKE_CASE (e.g., `PIXELFORMAT_RGBA8`)\n\n### 2. File Organization\n\n- **Source files**: All engine source code goes in `src/`\n- **Directory structure**:\n  - `src/core/` - Core utilities and data structures\n  - `src/platform/` - Platform-specific code (graphics, audio, input)\n  - `src/scene/` - Scene graph, rendering, materials, shaders\n  - `src/framework/` - High-level components and application framework\n  - `src/extras/` - Optional extras and utilities\n- **Build output**: Generated files go in `build/` (never edit these directly)\n- **Examples**: Live in `examples/src/examples/`\n- **Tests**: Unit tests go in `test/` with `.mjs` extension\n- **File naming**: Module file names should match the main class they contain\n  - Use kebab-case for file names (e.g., `graphics-device.js` for `GraphicsDevice` class)\n  - If a class is renamed, the file should be renamed to match\n  - Multiple related classes can share a file if they're tightly coupled\n\n#### Module Dependency Hierarchy\n\nThe codebase follows a strict hierarchical structure to maintain clean architecture:\n\n```\ncore → platform → scene → framework\n```\n\n**Rules**:\n- Lower-level modules **cannot import** from higher-level modules\n- Lower-level modules **cannot use instances** from higher-level modules\n- Example: `core/` cannot import from `platform/`, `scene/`, or `framework/`\n- Example: `scene/` cannot import from `framework/`\n\n**Known Exception**:\n- `CameraComponent` (from `framework/`) is currently used in multiple places at the `scene/` level\n- **Do not introduce new exceptions** unless explicitly requested and confirmed\n- When in doubt, ask before breaking the hierarchy\n\nThis hierarchy ensures:\n- Clean separation of concerns\n- Prevents circular dependencies\n- Makes the codebase more maintainable and testable\n\n### 3. Documentation Standards\n\n- **JSDoc is mandatory** for all public APIs:\n  ```javascript\n  /**\n   * Brief description of the function.\n   *\n   * @param {string} name - Parameter description.\n   * @param {number} [optional=0] - Optional parameter with default.\n   * @returns {boolean} Return value description.\n   * @example\n   * const result = myFunction('test', 5);\n   */\n  ```\n- **Include examples** for complex APIs\n- **Document side effects**: Mention if a function modifies state\n- **Link related APIs**: Use `@see` tags to cross-reference\n- **Mark deprecations**: Use `@deprecated` with migration instructions\n\n### 4. TypeScript Definitions\n\n- JSDoc comments are used to generate TypeScript definitions\n- Run `npm run build:types` to generate `.d.ts` files\n- Test types with `npm run test:types`\n- Use proper JSDoc type annotations:\n  - `@type {TypeName}` for variables\n  - `@param {TypeName} paramName` for parameters\n  - `@returns {TypeName}` for return values\n  - Support for generics, unions, and complex types\n- **Type-only imports**: Use `@import` for types referenced in JSDoc comments\n  - These imports are only for type information, not runtime code\n  - Place at the top of the file in a JSDoc comment block\n  - Example:\n    ```javascript\n    /**\n     * @import { Texture } from './texture.js'\n     * @import { Shader } from './shader.js'\n     */\n    ```\n  - These help TypeScript understand types without adding runtime dependencies\n\n### 5. Testing\n\n- **Write tests** for all new features and bug fixes if instructed\n- **Test location**: `test/` directory, organized by module\n- **Test naming**: Use descriptive names that explain what is being tested\n- **Run tests**: `npm test` (or `npm run test:coverage` for coverage)\n- **Test structure**:\n  ```javascript\n  describe('ClassName', function () {\n      describe('#methodName', function () {\n          it('should do something specific', function () {\n              // Test implementation\n          });\n      });\n  });\n  ```\n\n### 6. Performance Considerations\n\nThis is a **performance-critical** engine. Always consider:\n\n- **Avoid allocations in hot paths**: Reuse objects, use object pools\n- **Minimize function calls**: Inline critical code when necessary\n- **Cache property access**: Store frequently accessed properties in local variables\n- **Use typed arrays**: For numeric data (Float32Array, Uint8Array, etc.)\n\n### 7. Graphics API Considerations\n\n- **Multi-backend support**: Code must work with both WebGL2 and WebGPU\n- **Use abstraction layers**: Don't call WebGL/WebGPU APIs directly in high-level code\n- **Shader code**: Maintain both GLSL and WGSL versions\n  - GLSL: `src/scene/shader-lib/glsl/`\n  - WGSL: `src/scene/shader-lib/wgsl/`\n- **NullGraphicsDevice**: A dummy graphics device for headless/testing scenarios\n  - When adding public API methods to `GraphicsDevice`, add stub implementations to `NullGraphicsDevice`\n  - Stub methods should be empty or return safe default values to avoid crashes\n  - This ensures the engine can run without a real graphics backend for testing/server-side use\n\n## Project-Specific Rules\n\n### 8. API Stability and Deprecation\n\n- **Backward compatibility matters**: Breaking changes require major version bump\n- **Deprecation process**:\n  1. Mark API as `@deprecated` with alternatives\n  2. Add console warning in development builds\n  3. Keep deprecated code for at least one major version\n  4. Consider removing jsdocs completely\n- **Never remove public APIs** without proper deprecation cycle\n\n### 9. Build System\n\n- **Source is in `src/`**: Never edit files in `build/` directory\n- **Module exports**: Main exports defined in `src/index.js`\n\n### 10. Dependencies\n\n- **Minimal dependencies**: Avoid adding new dependencies unless absolutely necessary\n- **Types only**: `@types/*` and `@webgpu/types` are the main dependencies\n\n### 11. Error Handling\n\n- **Debug class**: Use `Debug` class (`src/core/debug.js`) for logging and assertions\n  - Methods include: `assert()`, `warn()`, `warnOnce()`, `error()`, `deprecated()`, `log()`, `trace()`\n  - **Important**: All Debug methods are stripped out in production builds\n  - Use `*Once()` variants to avoid spam in loops or frequent calls\n  - Don't use Debug in hot paths - even in debug builds, excessive logging impacts performance\n- **DebugHelper class**: Helper methods for debugging (also stripped in production)\n  - `setName()`, `setLabel()`, `setDestroyed()` for marking objects\n\n### 12. Code Comments\n\n- **Explain \"why\" not \"what\"**: Code should be self-documenting, but comments help with quick understanding\n- **Complex algorithms**: Explain the approach and any non-obvious optimizations\n- **TODOs**: Include issue reference or context\n  ```javascript\n  // TODO: Optimize this when texture streaming is implemented (#1234)\n  ```\n- **Avoid very obvious comments**: Don't state what the code clearly does\n\n### 13. Commit and PR Guidelines\n\n- **Clear commit messages**: Use conventional commits format\n  - `feat: Add feature description`\n  - `fix: Bug fix description`\n  - `perf: Performance improvement description`\n  - `docs: Documentation update`\n  - `refactor: Code refactoring`\n  - `test: Test updates`\n- **Reference issues**: Include issue number in commit message in format 'Fixed #1234'\n- **Small, focused commits**: Each commit should be a logical unit\n- **No generated files**: Don't commit files in `build/` directory\n\n### 14. Browser Compatibility\n\n- **Modern browsers only**: ES6+ features are allowed\n- **No polyfills in engine**: Users can add their own if needed (except `src/polyfill/`)\n- **WebGL 2.0 minimum**: WebGL 1.0 is not supported\n- **WebGPU support**: Must maintain compatibility with WebGPU API\n\n## Common Patterns\n\n### 15. Object Creation\n\n```javascript\n// Prefer class syntax with TypeScript-like property declarations\nclass MyClass {\n    /**\n     * @type {GraphicsDevice}\n     */\n    device;\n\n    /**\n     * @type {string}\n     */\n    name;\n\n    constructor(device, options = {}) {\n        this.device = device;\n        this.name = options.name ?? 'default';\n    }\n\n    destroy() {\n        // Clean up resources\n        this.device = null;\n    }\n}\n```\n\n### 16. Resource Management\n\n```javascript\n// Always provide destroy() method for objects holding resources\nclass Resource {\n    constructor() {\n        this._resource = createResource();\n    }\n\n    destroy() {\n        this._resource?.destroy();\n        this._resource = null;\n    }\n}\n```\n\n### 17. Root Cause Analysis\n\nAlways address the root cause of issues rather than implementing workarounds that hide or suppress problems:\n\n- **Identify the root cause**: When you encounter an error or unexpected behavior, investigate why it's happening\n- **Don't mask symptoms**: Avoid solutions that simply hide errors or suppress warnings without fixing the underlying issue\n- **Fix at the source**: When you identify the root cause, fix it where the problem originates, not where it manifests\n\n## Things to Avoid\n\n### 18. Anti-Patterns\n\n- **Don't use `var`**: Use `const` or `let` (except in legacy `scripts/` directory)\n- **Avoid `any` types**: Be specific in JSDoc type annotations\n- **No global state**: Everything should be instance-based\n  - Exception: Module-scope variables for local optimization are allowed (e.g., reusable Mat4 instances)\n  - These must never be exported and should only be used within the module\n- **Don't bypass abstractions**: Use the platform API, not direct WebGL/WebGPU calls\n- **Don't suppress linter warnings**: Fix the underlying issue\n\n### 19. Performance Anti-Patterns\n\n- **No allocations in render loop**: Pre-allocate and reuse if feasible\n- **Don't use `try/catch` in hot paths**: It prevents optimizations\n- **No string concatenation in loops**: Build arrays and join\n- **Don't create functions in loops**: Define functions outside\n\n## AI Agent-Specific Guidelines\n\n### 20. When Making Changes\n\n- **Read existing code first**: Understand the context and patterns\n- **Follow existing style**: Match the style of surrounding code\n- **Lint your changes**: Run `npm run lint`\n- **Update documentation**: Modify JSDoc comments when changing APIs\n- **Consider performance**: This is a real-time engine, every microsecond counts\n- **Check both WebGL and WebGPU**: Changes may affect both backends\n\n### 21. When Creating Examples\n\n- Examples go in `examples/src/examples/`\n- Follow existing example structure (see other `.example.mjs` files)\n- Include descriptive comments\n- Keep examples simple and focused on one feature\n\n### 22. When Writing PR Descriptions\n\n- **Format as a single code block**: Always deliver PR descriptions wrapped in triple backticks for easy copy/paste\n- **Structure**:\n  - Brief title and overview\n  - Bullet points for functionality changes\n  - Technical details section (if relevant)\n  - **Clearly list all public API changes** with before/after code examples\n  - List updated examples (if applicable)\n  - Performance considerations (if relevant)\n- **Focus on user-facing changes**: What developers using the engine will see/use\n- **Be concise but complete**: Include all breaking changes and new APIs\n- **Avoid excessive detail**: Group related changes together, don't list every tiny implementation detail or internal refactoring\n- **Only document public APIs**: Do not list functionality tagged with `@ignore`, `@protected`, or `@private` as these are internal implementation details\n\n## Resources\n\n- **API Reference**: https://api.playcanvas.com/engine/\n- **User Manual**: https://developer.playcanvas.com/user-manual/engine/\n- **Developer Site**: https://github.com/playcanvas/developer-site\n  - For large features, ask to add documentation to the User Manual\n  - Manual pages are Markdown files in the `docs/` directory\n- **Examples**: https://playcanvas.github.io\n- **Forum**: https://forum.playcanvas.com\n- **Discord**: https://discord.gg/RSaMRzg\n- **GitHub Issues**: https://github.com/playcanvas/engine/issues\n\n## Questions?\n\nWhen in doubt:\n1. Look at similar existing code in the codebase\n2. Check the ESLint configuration\n3. Review recent commits for patterns\n4. If unclear or multiple valid approaches exist, ask instead of picking a possibly incorrect solution\n\n---\n\n**Remember**: This is a library used by thousands of developers. Quality, performance, and stability are paramount. When in doubt, prefer conservative, well-tested changes over clever optimizations.\n\n","category":"root","tokens":3371}]}