Skip to content

Make variable card binding in the scripting terminal visible and safer - #83

Merged
rubensworks merged 4 commits into
master-1.21-ltsfrom
terminal-ux/card-binding
Oct 18, 2026
Merged

rubensworks merged 4 commits into
master-1.21-ltsfrom
terminal-ux/card-binding

Conversation

@rubensworks

@rubensworks rubensworks commented Oct 18, 2026 •

Copy link
Copy Markdown
Member

Independent of the terminal UX stack (#77 to #82), based directly on master-1.21-lts.

Changes

Don't bind variable cards to keywords. The card in the terminal is rebound to whatever word is under the cursor. Clicking on const or function rebound the card to a member that can never exist, while still showing the green check. Keywords are now rejected with a dedicated error (""const" is a keyword, so it can not be bound..."), and the card keeps its previous binding.

  • ILanguageHandler.getReservedWords() (empty by default), implemented for JavaScript.
  • Only words that are invalid names in a non-strict script are included. Strict-only words like let, static, yield and await are valid names in our scripts, so they stay bindable. A unit test checks the list against GraalJS itself (this caught those words in my first version of the list).
  • Game test testTerminalScriptingKeywordDoesNotRebindCard: bind to abc, select const (card stays abc), select def (card becomes def). Verified to fail without the fix.

Show which member the variable card is bound to. The bound member was only visible in the card tooltip, and the member a card would get was not visible at all. A label shows Bound to: <member> when a card is inserted, or Binds to: <member> when the slot is empty and a valid member is selected.

Set the card binding label apart from the inventory label. In the first version, the label was drawn left-aligned right above "Inventory", in the same style, so it read like part of the inventory heading. It is now right-aligned against the card status icon and slot, with the member name in blue. The not-yet-bound Binds to: case is lighter and italic. Long member names are cut off with …; the card tooltip still shows the full name.

Drop the inventory label in the scripting terminal. The player inventory is clear without its label. Dropping it frees its row for the binding label, which is now vertically centered on the card slot.

Validation

  • Reproduced in-game on master: card bound to double, clicking const changed it to const.
  • After: same steps keep double (also checked on the server side copy of the card), clicking offset rebinds to offset.
  • Label checked in-game for an empty slot, a bound card, and a 36-character member name.
  • ./gradlew build and ./gradlew runGameTestServer (23 tests) pass.

Known limitation

Clicking a function parameter or local variable (for example x in function double(x)) still rebinds the card, since that is a valid name. The label at least makes this visible immediately.

🤖 Generated with Claude Code

https://claude.ai/code/session_018MRyTdV3fSV5Q5NPGep4q9

Placing the cursor on a keyword such as "const" or "function" selected it
as a member, which silently rebound the card in the terminal to a member
that can never exist. Keywords are now rejected with a dedicated error, and
the card keeps its previous binding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018MRyTdV3fSV5Q5NPGep4q9
The member a card is bound to was only visible in the card's tooltip, and
the member it would be bound to was not visible at all. A label below the
editor now shows either.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018MRyTdV3fSV5Q5NPGep4q9
@coveralls

coveralls commented Oct 18, 2026 •

Copy link
Copy Markdown

Coverage Report for CI Build 39114757050

Coverage increased (+1.3%) to 48.646%

Details

  • Coverage increased (+1.3%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 180 coverage regressions across 6 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

180 previously-covered lines in 6 files lost coverage.

File Lines Losing Coverage Coverage
org/cyclops/integratedscripting/client/gui/container/ContainerScreenTerminalScripting.java 117 0.0%
org/cyclops/integratedscripting/inventory/container/ContainerTerminalScripting.java 46 47.31%
org/cyclops/integratedscripting/core/language/LanguageHandlerJavaScript.java 11 56.25%
org/cyclops/integratedscripting/core/evaluate/ScriptVariable.java 3 81.25%
org/cyclops/integratedscripting/core/network/GraalScriptFactory.java 2 71.05%
org/cyclops/integratedscripting/api/language/ILanguageHandler.java 1 0.0%

Coverage Stats

Coverage Status
Relevant Lines: 2675
Covered Lines: 1419
Line Coverage: 53.05%
Relevant Branches: 906
Covered Branches: 323
Branch Coverage: 35.65%
Branches in Coverage %: Yes
Coverage Strength: 24.86 hits per line

💛 - Coveralls

The binding label looked like the inventory label below it, while it is
about the card slot. It is now right-aligned next to the card status icon,
with the member highlighted, and the not yet bound case shown in italics.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018MRyTdV3fSV5Q5NPGep4q9
The player inventory is clear without its label, and dropping it frees its
row for the card binding label, which is now centered next to the card slot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018MRyTdV3fSV5Q5NPGep4q9
@rubensworks
rubensworks merged commit 1030ef3 into master-1.21-lts Oct 18, 2026
23 checks passed
@rubensworks
rubensworks deleted the terminal-ux/card-binding branch October 18, 2026 12:43
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.

3 participants