Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Help Streamlining this code in an Array, or Dataset/map?

Okay - I somewhat want a dating sim but not quite - the code below is to basically show how 'far' in the relationship you are with any of them. I'm using Sugarcube 2 (Latest), and Twine 2. My problem is in the code itself. How do I condense it into an array or datamap or whatever? $relationship(Char name) is basically when you 'start' talking to a certain character in the TWINE novel, and after a certain amount of storyline, you set their 'affection' toward your character, and I am placing it in a Storymenu Passage anyhow. (This code is from my StoryInit Passage).

And I am going to be having at least 60+ characters eventually once I get everything written out. Any ideas how to condense it?
<<set $relationshipJonas to false>>
<<set $relationshipSamuel to false>>
<<set $relationshipGrag to false>>
<<set $relationshipDamian to false>>
<<set $relationshipKelle to false>>
<<set $jonasAffection to 0>>

<<set $samuelAffection to 0>>

<<set $gragAffection to 0>>

<<set $damianAffection to 0>>

<<set $kelleAffection to 0>>

<<widget "relationships">>\
	<<set $relationships to true>>\
	<<nobr>>
		<<if $relationshipJonas>>\
			Jonas Leaf:
			 \<<if $jonasAffection gte 5>>\
				<<print "Acquaintances">>\
			<</if>>
			<<if $jonasAffection gte 10>>\
				\<<print "Friends">>
			<</if>>
			<<if $jonasAffection gte 20>>\
				<<print "Budding Romance">>
			<</if>>
			<<if $jonasAffection gte 30>>\
				"In love."
			<<else>>
				"Stranger"
			<</if>>
		<</if>>
		
		<<if $relationshipSamuel>>
			Samuel Lighthill: 
			\<<if $samuelAffection gte 5>>\
				"Acquaintances"
			<</if>>
			<<if $samuelAffection gte 10>>\
				"Friends"
			<</if>>
			<<if $samuelAffection gte 20>>
				"Budding Romance"
			<</if>>
			<<if $samuelAffection gte 30>>
				"In love."
			<<else>>
				"Stranger"
			<</if>>
		<</if>>
		<<if $relationshipGrag>>
			Grag: 
			\<<if $gragAffection gte 5>>\
				"Acquaintances"
			<</if>>
			<<if $gragAffection gte 10>>\
				"Friends"
			<</if>>
			<<if $gragAffection gte 20>>
				"Budding Romance"
			<</if>>
			<<if $gragAffection gte 30>>
				"In love."
			<<else>>
				"Stranger"
			<</if>>
		<</if>>
		<<if $relationshipDamian>>\
			Damian:
			\<<if $damianAffection gte 5>>\
				<<print "Acquaintances">>\
			<</if>>
			<<if $damianAffection gte 10>>\
				\<<print "Friends">>
			<</if>>
			<<if $damianAffection gte 20>>\
				<<print "Budding Romance">>
			<</if>>
			<<if $damianAffection gte 30>>\
				"In love."
			<<else>>
				"Stranger"
			<</if>>
		<</if>>
		<<if $relationshipKelle>>\
			Kelle:
			\<<if $kelleAffection gte 5>>\
				<<print "Acquaintances">>\
			<</if>>
			<<if $kelleAffection gte 10>>\
				\<<print "Friends">>
			<</if>>
			<<if $kelleAffection gte 20>>\
				<<print "Budding Romance">>
			<</if>>
			<<if $kelleAffection gte 30>>\
				"In love."
			<<else>>
				"Stranger"
			<</if>>
		<</if>>
	<<endnobr>>
<</widget>>

Comments

  • First. You have your widget in the wrong place. As noted in their documentation, widgets should go into their own separate widget-tagged passage.

    Second. Your <<if>> constructs are pretty abominable. They should probably look something like the following: (minus whitespace control and using Jonas as an example)
    <<if $relationshipJonas>>
    Jonas Leaf: 
    <<if $jonasAffection lt 5>>
    Stranger
    <<elseif $jonasAffection lt 10>>
    Acquaintances
    <<elseif $jonasAffection lt 20>>
    Friends
    <<elseif $jonasAffection lt 30>>
    Budding Romance
    <<else>>
    In Love
    <</if>>
    <</if>>
    


    Moving on to suggestions on data structuring.

    I would not recommend using an array, as you'd have do one of the following: remember which index belonged to which NPC, maintain a separate id-to-index mapping, or search though the array each time.

    I'd suggest using either Maps or generic objects, the latter being simpler so let's go with them for now. For example: (in your StoryInit special passage)
    <<set $npcs to {
    	jonas : {
    		name : "Jonas Leaf",
    		rel  : false,
    		aff  : 0
    	},
    	samuel : {
    		name : "Samuel Lighthill",
    		rel  : false,
    		aff  : 0
    	},
    	/* Etc. */
    }>>
    
    And an example of using it:
    <<if $npcs["jonas"].rel>>\
    <<=$npcs["jonas"].name>>: \
    <<if $npcs["jonas"].aff lt 5>>\
    Stranger\
    <<elseif $npcs["jonas"].aff lt 10>>\
    Acquaintances\
    <<elseif $npcs["jonas"].aff lt 20>>\
    Friends\
    <<elseif $npcs["jonas"].aff lt 30>>\
    Budding Romance\
    <<else>>\
    In Love\
    <</if>>\
    <</if>>
    

    That said, using a separate property just to track whether or not the player has started a relationship with them is somewhat wasteful. You could simply initialize their affection to -1, which would signify no relationship. For example:
    <<set $npcs to {
    	jonas : {
    		name : "Jonas Leaf",
    		aff  : -1
    	},
    	samuel : {
    		name : "Samuel Lighthill",
    		aff  : -1
    	},
    	/* Etc. */
    }>>
    
    And an example of using it: (only the very first line changes)
    /* Using a separate property to denote no relationship. */
    <<if $npcs["jonas"].rel>>\
    <<=$npcs["jonas"].name>>: \
    
    /* Using an affection of -1 to denote no relationship. */
    <<if $npcs["jonas"].aff gte 0>>\
    <<=$npcs["jonas"].name>>: \
    
    When the player starts a relationship with an NPC, you simply set their affection to a value greater than -1. For example:
    /* Mark relationship as started, but with no real affection yet. */
    <<set $npcs["jonas"].aff to 0>>
    
    /* Mark relationship as started, with an affection of 5. */
    <<set $npcs["jonas"].aff to 5>>
    
    You could make a widget for common operations like that as well. For example:
    @
    <</if>>\
    <</widget>>
    
    The widget does assume that affection scores will be limited to whole numbers.


    Moving on to your widget itself. It's fairly redundant, so I'd suggest using two widgets. One to check an individual NPC and another to invoke the first on all NPCs. For example:
    @
    <</if>>\
    <</widget>>
    
    /*
    	Shows the relationship status of all NPCs, via the
    	<<relationship>> widget.
    
    	<<allrelationships>>
    */
    <<widget "allrelationships">>\
    <<set
    	_npcIds to Object.keys($npcs),
    	_length to _npcIds.length
    >>\
    <<for _i to 0 ; _i lt _length; _i++>>
    <<relationship _npcIds[_i]>>
    <</for>>\
    <</widget>>
    
  • edited September 2016
    Wow. That is just... awesome. :) Above and beyond what I was expecting. I was halfway expecting hints or at least 'nudges' in the right direction. Thanks a ton. :)

    I'm putting each widget inside it's own Passage.

    And yes, I'm new to coding but it kept throwing <<else>> errors so that's why I ended up with what I did before. Thanks again :)
  • Gryphbear wrote: »
    I'm putting each widget inside it's own Passage.
    A widget tagged passage can contain multiple widgets, you don't need to place each widget within it's own passage.
    <<widget "one">>
    ...
    <</widget>>
    
    <<widget "two">>
    ...
    <</widget>>
    

  • edited September 2016
    greyelf wrote: »
    Gryphbear wrote: »
    I'm putting each widget inside it's own Passage.
    A widget tagged passage can contain multiple widgets, you don't need to place each widget within it's own passage.
    <<widget "one">>
    ...
    <</widget>>
    
    <<widget "two">>
    ...
    <</widget>>
    

    Oh. Okay. lol. Just NOT in the "Special" Passages, right. :) I'm working on entering the NPC's Map thing.
  • edited September 2016
    Gryphbear wrote: »
    I'm working on entering the NPC's Map thing.
    In addition to the syntax I showed before, where you create the NPCs map all at once:
    <<set $npcs to {
    	jonas : {
    		name : "Jonas Leaf",
    		aff  : -1
    	},
    	samuel : {
    		name : "Samuel Lighthill",
    		aff  : -1
    	},
    	/* Etc. */
    }>>
    
    Alternatively, you could break the creation of the NPC map into individual chunks if it would be easier for you. For example:
    /* Create an empty generic object to hold NPCs. */
    <<set $npcs to {}>>
    
    /* Fill the object with NPCs. */
    <<set $npcs["jonas"] to {
    	name : "Jonas Leaf",
    	aff  : -1
    }>>
    <<set $npcs["samuel"] to {
    	name : "Samuel Lighthill",
    	aff  : -1
    }>>
    /* Etc. */
    
  • Gryphbear wrote: »
    I'm working on entering the NPC's Map thing.
    In addition to the syntax I showed before, where you create the NPCs map all at once:
    <<set $npcs to {
    	jonas : {
    		name : "Jonas Leaf",
    		aff  : -1
    	},
    	samuel : {
    		name : "Samuel Lighthill",
    		aff  : -1
    	},
    	/* Etc. */
    }>>
    
    Alternatively, you could break the creation of the NPC map into individual chunks if it would be easier for you. For example:
    /* Create an empty generic object to hold NPCs. */
    <<set $npcs to {}>>
    
    /* Fill the object with NPCs. */
    <<set $npcs["jonas"] to {
    	name : "Jonas Leaf",
    	aff  : -1
    }>>
    <<set $npcs["samuel"] to {
    	name : "Samuel Lighthill",
    	aff  : -1
    }>>
    /* Etc. */
    

    Ah...well, Thanks. I already did fill it out ;)
  • edited September 2016
    I'm now running into <<set>>: Bad evaluation: Unexpected Identifier? issues. all I did was add another element inside each one - species : "Species name". Could that be the reason? or the formatting? I did sorta copy/paste the initial formatting that was listed here.

    Heh, I may have been missing an extra }. lol. Sorry.
  • I have a similar thing going on that I've done a bit with Harlowe's (datamap: ) But now I've moved to SugarCube and oh God I needed this information so much.

    Thanks!
  • I'm also adding an extra element - since I'd liek to see this show up in the relationship status area. but it still is giving me the <<set>> error... I have no idea why.
    <<set $npcs to {
    	jonas : {
    			name: "Jonas Leaf",
    			aff : -1,
    			species: "Human"
    	}, 
    	samuel : {
    			name: "Samuel Lighthill",
    			aff : -1,
    			species: "Dwarf"
    	}, 
    
    .... (about 50 other similar entries)...
    
    lyon : {
    			name: "Lyon Heartgem",
    			aff: -1,
    			species: "Dwarf"
    		}
    	}>>
    

    I've pasted the <<affection>>, <<relationship>>, and <<allrelationship>> widgets you've listed here into a standalone Passage called Relationships. I'm not sure where the error could be. Do I need to add another $arg[] or something?
  • Gryphbear wrote: »
    I'm now running into <<set>>: Bad evaluation: Unexpected Identifier? issues. all I did was add another element inside each one - species : "Species name". Could that be the reason? or the formatting? I did sorta copy/paste the initial formatting that was listed here.
    You've almost certainly broken the syntax somehow—a missing or extra: quote, comma, colon, or curly brace. We couldn't say without seeing the code.
  • edited September 2016
    Okay. I'll doublecheck it. Argh. I guess there's no help for it. I'll post the whole thing. I couldn't find anything missing, or extra. Nobody take my characters. ;) haha.
    <<set $npcs to {
    	jonas : {
    			name: "Jonas Leaf",
    			aff : -1,
    			species: "Human"
    	}, 
    	samuel : {
    			name: "Samuel Lighthill",
    			aff : -1,
    			species: "Dwarf"
    	}, 
    	grag : {
    			name: "Grag",
    			aff : -1,
    			species: "Minotaur"
    	},
    	damian : {
    			name: "Damian",
    			aff : -1,
    			species: "Centaur"
    	},
    	leon : {
    			name: "Leon",
    			aff : -1,
    			species: "Giant"
    	},
    	gahlan : {
    			name: "Gahlan",
    			aff : -1,
    			species: "Orc"
    			
    	},
    	anwyn : {
    			name: "Anwyn",
    			aff : -1
    			species: "Satyr"
    	}, 
    	gerald : {
    			name: "Gerald",
    			aff: -1,
    			species: "Giant"
    	},
    	bertram : {
    			name: "Bertram",
    			aff : -1,
    			species: "Satyr"
    	},
    	joshua : {
    			name: "Joshua",
    			aff : -1,
    			species: "Werewolf"
    	},
    	brandon : {
    			name: "Brandon", 
    			aff : -1, 
    			species: "Human"
    	},
    	markus : {
    			name: "Markus", 
    			aff : -1,
    			species: "Human"
    	},
    	talian : {
    			name: "Talian",
    			aff : -1,
    			species: "Giant"
    	}, 
    	ulfgar : {
    			name: "Ulfgar",
    			aff : -1,
    			species: "Half Dwarf"
    	},
    	paul : {
    			name: "Paul",
    			aff : -1,
    			species: "Human"
    	},
    	olann : {
    			name: "Olann Lighthill",
    			aff : -1,
    			species: "Dwarf"
    	},
    	mohammed : {
    			name: "Mohammed",
    			aff : -1,
    			species: "Human"
    	},
    	kyrziz : {
    			name: "Kyrziz",
    			aff: -1,
    			species: "Daemon"
    	},
    	erryl : {
    			name: "Erryl",
    			aff: -1,
    			species: "Giant"
    	},
    	aron : {
    			name: "Aron",
    			aff: -1,
    			species: "Centaur"
    	},
    	joel : {
    			name: "Joel",
    			aff: -1,
    			species: "Giant"
    	},
    	caleb : {
    			name: "Caleb",
    			aff: -1,
    			species: "Human"
    	},
    	larken : {
    			name: "Larken",
    			aff: -1,
    			species: "Minotaur"
    	},
    	gregory : {
    			name: "Gregory",
    			aff: -1,
    			species: "Incubus"
    	},
    	yorik : {
    			name: "Yorik",
    			aff: -1,
    			species: "Centaur"
    	},
    	kurtz : {
    			name: "Kurtz",
    			aff: -1,
    			species: "Boarman"
    	}, 
    	garrtz : {
    			name: "Garrtz",
    			aff: -1,
    			species: "Boarman"
    	},
    	edgar : {
    			name: "Edgar",
    			aff: -1,
    			species: "Human"
    	},
    	kelle : {
    			name: "Kelle",
    			aff: -1,
    			species: "Centaur"
    	},
    	zane : {
    			name: "Zane",
    			aff: -1,
    			species: "Human"
    	},
    	william : {
    			name: "William",
    			aff: -1,
    			species: "Human"
    	},
    	darrin : {
    			name: "Darrin",
    			aff: -1,
    			species: "Human"
    	},
    	wade : {
    			name: "Wade Stonegate",
    			aff: -1,
    			species: "Dwarf"
    	},
    	alric : {
    			name: "Alric",
    			aff: -1,
    			species: "Giant"
    	},
    	terrence : {
    			name: "Terrence",
    			aff: -1,
    			species: "Human"
    	},
    	james : {
    			name: "James Luck",
    			aff: -1,
    			species: "Daemon"
    	},
    	vance : {
    			name: "Vance",
    			aff: -1,
    			species: "Giant"
    	},
    	xavier : {
    			name: "Xavier",
    			aff: -1,
    			species: "Centaur"
    	}, 
    	casey : {
    			name: "Casey",
    			aff: -1,
    			species: "Human"
    	},
    	matthew : {
    			name: "Matthew Kinden",
    			aff: -1,
    			species: "Half Daemon/Human?"
    	},
    	andrew : {
    			name: "Andrew",
    			aff: -1,
    			species: "Human"
    	},
    	grull : {
    			name: "Grull",
    			aff: -1,
    			species: "Orc"
    	},
    	jared : {
    			name: "Jared",
    			aff: -1,
    			species: "Human"
    	},
    	mathias : {
    			name: "Mathias",
    			aff: -1,
    			species: "Orc"
    	},
    	bernard : {
    			name: "Bernard",
    			aff: -1,
    			species: "Dwarf"
    	},
    	garratt : {
    			name: "Garratt",
    			aff: -1,
    			species: "Orc" 
    	},
    	adam : {
    			name: "Adam Docbrach",
    			aff: -1,
    			species: "Human"
    	},
    	nathan : {
    			name: "Nathan",
    			aff: -1,
    			species: "Werebear"
    	},
    	ulven : {
    			name: "Ulven",
    			aff: -1,
    			species: "Human"
    	},
    	goral : {
    			name: "Goral",
    			aff: -1,
    			species: "Orc"
    	},
    	roger : {
    			name: "Roger",
    			aff: -1,
    			species: "Half Elf"
    	},
    	rygar : {
    			name: "Rygar Stormclan",
    			aff: -1,
    			species: "Dwarf"
    	},
    	seamus : {
    			name: "Seamus",
    			aff: -1,
    			species: "Satyr"
    	},
    	kenneth : {
    			name: "Kenneth",
    			aff: -1,
    			species: "Human"
    	},
    	patrik : {
    			name: "Patrik",
    			aff: -1,
    			species: "Minotaur"
    	},
    	hgorath : {
    			name: "Hgorath",
    			aff: -1,
    			species: "Orc"
    	},
    	kyle : {
    			name: "Kyle",
    			aff: -1,
    			species: "Human"
    	},
    	quinn : {
    			name: "Quinn",
    			aff: -1,
    			species: "Half Giant"
    	},
    	adrian : {
    			name: "Adrian",
    			aff: -1,
    			species: "Centaur" 
    	},
    	tyrell : {
    			name: "Tyrell",
    			aff: -1,
    			species: "Human"
    	},
    	perry : {
    			name: "Perry?",
    			aff: -1,
    			species: "Orc" 
    	},
    	flint : {
    			name: "Flint",
    			aff: -1,
    			species: "Dwarf" 
    	},
    	mikhail : {
    			name: "Mikhail",
    			aff: -1,
    			species: "Human"
    	},
    	klatus : {
    			name: "Klatus",
    			aff: -1,
    			species: "Orc" 
    	},
    	hargorn : {
    			name: "Hargorn",
    			aff: -1,
    			species: "Dwarf"
    	},
    	eodward : {
    			name: "Eodward",
    			aff: -1,
    			species: "Satyr"
    	},
    	alann : {
    			name: "Alann",
    			aff: -1,
    			species: "Werebear" 
    	},
    	warren : {
    			name: "Warren",
    			aff: -1,
    			species: "Werebear"
    	},
    	dennis : {
    			name: "Dennis",
    			aff: -1,
    			species: "Werebear"
    	},
    	terryl : {
    			name: "Terryl",
    			aff: -1,
    			species: "Giant"
    	},
    	mallo : {
    			name: "Mallo",
    			aff: -1,
    			species: "Centaur"
    	},
    	davyd : {
    			name: "Davyd",
    			aff: -1,
    			species: "Human" 
    	},
    	lyon : {
    			name: "Lyon Heartgem",
    			aff: -1,
    			species: "Dwarf"
    	}	
    	}>>
    
  • The seventh NPC, "Anwyn", is missing a comma after their affection property:
    	anwyn : {
    			name: "Anwyn",
    			aff : -1
    			species: "Satyr"
    	},
    
  • edited September 2016
    Thanks. (crawls away in embarrassment) LOL.

    Anyway, Thank you so much again hehe. It now works, more or less. I just have to figure out how to use it from studying your instructions.
  • edited September 2016
    Okay, a new issue - why is TWINE insisting that the Widget is a Macro that doesn't exist? The setup here is that I have all the code you posted as far as 'relationship' calculating and showing all relationships, etc etc in it's own Passage called Status, and Tagged "Widget". I made a new Passage connected to my StoryMenu Passage - and tried to put in <<relationship "jonas">> and even <<allrelationships>> - it keeps thinking both are macros.... that don't exist? As far as I know, that is the correct way to show a widget's name.

    I'm usign Twine 2.1.0b btw, now, if that has any bearing on the issues I'm having. if I have to, I will retroinstall 2.0.11 in case the new beta is the issue.
  • Twine (the application) has little or nothing to do with this.

    The Tag Names documentation shows the widget tag in lower-case where your example has it in mixed-case.

    Widgets are another way to create macros, which is why you may get a "macro does not exist" error.
  • greyelf wrote: »
    Twine (the application) has little or nothing to do with this.

    The Tag Names documentation shows the widget tag in lower-case where your example has it in mixed-case.

    Widgets are another way to create macros, which is why you may get a "macro does not exist" error.
    Evidently. :P I had it as "Widget" lol. Now it works fine. Thanks so much. It's been a long and a bit frustrating day getting it to work :) Thanks for everyone's help :)
  • edited October 2016
    One more question, if you would not mind answering. The system works pretty well - but I wanted to put a <<back>> in the Relationships Passage - As it is, it outputs nothing as directed if there are no relationships formed at all, but I do want a <<back>> link in there, that won't be pushed all the way down to the imaginary list of <<allrelationships>>'s widget.

    (This is in my Relationships Passage for Storymenu)
    <<allrelationships>>
    
    <<back>>
    

    This above gets me a blank sheet (in the beginning) - since there's nothing to list yet and the <<back>> macro all the way down the page - as if it's listed all of the relationships in 'whitespace'. But I do not want to have to use the History button to return to the previous page. I've tried every other place - even in the code for the outputting of each relationship. In any other place it gives me a <<back>> link after EVERY relationship 'set', or every 'non-existent' relationship.

    If you want, I can post the whole code again to see where I need to put the <<back>> macro.
  • I'm about to turn in and I'm headed to medical appointments tomorrow, however, you likely need to manage your line breaks--maybe whitespace in general--better.

    Go ahead and post your current <<allrelationships>> widget and any widgets it invokes. I'll try to get back to you as soon as I can--if someone else doesn't first.
  • edited October 2016
    Okay, here's my main chunk of code - the code I posted for setting up the $npcs is already up here in the thread which doesn't need to be posted here. This code below is inside a widget-tagged Passage called "Status".

    And currently, I have two StoryMenu Passages - Inventory and Relationships - the Inventory part doesn't need to be talked about since it works and all.

    Onto the Relationships Passage - I basically have a <<allrelationships>> widget in it, and that's about it.

    The new code regarding the phone # bit - I put phonestatus: false in each NPC's 'bio' datamap, so I can control when they actually 'show' the phone number when you select the relationship button. (In a dating sim, you do not always exchange phone numbers the moment you meet, or at the very end of the route. It varies.)

    I was wondering where to put the <<back>> in the <<allrelationships>> widget if I can so it will not repeat itself inside the <<For>> loop. If I put it in the relationship widget after every 'if _npc.aff etcetc #' before the <<elseif>> then I have a <<back>> link after EACH relationship. I only want one <<back>> link ont hat page, but I don't want to output it after all the whitespace that I get from putting <<allrelationships>> in the Relationships Passage.
    @
    <</if>>\
    <</widget>>
    
    /*
    	Shows the relationship status of all NPCs, via the
    	<<relationship>> widget.
    
    	<<allrelationships>>
    */
    <<widget "allrelationships">>\
    <<set
    	_npcIds to Object.keys($npcs),
    	_length to _npcIds.length
    
    >>\
    
    <<for _i to 0 ; _i lt _length; _i++>>
    <<relationship _npcIds[_i]>>
    <</for>>
    <</widget>>
    
    

    THe code will be updated sooner or later with more biographic info for each character, but it will be mainly output from the get-go later on. Btw, I don't really foresee more relationships than 1-2 in one route.
  • edited October 2016
    I don't think that I'd make <<back>> a part of <<allrelationships>>. Once the line break issue is corrected, simply do something like the following in your "Relationships" passage:
    <<allrelationships>><<back>>
    

    Now, about those line breaks….

    You need to remove all line breaks from the <<allrelationships>> widget—because loop—and have the <<relationship>> widget generate an extra line break to compensate. Additionally, <<relationship>> should only generate line breaks when it is actually printing data—i.e. if it is not going to print an NPC's data, then it should not generate any output.

    Beyond that, you're being horrifically redundant within the <<relationship>> widget. You should not be repeating the species and phone number displays within each affection case. Simply handle each data point once—i.e. affection THEN species THEN phone number THEN etc.

    Try the following code: (tested and working as intended)
    @
    <</if>>\
    <</widget>>
    
    /*
    	Shows the relationship status of all NPCs, via the
    	<<relationship>> widget.
    
    	<<allrelationships>>
    */
    <<widget "allrelationships">>\
    <<set
    	_npcIds to Object.keys($npcs),
    	_length to _npcIds.length
    
    >>\
    <<for _i to 0 ; _i lt _length; _i++>>\
    <<relationship _npcIds[_i]>>\
    <</for>>\
    <</widget>>
    

    EDIT: As a stylistic suggestion, which also helps minimize the size of your serialized data, I'd use hasphone—or hasPhone—over phonestatus.
  • Wow. Thanks. I'll start implementing this - and I appreciate all the help you've given me so far :)
  • edited October 2016
    I'm pretty sure it's not my data - I've double and triple checked the commas and the like, but when I click on Relationships (before I actually start playing the game)
    Error: <<allrelationships>>: error within widget contents (Error: <<set>>: bad evaluation: Cannot convert undefined or null to object)
    

    The problem is the code looks virtually indistinguishable from your previous copy, AND the one you just posted. I have no idea why THIS is happening. Help? lol. I greatly doubt it's to do with the $npcs Dataset I have. I have added a lot of stuff, but... it keeps only pointing to the <<allrelationships>> widget. Am I missing something obvious? The code looks identical to the one you posted earlier on in this thread.
    /*
    	Shows the relationship status of all NPCs, via the
    	<<relationship>> widget.
    
    	<<allrelationships>>
    */
    <<widget "allrelationships">>\
    <<set
    	_npcIds to Object.keys($npcs),
    	_length to _npcIds.length
    
    >>\
    <<for _i to 0 ; _i lt _length; _i++>>\
    <<relationship _npcIds[_i]>>\
    <</for>>\
    <</widget>>
    

    EDIT:

    I went through my $npcs dataset one character after another slowly - I eliminated anything that had an " or ' inside the main " "'s of each property and it's value. and made sure to put 'something' inside an "" if I don't have information for it yet. (essentialyl an "???" value.

    I just have no idea what could be causing the issue. I doublechecked an earlier post you made with this <<allrelationships>> widget - and it looks absolutely identical, but when I play the game, I get some errors like this -
    Error: <<set>>: bad evaluation: Cannot read property 'jonas' of undefined
    

    The above was basically doing <<set $npcs["jonas"].aff to 2>> essentially, and the other one was <<set $npcs["jonas".hasPhone to true>>. And both say they cannot find the $npcs code or think it's undefined for some reason. Am I missing an extra } or something?

    I'll check again.

    (Last edit)

    Does TWINE have issues with multiple line property values? or Sugarcube?
  • edited October 2016
    Multiline is fine. I'm not sure what's going wrong but the property object doesn't get passed over to the nested widget properly. Probably due to scope issues with temp variables.

    As a result, this will work:
    <<widget "allsounds">>
    <<set
    	$tmp = Object.keys($spriteData),
    	_length = $tmp.length
    >>
    <<for $i = 0; $i lt _length; $i++>>
    	<<sounds $tmp[$i]>>
    <</for>>
    <<unset $tmp, $i>>
    <</widget>>
    
    
    <<widget "sounds">>
    	<<print $spriteData[$args[0]].length>>
    <</widget>>
    

    Whereas replacing $tmp and $i with _tmp and _i respectively will not. Even more annoyingly, there's no for-in operator in sugarcube, so you gotta use this clunky story variables workaround to iterate the keys at present. The big thing to remember here is if you access $i or $tmp from any subsequent widget, or anywhere else before the unset gets called, you will be overwriting the original value as nothing is being passed byval - it's all a reference to the same variable / object. So if you have nested iterative functions they all need unique names. Otherwise weirdness and unintended behavior will ensue.

    Edit: sorry. I should adapt the code to your example. The above snippet is from my game. The code you want is:
    <<widget "allrelationships">>\
    <<set
    	$npcIds to Object.keys($npcs),
    	_length to $npcIds.length
    
    >>\
    <<for $i to 0 ; $i lt _length; $i++>>\
    <<relationship $npcIds[$i]>>\
    <<unset $npcIds, $i>>\
    <</for>>\
    <</widget>>
    

    Edit2:

    There is another way to work around this, namely to write the iterating code in JS and pass the result back to twine in a story variable, such as an array containing strings to print (which is what I originally tried when the temp variables failed). It doesn't make for prettier code though and has just as many issues as the story variable workaround.
  • First. Let me reiterate a point from my previous post. The code example I posted was copy/pasted from a working, fully functional, example project that I set up. The widgets have been tested and do work as intended.

    Gryphbear wrote: »
    I'm pretty sure it's not my data - I've double and triple checked the commas and the like, but when I click on Relationships (before I actually start playing the game)
    Error: <<allrelationships>>: error within widget contents (Error: <<set>>: bad evaluation: Cannot convert undefined or null to object)
    
    You are likely seeing that error because you've somehow broken value within the $npcs story variable or are doing something which is causing it to become unset.

    Gryphbear wrote: »
    The problem is the code looks virtually indistinguishable from your previous copy, AND the one you just posted. I have no idea why THIS is happening.
    This statement—and others—are making it sound like you're transcribing my examples by hand, rather than simply doing a copy/paste. I am, honestly, confused as to why you would do that.

    Gryphbear wrote: »
    I greatly doubt it's to do with the $npcs Dataset I have. I have added a lot of stuff, but... it keeps only pointing to the <<allrelationships>> widget. Am I missing something obvious?
    Try placing <<relationship "jonas">> somewhere before the test of <<allrelationships>>. I'm betting you'll find that it yields an error as well—for the reason I've outlined above.

    Gryphbear wrote: »
    […] when I play the game, I get some errors like this -
    Error: <<set>>: bad evaluation: Cannot read property 'jonas' of undefined
    
    The above was basically doing <<set $npcs["jonas"].aff to 2>> essentially, and the other one was <<set $npcs["jonas".hasPhone to true>>. And both say they cannot find the $npcs code or think it's undefined for some reason. Am I missing an extra } or something?
    And that confirms my theory. That error means that $npcs has become undefined/null and is no longer an object. As to how you've broken it, no one can say without seeing the code.

    Also, the <<set $npcs["jonas".hasPhone to true>> bit is missing a right square bracket—but that may have been a transcription error here (no copy/paste?).

    Gryphbear wrote: »
    Does TWINE have issues with multiple line property values? or Sugarcube?
    SugarCube does not have issues with it—assuming your syntax is correct.

    Twine does not have issues with any of your code, it's an IDE/compiler and has little to do with your code, save for compiling it into the story format.


    MoLoLu wrote: »
    Multiline is fine. I'm not sure what's going wrong but the property object doesn't get passed over to the nested widget properly. Probably due to scope issues with temp variables.
    Gryphbear is, as they noted in the opening post, using a recent version of SugarCube 2. The invocation <<relationship _npcIds[_i]>> does, in fact, pass the name of the NPC properly. Beyond that, as I noted in my previous post, this has all been tested by me and is working as intended.

    You, personally, are, or were, using a pre-v1.0.0 version of SugarCube. Unless you have recently switched to SugarCube 2, then your specific issue is that you do not have access to SugarCube 2 temporary variables as they are a feature that was added in SugarCube v2.3.0.

    For example, take the following code example:
    <<set _reaction to "/facepalm">>
    
    Within SugarCube ≥v2.3.0: It sets an special temporary variable which exists for the duration of the moment/turn within which it was created. It will be automatically unset at the beginning of the next moment/turn.

    Within SugarCube <v2.3.0: It sets a JavaScript variable which is locally scoped to the <<set>> invocation.

    TL;DR: What you've said is completely incorrect for the version of SugarCube 2 that Gryphbear is using. I'm not trying to be mean here, however, if you're going to attempt to help people, please try to ensure that the information you're passing on is correct—because passing on incorrect information helps absolutely no one.
  • edited October 2016
    I assure you I'm not sprouting disinformation. I updated Scaffold to the latest version of sugarcube an hour before this post and tested the code I posted. It did not work, just as the same principle did not for Gryph (got the same undefined error). Using story variables with exactly the same code and no other changes (except the unset macro) did.

    Edit, for clarity:

    Compiled in twine 1.4.1 with sc version v1.0.35 according to its header. I didn't test in Twine 2. I highly doubt any of the changes I've made to the header could have broken that functionality. This is very likely an issue with variable scope as temp variables work as intended within a single widget.

    By the way, why does the header vers not match the release vers? Had me confused and double checked just to make 100% sure I got the newest.
  • MoLoLu wrote: »
    […] I updated Scaffold to the latest version of sugarcube an hour before this post and tested the code I posted. […]

    […] Compiled in twine 1.4.1 with sc version v1.0.35 according to its header. […]
    The latest version of SugarCube is not v1.0.35. That is the latest version of the old, legacy v1 series. The latest version of SugarCube is v2.10.0.

    According to Gryphbear, they are using SugarCube version 2.x, not version 1.x. Unless they gave the wrong version, you are barking up the wrong tree.

    In my last post, I fully explained why the given code will not work in v1 and why it does in v2. Did you actually bother to read my post?
  • edited October 2016
    Edit: nvm. Seems I hit the wrong link. Will retest.
  • That link does point to the latest version, as I post this, v2.10.0. It also is demonstrably not v1.0.35, so you're doing something wrong somewhere. And no, there is nothing wrong with the contents of the archive—I just downloaded it and verified the version; this is all automated anyway, I do not create the archives by hand.

    If you simply extracted that archive within your targets directory, then you probably simply did not change the story format of your project within Twine. So that it may coexist alongside SugarCube v1 installations, because some people need that ability, it has a different name/ID—directory in Twine 1, but the effect is the same. In Twine 1, you want: Story menu > Story Format > Sugarcube-2. As an additional note, you cannot simply change the story format and save, as Twine 1 does not flag that as a modification of the project, so it won't save the change until you modify something else.
  • Can confirm. Monumental fuck-up on my part. Sorry for cluttering the thread.

    /slinks away quietly
  • @MoLoLu - No worries. You were trying to help :)

    @TheMadExile - Thank you for helping out again. I went through the dataset for $npcs a few entries at a time, tested things, and finally weeded out the errors I had in it that I hadn't actually 'seen' right away. Like a set of " "'s inside one of the String Properties. Among others. It is working like a charm again, and all I need to do is tweak the relationship widget slowly, and the dataset for more clearer output. (Meaning, Polish the content inside the string values so it doesn't look so copy/pasted) As it is, it's a bit messy. Plus - I was copy/pasting, rather than transcribing. :) Thanks. :)
Sign In or Register to comment.