Discussion: Creation of a "Global" GoW python system

Discussion: Creation of a "Global" GoW python system

Postby GPNMilano » Sat Dec 26, 2009 10:01 pm

It was suggested by our illustrious Tsar Hoikas that we move the conversation of something relevant to the guild and the future of age writing, off of PMs to a more public forum for the representatives so:

D'Lanor and I were discussing the use of chronicles in the vault, and the method to which they can be added for fan created ages in the current system we have.

For those who don't know, Chronicles are created via python scripts and written to the vault. A chronicle is a variable or string that is set into a specific node in the vault. Chronicles have multiple uses as they can A. Save a players progress in an age. B. Can be used to save variables for later updating. C. Can be used for cross age puzzles so that one can journey to one age, and then to another that are interconnected in their story, but have separate SDL, prp and age files.

D'Lanor suggested awhile ago using this system that he sent a proposal to Cyan about: Fan made age and vault chronicles. He has not heard back from Cyan yet. As I was planning on using this system in several of my ages. He proposed a more viable method in those discussions:

D'Lanor wrote:Happy holidays

I never heard back from Cyan. In the mean time I have also been using this idea for an age I am doing the wiring for. I made a global xChronHandler.py module and simplified the concept somewhat.
I am now handling the creation of both the Base and Age chronicle layers in the main Python file of the age(s) which use(s) them. In my original concept for MORE the Base chronicle would have been created in another age. To be more precise: in a Cyan age, which is not a desirable option anymore.

Here is the code from xChronHandler.py

Code: Select all
from Plasma import *
from PlasmaTypes import *
kChronicleUserAgeType = 4

def ISetBaseChron():
    vault = ptVault()
    entry = vault.findChronicleEntry('UserAges')
    if (type(entry) == type(None)):
        PtDebugPrint('ISetBaseChron: Create UserAges base chronicle')
        vault.addChronicleEntry('UserAges', kChronicleUserAgeType, '')
        return 1
    PtDebugPrint('ISetBaseChron: UserAges base chronicle found, do nothing...')
    return 0



def ISetSubChron(ageName):
    if (not ageName):
        return
    ourChild = None
    vault = ptVault()
    entry = vault.findChronicleEntry('UserAges')
    if (type(entry) == type(None)):
        PtDebugPrint('DEBUG: No UserAges chronicle')
        return
    chronRefList = entry.getChildNodeRefList()
    for subChron in chronRefList:
        theChild = subChron.getChild()
        theChild = theChild.upcastToChronicleNode()
        if (theChild.chronicleGetName() == ageName):
            ourChild = theChild
            break

    if (type(ourChild) == type(None)):
        PtDebugPrint(('ISetSubChron: Create subchronicle %s' % ageName))
        newNode = ptVaultChronicleNode(0)
        newNode.chronicleSetName(ageName)
        newNode.chronicleSetType(kChronicleUserAgeType)
        newNode.chronicleSetValue('')
        entry.addNode(newNode)



def IWriteAgeChron(ageName, chronName, chronVal):
    chronVal = str(chronVal)
    ourChild = None
    vault = ptVault()
    entry = vault.findChronicleEntry('UserAges')
    if (type(entry) == type(None)):
        PtDebugPrint('DEBUG: No UserAges chronicle')
        return
    chronRefList = entry.getChildNodeRefList()
    for ageChron in chronRefList:
        theChild = ageChron.getChild()
        theChild = theChild.upcastToChronicleNode()
        if (theChild.chronicleGetName() == ageName):
            PtDebugPrint(('IWriteAgeChron: %s chronicle found' % ageName))
            chronRefList2 = theChild.getChildNodeRefList()
            for ageChron2 in chronRefList2:
                theChild2 = ageChron2.getChild()
                theChild2 = theChild2.upcastToChronicleNode()
                if (theChild2.chronicleGetName() == chronName):
                    ourChild = theChild2
                    break

            if (type(ourChild) == type(None)):
                PtDebugPrint(('IWriteAgeChron: Create chronicle %s, value=%s' % (chronName,
                 chronVal)))
                newNode = ptVaultChronicleNode(0)
                newNode.chronicleSetName(chronName)
                newNode.chronicleSetType(kChronicleUserAgeType)
                newNode.chronicleSetValue(chronVal)
                theChild.addNode(newNode)
            else:
                if (ourChild.chronicleGetValue() == chronVal):
                    PtDebugPrint('IWriteAgeChron: Chronicle value already correct, do nothing')
                    return
                PtDebugPrint(('IWriteAgeChron: Change chronicle %s value to %s' % (chronName,
                 chronVal)))
                ourChild.chronicleSetValue(chronVal)
                ourChild.save()




def IReadAgeChron(ageName, chronName):
    vault = ptVault()
    entry = vault.findChronicleEntry('UserAges')
    if (type(entry) == type(None)):
        PtDebugPrint('DEBUG: No UserAges chronicle')
        return 0
    chronRefList = entry.getChildNodeRefList()
    for ageChron in chronRefList:
        theChild = ageChron.getChild()
        theChild = theChild.upcastToChronicleNode()
        if (theChild.chronicleGetName() == ageName):
            PtDebugPrint(('IReadAgeChron: %s chronicle found' % ageName))
            chronRefList2 = theChild.getChildNodeRefList()
            for ageChron2 in chronRefList2:
                theChild2 = ageChron2.getChild()
                theChild2 = theChild2.upcastToChronicleNode()
                if (theChild2.chronicleGetName() == chronName):
                    chronVal = theChild2.chronicleGetValue()
                    PtDebugPrint(('IReadAgeChron: %s chronicle found, value=%s' % (chronName,
                     chronVal)))
                    return chronVal


    PtDebugPrint(('IReadAgeChron: Chronicle %s missing' % chronName))
    return 0

And here is an example of how the Base and Age chronicle layers are created upon link in. The trick was to create them one by one in way the vault (especially the online one) can handle.

Code: Select all
from Plasma import *
from PlasmaTypes import *
import xChronHandler
class SomeAge(ptResponder,):

    def __init__(self):
        ptResponder.__init__(self)
        self.version = '1'
        print ('__init__%s v.%s' % (self.__class__.__name__,
         self.version))



    def OnFirstUpdate(self):
        pass


    def Load(self):
        pass


    def OnServerInitComplete(self):
        kTime = 0.1
        if xChronHandler.ISetBaseChron():
            kTime = 5
        PtAtTimeCallback(self.key, kTime, 1)



    def OnNotify(self, state, id, events):
        pass


    def OnTimer(self, id):
        if (id == 1):
            xChronHandler.ISetSubChron('SomeAge')



#glue section here

If the base chronicle already exists the age subchronicle is created immediately. If neither exists the vault is given some time to add the base chronicle before the age subchronicle is placed inside of it.


Our discussion touched upon a subject that, to me, would be a great addition to the GoW's and future age creation projects. A global system of python files. Such as xChronHandler.py. These would be stored in a PAK file, and distributed via the Offline KI. What could be done is someone submits an idea for a global python file, (any python file that can be used in multiple ages would fall into this category. This is how Cyan does it, which is why you find a great deal of their python files starting with "x" and then the name of the file. With this system, we would be able to avoid having multiple python files that do basically the same thing. We already call Cyan's python files for certain things, and I see no reason that Fan Created Ages can't use a more global system that is kept up to date by the GoW and distributed via the OfflineKI, or if we prefer a link on the Wiki.
You can't stop the truth. IC Blog
User avatar
GPNMilano
 
Posts: 1155
Joined: Mon Apr 21, 2008 5:50 am

Re: Discussion: Creation of a "Global" GoW python system

Postby Chacal » Sun Dec 27, 2009 1:51 am

This sounds good to me. Python is one of the hardest parts of writing and most writers' needs are almost the same. A unified library would greatly ease the process.

We (myself not included) have already proven that we can contribute on writing and maintaining code. The latest PyPrp version being an example.
Chacal


"The weak can never forgive. Forgiveness is an attribute of the strong."
-- Mahatma Gandhi
User avatar
Chacal
 
Posts: 2508
Joined: Tue Nov 06, 2007 2:45 pm
Location: Quebec, Canada

Re: Discussion: Creation of a "Global" GoW python system

Postby J'Kla » Sun Dec 27, 2009 4:29 am

I know this is something I have wanted to get a handle on for ages. I have numerous puzzle ideas that are locked for the want of variables. Most of my puzzle ideas are locked into a situation where you set a value based on what you find in the age and the exit or door to the next section opens.

At the moment we are tied to press the button and the door opens or find the book and link out.
User avatar
J'Kla
 
Posts: 1003
Joined: Wed Feb 20, 2008 3:16 pm
Location: Geordieland UK

Re: Discussion: Creation of a "Global" GoW python system

Postby Trylon » Sun Dec 27, 2009 3:37 pm

Good job posting this here! (PM's tend to flood my inbox :D)

Oh, and I like the idea!
One day I ran through the cleft for the fiftieth time, and found that uru held no peace for me anymore.
User avatar
Trylon
 
Posts: 1446
Joined: Fri Sep 28, 2007 11:08 pm
Location: Gone from Uru

Re: Discussion: Creation of a "Global" GoW python system

Postby diafero » Mon Dec 28, 2009 2:58 am

Sounds good to me - and I would be ok putting it into the Offline KI. Just PM me for my mail address, and I'll add it to the pak file so that it is included in the next release.

Now, I wonder, if some ages are going to depend on the Offline KI - there is another pain point which could be tackled: Fan-ages doing linking. Almost each time a fan-age links to another age using the kOriginalBook/kOwnedBook linking rules, they do it wrong. I can't really blame them for that since the system is completely awful. As a solution, I extended the Python module which started as Offline KI internal linking helper (xLinkMgr) to be able to link to all ages, and to retrieve all the necessary information from the AvailableLinks.inf file. Then I spent a good amount of time (some weeks) to tweak that file as well as the xKI.py and nxusBookMachine.py files (which also deal with age names) to be correct and consistent. That way I am quite sure all linking done via xLinkMgr.LinkToAge('agename', 'spawnpoint') will not break the vault (offline, hardly anyone will notice, but online that's a different matter). I even replaced many of the links Cyan created for POTS by xLinkMgr calls as they did it Completely Wrong (TM) in the second expansion pack. I wonder whether it would be a good idea to advise people to use that function instead of the Plasma API.

A counter-argument for both suggestions would be people not willing to install the Offline KI because they prefer their own hacked KI, like D'Lanor. They would have to manually add these files to their installation and keep them up-to-date.
I prefer e-mails to "diafero arcor de" (after adding the at and the dot) over PMs.

"Many people's horizon is a circle with a radius of zero. They call it their point of view."

Deep Island Shard | Offline KI
diafero
Deep Island Admin
 
Posts: 2966
Joined: Mon May 05, 2008 5:50 am
Location: Germany

Re: Discussion: Creation of a "Global" GoW python system

Postby D'Lanor » Mon Dec 28, 2009 8:27 am

diafero wrote:Sounds good to me - and I would be ok putting it into the Offline KI. Just PM me for my mail address, and I'll add it to the pak file so that it is included in the next release.

Now, I wonder, if some ages are going to depend on the Offline KI - there is another pain point which could be tackled: Fan-ages doing linking. Almost each time a fan-age links to another age using the kOriginalBook/kOwnedBook linking rules, they do it wrong. I can't really blame them for that since the system is completely awful. As a solution, I extended the Python module which started as Offline KI internal linking helper (xLinkMgr) to be able to link to all ages, and to retrieve all the necessary information from the AvailableLinks.inf file. Then I spent a good amount of time (some weeks) to tweak that file as well as the xKI.py and nxusBookMachine.py files (which also deal with age names) to be correct and consistent. That way I am quite sure all linking done via xLinkMgr.LinkToAge('agename', 'spawnpoint') will not break the vault (offline, hardly anyone will notice, but online that's a different matter). I even replaced many of the links Cyan created for POTS by xLinkMgr calls as they did it Completely Wrong (TM) in the second expansion pack. I wonder whether it would be a good idea to advise people to use that function instead of the Plasma API.

A counter-argument for both suggestions would be people not willing to install the Offline KI because they prefer their own hacked KI, like D'Lanor. They would have to manually add these files to their installation and keep them up-to-date.

Ok, I think I alreay have your email address. I will send the file to you when I get home (I am currently staying with my parents). Then I will write up some instructions and add them to the wiki.

I'm sure that people who can maintain their own hacked KI would be able to cope with that. ;)

Linking is a pet peeve of mine as well, which is one of the reasons I made the book template. It has always been my opinion that a fan age should never link to Cyan's ages because there is about 99% chance that you break the order of events as they were meant to be played (however, the book template does not attempt to prevent this).

My main concern with the Offline KI linking system however is that it was made for Alcugs shards and their incomplete set of linking rules. Is it adaptable to public ages, sub ages and child ages? Then there is also the fact that your system bypasses the avatar linking animations in the converted MOUL ages and worse, in existing POTS ages as well. The latest version of my book template can add avatar animations (although not by the same method as Cyan uses).

So with the concerns above in mind I have one question for you, diafero: If people use your function, can they still use the book template?

P.S. In Cyan's defense I would like to add that POTS obviously was not meant to be played online so they didn't have to bother about netlinking rules. Nor did they care how an age name would show up in a KI which did not exist. I bet that backfired in their face when they had to adapt these ages for MOUL. :D
"It is in self-limitation that a master first shows himself." - Goethe
User avatar
D'Lanor
 
Posts: 1980
Joined: Sat Sep 29, 2007 4:24 am

Re: Discussion: Creation of a "Global" GoW python system

Postby diafero » Mon Dec 28, 2009 2:18 pm

I'm sure that people who can maintain their own hacked KI would be able to cope with that. ;)
I'm glad you agree on this :)

Linking is a pet peeve of mine as well, which is one of the reasons I made the book template. It has always been my opinion that a fan age should never link to Cyan's ages because there is about 99% chance that you break the order of events as they were meant to be played (however, the book template does not attempt to prevent this).
Nor does the Offline KI, as can be seen by ages linking to the Cleft. However, it prevents breakage on the lower levels of the game, which is IMHO already better than nothing.

My main concern with the Offline KI linking system however is that it was made for Alcugs shards and their incomplete set of linking rules. Is it adaptable to public ages, sub ages and child ages?
Indeed the system was made with Alcugs Shards and POTS in mind, so no, it does not support any other rules besides "basic" and "original" as there is no need in POTS. The KI does not support UU anyway. I imagine it could be extended, but I wonder to what extend fan ages use this. So far, I found no example which broke by replacing the linking rule with either kBasicLink or kOriginalBook.

Then there is also the fact that your system bypasses the avatar linking animations in the converted MOUL ages and worse, in existing POTS ages as well. The latest version of my book template can add avatar animations (although not by the same method as Cyan uses).
If I have to decide between a broken vault due to wrong linking rules and missing linking animation, the result is quite obvious, I'd say ;-) . As for MOUL, they are not bypassed but simply were never added to the PRP by GPNMilano.

So with the concerns above in mind I have one question for you, diafero: If people use your function, can they still use the book template?
I've got a little script here which can automatically fix pak files based on your book template to use my linking manager instead of directly calling the Plasma API - using only the age filename and spawn point provided by the age writer while discarding the other, potentially wrong information. It definitely works well in all fan ages I ever tested, which should be all of them - including the linking animation in Prad.

P.S. In Cyan's defense I would like to add that POTS obviously was not meant to be played online so they didn't have to bother about netlinking rules. Nor did they care how an age name would show up in a KI which did not exist. I bet that backfired in their face when they had to adapt these ages for MOUL. :D
Defence accepted, but that doesn't change the fact that it's a pain to find all the spots where it's done wrong and fix them :D
I prefer e-mails to "diafero arcor de" (after adding the at and the dot) over PMs.

"Many people's horizon is a circle with a radius of zero. They call it their point of view."

Deep Island Shard | Offline KI
diafero
Deep Island Admin
 
Posts: 2966
Joined: Mon May 05, 2008 5:50 am
Location: Germany

Re: Discussion: Creation of a "Global" GoW python system

Postby Jamey » Wed Dec 30, 2009 11:15 am

I'm not very knowledgeable with Python Scripting & Programming, so please pardon my ignorance here :oops: Will these new scripts simplify processes used in age creation, and make things a little bit easier when using Python scripting when making fan-created ages?

Most of what has been said so far seems way over my head :? Props to everyone who understands this stuff! :P
KI#46415
Jamey
 
Posts: 528
Joined: Sat Oct 20, 2007 8:32 pm
Location: Chicago, IL

Re: Discussion: Creation of a "Global" GoW python system

Postby D'Lanor » Wed Dec 30, 2009 11:49 am

Yes, global Python modules are intended to make things easier. They are meant to let everybody make use of the same code without the need to copy the whole chunk into your own age's Python files.

The Python script that started the discussion deals with chronicles in the vault though, which is an aspect of Uru most writers are probably not aware of. Chronicles are used for puzzles which require the storage of personal player progress and other settings which are not tied to an age state.
"It is in self-limitation that a master first shows himself." - Goethe
User avatar
D'Lanor
 
Posts: 1980
Joined: Sat Sep 29, 2007 4:24 am

Re: Discussion: Creation of a "Global" GoW python system

Postby Jamey » Wed Dec 30, 2009 2:36 pm

D'Lanor wrote:Yes, global Python modules are intended to make things easier. They are meant to let everybody make use of the same code without the need to copy the whole chunk into your own age's Python files.


So, does this mean...no more alc-script in Blender? How does this work? One file for all ages?

D'Lanor wrote:The Python script that started the discussion deals with chronicles in the vault though, which is an aspect of Uru most writers are probably not aware of. Chronicles are used for puzzles which require the storage of personal player progress and other settings which are not tied to an age state.


So these "Chronicles" work sort of like... expansion packs for an age?



Sorry if these are confusing questions, but as I said, I know nothing about all of this, other than how to put alc-script into Blender. I'm an Artist and a 3D Modeler; Programming is not one of my best subjects :oops:
KI#46415
Jamey
 
Posts: 528
Joined: Sat Oct 20, 2007 8:32 pm
Location: Chicago, IL

Next

Return to Representative Discussion

Who is online

Users browsing this forum: No registered users and 0 guests

cron