Skip to content

fix(analysis): count elements the way the client-checked OverPy counter does - #308

Merged
Teakowa merged 2 commits into
mainfrom
fix/element-count-model
Sep 26, 2026
Merged

Teakowa merged 2 commits into
mainfrom
fix/element-count-model

Conversation

@e54-bot

@e54-bot e54-bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #305.

Program::element_count was about 37% below the client on a production project (OWBastion/Bastion, zh-CN main): 18891 against the client's 30070 for the OverPy build, whose own counter says 30067. The model now reproduces OverPy's figure to within 2 elements.

What changed

Derived by comparing every action and condition of that project against pinned OverPy 9.7.10's #!debugElementCount (2867 leaf actions, 309 rules), then fitting the missing costs:

  • a number literal costs two (the value and its literal); Team, Hero, Color, Button and Map constants likewise;
  • a variable read costs two (the value and its name), a variable named as an argument counts as that argument;
  • a comparison outside a rule condition costs two (its operator is a literal);
  • an omitted defaulted argument still fills its slot (Custom String has three replacement slots);
  • Else If, Else and End are actions; the count follows the canonical emitter, which closes the last action of a rule without End when it is an If and keeps every other End (a written and an omitted trailing End are one program);
  • Workshop setting values get the client's fixed adjustments;
  • hero pairs are counted per direct argument;
  • disabled rules, actions and conditions count like enabled ones instead of failing the whole program.

Evidence

On the project's main entry every action count equals OverPy's and the total is 30065 against OverPy's 30067. Eight rules differ by one where the emitter's End spelling differs from OverPy's (documented in docs/element-count.md). The client counted OverPy's build at 30070; the three elements of difference are not explained. The model is calibrated on this one project; constructs it does not exercise follow the Workshop.codes reference. docs/element-count.md states this, and tests/element_count.rs reproduces ten small OverPy-counted programs, one rule each.

Verification

cargo fmt --check, cargo clippy --workspace --all-targets -- -D warnings, cargo test --workspace --all-targets, workshop-catalog-gen check, git diff --check. The full-project comparison was run locally against OverPy's annotated output; the project source is not part of this repository.

Counts for existing programs change, so consumers that pinned a total will see different numbers.

…er does

The element count was 37% below the client on a production project. Number literals, constants that wrap a literal, variable reads, comparison operators, omitted defaulted arguments, and the Else If, Else and End actions were undercounted, and disabled rules, actions and conditions made the whole program uncountable.

Derive the missing costs from OverPy's per-action #!debugElementCount on 2867 actions of that project, count disabled actions and conditions like enabled ones, count hero pairs per direct argument, and keep the closing End of loops and subroutine rules while an If left open at the end of any other rule is not counted. Every action and rule count now equals OverPy's, and the total is 30067, OverPy's own figure. Document the model and its evidence in element-count.md and reproduce one rule per case in the tests.

Fixes #305

@Teakowa Teakowa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One blocking count-model issue.

Comment thread crates/workshop-rs/src/analysis/element_count.rs Outdated
…ter writes it

The count omitted the closing End of any final If in a non-subroutine rule and kept it in subroutine rules and, through nested last Ifs, elsewhere. The countable program does not record whether a trailing End was written, so a written and an omitted End are one program. Follow the canonical emitter: only the last action of a rule, when it is an If, is closed without End, in every rule. Nested blocks, While and For keep theirs.

Add tests that a written and an omitted trailing End cost the same, that only the last action is closed without End, and that the count of a program equals the count of its emitted text. State the eight rules where the count differs from OverPy on the calibration project.
@Teakowa
Teakowa merged commit 0c64104 into main Sep 26, 2026
10 checks passed
@Teakowa
Teakowa deleted the fix/element-count-model branch September 26, 2026 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Element count is about 37% below the client on a real project

2 participants