Dev setup, C++ and Node.js coding standards, testing requirements, commit conventions, security guidelines, and the PR process for gengine contributors.
Contributing
This page covers everything you need to contribute to gengine — setting up a development environment, following code standards, writing tests, and submitting pull requests.
Dev Setup
Prerequisites
| Tool | Version | Purpose |
|---|---|---|
| Unreal Engine | 5.7.2+ | Build target |
| Visual Studio | 2022 (v17.8+) | C++ compiler |
| Node.js | 18+ | MCP bridge development |
| npm | 9+ | Bridge dependency management |
| Git | 2.40+ | Source control |
Clone and build
# Clone into your project's Plugins directory
cd YourProject/Plugins
git clone https://github.com/enginesofcreation/gengine.git
# Initialize the mcp-bridge submodule
cd gengine
git submodule update --init --recursive
# Install bridge dependencies and build
cd Resources/mcp-bridge
npm install
npm run build
# Return to project root and generate project files
cd ../../../..
# Right-click the .uproject file > Generate Visual Studio Project Files
# Or via UnrealBuildTool:
"C:/Program Files/Epic Games/UE_5.7/Engine/Binaries/DotNET/UnrealBuildTool/UnrealBuildTool.exe" ^
-projectfiles -project="YourProject.uproject" -game -rocket -progress
Open the generated .sln in Visual Studio, set the configuration to Development Editor, and build.
Running tests
# All gengine tests
Automation RunTests gengine
# Specific module
Automation RunTests gengine.Tools
Automation RunTests gengine.Validators
Automation RunTests gengine.Bridge
Tests must pass before submitting a PR. The CI pipeline runs the full suite on every push.
C++ Standards
File constraints
- Maximum 500 lines per file. Split into multiple files if you exceed this.
- Maximum 50 lines per function. Extract helpers if a function grows beyond this.
- One class per header/source pair.
Copyright header
Every .h and .cpp file must begin with:
// Copyright Engines of Creation. All Rights Reserved.
UE 5.7 API targets
- Use only UE 5.7.2 APIs. Do not use deprecated patterns.
- Prefer
TObjectPtr<>over raw pointers forUPROPERTYmembers. - Use
GetClassPathName()notGetPathName()for class references. - Use
FTopLevelAssetPathfor asset registry filters (UE 5.1+ API).
UPROPERTY / UFUNCTION specifiers
Verify specifiers against UE 5.7 documentation before adding. Use unreal_get_ue_context to look up correct specifiers rather than copying from older code.
Error handling
Return FMCPResult::Error() for recoverable errors. Do not use check() or ensure() in tool handlers — these crash the editor. Log errors with UE_LOG(LogGengine, Error, ...) and return a structured error result.
// Good
if (!Asset)
{
UE_LOG(LogGengine, Error, TEXT("Asset not found: %s"), *AssetPath);
return FMCPResult::Error(FString::Printf(TEXT("Asset not found: %s"), *AssetPath));
}
// Bad — crashes the editor on failure
check(Asset != nullptr);
Naming conventions
| Kind | Convention | Example |
|---|---|---|
| Classes | PascalCase with prefix | FMCPTool_TextureAudit |
| Functions | PascalCase | ValidateContentPath |
| Variables | PascalCase with b prefix for bools | bIsRecursive |
| Constants | PascalCase or k prefix | kMaxSearchResults |
| UE log category | Define once, use everywhere | DEFINE_LOG_CATEGORY(LogGengine) |
Node.js Standards
TypeScript required
All bridge code must be written in TypeScript. No .js files in src/. The build step compiles to dist/.
Async/await over callbacks
Use async/await throughout. No raw Promise chains. No callback-style APIs.
// Good
const response = await fetch(url);
const data = await response.json();
// Bad
fetch(url).then(r => r.json()).then(data => { ... });
Error handling
Use typed error returns rather than throwing. Bridge functions return { ok: true, data } or { ok: false, error: string } union types.
type BridgeResult<T> = { ok: true; data: T } | { ok: false; error: string };
No any
TypeScript's any type is banned. Use unknown with type guards, or define proper interfaces.
Testing Requirements
| What you're changing | Required tests |
|---|---|
| New tool handler | Automation test: valid params, missing required param, invalid path, boundary values |
| New validator rule | Unit test: blocked input returns error, valid input passes |
| New bridge router entry | Jest test: correct REST endpoint called, response mapped correctly |
| New REST endpoint | Integration test: request/response shape, auth header required |
| Bug fix | Regression test that fails before the fix, passes after |
Test file naming
| Type | Location | Name pattern |
|---|---|---|
| C++ Automation | Source/Gengine/Private/Tests/ | MCPTool_{Name}_Test.cpp |
| Bridge Jest | Resources/mcp-bridge/src/__tests__/ | {module}.test.ts |
Commit Conventions
| Prefix | When to use |
|---|---|
feat: | New operation, new tool, new feature |
fix: | Bug fix in existing behavior |
test: | Adding or updating tests only |
docs: | Documentation changes only |
refactor: | Code restructuring with no behavior change |
security: | Security fix — always include in the PR description what was fixed |
Commit messages use the imperative mood and are under 72 characters:
feat: add texture_audit tool with dimension and compression checks
fix: reject NaN values in location parameters before game thread dispatch
test: add missing-param test for MCPTool_TextureAudit
Always run Automation RunTests gengine before committing. The CI pipeline will block PRs with failing tests.
Security Guidelines
- Never log parameter values at Info level — parameters may contain asset paths or user data. Log at
Verboselevel or redact. - Validate before touching editor state — all validation must happen in
MCPParamValidatorbeforeExecute()is called. - No eval, no dynamic code execution in the bridge — use static dispatch only.
- Report vulnerabilities privately — do not open a public GitHub issue for security bugs. Email security@enginesofcreation.com with a description and reproduction steps. You will receive a response within 48 hours.
PR Process
- Fork the repository and create a feature branch from
main. - Implement your change following the standards above.
- Write tests covering the new behavior and any edge cases.
- Run the full test suite —
Automation RunTests genginemust pass. - Build the bridge —
npm run buildinResources/mcp-bridge/must succeed with no TypeScript errors. - Open a PR against
mainwith:- A description of what changed and why
- Screenshots or log output if the change affects visible behavior
- A note on any security implications
- Address review feedback — maintainers aim to review PRs within 3 business days.
- Squash on merge — PRs are squash-merged to keep the main branch history clean.
PR checklist
- Copyright header on all new files
- No file exceeds 500 lines
- No function exceeds 50 lines
- All new parameters validated in
MCPParamValidator - Automation tests written and passing
- Bridge TypeScript compiles cleanly
- No
anytypes in TypeScript - Commit message follows convention
- Security implications noted in PR description (or "no security impact")