Coding Guidelines
Stability first, performance-focused, strict Clang 22 compliance, copyright-clean, ABI-safe. No recursion,
no new virtuals, no new Blueprint exposure, minimal templates. Gate anything that adds overhead or changes
behaviour behind a guard in CoreDefines.h.
These rules are stricter than stock Unreal's own coding standard. They exist because Vite's value proposition is predictable performance on Console Class hardware, and because a fork that breaks binary compatibility with its own shaders is unusable.
Core principles
Forbidden
Recursion
Banned. Use iterative patterns. Recursion makes stack usage unbounded and unpredictable, which matters on the hardware Vite targets.
New virtual functions
Do not add new virtuals unless strictly required. Where you can, cache existing engine virtuals rather than calling through them repeatedly.
Kismet / Blueprint API additions
No new BlueprintCallable or BlueprintPure functions without explicit approval. Every Blueprint-exposed
function adds reflection metadata, binary size and a call path that is slower than native C++. At the same type
the Blueprint Nativization system needs to remain stable.
Template-heavy patterns
Avoid templates unless they provide a clear performance or architectural benefit. Do not introduce patterns that increase compile times, binary size or code complexity. See Shader Compilation and PSO for why compile times are taken seriously here.
ABI-breaking modifications
Such modifications break PSO caching, ray tracing stability, serialization, and cross-platform and cross-vendor GPU behaviour. This is the single most common cause of immediate rejection.
Technical standards
- No undefined behaviour or non-standard extensions.
- Avoid implicit type conversions.
- Maintain memory correctness. Avoid large stack allocations; minimise dynamic memory.
- Prefer
constexpr,FORCEINLINEand zero-cost abstractions.
Performance rules
- Favour contiguous memory and cache-friendly layouts.
- Avoid unpredictable branching in hot paths.
- No
FStringprocessing, reflection calls, dynamic allocation or virtual dispatch inside per-frame loops. - Use SIMD-friendly math (SSE/AVX/NEON) where appropriate.
Rule 3 is the one most often violated by otherwise reasonable code. An FString format call in a per-actor
tick is invisible in a test scene and catastrophic at scale — see the
400-character CMC benchmark for what per-frame cost looks like when
multiplied out.
Work in progress
- Commit work in progress to alternative branches.
- Give a brief commentary on what is left to do.
- Delete temporary branches once they are no longer needed.
- Make other forkers aware of the work so effort is not duplicated.
Verification requirements
Compilation
Must compile cleanly under MSVC and be Clang compliant. "Compiles on my machine with warnings" is not clean.
Stability
- No crashes on startup, shutdown, or on the Tech Showcase project.
- No log spam.
- Guard all code not necessary for shipping.
ABI
- All shader-visible structs must remain bit-for-bit identical.
- No changes to payloads, bitmask layouts, uniform buffers or reflection flags.
- ABI violations result in immediate rejection.
Code gating
Anything that adds overhead or changes existing behaviour must sit behind a guard defined in
Engine\Source\Runtime\Core\Public\Misc\CoreDefines.h:
#ifndef VITE_MY_FEATURE
#define VITE_MY_FEATURE 0
#endif
Two rules follow from that. The default must leave the existing path untouched — a guard whose default value changes behaviour is not a guard. And the guarded code must actually be excluded when the switch is off, rather than compiled in and skipped at runtime, or the overhead you were gating is still being paid.
This is what makes optional features free for projects that do not use them, and it is why
VITE_PHYSX_FIXED_TIMESTEP and the rest of the
compile-time switches exist in the form they do. Document every new switch on
that page in the same change.
Review checklist
Confirm all of these before opening a pull request:
| Check | |
|---|---|
| No recursion | ☐ |
| No added virtual calls, existing engine virtuals cached where possible | ☐ |
| No new Kismet exposure | ☐ |
| Copyright-clean code | ☐ |
| ABI and bitmask integrity preserved | ☐ |
| Strict Clang compliance | ☐ |
| No undefined behaviour | ☐ |
| No performance regressions | ☐ |
| No unnecessary binary size increases | ☐ |
| No shader or RHI ABI mismatches | ☐ |
Overhead or behaviour changes gated in CoreDefines.h, defaulting off |
☐ |
| New compile-time switches documented | ☐ |
Marking your changes
Vite's engine modifications are marked inline so they survive upstream merges and are findable later. The existing convention in the tree uses trailing comments on modified lines:
case MP_Anisotropy:
CustomPinNames.Add({ MSM_CallistoBRDF, "Diffuse Fresnel" }); // AKCHANGES
CustomPinNames.Add({ MSM_Toon, "Softness" }); //Fletch
Follow whatever marker the surrounding code uses. For a new region, a // AKCHANGES START /
// AKCHANGES END pair makes the extent of the change clear.