Dynamic objects

I feel like a simpleton asking this, but…
What is the difference between Jesse McGrew’s Dynamic Objects extension, and Tara McGrew’s Dynamic Object extension, except that Jesse’s is much older. Which one should I use?

I am floundering on the documentation and example for how to use it. Tara says to define a prototype: what is that? I assume it is my original object but how do I define it? (I don’t see her doing that in her example.) It seems like it should be simple, but I cannot figure out the ‘magic incantation phrasing’. I want to take an existing adventurer (a Person subkind) (called Z) and create a copy so that Z is not overwritten the second time I create an adventurer.

After cloning a new object from an adventurer (called the original):
	increase the clone generation of the new object by 1;

Every turn when stage is complete:
	let the copy be a new object cloned from Z;
	say "New object is cloned. Name is [advName of copy][line break]";
	say "Do you have more characters?";
	if player consents:
		now stage is stName;
		increment AdvCounter;
		now advNext is entry AdvCounter in Ordlist;
		follow the name catching rule;

Of course, most of this is about creating the adventurer, not cloning–but cloning doesn’t seem to work. I create Barak but when I create Alice, she overwrites Barak and I am back to the problem that piushed me into the Dynamic Objects extension in the first place.

It’s the same author by a new name, and, conceptually, the same extension. Version 8/140515 of Dynamic Objects by Jesse McGrew works in 9.1/6L02 and, probably, in 8.5/6G60 and 9.2/6L38. It compiles in 9.3/6M62 but doesn’t entirely work.

Per discussion here:

@alwinfy updated it for 10.1; this one is Version 9.0.0 of Dynamic Objects by Tara McGrew. I haven’t used it.

(Tara didn’t want to cause problems with existing code and, so, preferred that the author name of record on the older version didn’t change.)

I have never used this extension and confess I don’t fully understand the problem you’re trying to solve, but it seems like you’ve got a “let” statement that’s creating the cloned object, which seems like it might be an issue? Variables created with “let” typically only stick around for the duration of the rule.

Edit: sorry, took a quick look at the documentation and appears this is the correct syntax, odd though it looks to my eyes!

1 Like

Yep, dynamic objects stick around in the world, but they don’t have permanent names attached to them.

1 Like

Strange that one can create dynamic objects without a name to reference them. What good is that?!

Just a guess, but wouldn’t it take the name of the parent-object similar to a non-specific kind?

Like if I say “A coin is a kind of thing. There are 50 coins in the money bag.” I’m declaring nonspecific kinds that are all “coin” and you can’t specify any individual one, but you can say TAKE 3 COINS.

If you want specific kinds, you need to declare them when play begins. Dynamic Objects (again I believe) is if you want to allow someone to take an infinite number of leaves from a pile or have a vending machine dispense unlimited candy bars - the generic objects can spawn without being pre-declared and taking up memory space.

If you want individualized kinds of things with different names, they’re not clones which is what the extension is meant to do.

You can give them names for the player to type and see in the game, but they’ll never have source code names, because source code names have to be defined, well, in the source code. And the point of dynamic objects is you’re not defining them in the source code.

1 Like

Right – you can still do stuff with them via tactics like “now a random foo in the location…” but they’re fairly unwieldy to work with. I still don’t fully understand the behavior you’re going for, but I do suspect just creating a bunch of specified generic adventurers off-stage and just moving them in as needed, while writing a routine to set the relevant properties to match the “clone” when required, will ultimately wind up being easier.

I have a similar challenge with my beta tester NPCs. Instead of using multiple clones, I use one NPC and change its attributes when I ‘swap’ it for another.

2 Likes

I want the player to create up to four adventurers, say Alice, Bob, Charlie, and David. I want the player to interact with them by name. I created a template Z with text property advName, with which the player could interact. This works perfectly for a single adventurer, but any subsequent adventurer overwrites Z. Ironically, the room is filled with the number of adventurers created, but I can’t get their names to identify them.
For example: tell Bob to put his sword away; or Alice buys a shield; etc.

I could statically create four adventurers and have the player name them. That would probably work, but I am going to need a group of similar things, say 5 zombies, that can be treated like clones: zombie 1, zombie 2, etc. I may end up using both approaches.

Ultimately, I want to change the command prompt so that the player can command each adventurer in turn, such as

Alice: > buy a shield
Bought.

Bob: > Put sword away
Sheathed.

etc.

This harks back to Gary Gygax’s original game where a “caller” reported to the Dungeon Master what each member of the team was doing. In my case, the player is talking via command prompt to the “Dungeon Master”.

If you know there’s a maximum of four adventurers, I would create them all statically rather than dynamically. It’ll just make your life a lot easier. Dynamic objects work in Inform, but they require a decent amount of hacking, so they’ll never be as straightforward as static ones.

1 Like

Yeah, and even for monsters and such, the static approach is going to be way easier (per a suggestion I think Hanon made in the other thread, you can just have half a dozen baddies labeled “monster1,” “monster2,” “monster3,” etc. and then just shuffle them on-stage and off-stage as needed. It’s honestly not even that much additional coding because instead of just having a code block that defines what a zombie (or whatever) is via assertions, you just write a “to transform X into a zombie” phrase using the “now” syntax and deploy as needed.

2 Likes

Daniel, Mike,
I will do that. I am disappointed because, being familiar with creating objects in other programming languages, I expected it to work differently.

I saw a post about a person who wanted to make table of monsters and call them out as needed. That would take a LOT OF MEMORY, depending on how many properties each monster had. I wonder how he worked that out.

Tolti-Aph, maybe? This is a game designed to mimic the tables of spells, monsters, weaponry, etc from early tabletop games.

Yes, it’s one of those things that seems really cool, and was fairly fully implemented in Inform 6, but in practice in real coding for text adventures is virtually never needed. This is because there is usually a fairly low upper limit to the number of instantiations of a type of object that need to be in play at once. Consequently, having a pre-declared stock of objects that can reused and brought into play when needed, with updated properties as required, is an intellectually less satisfying but practically adequate solution for the ‘spawning new monsters’ scenario, and for others such as coinage (where individual items are identical), having a single object with a numeric property representing quantity (much as one would have a single object with a numeric property representing volume for liquids) does the job.

The key to avoiding using up too much memory from pre-declared objects (although to be fair that’s rarely a consideration nowadays) is reuse of a limited stock of objects, respawned in the same or different forms.

This kind of sleight-of-hand is common in Inform. For example, the Standard Rules implement backdrops by having just one backdrop object that follows the player around as they move from room to room, creating the illusion of an object being in multiple places. Similarly, a standard technique to efficiently hide something from a player is to keep it off-stage and move it into play only when the player performs some action that reveals it.

That pre-declares its monster (and other) objects, the tables being used for Some kinds of monster are defined by the Table of Monstrous Beasts. thereby enabling assertions such as A hostile goblin called Vish is in the Gravel Track. to declare a goblin pre-populated with default properties for its kind. Unfortunately the some kinds of <kind> are defined by <table name> syntax is broken in Ver10 (fixed in the forthcoming release) although it still works fine in Ver 9.3/6M62.

A monster is a kind of person. A monster can be hostile or indifferent. A monster is usually hostile. Definition: A monster is scary if its strength is 50 or more. Definition: A monster is feeble if its strength is 10 or less. Some kinds of monster are defined by the Table of Monstrous Beasts.

Instead of asking a monster about something: say "[The noun] is unreachable on most levels."

After printing the name of a monster while looking: say " (STR [strength])".

Table of Monstrous Beasts
name		strength	hand-to-hand combat method	unarmed combat hit dice	defensive charm
goblin		5	"pummeling its green fists"	1d4			--
gnome		2	"slapping its feeble arms"	1d2			--
centaur		9	"kicking its hooves"	1d6			--
werespider	7	"clicking its mandibles"	1d8+1			--
wyvern		75	"beating its clawed wings"	2d8+5			--
half-orc		9	"burrowing with its claws"	1d6			--
harpy		15	"swooping with its talons"	2d6			aerial shield
giant bat		8	"diving to bite"		2d4			aerial shield
basilisk		4	"staring with cursed eyes"	4d6			--
purple worm	7	"biting with acidic teeth"	2d6+1			--
gargoyle		10	"punching stone fists"	1d8+1			--
cave troll		14	"swinging enormous fists"	3d4			--
cave spectre	12	"throwing curses"		2d4+3			exorcise undead
marsh spectre	18	"throwing curses"		4d4+3			exorcise undead
skeletal warrior	25	"slicing with ghostly blades"	2d6+3			exorcise undead
green hydra	32	"ducking its heads in turn"	3d8+3			aerial shield
frost giant		28	"throwing deadly icicles"	2d8+4			inner warmth
elemental demon	35	"whirling with venom"	4d4+2			--

An elemental demon called Zoorl the Elemental Demon is indifferent.[* Oh, the ennui of the underworld. The practical effect of this line is to create Zoorl and leave him out of play at the start of the game: he is the demon brought into being by the "summon elemental" spell.]

Here, An elemental demon called Zoorl... illustrates and explains the technique of creating something off-stage to be apparently summoned into existence (i.e. moved on-stage) when the time is right.

1 Like

OK, I’ve decided to try four statically created template adventurers and put them into a list through which I can traverse. However, can someone show me in the docs where these lists can be created when NOT IN A RULE? Nothing is mentioned in Chapter 21.
I can’t seem to create the adventurers and put them into a list.

An adventurer is a kind of person. 
An adventurer has some text called advName.
Team is a list of adventurers that vary.
W, X, Y, Z are adventurers.

AdvNext is some text that varies.
CardinalList is a list of text that varies. CardinalList is {"first", "second", "third", "fourth"}.
AdvCounter is a number that varies. AdvCounter is 0.

Lobby is a room. 
Description of Lobby is "[if unvisited]Welcome to the Ugly Ogre Inn! Excitement-starved adventurers meet here to form teams. Soon a team of adventurers will gather in the Lobby.[else] A team is gathering: [end if] ";

After looking in location:
	follow the adventurer-printing rule;
	
[Assigning the name from the player to the adventuer.]
Rule for printing the name of an adventurer (called char) (this is the adventurer-printing rule):
	say "[advname of char], a [advGender of char] [class of char]".

When play begins:
	add Z to team;

I add properties (name, gender, etc) using the Questions extension, which works well enough once I figured it out.
Adding Z to the team won’t compile IN OR OUTSIDE of a rule.
I am out of permutations of magical chants. Can someone throw me a rope?

What’s the compiler’s error message?

This stripped-down version of your example compiles for me in Inform 10.1.2:

An adventurer is a kind of person. 

Team is a list of adventurers that vary. 
[I'd write "varies" to make it clear to the reader that the list varies; but it doesn't make a difference here.]

W, X, Y, Z are adventurers.

Lobby is a room. 

When play begins:
	add Z to team;
	add X to team;

Every turn:
	say team;

And the output is that “Z and X” are listed as being on the team, as expected.

Alternatively to the “add Z to team;” syntax, you can also declare at the outset: “Team is a list of adventurers which varies. Team is {W, X, Y, Z}.”, for example. (And then remove team members if the party should be smaller than four.)

1 Like

For the record, your CardinalList is a list of ordinals, not cardinals. (Ordinals are first, second, third, etc; cardinals are one, two, three, etc.)

CM,
Thanks. I should have looked that up. :slightly_smiling_face:

I thought I did that. I’ll look through again, and include the compiler error if it happens again.