Home Artists Posts Import Register
Patreon importer is back online! Tell your friends ✅

Content

===
DISCLAIMER: If you are not interested in coding you might want to skip this ... ;)
===

Hi,

I have been thinking a bit about which tech changes to implement into the SJX Game Engine to upgrade it for SJX 2. These are all changes that do not introduce "new" features but may be the basis to do so efficiently.

Here is a list and the motivation behind it.

a.) Renpy and Python Upgrade

b.) Static Data Management (Locations, Quests, Items, Active Elements, ...)

c.) GAME registry system

d.) Establish an Upgrade Compatibility "Safe Zone"

Item a.) is obviously necessary to catch up with Renpy development, get access to new pygame module (explosions, clock, ...) and also mandatory after I upgrade my OS I assume.

Item b.) has plagued me since Princess. In effect, when the game starts for the first time, it reads in items, locations, clickable elements, etc. This means they are no longer easily changeable (e.g. if I update the item list the new item will not show up in game as long as the Game isn't restarted from start).
I plan to change that so every night the static data is re-analyzed and if necessary each item selectively updated in game. New locations, items etc can thus be be added without losing save game compatibility.

Item c.) is related to b.) So far I lazily updated static data items (e.g. location dict records, ...) with status info ("place visited" etc.). If I want the freedom to update static data elements over night, I need to relocate such status info to a kind of GAME registry that documents states related to static data elements.

If I introduce a.) , b.) and c.) I can possibly work for longer on a "labeled" (aka save game compatible) codebase without nuking process flow consistency. In conjunction with d.), which would mean that at one time in-game the process flow ascends to call hierarchy top level (e.g. every night) before descending again that point could be used for "robust" game states that do not need to care about process flow so much and can be used as hook points for patches and data scrubbers, enabling bigger update packages without sacrificing save game compatibility.

As users will never read any caveats where and when to save to safely retain compatibility ;) and will flood me with error messages as result, I need to add some kind of vetting / game freeze if the "safe spot migration save" rule has been not observed when trying to migrate a save game across versions.

Inside a version saving anywhere and everywhere will remain possible as ususal, as this is a good feature imho.

Let me know what you think. Above approach is not guaranteed to work but at least will allow content only upgrades in a compatible way.

y.v.

Files

Comments

waffel

My best advice is that this should be your last game in Ren'Py, your games scope have outgrown Ren'Py. Ren'Py is an engine that makes VN development easy, but gameplay and memory management horrendous. The problem with b), is trivial to solve in SDL, Godot, Gamemaker and Unity. What we should accept, is that the game where you switch, will be smaller than the last you made with Ren'Py so you have opportunity to adapt to a new engine. When you have acclimatized to a new engine, you will probably also see a general productivity increase.

y.v.

Yes, a new engine might be a good idea (probably Godot). But it can't harm to put my SJX code in Renpy on a solid footing for easy expansions ;) Whats SDL? Pygame?

Tansi

As to b), I think a nightly reload is the way to go. If slow, precompile and load via pickle/unpickle or the like. For savegame compatibility, I think there is no way around consistency rules and checks, also for your own testing. That will probably mean that major story additions require "hook points" or the like and cannot be done in other places. It may also mean you need a big, fat whiteboard for an overall game flowchart or something like it. Overall, I think you have reached the point where you need real architecture. That does increase complexity by at least an order of magnitude, but it allows you do to things you cannot currently do, like importing older saves. That seems to be the most pressing tech limitation you currently have.

y.v.

I did a trial with b.) and the quest database, which is reparsed every night since V0.9 or so. Time for that is negligible. The process flow architecture change for the "hook point" is the main architectural issue to solve imho, but i I climb up to main script level at one point every night the issue can be solved (provided this is the hook for save game migration and all other saves are not accepted in a new version)

Piotr Sulecki

As for b), I assume your intent is for it to work with the same saved game compatibility rules as always, right? I mean, if you load a game from 1.40 in 1.50, it shouldn't work, but if you load a saved game from 1.50.1 into 1.50.3, it should? If so, there's a way to do this during the game load. Create the static copies the same way you are doing now, and have them update the loaded items accordingly. I know RenPy allows you to specify a label to call after a game load (Brothel King 0.3 does that, and displays a warning if the loaded game was saved with a different game version than currently running); you can check the saved game version and selectively update the items. This way there's no need to do that every night.

y.v.

That is a good tip for the stop. I didn't know that you can modify the save and load code with hooks to include your own label. I will definitely have a look. The purpose behind that mechanism would be to have pure content updates, for example, with new locations or new items without destroying safe game compatibility and forcing the player to restart the game

Piotr Sulecki

Looking at the BK0.3 source code, there's simply an "after_load" label defined. This label doesn't occur anywhere else in the code, so this might simply be a RenPy hook. And yes, it's listed here (https://www.renpy.org/doc/html/label.html) as one of the special labels.

Mox

Why aren't you just extending the functionality of your Multiverse pods? They are already one of the best systems for save compatibility that I've seen. There must be a way to detect that Ren'py tried to load a game from a previous version. So when that happens, start a new game and auto-magically set the player at an appropriate checkpoint with the appropriate inventory contents as defined in the pod file. If you convert all quest progress into variables that are stored in the pod file when it is generated, then can't you also skip to that stage of each quest? A good rule of thumb might be one stage for each gallery image. I suppose the burden of generating a multiverse pod is still on the player. Unless you can generate one each time Ren'py saves and track which save file it goes with. If you can inject custom save data into the normal save files for use in case of a version update then you're fully auto-magic. So, you know, just refactor the entire game around a new style of save file. That's all. But yes, real software developers are supposed to separate the Model from the View (MVC). I don't think Ren'py was made with particularly robust software engineering principles in mind. It was more of "How can we make things easier for VN developers".

y.v.

Yes, that would be essentially creating save points and creating custom save formats. I still hope with a proper architecture something of a mix could be possible a.) save anywhere within versions b.) special save point resume across versions There is an executo on load save game hook I can use for b.), the art is only to find a "landing zone" for consolidation of process flow and data. If all works well this might be in the captains cabin in the "over night" code part. Advantage is, this approach would still allow me using the renpy save library (I'd hate to touch that thing...)