An author's reference for Bisquixe, a tool for adding audiovisual content to Inform projects (up: inline links and minor tweaks)

The Bisquixe interpreter enables the setting and changing of a web game’s CSS on the fly.

CSS is a cornerstone web technology used to manage the styling and presentation of web pages. It has always been possible for Inform authors to manually edit or provide their own custom CSS files for web games, but Bisquixe allows authors to set CSS within their source code.

Why would this be valuable? From a management perspective, some authors may dislike keeping track of multiple files for their releases. Additionally, authors may not be familiar with CSS, preferring to maintain a small set of changes within their projects.

Perhaps the greatest opportunity for authors is the ability to leverage Inform’s rules-based architecture. In-game events can accompany CSS changes, for instance. Perhaps a dramatic event calls for a different color scheme. It’s as simple as creating or extending an action-processing rule.

There are multiple threads containing guides and sample project code for Bisquixe. What is the rationale for creating this new thread? Those threads are not intended to serve as references. Rather than a guide, this thread will consist of short posts explaining specific features. It will include a table of contents. It will also be designated a wiki, granting editing privileges to the community.

FAQS (to be filled in later)

  1. I have a specific question about using bisquixe in my project. Can I ask it here? A: Please make a new Authoring: Inform 7 thread and use the “bisquixe” tag. This will help other authors find your question in a search.
  2. I want to add a new topic to this thread. A: That’s great! Please do. I request that editors make their additions as accessible (speak to readers of various skill levels) as possible.

Previous guide threads:
The Bisquixe interpreter for Inform 7 and Inform 10 styling (new: command bar)
Beginner's Guide to Styling Inform Releases with Bisquixe
Web styling with Bisquixe for new Inform authors (update: sample code for user-selectable light/dark modes)

Table of Contents

Introductions

  1. The Bisquixe interpreter
  2. The Simple Multimedia Effects extension
  3. Regarding CSS

Basic Web Styling with Bisquixe

  1. Phrases using css-set-fast
  2. Frequently styled parts of an Inform web game
  3. Frequently styled properties in web-based Inform games: colors and fonts
  4. Other frequently-specified elements and properties in web-based Inform games
  5. Styling input

Milestone: a styled webpage

  1. A note on organizing Bisquixe code
  2. A minimally yet thoroughly styled Inform game
  3. Assigning colors, fonts, and font-sizes for a styled web game

Using custom classes to style inline text

  1. Determining whether an interpreter supports Bisquixe while processing actions and activites
  2. Creating custom classes for inline styling
  3. Accounting for alternate interpreters

Using external resources

  1. External resources
  2. Using Google Fonts in a Bisquixe project
  3. A Tale of Two Informs
  4. Documentation review: including images in an Inform project
  5. Restoring images to released Inform websites
  6. Working with sound
  7. More information regarding interpreters

A closer look at CSS elements and properties

  1. Commonly styled CSS properties and elements
  2. background-image
  3. border
  4. Arrangements
  5. Manipulating shape and perspective
  6. Gradients

Hyperlinks

  1. Introducing hyperlinks
  2. Advanced application of hyperlinks
  3. Reserved

Further excursions

  1. Image scaling
  2. Accessibility
  3. Directly editing extensions, templates, and CSS
  4. Troubleshooting

In conclusion

  1. Onward
  2. Acknowledgements

Examples

Minor updates

15 Likes

The Bisquixe Interpreter

The Bisquixe interpreter is based on Quixe. In order to use Bisquixe in web-based games, authors must invoke it in their projects. First, download the interpreter here.

Releases · brirush84/Bisquixe

Once downloaded, place the contents of the zip file (a folder called “Bisquixe”) in the /Inform/Templates folder. By default, this Inform folder also holds the author’s projects and extensions folders.

Once the folder is in place, authors can release web games using the Bisquixe interpreter.

release along with a "bisquixe" interpreter.

For more information, see 25.11 in the Inform documentation.

It is important to know that Bisquixe works with a very specific version of the Glulx Entry Points extension. If problems arise, it may be necessary to change versions. A confirmed version of the extension is included below, both as a file and as raw code.

Glulx Entry Points version 10.0.150101

Glulx Entry Points.i7x (13.1 KB)

Version 10.0.150101 of Glulx Entry Points (for Glulx only) by Emily Short begins here.

"Provides hooks to allow the author to write specialized multimedia behavior that would normally go through HandleGlkEvent. This is a rather dull utility library that will be of most use to authors wanting to write Glulx extensions compatible with other Glulx extensions already in use."

Use authorial modesty.

Section - Use option

[As of version 10, Glulx Entry Points has a somewhat more flexible approach to event handling than did earlier versions: Whereas the latter consulted one of eight separate rulebooks depending on the event type, Glulx Input Loops passes the event type into a single parametrized rulebook. This means, for example, that we can have a general rule for event handling that fires no matter what the event, alongside the usual event-based rules. It allows us to group events by broader type (e.g. events generated by the player vs. events generated by the system).

Many existing extensions are based on the older system, however, and we would break those extensions if we simply removed the older event-handling rulebooks. So, we retain them, and Glulx Entry Points will (by default) still pass event-handling to those rulebooks. This means that existing code will continue to work as before, and we can also use the new parameterized rulebook if we like.

This use option disables the old rulebooks, and should be used only when we know that we are not using an extension that depends on the old rulebooks.]

Use direct event handling translates as (- Constant DIRECT_GLK_EVENT_HANDLING; -).


Section - New rulebooks

[This first set of rulebooks--the event-handling rulebooks--are now deprecated in favor of the "glulx input handling rulebook".]
The glulx timed activity rules is a rulebook.
The glulx redrawing rules is a rulebook.
The glulx arranging rules is a rulebook.
The glulx sound notification rules is a rulebook.
The glulx mouse input rules is a rulebook.
The glulx character input rules is a rulebook.
The glulx line input rules is a rulebook.
The glulx hyperlink rules is a rulebook.

The glulx zeroing-reference rules is a rulebook.
The glulx resetting-windows rules is a rulebook.
The glulx resetting-streams rules is a rulebook.
The glulx resetting-filerefs rules is a rulebook.
The glulx object-updating rules is a rulebook.


Section - Global variables

Current glulx rock is a number that varies.
Current glulx rock-ref is a number that varies.

Glulx replacement command is some indexed text that varies.

Library input context is a number variable. [This describes the event context in which input was received, e.g. whether the Inform library was awaiting line input or char input. If 0, the library was awaiting line input, if 1, char input. This is not as useful as an event-typed value would be; with such a value, we could detect any input context--e.g., we are waiting for hyperlink input. Perhaps a future version of Glulx Entry Points will discard the old convention in favor of a more expansive system.]


Section - Gestalts

To decide whether glulx character input is supported:
	(- ( glk_gestalt(gestalt_CharInput, 0) ) -)

To decide whether glulx mouse input is supported:
	(- ( glk_gestalt(gestalt_MouseInput, winType_AllTypes) ) -)

To decide whether glulx graphic-window mouse input is supported:
	(- ( glk_gestalt(gestalt_MouseInput, winType_Graphics) ) -)

To decide whether glulx text-grid mouse input is supported:
	(- ( glk_gestalt(gestalt_MouseInput, winType_TextGrid) ) -)

To decide whether glulx timekeeping is supported:
	(- ( glk_gestalt(gestalt_Timer, 0) ) -)

To decide whether glulx graphics is supported:
	(- ( glk_gestalt(gestalt_Graphics, 0) ) -)

To decide whether glulx text-buffer graphics is supported:
	(- ( glk_gestalt(gestalt_DrawImage, winType_TextBuffer) ) -)

To decide whether glulx graphic-window graphics is supported:
	(- ( glk_gestalt(gestalt_DrawImage, winType_Graphics) ) -)

To decide whether glulx PNG transparency is supported:
	(- ( glk_gestalt(gestalt_GraphicsTransparency, 0) ) -)

To decide whether glulx sound is supported:
	(- ( glk_gestalt(gestalt_Sound, 0) ) -)

To decide whether glulx mod sound is supported:
	(- ( glk_gestalt(gestalt_SoundMusic, 0) ) -)

To decide whether glulx sound volume is supported:
	(- ( glk_gestalt(gestalt_SoundVolume, 0) ) -)

To decide whether glulx sound notification is supported:
	(- ( glk_gestalt(gestalt_SoundNotify, 0) ) -)

To decide whether glulx hyperlinks are supported:
	(- ( glk_gestalt(gestalt_Hyperlinks, 0) ) -)


Section - IdentifyGlkObject routine

Include (-

   [ IdentifyGlkObject phase type ref rock;
	  if (phase == 0) { ! Zero out references to our objects.
	 if (FollowRulebook( (+glulx zeroing-reference rules+) ) && RulebookSucceeded()) { rtrue; }
	  }

	  if (phase == 1) { ! Reset our windows, streams and filerefs.
	(+ current glulx rock +) = rock;
	(+ current glulx rock-ref +) = ref;
		 switch (type) {
			0: ! it's a window 
			   	FollowRulebook( (+ glulx resetting-windows rules +) );
	 1 : ! it's a stream
			   	FollowRulebook( (+ glulx resetting-streams rules +) );
		   2 : ! it's a file reference
			   	FollowRulebook( (+ glulx resetting-filerefs rules +) );
		 }
		 return;
	  }

	  if (phase == 2) { ! Update our objects.
		 if (FollowRulebook( (+glulx object-updating rules+) ) && RulebookSucceeded()) { rtrue; }
	  }

   ];

-) replacing "IdentifyGlkObject".


Section - Event types

A g-event is a kind of value. The g-events are timer-event, char-event, line-event, mouse-event, arrange-event, redraw-event, sound-notify-event, and hyperlink-event.

To decide which g-event is null-event: (- 0 -)


Section - Events dependent on the player

Definition: A g-event is independent of the player rather than dependent on the player if it is timer-event or it is sound-notify-event or it is arrange-event or it is redraw-event.


Section - Wrappers for event structure, return values, etc

To wait for glk input:
	(- glk_select(gg_event); -)

To decide whether the current input context is line input:
	(- ( (+ library input context +) == 0 ) -)

To decide whether the current input context is char/character input:
	(- ( (+ library input context +) == 1 ) -)
	
To decide which g-event is the current glk event:
	(- evGlobal-->0 -)
	
To decide what number is the window of the current glk event:
	(- evGlobal-->1 -)
	
To decide what number is the character code returned:
	(- evGlobal-->2 -)

To decide what number is input replacement:
	(- 2 -)

To decide what number is input continuation:
	(- 1 -)


Section - Event Handling

[This is an I7 version of the event handling that was included in the I6 HandleGlkEvent routine in previous versions of Glulx Entry Points, with minor changes to allow any event type to provide a replacement command. Converted to I7 code in version 10.]

To decide what number is the value returned by glk event handling (this is the handle glk event rule):
	now glulx replacement command is "";
	follow the glulx input handling rules for the current glk event;
	if the outcome of the rulebook is the replace player input outcome:
		decide on input replacement;
	if the outcome of the rulebook is the require input to continue outcome:
		decide on input continuation;
	follow the command-counting rules;
	if the rule succeeded:
		follow the input-cancelling rules;
		follow the command-showing rules;
		follow the command-pasting rules;
		if the [command-pasting] rule succeeded:
			decide on input replacement.


Section - HandleGlkEvent routine

Include (- Array evGlobal --> 4; -).

Include (- 

  [ HandleGlkEvent ev context abortres newcmd cmdlen i ;
	  for (i=0:i<3:i++) evGlobal-->i = ev-->i;
	  (+ library input context +) = context;
	  return ((+ handle glk event rule +)-->1)();
  ];

-) replacing "HandleGlkEvent".


Section - Useful function wrappers

To update/redraw the/-- status line:
	(- DrawStatusLine(); -)

To print prompt:
	(- PrintPrompt(); -)


Section - The glulx input handling rulebook

[These rules route input to the separate event-handling rulebooks originally used by older versions of Glulx Entry Points. They do nothing if we have activated the direct event handling use option.]

The glulx input handling rules are a g-event based rulebook. The glulx input handling rules have outcomes replace player input (success) and require input to continue (success).

Last glulx input handling rule for a timer-event when the direct event handling option is not active (this is the redirect to GEP timed activity rule):
	abide by the glulx timed activity rules.

Last glulx input handling rule for a char-event when the direct event handling option is not active (this is the redirect to GEP character input rule):
	abide by the glulx character input rules.

Last glulx input handling rule for a line-event when the direct event handling option is not active (this is the redirect to GEP line input rule):
	follow the glulx line input rules;
	if the rule succeeded:
		replace player input.

Last glulx input handling rule for a mouse-event when the direct event handling option is not active (this is the redirect to GEP mouse input rule):
	abide by the glulx mouse input rules.

Last glulx input handling rule for an arrange-event when the direct event handling option is not active (this is the redirect to GEP arranging rule):
	abide by the glulx arranging rules.

Last glulx input handling rule for a redraw-event when the direct event handling option is not active (this is the redirect to GEP redrawing rule):
	abide by the glulx redrawing rules.

Last glulx input handling rule for a sound-notify-event when the direct event handling option is not active (this is the redirect to GEP sound notification rule):
	abide by the glulx sound notification rules.

Last glulx input handling rule for a hyperlink-event when the direct event handling option is not active (this is the redirect to GEP hyperlink rule):
	abide by the glulx hyperlink rules.



Section - Debounce arrange events - unindexed

[ Gargoyle sends an arrange event while the user is dragging the window borders, but we really only want one event at the end. Debounce the arrange event to ignore the earlier ones. ]

Arranging now in GEP is a truth state variable. Arranging now in GEP is false.

First glulx input handling rule for an arrange-event while arranging now in GEP is false (this is the debounce arrange event rule):
	let i be 0; [ for the I6 polling code to use ]
	let final return value be a number;
	let arrange again be true;
	[ Poll for further arrange events ]
	while 1 is 1:
		poll for events in GEP;
		if the current event number in GEP is 0:
			break;
		otherwise if the current glk event is an arrange-event:
			next;
		[ We have a different event ]
		otherwise:
			[ Run the arrange rules ]
			let temp event type be the current glk event;
			set the current glk event in GEP to an arrange-event;
			now final return value is the glulx input handling rules for an arrange event;
			set the current glk event in GEP to temp event type;
			now arrange again is false;
			now final return value is the value returned by glk event handling;
			break;
	[ Run the arrange rules if we didn't get another event type ]
	if arrange again is true:
		now final return value is the glulx input handling rules for an arrange event;
	[ Return values ]
	if final return value is input replacement:
		replace player input;
	if final return value is input continuation:
		require input to continue;
	rule fails;

To decide what number is the glulx input handling rules for an arrange event:
	let final return value be a number;
	now arranging now in GEP is true;
	now final return value is the value returned by glk event handling;
	now arranging now in GEP is false;
	decide on final return value;

To poll for events in GEP:
	(- glk_select_poll( gg_event ); for ( tmp_0 = 0 : tmp_0 < 3 : tmp_0++) { evGlobal-->tmp_0 = gg_event-->tmp_0; } -).

To decide what number is the current event number in GEP:
	(- evGlobal-->0 -).

To set the current glk event in GEP to (ev - a g-event):
	(- evGlobal-->0 = {ev}; -).



Section - Command-counting rules

The command-counting rules are a rulebook.

A command-counting rule (this is the ordinary checking for content rule):
	if the number of characters in the glulx replacement command is 0, rule fails;
	rule succeeds.


Section - Input-cancelling rules
	
The input-cancelling rules are a rulebook.

An input-cancelling rule (this is the cancelling input in the main window rule):
	cancel line input in the main window;
	cancel character input in the main window;
	
To cancel line input in the/-- main window:
	(- glk_cancel_line_event(gg_mainwin, GLK_NULL); -)
	
To cancel character input in the/-- main window:
	(- glk_cancel_char_event(gg_mainwin); -)


Section - Command showing rules

The command-showing rules are a rulebook.

A command-showing rule (this is the print text to the input prompt rule):
	say input-style-for-glulx;
	say Glulx replacement command;
	say roman type;

To say input-style-for-Glulx: 
	(- glk_set_style(style_Input); -)
 

Section - Command pasting rules

The command-pasting rules are a rulebook. 

A command-pasting rule (this is the glue replacement command into parse buffer rule): 
	change the text of the player's command to the Glulx replacement command;
	rule succeeds.
	
Glulx Entry Points ends here.
3 Likes

The Simple Multimedia Effects Extension

While the Bisquixe interpreter grants browser support, it does not add new features or capabilities to our Inform projects. To actually use Bisquixe in our code, we will need to install an extension.

Bisquixe currently supports Inform 10.1 and compiler 6M62. Depending on the version of Inform used, authors will either require “Simple Multimedia Effects” or “Simple Multimedia Effects for v10.” Both are downloadable here.

Releases · brirush84/Bisquixe

Once downloaded, it must be installed. In order to install extensions from within the Inform IDE, simply click the “file” drop-down menu at upper left and select “install extension.”

!Important

At the time of this writing, both versions of “Simple Multimedia Effects” have a hard limit of 64 characters that our CSS code can contain. This will likely be adjusted in future versions of the extension, but, for now, I recommend that authors add the folowing code to either individual projects or, perhaps better, to the “Simple Multimedia Effects” and “Simple Multimedia Effects for v10” extensions to increase the character limit (thanks to @draconis for these solutions!).

Inform 10 code
Include (- Constant GG_ANYTOSTRING_LEN 258; -) replacing "GG_ANYTOSTRING_LEN".
Inform 9 code
Include (-
! Glulx_PrintAnything()                    <nothing printed>
! Glulx_PrintAnything(0)                   <nothing printed>
! Glulx_PrintAnything("string");           print (string) "string";
! Glulx_PrintAnything('word')              print (address) 'word';
! Glulx_PrintAnything(obj)                 print (name) obj;
! Glulx_PrintAnything(obj, prop)           obj.prop();
! Glulx_PrintAnything(obj, prop, args...)  obj.prop(args...);
! Glulx_PrintAnything(func)                func();
! Glulx_PrintAnything(func, args...)       func(args...);

[ Glulx_PrintAnything _vararg_count obj mclass;
	if (_vararg_count == 0) return;
	@copy sp obj;
	_vararg_count--;
	if (obj == 0) return;

	if (obj->0 == $60) {
		! Dictionary word. Metaclass() can't catch this case, so we do it manually
		print (address) obj;
		return;
	}

	mclass = metaclass(obj);
	switch (mclass) {
	  nothing:
		return;
	  String:
		print (string) obj;
		return;
	  Routine:
		! Call the function with all the arguments which are already
		! on the stack.
		@call obj _vararg_count 0;
		return;
	  Object:
		if (_vararg_count == 0) {
			print (name) obj;
		}
		else {
			! Push the object back onto the stack, and call the
			! veneer routine that handles obj.prop() calls.
			@copy obj sp;
			_vararg_count++;
			@call CA__Pr _vararg_count 0;
		}
		return;
	}
];

[ Glulx_PrintAnyToArray _vararg_count arr arrlen str oldstr len;
	@copy sp arr;
	@copy sp arrlen;
	_vararg_count = _vararg_count - 2;

	oldstr = glk_stream_get_current();
	str = glk_stream_open_memory(arr, arrlen, 1, 0);
	if (str == 0) return 0;

	glk_stream_set_current(str);

	@call Glulx_PrintAnything _vararg_count 0;

	glk_stream_set_current(oldstr);
	@copy $ffffffff sp;
	@copy str sp;
	@glk $0044 2 0; ! stream_close
	@copy sp len;
	@copy sp 0;
	return len;
];

Array AnyToStrArr -> GG_ANYTOSTRING_LEN+1;

[ Glulx_ChangeAnyToCString _vararg_count ix len;
	ix = GG_ANYTOSTRING_LEN-2;
	@copy ix sp;
	ix = AnyToStrArr+1;
	@copy ix sp;
	ix = _vararg_count+2;
	@call Glulx_PrintAnyToArray ix len;
	AnyToStrArr->0 = $E0;
	if (len >= GG_ANYTOSTRING_LEN)
		len = GG_ANYTOSTRING_LEN-1;
	AnyToStrArr->(len+1) = 0;
	return AnyToStrArr;
];
-) instead of "Glulx-Only Printing Routines" in "Glulx.i6t".

Use maximum Glk string length of at least 258 translates as (- Constant GG_ANYTOSTRING_LEN = {N}+2; -).
4 Likes

Regarding CSS

CSS is a cornerstone web technology that specifies the appearance and styling of web pages.

Inform web interpreters come with default styling contained in CSS files. These files specify colors, fonts, and other visual features. If you have played an Inform game via a web page, you have engaged with CSS.

Bisquixe is not a requirement for editing or customizing the default CSS for these games. This can be accomplished by editing a file external to the project. However, while there are limitations—Bisquixe code formatting requirements are strict—many CSS customizations can be specified within a Bisquixe project.

Why would an author want specify CSS in an Inform project instead of using a file?

Many authors will find management of a separate CSS file cumbersome. Inexperienced authors might prefer the simplified format of Bisquixe code.

Authors will probably find the ability to use Inform’s rules-based architecture the most compelling reason for using Bisquixe. With it, incorporating CSS changes into action processing is a simple matter. For instance, all three of these possibilities are valid:

when play begins:
	css-set-fast ".BufferWindow; background; blue";
	
every turn when the player carries the blue diamond:
	css-set-fast ".BufferWindow; background; blue";
	
carry out attacking the innocent bystander:
	css-set-fast ".BufferWindow; background; red";	

In fact, we can make css changes while processing activities and other rulebooks:

a rule for printing the name of the orange:
	css-set-fast ".BufferWindow; background; orange";

Bisquixe changes are laid atop settings specified in the Bisquixe interpreter’s default CSS. If the author’s project does not specify a font size, for instance, the game’s web page will style font size according to the default CSS.

While reading CSS can be intimidating for beginners, it is worth knowing where to look. Bisquixe’s default css and location is \Inform\templates\Bisquixe\glkote.css (by default, \Inform also contains the author’s projects and extensions).

Persons familiar with the Quixe interpreter should be aware that default css for Bisquixe is similar, but not identical.

4 Likes

The “css-set-fast” phrase

Bisquixe projects use a specifically-formatted phrase to specify CSS. The formatting is

css-set-fast "[specifically-formatted-css information]";

Note that everything following css-set-fast is a text. Consider the way CSS specifies the font size for .BufferWindow, the part of the game window where commands and feedback text are displayed (i.e., the main play area).

.BufferWindow {
  font-size: 15px;
}

Bisquixe processes CSS as a sequence of text strings separated by the ; semicolon character. The Bisquixe equivalent of the above CSS would be

css-set-fast ".BufferWindow; font-size; 15px"

Note that while the above CSS will load whenever the page loads, our css-set-fast phrase will not compile as-is. It must be part of a rule. If we wish to set a new font size when play begins, we have to say so.

when play begins:
	css-set-fast ".BufferWindow; font-size; 16px";

Although there are more complex cases to discuss, basic style configurations can be made by identifying the component parts and separating them with semicolons. Examining the default Bisquixe CSS can provide initial insight into the way things are named.

Note that css-set-fast phrases can be highly sensitive to case because, while CSS itself is case-insensitive, classes and IDs are case-sensitive. .BufferWindowworks, but .Bufferwindow does not. The first part of a css-set-fast string should always be assumed to be case sensitive.

Note that some spaces have been added for readability’s sake. As a reminder: the current version of Bisquixe has a hard character limit of 64; it is recommended that authors use the code in this post to raise that ceiling to 256.

4 Likes

Frequently styled parts of a web-based Inform game

While multiple files are required to run games released with the Bisquixe interpreter, this discussion of Inform’s web presentation involves three files:

glkote.css: this previously-discussed file is the “default” template for most Bisquixe styling.
play.html: while we will rarely (if ever) modify this file, it can be useful as a reference. This file is the web page that contains our game.
style.css: This file does not configure the contents of our running game. rather, it specifies the behavior of the web page holding it. While a typical Bisquixe implementation will only interact with these settings sparingly, it is useful to know where to find them.

There are six commonly-styled parts of a Bisquixe game, all mentioned in one or more of the above files:

  • .play: the entire browser window containing our game.
  • #gameport: a subdivided portion of the .play window dedicated to running our game.
  • .BufferWindow: a portion of the #gameport dedicating to displaying both player commands and player feedback.
  • .GridWindow: a small horizontal window at the top of the #gameport. Frequently called the “status line” or “status bar.”
  • Input: Referring to “input” might mean multiple things. There is the .Input field, the text that appears as it is typed (.BufferWindow .Input), and the text as it appears in the .BufferWindow after the enter key has been pressed (.Style_input). While these variations can be confusing, they all must be considered different configurations.
  • Inline text: Bisquixe can additionally change text via substitutions. While the above components modify games more or less at the window level, using Bisquixe inline via styles allows for greater drama and specificity.

Our web game has a hierarchical construction, and children can inherit styling from their parents if they do not have settings of their own. While .BufferWindow could inherit font-size from .play, it does not because .BufferWindow already has a configured font-size. In fact, this seldom comes up because we begin with a website that is already styled and functional.

5 Likes

Frequently styled properties in web-based Inform games: colors and fonts

The parts of an Inform web-based game that we have discussed are all either ID selectors (#gameport) or class selectors (.BufferWindow, .GridWindow, .play, etc). These parts have properties, and those properties can be assigned values.

The most common formulation of page-level styling will be arraged as follows:

	css-set-fast "[ID, class, or pseudo-class]; [property]; [value]";

This is equivalent to the following declaration in a CSS file:

[ID, class, or pseudo-class] {
 [property]: [value];
}

While this reference is not a CSS guidebook, authors unfamiliar with the technology will likely benefit from a short discussion of commonly-used properties.

color and background-color (or background).

A styled webpage will usually feature custom colors. The .BufferWindow will likely have a background color and the text within will have a color. There are multiple options for assigning values to these properties:

We can use a <named-color>. Using the names listed here, we can assign colors. Example:

	css-set-fast ".GridWindow; color; floralwhite";
	css-set-fast ".play; background; black";

Authors requiring more granular control over color values can use RGB values or even hex values.

	css-set-fast ".BufferWindow; color; rgb(255, 251, 0)";
	css-set-fast ".BufferWindow; color; #fffb00";

HTML color codes can be found online; an internet search for html color codes will likely hit on several options. I often use this one.

font-size and font-family

There are multiple options for assigning a font-size value. Because the default Bisquixe template uses px values, I recommend that beginners do the same. Experienced coders may have other preferences, and Bisquixe can accomodate them. The default font-size for Bisquixe is 15px.

Because iOS Safari enforces a zoom over input fields smaller than 16px, authors may wish to change the default.

	css-set-fast ".BufferWindow; font-size; 16px";

With font-family, authors can specify preferred fonts as a list. There are some intricacies to this, as font availability can vary from player to player depending on factors beyond the author’s control. While it is possible to download additional fonts via Bisquixe, for now it is enough to discuss two possibilities: “web-safe fonts” and generic font families.

A “web-safe” font is one that, in theory, nearly all web browsers can access. Some sources are conservative in their estimates. CSS Schools cites exactly nine web-safe fonts. Other web pages, more optimistically, cite twenty or more! Our list of fonts is ordered in descending preference; the web page will use the first available font in the list. It is also wise to imagine the list as ordered in terms of ascending safety, and the last entry will be a generic category that serves as a fallback. Consider the following phrase:

	css-set-fast ".BufferWindow; font-family; Optima, Arial, sans-serif";

A web browser will use the first listed font available, and, if all else fails, it will use whatever sans-serif font it prefers. Because of the uncertain nature of player system configuration, it is essential to specify a generic font familiy when assigning values to the font-family property.

3 Likes

Other frequently specified content in web-based Inform games

There are still other elements, classes, and properties that are specified in a styled web game, although they do not receive the same attention. Authors will typically set them once and forget about them.

classes and pseudo-classes

.links

The default web template displays links on the left-hand side of the screen. We can configure these however we like, using properties we have already discussed.

	css-set-fast ".links; font-size; 45px";

We can even use the display property to omit them altogether.

	css-set-fast ".links; display; none";

a:

While the above section specifies the .links class, that class does not actually configure links within our game. To do that, we use assign properties to a:link. There are in fact multiple pseudo-classes related to links that websites use. a:hover, for instance, is commonly seen in the wild, but it has no apparent effect within our Bisquixe game. Similarly, a:visited applies to links directed at the outside world (the interpreter credit, for instance, or the default links at the left side of the .play window, but never applies to links with the #gameport.

In practice, authors will specify a:link commonly, a:visited rarely, and seldom any other link-related pseudo-class.

	css-set-fast "a:link; color; yellow";
	css-set-fast "a:link; font-family; cursive";

Our web page only displays one type of link (a). When links appear in multiple parts of a web page, care must be taken to choose a color that will make sense everywhere.

.interpretercredit

The .interpretercredit class displays at the bottom-left of the default website. It can be styled like any other text. However, since it is a link, the most common properties will likely already be assigned via a:link. It moreover inherits properties from .play.

	css-set-fast ".interpretercredit; background; green"

Note that it would be poor form to forego crediting the interpreter entirely. At bare minimum, it should be mentioned along with installed extensions in response to a VERSION command in-game. This can be accomplished via a new rule. For example:

report requesting the story file version:
	say "Quixe interpreter by Andrew Plotkin
[line break] - (http://eblong.com/zarf/glulx/quixe/)"

properties

padding

The padding property can used to specify space between an element’s contents and its border. As a commonly-applicable case, added spacing between text and its container’s edge can make content more readable. New authors may be surprised at the number of ways one can specify padding (as the above link will attest), but in simplicity’s name this reference will provide only one example. For a padding property with four specified values (6px 10px 6px 2px), the values are read clockwise, starting at the top:

  • 6px: padding at the top border of the element
  • 10px: padding at the right edge of the element
  • 6px: padding at the bottom edge of the element
  • 2px: padding at the left edge of the element

In the below example, 20px is specified at left and right, and 10px is specified for top and bottom.

	css-set-fast ".BufferWindow; padding; 10px 20px 10px 20px";

left, right, top, bottom

These properties specify an offset between a container and its contents. The default template uses left and right properties to position the #gameport within the .play area containing it. Specifying position creates a boundary area that can hold the links customarily printed at the left side of the template’s window. Even if we choose to remove those links (I always do), a proportional boundary prevents the readable area from becoming uncomfortably wide on widescreen displays.

The default template setting is 18% for both left and right properties on non-mobile displays. Values of 0% create a one-to-one overlap between .play and #gameport. top and bottom default to 0%.

	css-set-fast "#gameport; left; 30%";
	css-set-fast "#gameport; top; 5%";

white-space

The Bisquixe interpreter strips “extra” white space (space characters) from web games by default, and many authors will wish to leave their custom spacing intact. We can adjust this behavior at the .BufferLine. This class has not been mentioned before; it is the smallest unit of output, and the .BufferWindow contains them. Since BufferLine inherits properties from .BufferWindow already, it is seldom customized.

In cases where finer control is needed, we turn to it, setting a value for the white-space property.

	css-set-fast ".BufferLine; white-space; pre-wrap";
3 Likes

Styling input

The display of an Inform game is like text from a printer. Once the words are laid to paper, they cannot change. The command line is different, of course. It changes as players enter their commands. Once the player presses enter, though, their commands become more unchanging words on the page.

Styling “input” can mean more than one thing, then. The dynamic text of the command line has properties, and the newly-static text of issued commands has separate properties.

The command interface is like a window unto itself. It can have a background color, and the text within can be configured normally. For instance, we could specify a blue, cursive font printing over a gray background. A dubious combination, to be sure!

Usually, the container holding input is styled via the .Input class, and the text within it is specified via the .BufferWindow .Input class.

	css-set-fast ".BufferWindow .Input; font-size; 30px";
	css-set-fast ".BufferWindow .Input; font-family; Brush Script MT";
	css-set-fast ".BufferWindow .Input; color; blue";
	css-set-fast ".Input; background; gray";

Meanwhile, previously-issued commands inherit properties from .BufferWindow and can be further styled via the .Style_input class. The default template assigns a specific color (black) and weight (bold). If font color has been changed for .BufferWindow, then .Style_input might be altered to match.

	css-set-fast ".BufferWindow; color; purple;";
	css-set-fast ".Style_input; color; purple;";
	css-set-fast ".Style_input; font-weight; bolder";

The font-weight property is used to specify bold type.

It’s important to note that the command prompt itself is not part of this equation! That prints according to properties assigned to .BufferWindow. It is possible to configure it independently using inline substitutions, a more advanced tactic to be discussed later.

2 Likes

A note on organizing Bisquixe code

Since Bisquixe leverages CSS, and since there are nearly endless permutations of elements, properties, and values possible, we could easily get lost in a morass of similar-looking lines of code. That being so, two suggestions are offered:

Use multiple rules

Our initial styling rules could all fit into one when play begins rule. This would work fine, mechanically. However, if we separate these phrases into multiple rules, they will be easier to read and troubleshoot.

Additionally, should we ever need to reapply some of our styling, we only need follow the existing rule, i.e.,

after examining the teapot:
	follow the default BufferLine rule;

Assign logical names to the rules

It is best to have an organizational strategy. Perhaps our game features both “light” and “dark” color schemes. Since these might change during play, it makes sense to make rules specifying colors for each mode.

This is the dark mode rule:

and

This is the light mode rule:

General styling phrases pertaining to .play, #gameport, a:links and so forth might be homed in their own rule:

This is the initial window setup rule:

And so on. The important thing is that we arrive at a sensible scheme that is easy for us to read and troubleshoot.

3 Likes

Example: a minimally yet thoroughly styled Inform game

While we have only begun to explore the possibilities of CSS and Bisquixe, we have learned enough to style the most common and visible parts of an Inform game. In other words, we are ready to make a game that is visually our own. What does that look like?

All of the needed code will execute when play begins, but, as we have recently discussed, we should take a moment to consider organization. We’ll use the word initial in the names of our rules, since that is an accurate characterization: they specify the initial styling of the game. Note that we can call these rules whatever we like, so it is best to choose names that make good, intuitive sense.

when play begins:
	follow the initial state of play rule;
	follow the initial BufferLine rule;
	follow the initial GridWindow rule;
	follow the initial Input rule;

We can walk through these in order, generously commenting as we go.

Our initial state of play rule specifies general characteristics of the web page. We’ll specify the placement of the #gameport within the .play area, and set a background color. We’ll additionally adjust the behavior of links and other items that customarily occupy the left-hand side of the .play area.

this is the initial state of play rule:
	css-set-fast ".play; background; #4D4B4B" [the color of the area outside of the playable #gameport];
	css-set-fast "#gameport; left; 20%" [the relative offset between .play and #gameport; defaults to 18%];
	css-set-fast "#gameport; right; 20%";
	css-set-fast ".links; display; none" [omits built-in links at left. this class could alternatively used to specify different properties];
	css-set-fast ".coverimage; display; none" [we can omit the cover art as well];
	css-set-fast "a:link; color; #49C5FC"; [specifies the color of all links both inside and outside of the #gameport];
	css-set-fast "a:visited; color; #49C5FC"; [specifies the color of all links both inside and outside of the #gameport];
	css-set-fast ".interpretercredit; font-family; Verdana, sans-serif"; [alters the font of .interpretercredit to match .BufferWindow]

The player will be looking at the .BufferWindow most of the time, so we will configure it for legibility and appropriate color contrast.

this is the initial BufferWindow rule:
	css-set-fast ".BufferLine; white-space; pre-wrap"; [leaves white space as-is; does not remove]
	css-set-fast ".BufferWindow; font-size; 16px" [the default value is 15px];
	css-set-fast ".BufferWindow; background; #e4e9ec" [the 'fill' color for the .BufferWindow];
	css-set-fast ".BufferWindow; color; #11022cff" [the font color];
	css-set-fast ".BufferWindow; font-family; Verdana, sans-serif" [a web-safe font followed by a generic font family];
	css-set-fast ".BufferWindow; padding; 10px 20px 10px 20px"; [modifies the default padding]
	css-set-fast ".BufferLine; white-space; pre-wrap";[set to honor all in-project space characters]

Next, we will similarly configure the .GridWindow or “status bar.” While there is no hard-and-fast rule, the status bar is typically specified to use a monospace font. Because some monospace fonts (such as Courier New) seem to lack “weight,” we will use bold type for the .GridWindow.

this is the initial GridWindow rule:
   css-set-fast ".GridWindow; font-size; 17px" [the default is 15px];
   css-set-fast ".GridWindow; background; #18033f";
   css-set-fast ".GridWindow; color; #dbf1ffff";
   css-set-fast ".GridWindow; font-family; Monaco, 'Courier New', monospace";
   css-set-fast ".GridWindow; font-weight; bold"; [some monospace fonts are narrow and are more legible when specified as bold]
   css-set-fast ".GridWindow; padding; 10px 20px 10px 20px"; [modifies the default padding]

Styling input may initially intimidate. There are multiple classes and properties in play, and it is not always clear where and what we should specify. In most cases, though, we can think of .Input as a container and .BufferWindow .Input as the content within it.

this is the initial input rule:
	css-set-fast ".Input; background; transparent" [this setting does nothing as-is, but is provided for reference];
	css-set-fast ".BufferWindow .Input; font-size; 16px"; [set to match the styling of the .BufferWindow]
	css-set-fast ".BufferWindow .Input; color; #11022cff";
	css-set-fast ".BufferWindow .Input; font-family; Verdana, sans-serif";
	css-set-fast ".Style_input; color; #11022cff"; [.Style_input specifies the appearance of the command after it has been entered]

This is enough to put our mark on our own Inform game, using text and colors that complement what we have made.

3 Likes

Assigning values for color, font, and font-size for a styled web game

When choosing colors and fonts for an Inform game, there are important considerations regarding legibility and photosensitivity. Readers respond differently to “light” and “dark” modes, and color choices can introduce eye strain or even headaches.

There is likely no perfect website, but there are resources and best practices available for authors to rely on.

The evolving APCA Contrast Method represents the current state of the art for evaluating color contrast in web pages. It evaluates legibility according to three characteristics:

  • Color contrast (determined by color and background properties)
  • Character weight (font-weight property)
  • Character size (font-size property)

Using an APCA contrast checker, authors can verify the legibility of in-game text.

Font selection is, itself, more art than science. Some choices, such as members of the cursive family, seem obviously poor. When in doubt, a little research goes a long way, as accessibility is a widely-discussed topic online. An internet search regarding a specific font will often prove productive, i.e., is Verdana an accessible font. Sometimes, fonts seem heavier or lighter than they would ideally be. The font-weight property can be specified to make text more legible in such cases.

Since modern websites (including ones made with Bisquixe) support in-browser zoom in/out, font-size is a starting point from which players can adjust. One consideration is that Apple’s iOS will “zoom” automatically on input fields with font sizes smaller than 16px, a behavior that authors and players alike may wish to avoid. In any case, the font-size property should comply with APCA guidance.

In many cases, options for both light and dark color schemes will be desirable. Strategies for providing such options will be identified in a future post.

Ultimately, though, web styling is simply another technical element of an Inform project that should be evaluated by testers. The guidance of this reference is to begin with best practices and end with playtesting.

3 Likes

Determining whether an interpreter supports Bisquixe while processing actions and activites

Compiling a Bisquixe game creates a GBLORB file, just as compiling any other Glux game does. That being so, it can run in any Glux-compatible interpreter. However, only the Bisquixe interpreter, running in a web page, can render our CSS effects.

This is because the Simple Multimedia Effects (and Simple Multimedia Effects for v10) extension checks to see if the current interpreter is Bisquixe before doing its work.

The lone exception to this rule is the hyperlinks feature discussed later in this reference.

We might have a need to check if Bisquixe is supported. A game might print a message, for instance, if Bisquixe is not supported.

This requires a bit of Inform 6 to call a Glk gestalt function. While the Glk specification lies far beyond the scope of this reference, it may be useful to understand in a general way that GBLORB files compiled with Bisquixe are portable in a limited way.

To decide if bisquixe is supported:
	(-(glk_gestalt(5376, 0) )-)

This code is enough to confirm compatibility, and we can perform this evaluation at any time while processing actions and activities.

check jumping:
	unless bisquixe is supported, say "Bisquixe is not supported." instead;
2 Likes

Creating custom classes for inline styling

So far, this reference has only discussed CSS styling at the window level, and those features are enough to customize appearance on a per-game basis. They are applied as rules during activities and action processing. Specifying properties in this way is a powerful tool, and many more examples of this power are provided later in this reference.

It is possible to apply styling at a more granular level. In fact, an author can apply styling per passage, sentence, word, and even character! This is accomplished via Inform’s built-in capacity for text substitution.

To do so, we must first define custom classes. Their names must be words without spaces, but the details are up to the author. A class for printing a large font might be called “large”.

to say large text:
	set-any-class "large";

This is accomplished via a simple to say definition.

The stated name of this substitution is “large text.” We can invoke it in any printed text. For instance:

instead of jumping:
	say "[large text]This is large text.[roman type]";

This text will not be modified, though, because we have not yet applied any properties to our new class.

A new class defined by set-any-class "large" is specified as .Style_large. This new class is case-sensitive, just as all others are.

Since it will be used as a text substitution, it will not be applied until it is invoked as something said. However, it must be added to the project as a css-set-fast phrase before it can be substituted. These are best established at the start of play.

css-set-fast phrases invoking these new classes have no other effect. They only serve to prepare a game for subsequent text substitutions.

when play begins:
	follow the large text rule;

this is the large text rule:
	css-set-fast ".Style_large; font-size; 30px";

This is all that is required for our text to display as desired.

	say "[large text]This is large text.[roman type]";

Note the use of the [roman type] substitution at the end of the text. From there on, any printed text will appear as styled within the .BufferWindow class, returning to the configured defaults for its game.

2 Likes

Accounting for alternate interpreters

If Bisquixe styling only applies within web games, should authors provide a GBLORB file? Doing so will ensure that a game can be played on Glux-capable interpreters like Lectrote and Gargoyle. However, such players will not experience the author’s work as intended, so the creator’s efforts will—to varying extents—have been in vain.

For many authors, this is a fraught decision. While younger players and newcomers—a very important audience, to be sure—often favor web-capable games such as those hosted at itch.io, others seem unwilling to engage with Inform games for the web.

Note: while this may be unclear, this is a discussion of games using web technology and web browsers. Such games can be played locally—it would be hard to develop them otherwise! This post is concerned with browser games, not internet access.

In this regard, creators of works in Twine, Ink, Decker, and Ren’py (among others) are granted license that Inform authors may not be. While this reference assumes that visual content can enhance an Inform work, these realities must be acknowledged.

The author must decide, then, whether or not to honor conservatism.

Many creators will understandably want to find players wherever they can, and, in the name of their ambitions, they must account for the behaviors of alternate interpreters.

Since we have a means for detecting the Bisquixe interpreter, we can account for such cases. Consider the text of our recent [large text] substitution. While Bisquixe cannot apply this property in other interpreters, an Inform project can be tailored to deal with alternate scenarios.

In the below example, the to say definition has been modified to specify Inform’s built-in fixed letter spacing substitution when Bisquixe is not supported.

to say large text:
	if bisquixe is supported, set-any-class "large";
	otherwise:
		say fixed letter spacing.

instead of jumping:
	say "[large text]This is [if bisquixe is supported]large text[otherwise]fixed letter type[end if].[roman type]";
	say line break;

This kind of handwork can create significant overhead, so it is a best practice to avoid directly discussing web styling in-text.

2 Likes

2 posts were split to a new topic: Reasons a player might not want to engage with Web-Based parser deployments

External resources

Since a Bisquixe game is a web page, it has access to external files that the typical Inform game does not. A compiled Inform GBLORB contains within it specified images and sound files, for instance. In fact, a GBLORB has very limited access to the world beyond its walls. It can save and restore games, write transcripts, and read or write to external text files.

Bisquixe can do far more than that. It can access external images, sounds, and fonts. It can also link to external files, such as walkthroughs or feelies.

These features bring new organizational requirements, of course. To avoid deletions and other mishaps, copies of files really should be maintained outside of the release folder. A new folder in the project’s materials directory seems a natural fit, though the author can and should use whatever system works best for them.

3 Likes

Using Google Fonts in a Bisquixe project

Using “web-safe” fonts extends Inform’s base capabilities significantly, but Bixquixe authors have access to many more options. In fact, the entirety of Google Fonts is at our disposal!

Bisquixe uses a specific phrase for retrieving fonts from Google Fonts.

	import-google-fonts "[your+chosen+font]&family=[another+chosen+font]";

Persons experienced with Google Fonts with CSS know that the CSS equivalent is longer:

href="https://fonts.googleapis.com/css?family=Bodoni+Moda"

Bisquixe fills most of this in already, so we need only begin with the name of a font.

	import-google-fonts "Bodoni+Moda";

Where do we get the name? It is important to note that an import-google-fonts phrase will not tolerate space characters, because it is derived from a web address. Spaces are therefore signified with the plus (+) character. As for the specific name to be used, we can verify that via simple steps.

  1. Select the font of choice.
  2. At top-right, click the Get font button.
  3. Click the < > Get imbed code at upper right.
  4. Select the @import radio button.
  5. Within the upper code box, find the family=[your+font+here] code.
  6. The text after the equal sign, a font name with + characters instead of space characters, is what must be designated in the import-google-fonts phrase.

Bisquixe adds the intial family= string to our download phrase, so we need not include it. However, if we require more fonts, we must add it ourselves. For three fonts, then, our phrase would look like this:

	import-google-fonts "[font+1]&family=[font+2]&family[font+3]"; 

Note, again, that there are no spaces in our text string.

By default, the character limit for our bisquixe strings is 64 characters. Unless we increase it by using the code in this post, we will likely be restricted to three fonts.

Once downloaded, they can be assigned to the font-family property in the way that we have done before, either as game-wide CSS or as an inline setting.

	css-set-fast ".GridWindow; font-family; Roboto Mono, monospace";

In this case, fonts do include space characters, so care must be taken to verify phrasing.

2 Likes

A Tale of Two Informs

This reference is written from the perspective of an author working with Inform 10.1.2, which is, at the time of this writing, the most recent release. For reasons beyond the scope of this work, other authors continue to use Inform “9” or, more accurately and less apprehensibly, 6M62.

This seldom matters to Bisquixe users. There are two different “Simple Multimedia Effects” extensions, one for each version of Inform, but we authors use them in the exact same ways. We use the same phrases, and the format for specifying values is no different from version to version. Every line of code shared in this reference works identically, whether we use version 9 or 10. This is a version-agnostic guide.

However, discussion of in-game images will naturally lead many to thoughts of page layout. Perhaps the author would like to present images in a separate window while maintaining text input and output inside a large “main” window. Older readers of this guide will remember that many commercial games of the 1980s were organized in this way.

Authors planning their projects ought to know that Inform 9 supports this sort of screen division via an extension called “Flexible Windows.” Inform 10, on the other hand, has no such capacity. This feature will be restored in Inform 11, but there is no established timeline for releasing the next version of Inform. If we wish to create an Inform project with multiple windows now, our only choice is Inform 9.

The use of Flexible Windows is a topic beyond the scope of this guide, but it is only appropriate to advise readers of the options before them. Authors should carefully consider their design goals before committing to a version of Inform.

This reference will discuss images within the primary, default window for an Inform web project, the .BufferWindow, but general concepts will apply to images printed anywhere.

5 Likes

Documentation Review: Including Image Files in an Inform Project

Before discussing images in a web-based Inform game, it is best to review the inclusion of image files in an Inform project. These are discussed in Chapter 23 of the Inform 10 Documentation. The perspective of this reference is that images can add a lot to a project. At the same time, poorly-chosen ones can detract.

Images, then, are yet another question of art that creators and critics must answer. How do we go about implementing them?

Declaring image files

The practice for adding files to Inform projects is to declare them. The declaration involves two values: thefigure name and the "[file name]". The figure name is what we use to refer to the file within our project. The file name is mentioned only once in this initial declaration.

In other words, files are incorporated into Inform by declaring values that do not change. We cannot have an image file that varies, for instance, though we can have a figure name that varies. Declaring an image file requires a reference name beginning with the word figure. For example:

figure frob is the file "frob.jpg".

The formatting is very specific. File names are always placed within quotation marks, and only designated file types are permitted. The permitted image types are Joint Photographic Experts Group (JPEG) and Portable Network Graphics (PNG). When releasing a project, inform will verify file extensions.

Inform will test-compile a project whether the files are present or not, but to release a project with designated image files, said files must be located in the .materials\figures directory.

Once we have a figure name, we can use it in rules and definitions.

Displaying image files within an Inform project

It is useful to think of an Inform game’s output as something emerging from a line-feed printer. The output hits the page, feeds forward, and then the next bit of output displays, and so on. These units of output are, in a web-based inform game, referred to as a .BufferLine. Even though an image may take up far more space on the screen than a snippet of text might, each
displays as a .BufferLine class within the larger .BufferWindow.

The displayed image is just like displayed text in that once it reaches the page, it cannot be changed or altered. Like text output, it will scroll up and out of sight as more .BufferLine content is added to the .BufferWindow.

In this sense, it is useful to think of a phrase beginning with display as a very specialized relative of say. Both send output directly to a .BufferLine. We use display as follows:

	display figure frob;

Again, only our declared figure name is used. It isn’t possible to refer directly to the image by file name here.

Since this pharase sends output as a .BufferLine, we invoke it just as we would while saying a text.

instead of jumping:
	display figure frob;

or

this is the frob visibility rule:
	display figure frob;

or

to say iFrob:
	display figure frob;

or even

after printing the name of the frob (this is the frob display rule):
	display figure frob;

Using Inform’s built-in support for alt-text

We can declare text descriptions for images when we declare the images themselves. The text description is appended in parentheses at the end of the phrase. For instance:

figure frob is the file "frob.jpg" ("A multi-pronged frob with a knurled handle.").

Some authors may wish to take a further step and create a separate screen reader mode. Acessibility is a subject that merits dedicated consideration. Please refer to

(add link to accessibility post once written)

More on the figure name value.

Because figure name is a value, we can use it in conditions and rules. Consider:

to decide which figure name is the current figure:
	if the location is lab, decide on figure frob;

instead of jumping:
	display the current figure;

Internally, multimedia resources (sound and image files) each have an assigned Glulx resource ID. This happens automatically; authors do not assign them or request that they be assigned. They can be referred to in this way:

	...Glulx resource ID of figure frob...

In practice, authors seldom need to refer to a file’s Glulx resource ID, but authors of web games may find it necessary to do so. This will be explained in the next post, which explores specific considerations for using images in web-based Inform games.

4 Likes