How to change the color of the room name

Fairly simple question: I simply want to have a different color font for a room name when the player enters. (Instead of "You are in" I have opted for the room name to be in bold, but this isn't stark enough for my UI, so I want it to be a different color from the rest of the text.)

I have searched far and wide, but can't find an answer to this. I don't know how to insert JavaScript stuff into my Quest game, though I have looked at the tutorials on Customising the UI, etc.


And by the same token, how do I change the color of the game title that displays up top when you first start?


Fairly simple question: I simply want to have a different color font for a room name when the player enters.

Unfortunately, there isn't such an easy way to do that.

The simplest option would be just to include the colour as part of the name. Like, giving a room the alias: {colour:red:Kitchen} or similar.

If you want to do it without changing every room, then you could modify the core function GetDisplayName like this:

  <function name="GetDisplayName" type="string" parameters="obj">    if (obj = game.pov.parent) {
      return ("{colour:green:" + GetDisplayAlias (obj) + "}")
    }
    else      return (GetDisplayNameLink(obj, ""))    }  </function>

Or on the web version, where you can't modify the core functions, you could have a script in your start script to rename all the rooms:

foreach (room, AllRooms()) {
  room.alias = "{colour:blue:" + GetDisplayAlias (room) + "}"
}

Not really a perfect solution, but I think it should work.

And by the same token, how do I change the color of the game title that displays up top when you first start?

You can put text processor directives in the title. Or I think you could add to your UI initialisation script (on the game's "Advanced Scripts" tab, once you've enabled it on the "Features" tab):

JS.eval("$('<style>').text('.title span:first-child { color: purple }').appendTo('head');")

See if this works. It’s a copy-paste job from my “Quest - Tutorials and templates” game.


Do you see these little things: < and > ? If you type 

font color = "red" OMG!! It's red font! 

between them, it will change the font to red!

You also need to type 

/font 

between those bracket things to end the red font and return to preset black.

mrangel is way smarter than me so if you can make sense of his suggestion, try it first. If not, try mine. Let us know.


Hi, Thanks so much for the fast response. I tried the "web" option on start script first, since it seemed more simple and I knew how to access the start script. It didn't work.

About modifying the GetDisplayName function, how do I access that, or where in my game do I put it? I think you mean I have to modify a Core aslx file or something, is that right? Or can I just put it in the start script?


You can easily set a room's name to either <span style="color: red">Kitchen</span> or {colour:red:Kitchen} and it should have the same effect. I suggested the latter because it's easier to type.

<span color="red">Kitchen</span> is old and generally considered by bad form, but probably still works. Using font as an alias for span is really old and its use is discouraged (I think since around 1999), but likewise, it still probably works.

I also suggested alternatives in code in case the OP is making a large game and doesn't want to do that for every single name.


I tried the "web" option on start script first, since it seemed more simple and I knew how to access the start script. It didn't work.

Did it just not work?
It works for me.

Can you share a link to your game, so I can try to work out what's different between them?

About modifying the GetDisplayName function, how do I access that, or where in my game do I put it?

In the web editor, this isn't possible. In the desktop editor, there is a way to show the core objects and edit them; but I'll have to leave someone who actually has a copy of the desktop Quest to explain that.


Okay, the "start script" option does work, but so far only with blue or green. I was trying for "light green" because that seemed to go with my whole setup. I'll keep playing with colors, but THANK YOU!

You guys are awesome! Thanks so much.


One more thing: I need to reinstate capital (upper case) on the first letter on each room name in that bit of code. Is that like "UCase ()" and where exactly would that fit in?


I was trying for "light green" because that seemed to go with my whole setup.

I think there's a lightgreen. A list of valid colour names can be found at https://w3schools.com/colors/colors_names.asp - note that there are no spaces in a colour name.

One more thing: I need to reinstate capital (upper case) on the first letter on each room name in that bit of code. Is that like "UCase ()" and where exactly would that fit in?

UCase would put it in all-caps. If you want to capitalise the first letter you'd use CapFirst, like this:

foreach (room, AllRooms()) {
  room.alias = "{colour:lightseagreen:" + CapFirst(GetDisplayAlias (room)) + "}"
}

Hey thanks a million! I am including you in my credits for such awesome help.


I don't think giving the room the alias {colour:red:Kitchen} will work.

Sorry, I'll rephrase that... It will work, the room name will be 'Kitchen' in the colour 'red', but the location bar at the top of the screen now says '{colour:red:Kitchen}'.

Not sure how you would go about changing that.

You could always decide not to show the location bar, by unchecking its function on the 'Interface' tab of the main 'game' object.


Thanks for pointing that out Dr Agon.

Does the <span> version display correctly in the status bar? If not, I should be able to come up with a one-line JS to fix it.


I don't use the location bar. But Doctor Agon, I am having that issue up top with the title of the whole game in the Quest window, due to using that same code for the game name...


I don't think giving the room the alias {colour:red:Kitchen} will work.

Sorry, I'll rephrase that... It will work, the room name will be 'Kitchen' in the colour 'red', but the location bar at the top of the screen now says '{colour:red:Kitchen}'.

Not sure how you would go about changing that.

To fix that, use the <span> version of the code. Like this:

foreach (room, AllRooms()) {
  room.alias = "<span style=\"color: lightseagreen\">" + CapFirst(GetDisplayAlias (room)) + "</span>"
}

That will, however, also cause the room name in the location bar to be that colour. If you want to prevent that happening (because you want it to be a different colour to go with the location bar's background), you would add a line to the UI Initialisation script:

JS.eval ("$(function () {updateLocation = function(i) {$('#location').text($('<span>').html(i).text());};});")

I am having that issue up top with the title of the whole game in the Quest window, due to using that same code for the game name...

I thought there might be an issue of that kind; the JS.eval code in my earlier post should work in that case.


WAIT! mrangel, I think I just now understood your JS intructions -- I see now that it comes after my query about the game's title, so I have not tried that option yet for the name of the whole game. (I had tried to put the {colour...} stuff right into the name box under the "game" tab.)


Thanks ! I will try the JS on my game title.

Right now, the other code for the rooms is interfering with Object/Room objects. It won't let the player interact with obj/rm's. So maybe I need to filter the "All Rooms" aspect of the code, so that only Rooms (pure ones, not hybrid ones) are affected -- in other words, I only want locations to be light green, not object-rooms. Hmm...


Okay, the JS for my game title worked like a charm!

About the other concern with my obj/rooms: I am going through all rooms one by one, and I am only finding the odd one here or there. So I put an "if" line in there to avoid those obj/rooms, and also an "if" filter to avoid anything with HasAttribute "look." So far it's working.

Thanks again!


The problem with filtering out object/rooms is that their names will show up a different colour from all the other rooms when the player is in them; because you're changing the colour the object displays as.

I believe there's a feature which lets you give individual objects a colour for their object links; if you set this to "red !important" and the object/room's name to <span style="color:lightgreen">cage</span> then it would show up red when displayed as an object link, but light green when displayed as text (such as in the "You are in" line).

If it's causing problems with the player being able to use commands on an object, it might help to put the object's real alias (without the colour code) into its list of alternate aliases (I think that's on the 'Object' tab but not certain).

The GetDisplayName option is probably better; because rather than changing the object's alias, it causes the object's name to be rendered differently when the player is inside it. But I'm afraid I don't have the desktop Quest editor here, so I can't give real advice on how to change the core functions.

Hmm… an alternate method:

If you change it back to displaying "You are in a …" then you could use some javascript to search for that text and change it whenever text is output.

The javascript would look like:

addText = function(text) {
    if (getCurrentDiv() == null) {
        createNewDiv("left");
    }
    if (savingTranscript) {
        SaveTranscript(text);
        ASLEvent("UpdateTranscriptString", text);
    }
    getCurrentDiv().append(text).find("span:contains(You are in)").each(
      $(this).text($(this).text().replace(/^You are in(?: an| a|)\s*(.)/i, function (i,j) {return (j.toUpperCase());})).css({color: 'lightgreen', fontWeight: 'bold'})
    );
    $("#divOutput").css("min-height", $("#divOutput").height());
};

To embed this in Quest, you would compress it down to this line, which can be included in your UI Initialisation script:

JS.eval("$(function(){addText=function(t){null==getCurrentDiv()&&createNewDiv('left'),savingTranscript&&(SaveTranscript(t),ASLEvent('UpdateTranscriptString',t)),getCurrentDiv().append(t).find('span:contains(You are in)').each($(this).text($(this).text().replace(/^You are in(?: an| a|)\s*(.)/i,function(t,e){return e.toUpperCase()})).css({color:'lightgreen',fontWeight:'bold'})),$('#divOutput').css('min-height',$('#divOutput').height())}});")

I've highlighted the parts that you might want to change:

  • You are in - text that it matches to find paragraphs to colour
  • You are in(?: an| a|) - text to remove from the start of the paragraph
  • color:'lightgreen',fontWeight:'bold' - style information to apply to matching paragraphs

Thanks, mrangel! I think the "GetDisplayAlias" is the better way to go, 'cause I'm using it not only with Rooms, but also with certain artifacts, and so far it allows me to retain default prefixes (a/an/the) on the objects (artifacts).

My filter is working, but as you pointed out, I don't have the desired color for those Obj/Rooms on them when you enter. It's okay with me, because something unusual is going on in the story at those points, and it's a tradeoff that is worth it to me for avoiding Error messages.

Whew -- those JS! I actually enjoy coding (and prefer it now WAY more than using the GUI interface), but the Java stuff you dropped there is beyond me. (Instead of "You are in..." I opted for the room's name in bold for my game.) At this point, I should probably play it safe. This has been a tremendous help!!! Thank you!


The javascript mostly isn't mine. When you use msg() in Quest, it adds some HTML for formatting, and then calls the built-in javascript function addText to actually display it on the screen.

The code I provided just replaces addText with a slightly modified version. I only changed:

getCurrentDiv().append(text);

to:

    getCurrentDiv().append(text).find("span:contains(You are in)").each(function () {
      $(this).text($(this).text().replace(/^You are in(?: an| a|)\s*(.)/i, function (i,j) {return (j.toUpperCase());})).css({color: 'lightgreen', fontWeight: 'bold'})
    });

Which breaks down as:

  • getCurrentDiv - find the current textbox being used for output (part of the original code)
  • append(text) - add the new text to the end of it (part of the original code)
  • find("span:contains(You are in)") - find any paragraphs which contain the text "You are in"
  • each (function () { - call the following function on each matching paragraph
    • $(this) - get the matching paragraph
    • .text( - set its contents to the text generated by:
      • $(this) - get the matching paragraph (again)
      • .text(). - get the text inside it
      • .replace(/^You are in(?: an| a|)\s*(.)/i - Find the phrase "You are in", optionally followed by "a" or "an", and then a single letter
        • function (i,j) {return (j.toUpperCase());} - replace it with the final letter of the matched string, changed to upper case
    • .css({color: 'lightgreen', fontWeight: 'bold'}) - and apply bold and colour to that paragraph

This is a bit of an ugly workaround; including the "You are in" text just so that we can search for that text, change the colour of all the lines that contain it, and then remove it again. But it does mean that it only changes the colour of the room name in the line at the top of a description, and not anywhere else it might be used.


Hey I was checking this post out and had a question of my own. I'm trying to change the color of strings in the Object/Locations panel.

"<span style=\"color: red\">" + CapFirst(GetDisplayAlias (room)) + "</span>"

does a great job of changing the color of the object to red, but if I try to use

"<span style=\"color: black\">" + CapFirst(GetDisplayAlias (room)) + "</span>"

On the same alias afterwards it will not change from red to black, but instead stay red.


What do you mean by "on the same alias"? That code is right; but I don't know where you're putting it. Changing an attribute or return value will only make a visible change when it's actually returned.


I have an equip item function and unequip item function that I'm running on different objects(weapons/armors/swords/etc).

If I run the (item.alias = "color red") line from above in the equip function, the items name will turn red.

Unfortunately when I run the (item.alias = "color black") line from above in the unequip function, the items name continues to stay red.

Honestly I don't even really need to use color, if there's a way to unbold a name that would work great as well since making text bold is extremely simple.


Wait... item.alias =?

So you're doing:

item.alias = "<span style=\"color: red\">" + CapFirst(GetDisplayAlias (room)) + "</span>"

?

So if the item's alias was originally "sword", after running that function its alias is: <span style="color: red;">Sword</span>, and after the second line it would be <span style="color: black;"><Span style="color: red;">Sword</span></span> (in which case it's red, because the innermost span takes priority)

Or are you setting item.listalias?


A thought about making an object change colour in the inventory pane if it's equipped:

item.listalias = "<span style=\"color: {either " +item.name + ".equipped:red:black};\">" + CapFirst (GetDisplayAlias (item)) + "</span>"

You can just set the list alias once, and it will change colour depending on the value of the object's equipped flag.

Note that you can only do this with the listalias variable; as the core function GetListDisplayAlias only runs the text processor if listalias exists.

Note also that this might not force the list to refresh; but it shouldn't be hard to work around that.


I was 100% doing

item.alias = "<span style=\"color: red\">" + GetDisplayAlias (item) + "</span>"

So the red was taking priority.

item.listalias = "<span style=\"color: {either " +item.name + ".equipped:red:black};\">" + CapFirst (GetDisplayAlias (item)) + "</span>"

This looks interesting, so this add's both red and black options to the listalias, then checks the boolean equiped and picks one based on if its true or false?

I plugged it into my equip/unequip functions and everything seems to be working! How on earth does this work??


It sets the listalias to a string like: <span style="color: {either sword7.equipped:red:black}">Sword</span>, with the name of the item in it.

When the inventory pane is refreshed (which usually happens every turn, but sometimes doesn't; I've not been able to figure out why), it uses this function internally:

  <function name="GetListDisplayAlias" type="string" parameters="obj">
    <![CDATA[
    if (HasString(obj, "listalias")) {
      // Modified by KV
      result = ProcessText(obj.listalias)
    }
    else {
      result = GetDisplayAlias(obj)
    }
    return (result)
  ]]>
  </function>

So if the object has a listalias attribute, it runs ProcessText on it first, and sends the result to the browser.

ProcessText searches the string it's been given for a {, and then checks if the word that follows that one the defined text processor commands. In this case, {either a:b:c} uses eval() to get the value of expression a (in this case sword7.equipped); if that's true it replaces that expression with b; otherwise it replaces it with c.

So after calling ProcessText, GetListDisplayAlias returns either <span style="color: red">Sword</span> or <span style="color: black">Sword</span>


The text processor is pretty powerful; but can also be rather slow. So depending on your circumstances, it might be better to use your original code in the form:

item.listalias = "<span style=\"color: red\">" + GetDisplayAlias (item) + "</span>"

Because this one changes only the listalias and not the alias of the item, GetDisplayAlias(item) will return just the item's original alias, without any colour applied. So you could change it back to the default colour by doing either item.listalias = GetDisplayAlias (item), or just item.listalias = null (the latter removes the listalias, causing the unmodified alias to appear in the sidebar).


I think I get it. So the check the browser uses, sends it through the ProcessText function first if it has a listalias. Then the process text function reads the brackets in the string as an expression "{textprocessorcommand + variable:a:b:c:etc}". Then depending on the textprocessorcommand it will select a:b:c:etc.

Is that right?


I think you got it.

You can use text processor commands in almost any text that's sent to the browser; they're the usual way to change part of an object or room's description without needing to make a script. Because they're run before sending anything to the browser, it's fine to use them to alter part of an HTML tag.


Log in to post a reply.

Support

Forums