Protected Primitives
Score, health, and position live in memory. A cheat tool can change those numbers. Protected fields hide the real value and notice the change.
Walkthrough: Memory protection.
How to use
Replace the normal type with the protected type. Read, write, and math stay the same.
//UInt
ProtectedUInt16 a = 1234;
ProtectedUInt32 b = 5678;
ProtectedUInt64 c = 91011;
//Int
ProtectedInt16 d = 123;
ProtectedInt32 e = 5678;
ProtectedInt64 f = 91011;
//Float
ProtectedFloat g = 1234.123f;
//Double
ProtectedDouble h = 1234.123d;
//String
ProtectedString i = "My Protected Text";
//Vector
ProtectedVector2 j = new Vector2(1,2);
ProtectedVector2Int j2 = new Vector2Int(1,2);
ProtectedVector3 k = new Vector3(1, 2, 3);
ProtectedVector3Int k2 = new Vector3Int(1, 2, 3);
ProtectedVector4 l = new Vector4(1, 2, 3, 4);
ProtectedVector4Int l2 = new Vector4Int(1, 2, 3);
//Quaternion
ProtectedQuaternion m = new Quaternion(1, 2, 3, 4);
//Bool
ProtectedBool n = false;
//Decimal
ProtectedDecimal o = 12312.534m;
//DateTime
ProtectedDateTime p = System.DateTime.Now;
Add PrimitiveCheatingDetector to the AntiCheat-Monitor. A protected field uses a trap value. When that trap is read or written, the detector is told.

Drag and drop the prefab onto the AntiCheat monitor in your scene.
Custom Observer
If you would like to write a custom listener for the detector, you can attach an observer:
// Get the detector from the AntiCheat monitor.
var detector = AntiCheatMonitor.Instance
.GetDetector<PrimitiveCheatingDetector>();
// Subscribe as observer and get notified on cheating.
detector.Subscribe(myObserver);