Howdy, Stranger!

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

How can I write a find:replace function for gender? [Snowman 1.3]

Hello, could someone explain how find:replace functions work in Snowman 1.3 I'd like to use it as means to assign a player's gender. The current code I'm working with looks something like this, and it doesn't make the writing process any easier.
I wish <% if (s.player_sex == "female") { %>she<% } %><% if (s.player_sex == "male") { %>he<% } %> was still here.

Comments

  • I'm unsure what you mean by "find:replace functions", however, you could create some gender pronoun functions to ease things along.

    For example, a `he()` function: (goes in Story JavaScript)
    // Create a `gender` object on `window` for namespacing.
    window.gender = {};
    
    // Add a `he()` function to `gender`.
    window.gender.he = function () {
    	var s = story.state;
    
    	// Handle 'he' & 'she' pronouns.  Others may be added if necessary.
    	switch (s.player_sex) {
    	case 'male':   return 'he';
    	case 'female': return 'she';
    	}
    
    	// Complain if you've fat-fingered an assignment to `player_sex`
    	// or forgot to add cases for new genders.
    	throw new Error('unknown player sex in he()');
    };
    

    Usage:
    I wish <%= gender.he() %> was still here.
    
  • Awesome, that'll work just as well. Thank you.

    How might I let the player choose the pronoun assignment if I were to use a popup window? I might also need to prevent progress until one is selected, or find a way to code a default pronoun like 'they' or 'theirs' if nothing is chosen.

    And is this the correct way of adding additional pronouns to that list?
    // Create a `gender` object on `window` for namespacing.
    window.gender = {};
    
    // Add a `possessive.determiner()` function to `gender`.
    window.gender.possessive.determiner = function () {
    	var s = story.state;
    
    	// Handle 'him' & 'her' pronouns.  Others may be added if necessary.
    	switch (s.player_sex) {
    	case 'male':   return 'him';
    	case 'female': return 'her';
    	}
    
    	// Complain if you've fat-fingered an assignment to `player_sex`
    	// or forgot to add cases for new genders.
    	throw new Error('unknown player sex in him()');
    };
    

    Usage:
    I told<%= gender.him() %> not to do that.
    
    // Create a `gender` object on `window` for namespacing.
    window.gender = {};
    
    // Add a `possessive.pronoun()` function to `gender`.
    window.gender.possessive.pronoun = function () {
    	var s = story.state;
    
    	// Handle 'his' & 'hers' pronouns.  Others may be added if necessary.
    	switch (s.player_sex) {
    	case 'male':   return 'his';
    	case 'female': return 'hers';
    	}
    
    	// Complain if you've fat-fingered an assignment to `player_sex`
    	// or forgot to add cases for new genders.
    	throw new Error('unknown player sex in his()');
    };
    

    Usage:
    I thought it was <%= gender.his() %> idea.
    
  • Glitch wrote: »
    How might I let the player choose the pronoun assignment if I were to use a popup window?
    That's going to need some clarification. You can allow them to choose in any number of ways—links, radio buttons, listbox, etc.

    Using a popup complicates things. Is there a good reason for wanting to use a popup?

    Glitch wrote: »
    I might also need to prevent progress until one is selected, or find a way to code a default pronoun like 'they' or 'theirs' if nothing is chosen.
    The former should be easy, if you use a passage rather than a popup.

    The latter is also easy, in theory, just add a default case to the switch and remove the error—I say in theory, because, as shown below, pronouns may vary depending on context, so you have to give it a little forethought. I can provide examples if necessary.

    Glitch wrote: »
    And is this the correct way of adding additional pronouns to that list?
    1. You should create the window.gender object exactly once.
    2. You're naming the functions incorrectly—both syntactically and with how you're attempting to call them.
    For example, including your two new functions it should look something like the following—function contents removed to declutter the example:
    // Create a `gender` object on `window`, for namespacing.
    window.gender = {};
    
    // Add several pronoun functions to `gender`.
    window.gender.he = function () {
    	// […]
    };
    
    window.gender.him = function () {
    	// […]
    };
    
    window.gender.his = function () {
    	// […]
    };
    

    Here's a version which makes the function declarations part of the initial window.gender object literal, rather than adding them to the object afterwards—which might make it a bit easier to wrap your head around. It also improves the error message and addresses an issue in your his() function when combining it with a noun—specifically, when to use "her" versus "hers".
    /*
    	Create a `gender` object on `window`, for namespacing, and add
    	several gender related pronoun functions to it.
    */
    window.gender = {
    	he : function () {
    		var s = story.state;
    
    		switch (s.player_sex) {
    		case 'male':   return 'he';
    		case 'female': return 'she';
    		}
    
    		throw new Error('unknown player sex "' + s.player_sex + '"');
    	},
    
    	him : function () {
    		var s = story.state;
    
    		switch (s.player_sex) {
    		case 'male':   return 'him';
    		case 'female': return 'her';
    		}
    
    		throw new Error('unknown player sex "' + s.player_sex + '"');
    	},
    
    	his : function (withObject) {
    		var s = story.state;
    
    		switch (s.player_sex) {
    		case 'male':   return 'his';
    		case 'female': return withObject ? 'her' : 'hers';
    		}
    
    		throw new Error('unknown player sex "' + s.player_sex + '"');
    	}
    };
    
    You may find it more palatable to use separate functions to handle the "her"/"hers" distinction, rather than using a parameter—e.g. gender.his() & gender.hisWithObject() versus gender.his() & gender.his(true). Either way, it's something you're going to have to keep an eye out for while writing.

    Usage:
    I wish <%= gender.he() %> was still here.
    	↳ I wish he was still here.
    	↳ I wish she was still here.
    
    I told <%= gender.him() %> not to do that.
    	↳ I told him not to do that.
    	↳ I told her not to do that.
    
    I thought it was <%= gender.his() %>.
    	↳ I thought it was his.
    	↳ I thought it was hers.
    
    I thought it was <%= gender.his(true) %> idea.
    	↳ I thought it was his idea.
    	↳ I thought it was her idea.
    
  • Using a popup complicates things. Is there a good reason for wanting to use a popup?
    If popup boxes complicate things, could I implement it via the buttons I already have in place? And I felt that asking a player's gender outside the context of the story would've been less clunky, is all. I'll probably be able to figure something out using buttons.

    How would I implement buttons that use an existing style-sheet?
    /*choice button*/
    
    #choices {
    	list-style: none;
    	padding: 0;
    	border: 1px solid #bbb;
    }
    #choices li {
    	margin: 0;
    	padding: 0;
    }
    #choices li:not(:first-child) {
    	border-top: 1px solid #bbb;
    }
    #choices li a {
    	display: block;
    	margin: 0;
    	padding: 0.5em 0.8em;
    	border: none;
    	text-decoration: none;
    	font-size: 75%;
    }
    #choices li a:hover {
    	color: #fff;
    	background-color: #718389;
    }
    
    The latter is also easy, in theory, just add a default case to the switch and remove the error—I say in theory, because, as shown below, pronouns may vary depending on context, so you have to give it a little forethought. I can provide examples if necessary.
    I'm comfortable with using a passage instead. And I'd really appreciate some examples. Most of that went over my head.
    You should create the window.gender object exactly once.You're naming the functions incorrectly—both syntactically and with how you're attempting to call them. For example, including your two new functions it should look something like the following—function contents removed to declutter the example:
    Alright, if I need to add any more options, I'll work with that example.
    Here's a version which makes the function declarations part of the initial window.gender object literal, rather than adding them to the object afterwards—which might make it a bit easier to wrap your head around. It also improves the error message and addresses an issue in your his() function when combining it with a noun—specifically, when to use "her" versus "hers".
    Great, that clarifies it a bit. Thank you for taking the time to code that.
  • edited July 11
    Glitch wrote: »
    How would I implement buttons that use an existing style-sheet?
    Unless you want them to look different, I'd simply use what you already have. For example, here's one equivalent of a setter link in Snowman which will set player_sex and forward the player to the specified passage:
    <ul id="choices">
    	<li><a href="javascript:story.state.player_sex='male';story.show('Some Passage');">Boy</a></li>
    	<li><a href="javascript:story.state.player_sex='female';story.show('Some Passage');">Girl</a></li>
    </ul>
    

    Glitch wrote: »
    […] I'd really appreciate some examples. Most of that went over my head.
    Here's gender.his(), from the all-in-one object literal example, rewritten to return neutral pronouns when player_sex is either undefined or any value other than 'male'/'female', rather than throwing an error:
    	his : function (withObject) {
    		var s = story.state;
    
    		switch (s.player_sex) {
    		case 'male':   return 'his';
    		case 'female': return withObject ? 'her' : 'hers';
    		default:       return withObject ? 'their' : 'theirs';
    		}
    	}
    
    Usage, with varying values for player_sex:
    I thought it was <%= gender.his() %>.
    	↳ I thought it was his.
    	↳ I thought it was hers.
    	↳ I thought it was theirs.
    
    I thought it was <%= gender.his(true) %> idea.
    	↳ I thought it was his idea.
    	↳ I thought it was her idea.
    	↳ I thought it was their idea.
    
  • It works! Thank you very much!

    I've found a tiny grammatical error, but I think I know how to correct it. I'm just gonna run it by you to see if you've got an alternative solution, this one is a bit clunky. So, when they, them, theirs is the variable used for sex, sentences that use 'he' and 'she' no longer work with 'they' because of its default plurality.

    e.g. The sentence "I wish he/she was still here." becomes "I wish they was still here". Was needs to be replaced with were. So it's now written. "I wish <%= gender.he() %> <%= gender.was() %> still here."

    Here's my JavaScript with this new variable implemented.
    /*
    	Create a `gender` object on `window`, for namespacing, and add
    	several gender related pronoun functions to it.
    */
    window.gender = {
    	he : function () {
    		var s = story.state;
    
    		switch (s.player_sex) {
    		case 'male':   return 'he';
    		case 'female': return 'she';
    		default:       return 'they';
    		}
    	},
    		
    	was : function () {
    		var s = story.state;
    
    		switch (s.player_sex) {
    		case 'male':   return 'was';
    		case 'female': return 'was';
    		default:       return 'were';
    		}
    	},
    
    	him : function () {
    		var s = story.state;
    
    		switch (s.player_sex) {
    		case 'male':   return 'him';
    		case 'female': return 'her';
    		default:       return 'them';
    		}
    
    	},
    
    	his : function (withObject) {
    		var s = story.state;
    
    		switch (s.player_sex) {
    		case 'male':   return 'his';
    		case 'female': return withObject ? 'her' : 'hers';
    		default:       return withObject ? 'their' : 'theirs';
    		}
    	}
    };
    
  • Word agreement when juggling different senses and meanings can be a pain. I think what you've got there is a reasonable, if not entirely palatable, solution.

    As long as you allow players to choose not to choose a gender, then you're going to have this issue.

    TIP: Assuming you'll be typing these in a lot, you might want to consider shortening the namespace object's name a bit—just don't clobber a built-in. For example:
    // Maybe `sex`—don't use `s`, as that's Snowman's in-template `story.state` shortcut.
    window.sex = {
    	// […]
    };
    
    // Or `g`, for gender.
    window.g = {
    	// […]
    };
    
    // Perhaps `p`, for pronoun.
    window.p = {
    	// […]
    };
    
  • Perfect, thank you very much, TheMadExile. I'm glad we could wrap this up before the forum closes. I've implemented those changes, and it's all working beautifully thanks to you.
Sign In or Register to comment.