Angband.oook.cz
Angband.oook.cz
AboutVariantsLadderForumCompetitionComicScreenshotsFunniesLinks

Go Back   Angband Forums > Angband > Variants

Reply
 
Thread Tools Display Modes
Old June 6, 2013, 19:33   #11
Magnate
Angband Devteam member
 
Join Date: May 2007
Location: London, UK
Posts: 5,057
Magnate is on a distinguished road
Send a message via MSN to Magnate Send a message via Yahoo to Magnate
Quote:
Originally Posted by mtadd View Post
4) default stat allocation when selecting point-based roller
Argh. I suppose it's inevitable that with such a variant-friendly game engine we're going to end up with multiple birth systems, but IMO this has always been an area where choice isn't needed. Are we going to have the autoroller too?!
Quote:
5) random name generation
That reminds me - Derakon, are you intending to use Sheldon W Simms's random name generator, beloved of *bands? Or something else? Porting the existing one would be a nice self-contained project for someone (possibly me if it's not done by the time I get to randarts).

Also, at the end of devlog #5 you asked:
Quote:
Regarding having e.g. "<+5 fin>", any thoughts on having pvals generally display short text for what they modify? In Vanilla it's just "<+4, +1>" and the like. v4's items tend to have longer names in general, and I suspect it's only going to get worse in Pyrel...
Personally I think the names are already so long that there's no point attempting to convey any more information in the name line, and we should assume that all info (including even 'primary' stats like dice, AC, balance, heft) will be obtained from the 'I'nspect screen. Any space that is available for items with short names will barely contain primary stats and plusses, let alone pvals.

Having said that, there's no reason you couldn't come up with two- or three-letter abbreviations for all the possible pval stats, so they could be represented like resists.
__________________
"3.4 is much better than 3.1, 3.2 or 3.3. It still is easier than 3.0.9, but it is more convenient to play without being ridiculously easy, so it is my new favorite of the versions." - Timo Pietila
Magnate is offline   Reply With Quote
Old June 6, 2013, 20:56   #12
Derakon
Prophet
 
Derakon's Avatar
 
Join Date: Dec 2009
Posts: 8,927
Derakon is on a distinguished road
Quote:
Originally Posted by Magnate View Post
Argh. I suppose it's inevitable that with such a variant-friendly game engine we're going to end up with multiple birth systems, but IMO this has always been an area where choice isn't needed. Are we going to have the autoroller too?!
This is one area that ought eventually to be handled by procs, if for no other reason than that the birth system as a whole requires knowledge of what races and classes are available (and that races and classes are things that the player would care about). The final birth system will look rather different from the first pass.

Quote:
That reminds me - Derakon, are you intending to use Sheldon W Simms's random name generator, beloved of *bands? Or something else? Porting the existing one would be a nice self-contained project for someone (possibly me if it's not done by the time I get to randarts).
I honestly never thought about this. If someone wants to implement it, they're welcome to do so.

Quote:
Personally I think the names are already so long that there's no point attempting to convey any more information in the name line, and we should assume that all info (including even 'primary' stats like dice, AC, balance, heft) will be obtained from the 'I'nspect screen. Any space that is available for items with short names will barely contain primary stats and plusses, let alone pvals.
This is true for some weapons and armor, but not for all, and not for jewelry. Where possible we ought to be able to provide all important information in the item name.

Quote:
Having said that, there's no reason you couldn't come up with two- or three-letter abbreviations for all the possible pval stats, so they could be represented like resists.
Yes, I think that's probably the way to go here. Have a list somewhere that ranks all the stats in tiers (with default low-priority values for unlisted stats), and then try to stuff as much information into the name as possible without running over some maximum name length.
Derakon is offline   Reply With Quote
Old June 12, 2013, 18:57   #13
Derakon
Prophet
 
Derakon's Avatar
 
Join Date: Dec 2009
Posts: 8,927
Derakon is on a distinguished road
Time to do some designing. Magnate requested that we have a working save/load system, so how do we go about doing that?

The game state is defined by the following items:

* All Containers in the GameMap
* The Things in those Containers
* Any Containers in those Things (e.g. inventory, equipment)
* Any Things in those Containers, etc. etc. etc.

In other words, we need to be able to recursively serialize all of the Things in the game, as well as their relationships (i.e. the Containers). Note that serializing a Thing also includes serializing its Stats and any relevant Procs, but that's comparatively straightforward, so I'm ignoring it for the moment.

It seems to me that the simplest way to handle this is to have a class that is responsible for martialling all of these serializations. The basic flow would look like this:
Code:
1) The user selects the "Save" command. 
2) This calls GameMap.save()

In GameMap class:
def save(self, filename):
    serializer = gameSerializer.GameSerializer()
    for container in self.idToContainerMap.values():
        serializer.addContainer(container)
    serializer.writeFile(filename)

In GameSerializer class:
def addContainer(self, container):
    if container.id in self.idToContainerContents:
        # Already have this container.
        return
    self.idToContainerContents[container.id] = []
    for thing in container.contents:
        self.idToContainerContents[container.id].append(thing.id)
        self.addThing(thing)

def addThing(self, thing):
    if thing.id in self.idToThingSerialization:
        # Already serialized this Thing.
        return
    self.idToThingSerialization[thing.id] = thing.getSerialization()
    self.idToThingContainers[thing.id] = []
    for container in thing.getContainers():
        self.addContainer(container)
self.idToThingContainers[thing.id].append(container.id)
In other words, we build up a mapping of Container IDs to Thing IDs ("This Container holds these Things"), a mapping of Thing IDs to lists of Container IDs ("This Thing has these Containers"), and a mapping of Thing IDs to shallow serializations of Things ("shallow" meaning "can be used to reconstruct the Thing, but not the containers in the Thing").

The generated file then contains all of the Container <-> Thing relationships, as well as the Thing serializations, all appropriately labeled. When we want to recreate the game state, first we create all of the necessary Containers; then, as we deserialize Things, we can put them into Containers, and put Containers into them, as appropriate.

There are a lot of details I'm glossing over here; in particular, Proc serialization and deserialization is going to be moderately tricky. That should all be handled as a subset of Thing [de]serialization though (i.e. Procs don't ever exist independent of Things). The above-described system ought to be enough to get us working, though.

Thoughts?
Derakon is offline   Reply With Quote
Old June 12, 2013, 21:02   #14
AnonymousHero
Veteran
 
AnonymousHero's Avatar
 
Join Date: Jun 2007
Posts: 1,367
AnonymousHero is on a distinguished road
I may very well be missing something, but aren't procs just (basically) string references to a blob of code? Surely, you aren't expecting to serlialize/deserialize the actual code in any coherent way?
AnonymousHero is offline   Reply With Quote
Old June 12, 2013, 21:34   #15
Derakon
Prophet
 
Derakon's Avatar
 
Join Date: Dec 2009
Posts: 8,927
Derakon is on a distinguished road
No, I'm not planning on trying to serialize the code. But sometimes Procs create some state that needs to be preserved. For example, this is how temporary status effects are handled:

* Proc is invoked to create status effect.
* Proc creates a new StatMod in the target's Stats instance, flagging the status effect as active.
* Proc creates a synthetic Timer Thing which counts down the turns of the status's duration.
* When the Timer runs out, it calls a function in the Proc, which removes the StatMod.

The relationship between the Proc and the Timer is one of the Timer having a function pointer to one of the Proc's functions; obviously that isn't going to persist across [de]serialization, so it needs to be recreated. That's going to be tricky.

Now, when we have a function pointer, it'll look something like this:
Code:
<bound method Foo.foo of <__main__.Foo instance at 0x1004a73f8>>
One possible way to handle this particular issue, then, would be for the Timer's serialize() function to contain a note "I need to refer to the function 'TemporaryStatModProc.removeMod' of the object 0x1004a73f8". Then the Serializer would be responsible for recognizing that address, finding the corresponding object, and replacing the address with the object's ID.

Hm, though now that I look at the code, there's not actually a removeMod() function; it's a lambda. That could be a problem. Certainly, serializing a lambda with its bound context is not a reasonable approach. We could always just say "don't use lambdas", but they're awfully handy things...
Derakon is offline   Reply With Quote
Old June 12, 2013, 21:45   #16
AnonymousHero
Veteran
 
AnonymousHero's Avatar
 
Join Date: Jun 2007
Posts: 1,367
AnonymousHero is on a distinguished road
Oh, I see... what you really want is a representation of procs (including all their dependencies and state)... which you basically can't get because of the hiding implied by lambdas.

I'm afraid I cannot offer any sensible advice, then. AFAICT the only solution is to *embed* the proc language such that it's actually a language that's *interpreted* bt the Pyrel game code (as an AST). Of course it could also be compiled to python bytecode or whatever when actually executed, but that's just an optimization...
AnonymousHero is offline   Reply With Quote
Old June 12, 2013, 22:04   #17
Derakon
Prophet
 
Derakon's Avatar
 
Join Date: Dec 2009
Posts: 8,927
Derakon is on a distinguished road
If at all possible, I want to avoid any approach that involves serializing bytecode (or code represented in any other manner, for that matter). As soon as you do that, you can't trust any distributed savefile to not be malicious. For similar reasons I can't use the pickle library in Python to do [de]serialization for me -- pickle allows you to create custom objects with their own [de]serialization routines which can do anything.

At this point, I'm hoping there's something clever that I've missed, but I'm not especially optimistic.
Derakon is offline   Reply With Quote
Old June 12, 2013, 22:15   #18
AnonymousHero
Veteran
 
AnonymousHero's Avatar
 
Join Date: Jun 2007
Posts: 1,367
AnonymousHero is on a distinguished road
Indeed -- off the top of my head, I think the only possibility is embedding and reification (...but I may very well have missed something!).
AnonymousHero is offline   Reply With Quote
Old June 13, 2013, 19:41   #19
Magnate
Angband Devteam member
 
Join Date: May 2007
Location: London, UK
Posts: 5,057
Magnate is on a distinguished road
Send a message via MSN to Magnate Send a message via Yahoo to Magnate
I wonder if a non-coder's perspective might be helpful: could we change the way procs affect state? If, for example, the temporaryStatModProc created a timer that was a member of the Thing itself (thing.temporaryStatModProc1Timer), then it would be trivially serialised along with the Thing. Then all we need is to decode the timer expiry into the relevant proc trigger. This basically moves the problem from serialisation to mapping of procs to timers.
__________________
"3.4 is much better than 3.1, 3.2 or 3.3. It still is easier than 3.0.9, but it is more convenient to play without being ridiculously easy, so it is my new favorite of the versions." - Timo Pietila
Magnate is offline   Reply With Quote
Old June 13, 2013, 20:17   #20
Derakon
Prophet
 
Derakon's Avatar
 
Join Date: Dec 2009
Posts: 8,927
Derakon is on a distinguished road
You can do that, but it amounts to codifying what effects Procs are allowed to have. Currently they can do anything as long as you're willing to write the code for them (including the code to handle [de]serialization of course).

Codifying allowable Proc effects is roughly equivalent to codifying how Procs are allowed to function internally (c.f. disallowing lambda functions) -- both constrain your options to make the serialization process feasible. However, the latter is more flexible and thus IMO more desirable.
Derakon is offline   Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Pyrel dev log, part 5 Magnate Variants 114 June 2, 2013 15:10
Pyrel dev log, part 4 Magnate Variants 116 March 11, 2013 19:53
Pyrel dev log, part 3 Derakon Variants 108 November 12, 2012 23:30
Pyrel dev log, part 2 Derakon Variants 126 September 11, 2012 23:03
Pyrel dev log Derakon Variants 64 June 8, 2012 11:58


All times are GMT +1. The time now is 07:53.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.