egametang/ET · critical · Exception

condition variable registry is not initialized

Error message

condition variable registry is not initialized

What it means

Thrown by ConditionExprParser.ParseCompare when ConditionVariableRegistry.Instance is null. The registry is a Singleton populated at framework startup via its Awake (which scans ConditionVariableAttribute types). A null instance means the singleton was never created/registered, so no variables can resolve — parsing cannot proceed.

Source

Thrown at Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionExprParser.cs:119

        }

        private BTNode ParseCompare()
        {
            ConditionToken variableToken = this.Expect(ConditionTokenType.Identifier);
            this.ReadVariable(variableToken.Text, out string ownerKey, out string variable, out bool hasOwnerKey);
            string[] paramValues = this.ReadParams(out bool hasParams);
            ConditionCompareOp op = this.ReadCompareOp();
            ConditionToken valueToken = this.Expect(ConditionTokenType.Number);
            int errorCode = this.defaultErrorCode;
            if (this.Match(ConditionTokenType.Colon))
            {
                errorCode = this.ReadErrorCode();
            }

            ConditionVariableRegistry registry = ConditionVariableRegistry.Instance;
            if (registry == null)
            {
                throw new Exception("condition variable registry is not initialized");
            }

            if (!registry.TryGetNodeType(variable, out Type nodeType))
            {
                throw new Exception($"condition variable not registered: {variable}");
            }

            BTCondition node = Activator.CreateInstance(nodeType) as BTCondition;
            if (node == null)
            {
                throw new Exception($"condition variable node create error: {nodeType.FullName}");
            }

            node.Id = this.NextNodeId();
            if (node is BTNumericCompare numericCompare)
            {
                if (hasParams)
                {

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Ensure ET framework startup (which creates and awakens ConditionVariableRegistry) completes before any condition expression is parsed.
  2. In tests/tools, bootstrap the singleton/CodeTypes system first, or inject a mock registry.
  3. Verify nothing disposes/resets ConditionVariableRegistry before parsing.
  4. Check startup ordering so config import happens after singleton initialization.

Example fix

// before (test parses without bootstrap)
var tokens = new ConditionExprLexer("HP > 0").Tokenize();
var root = new ConditionExprParser(tokens, 0).Parse(); // throws [55]

// after (bootstrap registry first)
World.Instance.AddSingleton<ConditionVariableRegistry>();
// ... then parse
var root = new ConditionExprParser(tokens, 0).Parse();
Defensive patterns

Strategy: validation

Validate before calling

if (ConditionVariableRegistry.Instance == null) { /* bootstrap singletons before parsing */ }
// Ensure framework startup (World.AddSingleton<ConditionVariableRegistry>()) completed first.

Prevention

When it happens

Trigger: Parsing a condition expression before the framework initialized ConditionVariableRegistry; running the parser in a context (e.g. a raw unit test or tool) that bypassed the ET singleton bootstrap; the registry was disposed/reset between bootstrap and parse.

Common situations: Unit tests that construct ConditionExprParser directly without bootstrapping singletons; an editor/tool process that did not run the full ET startup; ordering bug where config parsing runs before CodeTypes/Singleton initialization.

Related errors


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/e229d9a1d04bd854. Report an issue: GitHub.