Advanced

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

ToolVersionPurpose
Unreal Engine5.7.2+Build target
Visual Studio2022 (v17.8+)C++ compiler
Node.js18+MCP bridge development
npm9+Bridge dependency management
Git2.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.

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 for UPROPERTY members.
  • Use GetClassPathName() not GetPathName() for class references.
  • Use FTopLevelAssetPath for 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

KindConventionExample
ClassesPascalCase with prefixFMCPTool_TextureAudit
FunctionsPascalCaseValidateContentPath
VariablesPascalCase with b prefix for boolsbIsRecursive
ConstantsPascalCase or k prefixkMaxSearchResults
UE log categoryDefine once, use everywhereDEFINE_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 changingRequired tests
New tool handlerAutomation test: valid params, missing required param, invalid path, boundary values
New validator ruleUnit test: blocked input returns error, valid input passes
New bridge router entryJest test: correct REST endpoint called, response mapped correctly
New REST endpointIntegration test: request/response shape, auth header required
Bug fixRegression test that fails before the fix, passes after

Test file naming

TypeLocationName pattern
C++ AutomationSource/Gengine/Private/Tests/MCPTool_{Name}_Test.cpp
Bridge JestResources/mcp-bridge/src/__tests__/{module}.test.ts

Commit Conventions

PrefixWhen 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 Verbose level or redact.
  • Validate before touching editor state — all validation must happen in MCPParamValidator before Execute() 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

  1. Fork the repository and create a feature branch from main.
  2. Implement your change following the standards above.
  3. Write tests covering the new behavior and any edge cases.
  4. Run the full test suiteAutomation RunTests gengine must pass.
  5. Build the bridgenpm run build in Resources/mcp-bridge/ must succeed with no TypeScript errors.
  6. Open a PR against main with:
    • A description of what changed and why
    • Screenshots or log output if the change affects visible behavior
    • A note on any security implications
  7. Address review feedback — maintainers aim to review PRs within 3 business days.
  8. 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 any types in TypeScript
  • Commit message follows convention
  • Security implications noted in PR description (or "no security impact")