Pages

Saturday, May 10, 2025

Debugging Energy Logic in EJS: Solving the “Balanced” Mystery

 

Debugging Energy Logic in EJS: Solving the “Balanced” Mystery

Easy JavaScript Simulations (EJS) is a powerful platform for building interactive physics models. But even powerful tools can behave in puzzling ways. This is the story of a recent debugging journey to fix a subtle but critical logic flaw in an energy conservation simulation titled "LOLmaster_v18".

🧩 The Puzzle: When “Balanced” Isn’t Balanced

A user reached out with a curious issue: their simulation reported a “Balanced” energy state under conditions that clearly shouldn’t be balanced.

Here’s what was happening:

  • The initial state was configured to show only Kinetic Energy (K).

  • Users selected the energy types they expected to be present via two sets of checkboxes: “Check 5” (initial state) and “Check 6” (final state).

  • The problem: If a user dragged an energy bar (e.g., Elastic Energy, E) to a non-zero value without selecting that energy type in Check 5 or 6, the simulation sometimes still declared the system as “Balanced.”

This contradicted the user's intent and undermined the educational value of the simulation.

https://sg.iwant2study.org/ospsg/index.php//1199
link

https://sg.iwant2study.org/ospsg/index.php//1199
link


🔍 Investigating the Source: _source.json

In EJS, the entire simulation structure—model, variables, logic, and interface—is stored in a single file called _source.json. This file includes:

  • Metadata about the simulation

  • A Model section defining:

    • Variables (C, E, K, iniTotalEnergy, etc.)

    • Initialization code

    • Fixed relations (real-time logic)

    • Custom functions

  • A View section defining all UI elements and their bindings

To uncover the bug, we dove into the custom logic—specifically the function answers1(), which assesses whether energy states are balanced.

🧠 Root Cause: A Too-Forgiving Helper Function

The function answers1() relies on a helper called check5n6assistant(), which validates if the user's checkbox selections match the actual energy bar values.

Here’s a simplified version of the logic:

javascript
function check5n6assistant(C, E, G, I, K, N, energyLst, stateWord) { let checkLst = [C,E,G,I,K,N]; for (let i = 0; i < energyLst.length; i++) { if ((checkLst[i] == false) && (energyLst[i] != 0) && (!ignoreEnergyLst.includes(i))) { // User said energy is NOT present, but it is return false; } else if ((checkLst[i] == true) && (energyLst[i] == 0)) { // User said energy IS present, but it's not return false; } } return true; }

The issue lies in this part:

javascript
&& (!ignoreEnergyLst.includes(i))

This condition let the simulation ignore mismatches if the scenario designer generally allowed that energy type (e.g., Elastic energy) to be non-zero. But this overrode the user's explicit selection and created a mismatch between intention and feedback.

The Fix: Stricter, Clearer Validation

To make the simulation truly responsive to user input, we removed the conditional forgiveness:

javascript
// Fixed logic: if ((checkLst[i] == false) && (energyLst[i] != 0)) { return false; }

Now, if a user says an energy type shouldn’t be present, but the bar is non-zero, the simulation properly flags it as unbalanced—regardless of any general allowances by the scenario designer.

🛠️ Applying the Fix: A Few Twists

Fixing the logic was conceptually simple. Implementing it wasn’t.

  1. Initial Attempt with replace_in_file
    We tried a precise string replacement in _source.json, but it failed due to escaped characters, whitespace, and formatting. Code inside EJS JSON files is stored as stringified JavaScript, making replacements tricky.

  2. Fallback to write_to_file
    A safer but heavier approach was to rewrite the entire file with the corrected code. This approach is robust but requires more setup and care.

  3. The Human Touch
    In the end, the user, fully understanding the issue by then, applied the fix manually. It was a beautiful moment of human-AI collaboration, where mutual understanding resolved what tools alone couldn’t.

💡 Key Takeaways

This journey was more than just a fix—it was a learning experience:

  • Know your data structures: EJS’s _source.json is powerful but demands precision.

  • Be exact when replacing code in stringified formats—whitespace and escape characters count.

  • Iterate, refine, repeat: Debugging is detective work and trial-and-error.

  • Collaboration matters: AI can diagnose and suggest, but human insight still carries the day.

Thanks to this collaborative effort, “LOLmaster_v19” now reflects energy conservation logic more faithfully—bringing learners one step closer to mastering physics.

https://sg.iwant2study.org/ospsg/index.php//1199
link




No comments:

Post a Comment