The answer very much depends on the behaviour you need from your called label. You're correct that
call_in_new_context will return control to your python code (along with any value returned by the label), the potential gotcha is that any recording of rollback within that label will be lost when it returns (this includes saving, any save made while in the call will load prior to it). This also means that after rolling back over the interaction calling your function, when attempting to roll-forward over it, the
call_in_new_context will repeat (as expected) but due to the missing rollback state rolling forward through it will not be possible.
Given your example this means that you would be unable to roll-forward through the
pause statement in
my_label, as it's an interaction.
Generally, assuming you wish to retain functional rollback behaviour for your players, I'd recommend not triggering any interactions with your called label. If however, as in this case, this is not possible and you need interactions within it, you have several options:
1) If the return value doesn't matter (as it appears not to in your case) and you're happy to forgo the label call during roll-forward, you could simply add a "if not in rollback" condition to the
call_in_new_context skipping the entire thing when rolling-forward.
2) If you're happy to skip the content of the label on roll-forward but you
do need the return value, you could capture the return value the first time, and store it in the rollback log manually so that when rolling-forward the label isn't called, but instead the value it would have returned is read out of rollback (look into the
checkpoint and rollforward_info functions for this).
3) Invert your current python-based design - instead of calling a function to abstract out python calculations and doing an additional label call from python, instead call a label to abstract out a renpy call and do some python calculations via python calls (which, now that I read it isn't terribly clear, so here's a potential example):
Code: Select all
label a_method(self):
# Scope the rv variable to this label call so that it doesn't leak out to the global scope.
$ renpy.dynamic('rv')
$ self.a_method_pre()
# You could call my_label here, or alternatively in-line its contents if it makes sense to do so.
call my_label
$ rv = self.a_method_post()
return rv
Hope this helps explains the limitations of using
call_in_new_context with a game (it's more designed for menus from what I can gather), and maybe has a solution that will work for you, good luck!