First. Your example code probably isn't doing what you think it is. You're using two separate variables there: the temporary variable _total_energy and the story variable $_total_energy. If that was intentional, then you're probably only going to be confusing potential helpers by doing that, so you might want to reconsider your naming scheme.
----
You'll probably want to verify that the player hasn't entered something that cannot be converted into an integer at, or near, the <<textbox>> itself, so you'll more than likely want something like the following:
@@#display_total_energy;$total_energy@@ <<textbox "_total_energy" $total_energy>> \
<<button "Change">>
<<replace "#error_total_energy">><</replace>>
<<set _total_energy to Number.parseInt(_total_energy.trim(), 10)>>
<<if not Number.isInteger(_total_energy)>>
<<replace "#error_total_energy">>Error: invalid integer<</replace>>
<<else>>
<<set $total_energy to _total_energy>>
<<replace "#display_total_energy">>$total_energy<</replace>>
<</if>>
<</button>> \
@@#error_total_energy;@@
PS: If you ever needed to accept both floating point and integer numbers, then that might look something like the following instead:
@@#display_total_energy;$total_energy@@ <<textbox "_total_energy" $total_energy>> \
<<button "Change">>
<<replace "#error_total_energy">><</replace>>
<<set _total_energy to Number(_total_energy.trim())>>
<<if Number.isNaN(_total_energy) or not Number.isFinite(_total_energy)>>
<<replace "#error_total_energy">>Error: invalid number<</replace>>
<<else>>
<<set $total_energy to _total_energy>>
<<replace "#display_total_energy">>$total_energy<</replace>>
<</if>>
<</button>> \
@@#error_total_energy;@@