View unanswered posts | View active topics It is currently Sat Nov 22, 2014 2:01 pm



Reply to topic  [ 29 posts ]  Go to page 1, 2  Next
Dynamic Types 
Author Message
Developer
Developer

Joined: Thu Jul 24, 2003 9:53 pm
Posts: 2356
Post Dynamic Types
I'm working on Betel's evalXML suggestion: http://wiki.neurohack.com/transcendence/trac/ticket/737

I've come up with a design for a feature I call "Dynamic Types" and I'd love some feedback:

The goal of Dymanic Types is to allow an extension to create new types at runtime. For example, this might allow a mod to create a weapon with random properties. As with Betel's suggestion, the way this works is by providing an XML string that describes the type (using all the normal syntax, including embedded code) and adding it as a new type at runtime.

To implement this, I propose the following:

TEMPLATE TYPE

Imagine syntax like this:

Code:
<TemplateType UNID="&itRandomWeapon;">
   <StaticData>
      <Template><![CDATA[
         <ItemType
            name="%itemName%"
            ...
            >
            <Weapon
               damage="%itemDamage%"
               ...
               >
               %itemEffect%
            </Weapon>
         </ItemType>
      ]]></Template>
   </StaticData>

   <Events>
      <OnEval><![CDATA[
           (subst (typGetStaticData &itRandomWeapon; "Template")
              {
                 itemName : (random '("Arguil cannon" "Brodian lancer" "Catapon weapon"))
                 itemDamage : (random '("damage='laser:3d6'" "damage='particle:1d8'"))
                 itemEffect : (random '(
                    "<Effect><Beam beamType='laser' primaryColor='255, 255, 0'/></Effect>"
                    "<Effect><Beam beamType='laser' primaryColor='0, 255, 255'/></Effect>"
                    ))
                 }
              )
      ]]></OnEval>
   </Events>
</TemplateType>


At game-creation time (before we bind UNIDs to structures) we iterate over all template types and evaluate them. In the example above, the UNID "&itRandomWeapon;" will be initialized to the result of the evaluation of the OnEval code. The semantics of OnEval are simple: we expect it to return a string of well-formed XML and we load it as if it were any other type.

Doing this at game creation time has a few advantages:

1. You can use the UNID (&itRandomWeapon;) in any other type (e.g., ship classes) as if it were a normal type.
2. I think you can specify an existing UNID (e.g., &itLaserCannon;) which will cause the dynamic type to override the existing one. [there might be roadblocks I haven't thought about.]
3. You can generate types (such as SystemMap) that are only used at game-creation time.

[A few notes of the above: First notice that I use the CDATA syntax. That's just standard XML syntax so that we don't have to escape all the angle-brackets (that works in today's XML parser). Second, notice the subst command takes a struct of key/value pairs--this makes the syntax easier, IMHO, and is something that I think I will add in 1.08.]

DYNAMIC TYPE FUNCTIONS

I think the above handles 80% of the use-case, and if people agree, the above might be all I get done in 1.08. But another possible use case is to create types in the middle of the game. For example, imagine that a quest needs to generate a weapon based on an item that the player brings.

We can add the following functions to help:

(unvCreateType UNID string) -> True/Nil

This function takes an UNID (see below) and a string. The string is just some well-formed XML string that could be generated using the subst technique above. If successful, this will register a new type associated with the given UNID. You can then use the UNID in any function that accepts it (e.g., itmCreate).

The type that you create will be persisted with the game.

There are a few limitations:

1. The UNID must be unused (thus, you cannot override a type using this technique, even one that was previously created with the function)
2. The kinds of types that you can create is more limited. E.g., you cannot create a SystemType with this technique.

To help generate UNIDs, we need a new functions:

(unvDynamicUNID string) -> UNID

This function works as follows: If "string" has not yet been bound, it generates a new UNID (from the 0xF??????? space) and associates the string with it. If the string has already been bound, it just returns the UNID for that string.

You can now use this function to create new types without having to worry about UNIDs. For example, you can do something like:

(unvCreateType
(unvDynamicUNID "myNewAmazingWeapon")
XMLforNewWeapon
)

and then:

(itmCreate (unvDynamicUNID "myNewAmazingWeapon") 1)

I'd love to hear feedback on this design. As I said, I'm leaning towards implementing template types for 1.08 and leaving the dynamic type functions for later, but I'm happy to hear counter-arguments.


Mon Feb 20, 2012 7:29 pm
Profile WWW
Fleet Officer
Fleet Officer
User avatar

Joined: Sun Mar 05, 2006 6:31 am
Posts: 1920
Post Re: Dynamic Types
hmm I like it but have a couple questions.

Would storage.xml be loaded before this allowing us access to data saved there?
Would we be able to use typSetGlobalData or something else to communicate between different evaluations? (other than globals of course)
I am assuming that it isn't saved in the saved game is this correct?, or do you load the save game when the game first runs so we can do the title screen ships.

_________________
Crying is not a proper retort!


Mon Feb 20, 2012 8:03 pm
Profile
Developer
Developer

Joined: Thu Jul 24, 2003 9:53 pm
Posts: 2356
Post Re: Dynamic Types
Betelgeuse wrote:
hmm I like it but have a couple questions.

Would storage.xml be loaded before this allowing us access to data saved there?
Would we be able to use typSetGlobalData or something else to communicate between different evaluations? (other than globals of course)
I am assuming that it isn't saved in the saved game is this correct?, or do you load the save game when the game first runs so we can do the title screen ships.


1. Yes, Storage.xml is loaded first, so you can use it.
2. typGet/SetGlobalData is a little tricky. You can definitely call it on static types; you definitely can't call it on dynamic types that have not yet been defined. It will probably fail if you try to call it for your own type in the middle of OnEval (but I'm not sure).
3. The dynamic types are saved along with the game, so you don't have to re-create them. In fact, you'll get an error if you try to redefine them.


Tue Feb 21, 2012 1:20 am
Profile WWW
Fleet Admiral
Fleet Admiral
User avatar

Joined: Tue Feb 05, 2008 1:10 am
Posts: 5138
Location: At his shipyards, building the TSB fleet.
Post Re: Dynamic Types
:D

To say the least, this is very, very cool. I can do some more fancy things for wyvera & the tinkers (TSB) with this.

_________________
(shpOrder gPlayership 'barrelRoll)
Image
Image


Tue Feb 21, 2012 6:07 am
Profile WWW
Fleet Officer
Fleet Officer
User avatar

Joined: Sun Mar 05, 2006 6:31 am
Posts: 1920
Post Re: Dynamic Types
one question, what happens when you start a new game when your old game had dynamic types defined? Would it be locked into those? Or would things that are dynamic type dependent not be on the title screen (then when are they bound)?

_________________
Crying is not a proper retort!


Tue Feb 21, 2012 10:00 am
Profile
Fleet Officer
Fleet Officer

Joined: Wed Jan 14, 2009 3:08 am
Posts: 1651
Location: Enslaved by the Iocrym
Post Re: Dynamic Types
This looks very cool George. What a lot of fun we can have with this! :)

Personally I think the dynamic type functions sound most exciting, but I have no argument for why we should have those first. One question I do have about them though, is if the xml you must provide can be a string. So, "<ItemType ...>...</ItemType>"?

Other than that I can not think of anything that has not already been brought up. Except that, wow, I seriously need to get modding again once 1.08 comes out. So many cool new toys. Thanks! XD

_________________
Get your own Galactic Omni Device
Get it now. It's free!!
Image


Tue Feb 21, 2012 5:26 pm
Profile
Developer
Developer

Joined: Thu Jul 24, 2003 9:53 pm
Posts: 2356
Post Re: Dynamic Types
Betelgeuse wrote:
one question, what happens when you start a new game when your old game had dynamic types defined? Would it be locked into those? Or would things that are dynamic type dependent not be on the title screen (then when are they bound)?


When you press "New Game" all dynamic types are reset to initial conditions (whatever the adventure/extensions define).
When you press "Load Game" the dynamic types are initialized to whatever the saved game specifies.
[That is, dynamic types are bound to the game and do not "leak" from one game to another. If you want to share dynamic types across games then you can use Storage.xml for that.]


Tue Feb 21, 2012 6:19 pm
Profile WWW
Developer
Developer

Joined: Thu Jul 24, 2003 9:53 pm
Posts: 2356
Post Re: Dynamic Types
alterecco wrote:
This looks very cool George. What a lot of fun we can have with this! :)

Personally I think the dynamic type functions sound most exciting, but I have no argument for why we should have those first. One question I do have about them though, is if the xml you must provide can be a string. So, "<ItemType ...>...</ItemType>"?

Other than that I can not think of anything that has not already been brought up. Except that, wow, I seriously need to get modding again once 1.08 comes out. So many cool new toys. Thanks! XD


Turns out that creating a new function was easier than doing the TemplateType, so I did that first to test. And you can use a string. Here is an example that I just tested:

Code:
<OnGlobalUniverseCreated>
<![CDATA[
   (typCreate 0xf0000001 (cat
      "<ItemType name='cool item' level='1' value='100' mass='1' frequency='notRandom' description='Wow, I just created this!'>"
      "<Image imageID='&rsItems1;' imageX='192' imageY='96' imageWidth='96' imageHeight='96'/>"
      "</ItemType>"
      ))
]]>
</OnGlobalUniverseCreated>


The CDATA syntax is just so that I can use angle-brackets in the string. And notice also that I used single-quotes instead of double-quotes for the attributes. I believe this is supported by standard XML and it makes it easier to embed in a string.

p.s.: I also called the function typCreate instead of unvCreateType.


Tue Feb 21, 2012 6:23 pm
Profile WWW
Fleet Admiral
Fleet Admiral
User avatar

Joined: Tue Aug 26, 2008 12:02 am
Posts: 2058
Post Re: Dynamic Types
Betel thinks unvtypcreate can't overwrite a static type the way templatetype can.

What I'm really after is nonrandom templatetype. A fully random weapon can get completely out of balance so I want to be able to eg. generate a damage string then generate a firerate subject to additional constraints based on the damage string then generate a power use dependent on the exact damage and firerate.

And then I want to be able to make another weapon dependent on the first. Suppose the first is my randomization of the Turbolaser. I want to be able to generate a dual turbolaser and omni turbolaser with stats based on the turbolaser.

To do this I need to either be able to overwrite static types with unvtypcreate or embed translisp in templatetype and control or at least predict the order of evaluation of templatetypes. (If they evaluate in UNID order I can do the actual randomization on whichever base type has the lowest UNID. If they evaluate in file order within a file I can put the simplest version first. Except possibly the Moskva line I think the simplest version always has the lowest UNID anyways.) I'm pretty sure if unvtypcreate is able to overwrite static types I can control the order by placing them in a block.

_________________
Literally is the new Figuratively


Tue Feb 21, 2012 8:10 pm
Profile
Fleet Admiral
Fleet Admiral
User avatar

Joined: Tue Feb 05, 2008 1:10 am
Posts: 5138
Location: At his shipyards, building the TSB fleet.
Post Re: Dynamic Types
Will we be able to change the stats once set? And if not, can we delete old ones so that we don't waste our UNID space?

_________________
(shpOrder gPlayership 'barrelRoll)
Image
Image


Tue Feb 21, 2012 8:42 pm
Profile WWW
Developer
Developer

Joined: Thu Jul 24, 2003 9:53 pm
Posts: 2356
Post Re: Dynamic Types
Atarlost wrote:
Betel thinks unvtypcreate can't overwrite a static type the way templatetype can.

What I'm really after is nonrandom templatetype. A fully random weapon can get completely out of balance so I want to be able to eg. generate a damage string then generate a firerate subject to additional constraints based on the damage string then generate a power use dependent on the exact damage and firerate.

And then I want to be able to make another weapon dependent on the first. Suppose the first is my randomization of the Turbolaser. I want to be able to generate a dual turbolaser and omni turbolaser with stats based on the turbolaser.

To do this I need to either be able to overwrite static types with unvtypcreate or embed translisp in templatetype and control or at least predict the order of evaluation of templatetypes. (If they evaluate in UNID order I can do the actual randomization on whichever base type has the lowest UNID. If they evaluate in file order within a file I can put the simplest version first. Except possibly the Moskva line I think the simplest version always has the lowest UNID anyways.) I'm pretty sure if unvtypcreate is able to overwrite static types I can control the order by placing them in a block.


I think I get it.

TemplateTypes within an extension are guaranteed to evaluate in UNID order. [Eventually, I will probably have to alter the evaluation order of each extension based on dependencies. For example, if extension B depends on extension A, then TemplateTypes in extension A need to evaluate first, regardless of UNID.]

I should create an event that fires before any TemplateType is evaluated (something like <OnGlobalInitTypes>). You could create all your randomizations there in the proper order (and store them in global variables or whatever). Then all your TemplateTypes (for the turbolaser and dual turbolaser) can refer to the globals. Then you don't care what order the TemplateTypes get evaluated in.

It would also be pretty easy for me (I think) to allow OnGlobalInitTypes to call unvCreateType to override static types (this would be the only event in which you could do that). Then you can do all the work in script without any TemplateTypes.

p.s.: Now I know why you want this: http://wiki.neurohack.com/transcendence/trac/ticket/741 (which is unfortunately not that easy). If you could extract the XML from an existing type you could alter it and create a new type. For example, you could have a function that creates an omni version of any existing weapon.


Tue Feb 21, 2012 8:52 pm
Profile WWW
Developer
Developer

Joined: Thu Jul 24, 2003 9:53 pm
Posts: 2356
Post Re: Dynamic Types
Wolfy wrote:
Will we be able to change the stats once set? And if not, can we delete old ones so that we don't waste our UNID space?


No, not within a game, unfortunately. [Nor can we delete them, since we would have to search through all systems looking for references to the type you deleted--or risk a crash.]

But don't worry about UNID space. You can call unvDynamicUND more than 250,000,000 times before it runs out of UNIDs (it allocates UNIDs out of the reserved 0xF??????? space). [And this is a per-game limit--if you start a new game, the limit resets.]


Tue Feb 21, 2012 8:59 pm
Profile WWW
Fleet Officer
Fleet Officer

Joined: Wed Jan 14, 2009 3:08 am
Posts: 1651
Location: Enslaved by the Iocrym
Post Re: Dynamic Types
<OnGlobalInitTypes> seems like a very good idea.

Also, do angle brackets inside strings really get interpreted as xml if not inside a CDATA block?

_________________
Get your own Galactic Omni Device
Get it now. It's free!!
Image


Wed Feb 22, 2012 12:29 am
Profile
Fleet Officer
Fleet Officer
User avatar

Joined: Sun Mar 05, 2006 6:31 am
Posts: 1920
Post Re: Dynamic Types
a few of functions that came from irc discussions (should I make tickets for each of these?)

(itmSetFrequency UNID frequency) ;sets the frequency of an item
(staSetLevelFrequency UNID levelFrequency) ;sets the level frequency of a station

this would allow us to remove old items and stations (both static and dynamic) without breaking the game

(shpSwapWeapon ship equippedItem itemToBeSwapped) -> the swapped out item ; you would use this to install the itemToBeSwapped preserving weapon selected

(shpSwapArmor ship equippedItem itemToBeSwapped) -> the swapped out item ; you would use this to install the itemToBeSwapped preserving hp without

(shpSwapShield ship equippedItem itemToBeSwapped) -> the swapped out item ; you would use this to install the itemToBeSwapped preserving hp

_________________
Crying is not a proper retort!


Wed Feb 22, 2012 12:50 am
Profile
Fleet Admiral
Fleet Admiral
User avatar

Joined: Tue Aug 26, 2008 12:02 am
Posts: 2058
Post Re: Dynamic Types
The swap functions exist already. There's a minor problem with the weapon swapping function that can be fixed with tickets49 and 748.

_________________
Literally is the new Figuratively


Wed Feb 22, 2012 1:25 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 29 posts ]  Go to page 1, 2  Next

Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.