call_in_new_context creates a new context, which has its own set of game state. This includes the scene lists that comprise the layers, the call stack, and so on.Aenakume wrote:Uh oh, that might make things difficult. ^_^; i thought that's what renpy.call_in_new_context() did.
Only the outermost context (the default one) can be saved in and rolled-back in, since otherwise, you'd have to be able to start execution in the middle of a block of python code. And that's something we can't do. Code needs to be designed to work around this.
(Loading a game performs a rollback during the load process, so it will always go back at least to the start of a python statement.)
Re: the map engine
Your best bet is to structure it as an event driven system. The displayable has two states: static and dynamic. In the static state, it just shows the map, and doesn't let people interact with it. When the user calls a special function, it switches to the dynamic state, which lets people walk about the screen. This function returns when an "event" occurs... an event could be an encounter with a character or a hotspot or something.
Each event is an object giving the parameters of the encounter. This is returned from the special function, and passed into Ren'Py code that decides what to do with it, jumping to the Ren'Py code for the appropriate encounter. When the encounter is done, it jumps back to a label that calls the special function again, starting the cycle anew.
Each python block should contain at most one logical interaction with the user. These logical interactions could consist of multiple ui.interacts (for example, purchasing an item in a shop could require confirmation), but they should be something the user sees as a single event to roll back over.
Code inside callbacks (and similarly, code run from renpy.Displayables) should be relatively simple. Its job is to decide two things:
- Is this the end of the interaction?
- If so, what should the interaction return?
Once the return value from ui.interact is known, it can be dealt with by normal Ren'Py code, running in the outermost context.