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 suite — Automation RunTests gengine must pass.
  5. Build the bridge — npm 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")