One page per rule. The help link of every diagnostic
(https://github.com/CheatEngineNet/CheatEngine.SDK/blob/main/analyzers/docs/<ID>.md) lands on the page of that rule.
Each page is
written for the plugin author who just saw the message: cause, reason, exact definition, fix, when to suppress.
Identifier ranges: CESDK0xxx plugin shape and bootstrap (category CheatEngine.SDK.Plugin), CESDK1xxx
runtime-safety usage (CheatEngine.SDK.Usage), CESDK2xxx Lua generator input (CheatEngine.SDK.Generation). The
separate EngineApi generator owns
CESDK3xxx for curated-spec grammar and generated-identity diagnostics. CESDK5xxx marks compiler-enforced
[Experimental] API gates, held unqualified until their audit criteria pass. CESDK7xxx marks members obsoleted after
1.0.0 ([Obsolete(DiagnosticId = …)]). Identifiers are never renumbered or reused.
| Id | Title | Severity | Code fix |
|---|---|---|---|
| CESDK0001 | Plugin class cannot be constructed by the generated entry point | Error | Replace abstract or static with sealed, add a constructor, make the constructor public |
| CESDK0002 | More than one plugin class in the assembly | Error | None |
| CESDK0003 | Manual Cheat Engine bootstrap is missing or malformed | Error | Add the exact CESDK.CESDK.CEPluginInitialize(IntPtr, int) contract |
| CESDK0004 | Plugin assembly declares a namespace under 'CESDK' | Warning | None |
| CESDK0005 | Source type collides with the generated Cheat Engine entry point | Error | Rename it, or explicitly own the complete manual bootstrap |
| CESDK0006 | Method exports a classic Cheat Engine native plugin entry point | Warning | None |
| CESDK1001 | Plugin startup code calls an enabled-only API | Error | Move the call to OnEnable |
| CESDK1003 | A Cheat Engine-owned value is being destroyed | Error | Keep it borrowed or use an explicit Owned<T> transfer |
| CESDK1004 | Exception can escape an [UnmanagedCallersOnly] method | Warning | Wrap the body in try/catch |
| CESDK1005 | Plugin lifecycle callback must not be async void |
Error | Keep OnEnable/OnDisable synchronous |
| CESDK1020 | PointerSize built from the plugin process width | Warning | None; read the target bitness or configured pointer size from Cheat Engine |
| CESDK2001 | Lua binding needs AllowUnsafeBlocks | Error | None |
| CESDK2002 | Type cannot receive a generated Lua binding part | Error | None |
| CESDK2003 | [LuaFunction] method cannot be exported by a generated thunk | Error | None |
| CESDK2004 | [LuaGlobal] method cannot receive a generated body | Error | None |
| CESDK2005 | Lua function name is duplicated | Error | Give one valid export a distinct Lua name |
| CESDK2006 | Lua annotation target cannot receive generated code | Error | Declare the supported borrowed-handle/member shape |
| CESDK2007 | User member collides with a generated Lua binding identity | Error | Rename the member or change the binding declaration |
| CESDK2010 | Optional Lua argument is not in a trailing run | Error | Declare optional arguments after the required ones |
| CESDK2011 | Optional or variadic Lua result shape is invalid | Error | Required, then optional results; one variadic pair last |
| CESDK2012 | Type impersonates an SDK Lua contract type | Error | Use the CheatEngine.SDK.Lua type |
| CESDK2013 | LuaOptional is not supported in this position | Error | Use an argument or an out result of a supported kind |
| CESDK3001 | Engine API specification is invalid | Error | Correct the reported spec line |
| CESDK3002 | Engine API specification has a generated-identity conflict | Error | Keep one spec file per generated type |
| CESDK3003 | Engine API specification does not declare the ce77 contract | Error | Add the contract: ce77 header |
| CESDK3004 | Engine API optional argument is invalid | Error | Declare opt: arguments last |
| CESDK3005 | Engine API optional or variadic result is invalid | Error | result:, then opt-result:, then one rest: |
| CESDK5001 | Worker-thread Lua admission is experimental | Error (compiler) | None |
| CESDK5010 | Scan deadline and cooperative termination are experimental | Error (compiler) | None |
| CESDK5011 | First-found AOB scan is experimental | Error (compiler) | None |
| CESDK7001 | PointerSize.FromArchitecture is obsolete | Warning | None; use TargetArchitectureObservation.ConfiguredPointerSize or Bitness |
| CESDK9102 | A CheatEngine.SDK plugin library sets PublishAot (MSBuild, packaged build target) | Warning | None |
Configure a rule like any other analyzer diagnostic:
[*.cs]
dotnet_diagnostic.CESDK1004.severity = errorCESDK0002 through CESDK0005, and CESDK2005, are compilation-end diagnostics. They need the whole project, so
they are reported in build output and in full-solution analysis where an IDE offers it, not while typing. The
generation-specific plugin rules run only when the direct package build property explicitly supplies
CheatEngineSdkGenerateEntryPoint=true; explicit false activates the manual-bootstrap check CESDK0003, and an
absent property stays silent.
CESDK2005 carries the CompilationEnd tag because it flags two valid [LuaFunction] members of one type that share
a Lua name. The tag lets the local shape diagnostics (CESDK2001–CESDK2004, CESDK2006, CESDK2007) remain visible
while typing.
CESDK1002 is intentionally unassigned until the CE 7.7 main-thread dispatcher contract has opt-in live evidence. A
runtime guard exists today; that is not enough evidence for a static thread-affinity analyzer rule.
Adding a rule: constant in CheatEngine.SDK.Analyzers/Diagnostics/DiagnosticIds.cs, descriptor in
DiagnosticDescriptors.cs, row
in AnalyzerReleases.Unshipped.md, page here, tests. DiagnosticCatalogTests fails when the page, release-tracking row
or tracking uniqueness of a descriptor is missing.