GUI Tutorial: Difference between revisions
No edit summary |
|||
(42 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
People keep asking how to set up the gui, so, here's some information you can expand upon. | People keep asking how to set up the gui, so, here's some information you can expand upon. | ||
The GUI is set up using the #SPLIT and #DRAW commands, and using your #VAR's. | The GUI is set up using the #SPLIT and #DRAW commands, often using #FORMAT, and using your #VAR's. | ||
(I strongly suggest enabling MSDP so you receive all the variables the mud sends automatically so you can start building things to display those. See [[MSDP Script|HERE]]) | |||
First, establish your desired top/bottom screen #SPLIT: | =Split Your Screen= | ||
First, establish your desired top/bottom screen #SPLIT with some room to print data into. I go 4 or 5 lines top and bottom. | |||
*Run your #SPLIT command manually or make an alias that might be handy later for resetting. | |||
**The #BUFFER command reprints the scrolling region after splitting: | |||
#ALIAS {split} { | #ALIAS {split} { | ||
#SPLIT 5 5; | #SPLIT 5 5; | ||
#BUFFER end; | #BUFFER end; | ||
} | } | ||
=Draw Stuff= | |||
Second, you can draw tiles or boxes of data into your split region, using the coordinate system. | |||
*'''Coordinate System''' | |||
**The coordinate system is "Row Col Row Col" with the first Row-Col pair being the 'upper left' point of box, and the second Row-Col pair being the lower right corner of the box. | |||
**Negative values can be used to mean 'rows from end'. This is used by the #draw command to either "#draw box' or "#draw tile". | |||
*'''Boxes vs. Tiles:''' | |||
**'''Tile:''' Can be a single space, one character high/wide. If you have data that is exactly 2x3 characters, you can draw a 2x3 tile for example. If your data exceeds that tile space, it is truncated. | |||
**'''Box:''' Can be a large space, typically good for drawing lists into, like affects or communications lines, etc. Lines that may vary in size so you don't know the exact required space and wouldn't want to use a tile. | |||
'''Example:''' 1 1 -5 -5 | |||
*Box will be from the upper-most left corner (row 1 column 1) to the point 5 rows from the right end of your screen, and 5 rows above the bottom row on your screen) | |||
*To learn how these work, I would suggest just playing around with them in a blank tintin session, you don't even have to be connected to a mud. | |||
*You can do #screen clear all to wipe the screen after each command to wipe the slate | |||
#draw box 1 1 -10 -10 hellooooooo | |||
#draw box 10 10 25 25 hellooooooo (So box starts upper left corner row 10 down from the top, column 10 in from the left side. Goes to row 25, column 25 for lower right corner). | |||
#draw tile 30 20 30 25 123456 (tile drawn on the 30th row, from columns 20 to 25 (so 6 spaces). If you try to draw 1234567 you'll see it gets wrapped/truncated and only prints '7') | |||
You can also play with lots of colors and formatting options. See #help draw. | |||
Here we are printing the room/area name on line 3 (down from the top) and it will go the upper left corner ( | |||
#ALIAS {draw} { | #ALIAS {draw} { | ||
# | #DRAW red tile 3 2 3 44 $msdp_info[ROOM_NAME]; | ||
#DRAW tile | #DRAW blue tile 2 2 2 44 $msdp_info[AREA_NAME]; | ||
} | } | ||
To clarify, the coordinates are <row> <column> <row> <column> and set the upper-left point, and lower-right point. | |||
You'll have to read #Help draw to understand all your options, and get good at the coordinate system to place those into exact positions on screen. You'll also want to learn #FORMAT so you can add additional controls and style to those. | |||
==Format Tiles== | |||
Using #format we can set more colors, and more importantly lengths/aligns to your tiles. Here, we format the msdp vars into our own stylized vars first, then draw those. | |||
#ALIAS {draw} { | |||
#FORMAT {room_string} {%c%.44s} {<acf>}{$msdp_info[ROOM_NAME]}; | |||
#DRAW tile 3 2 3 46 $room_string; | |||
#FORMAT {area_string} {%c%.40s} {<ffa>}{$msdp_info[AREA_NAME]}; | |||
#DRAW tile 2 2 2 46 $area_string; | |||
} | |||
The format commands are saying we want to format a new variable named "room_string" that will be comprised of an rgb color code (%c), and then a 44 character string (%.44s). We then define the color code as the <acf> color (blue) and the string as the room name we get from msdp. | |||
So, first we format the room name string to be exactly 44 characters. Then we draw a tile of the exact size to contain that 44 characters (between columns 2 - 46 in this example). | |||
However - having a singular alias like this 'draw' example can become a problem when it comes to auto-updating the screen however. It works well for updating one tile or box, but, you don't want to be re-drawing your entire gui every time any part of it needs updating. Bear that in mind. Maybe make an alias like draw_area_info to draw the room/area/geo and that's it. Make several commands to draw different parts of your gui, and trigger each individually, not the whole screen all at once. | |||
=Draw Lists= | |||
Instead of drawing individual tiles, you can also generate a list and draw that all at once. | Instead of drawing individual tiles, you can also generate a list and draw that all at once. | ||
For example: | |||
#list example add example text blablabla stuff | |||
Looks like: | |||
#VARIABLE {example} | |||
{ | |||
{1} {example} | |||
{2} {text} | |||
{3} {blablabla} | |||
{4} {stuff} | |||
} | |||
Can use #draw to print that all inside a box like this: | |||
#draw box 10 10 20 40 $example[1..-1] | |||
If you set those coordinates into a SPLIT region, the box will remain in place until it is redrawn at some point (perhaps by an alias you have, or scripted #event or #action). | |||
If you set those coordinates into the scrolling region, the box will scroll away with the rest of the game text. | |||
Note that when using a list, you can choose which list indexes (lines) you want to draw with the numbers inside the brackets. So 1..-1 is the first var (1) to the one before the end of the var (i.e. the last thing in the list) (-1), if you only want the last 5 you would just use -5..-1, etc. | |||
If you capture all speech/tells/etc to a list, you can see the last 10 things sent to you with values like -10 -1 for example. | |||
==Format a List== | |||
We can also of course use #format to stylize the contents of our list. This alias takes your full affects list from msdp, and sets a color based on how many ticks remaining the spell is. | |||
<pre> | <pre> | ||
#alias get_affects { | #alias get_affects { | ||
Line 42: | Line 114: | ||
</pre> | </pre> | ||
That will generate a $affects | That will generate a var named $affects. Type "#VAR affects" to see what it looks like. Once you get that looking how you want, you can draw that list anywhere. | ||
For example, here we can just print it into a box in the scrolling region: | |||
#draw box 10 60 50 90 $affects[1..-1] | |||
If you have short lists, those could probably fit in your top/bottom split. For long lists, you'll probably want to use #split to add a sidebar and draw it there. See my other sidebar script. | |||
=Auto-Updates= | |||
Now, let's say you want some of these tile or list draws auto-update as those vars update. Can use an #event for that, like: | |||
# | #EVENT {VARIABLE UPDATED msdp_info[ROOM_NAME]} {RE-DRAW RELEVANT TILE!} | ||
However, instead of writing the re-draw code right into that event, I prefer to write those as aliases and have the event fire the alias. That way, other things/scripts can also re-draw those tiles, and you don't have to keep rewriting the code for each one, they can all just call the alias. | |||
#ALIAS {draw_room_tile} { | |||
#FORMAT {room_string} {%c%.44s} {<ddd>}{$msdp_info[ROOM_NAME]}; | |||
#DRAW tile 3 2 3 44 $room_string; | |||
} | |||
#ALIAS {draw_area_tile} { | |||
#FORMAT {area_string} {%c%.40s} {<bbb>}{$msdp_info[AREA_NAME]}; | |||
#DRAW tile 2 2 2 43 $area_string; | |||
} | |||
Then | Then have an event to update each one: | ||
#EVENT {VARIABLE UPDATED msdp_info[ROOM_NAME]} {draw_room_tile} | |||
#EVENT {VARIABLE UPDATED msdp_info[AREA_NAME]} {draw_area_tile} | |||
How you manage your vars, and how/when to draw/update them is up to you. I've experimented with a few approaches, and have found that handling each screen element as its own small tile, with its own draw alias, with its own event, runs quite efficiently so I'm only ever drawing tiny tiles, and not redrawing the whole screen and doing unnecessary computation to generate parts of the screen that haven't changed. You can still have a 'draw everything' type alias that may need to run sometimes, but that would just be a string of all the little tile draw aliases. | |||
=Conclusion= | |||
The concepts here are just the tip of the iceberg. You'll run into a lot of headscratchers along the way as far as how to properly set up your gui so it doesn't have conflicts, or draw things redundantly, and auto-updates, and doesn't fight with other sessions. Also, you'll have to put a bit of effort into how to actually integrate it into the rest of your system. | |||
For me, I load my gui script after mud connection (as a module in my tt5 suite). I have some additional triggers firing in my connection script that then push gui re-draws upon things like session activation (changing characters), msdp reception updates, other variable updates, and code to limit when/where I draw to only work upon the active character session. This is kinda where things really get into the weeds, and you'll have to spend some time and thought on how best you want to handle all that sort of stuff. Session management is a bitch, you'll want to become familiar with the #events for session connection/activation/deactivated, as those are good times to draw your gui stuff, or wipe it out. | |||
General advice: | |||
*The simpler you can make each gui element, the better. You should be able to get very specific about what you want to draw, or redraw, so that the rest of your scripting can easily update your screen without too much work. | |||
*As a beginner at this, I would suggest just trying to get one split region working and printing some info, for example, just set a bottom prompt and try to start putting your basic character info there, similar to your prompt, see if you can get that working. Before you draw out your entire screen in some elaborate fashion like I have, start small, one bar, and get that all working before you expand. |
Latest revision as of 07:51, 22 April 2024
People keep asking how to set up the gui, so, here's some information you can expand upon.
The GUI is set up using the #SPLIT and #DRAW commands, often using #FORMAT, and using your #VAR's.
(I strongly suggest enabling MSDP so you receive all the variables the mud sends automatically so you can start building things to display those. See HERE)
Split Your Screen
First, establish your desired top/bottom screen #SPLIT with some room to print data into. I go 4 or 5 lines top and bottom.
- Run your #SPLIT command manually or make an alias that might be handy later for resetting.
- The #BUFFER command reprints the scrolling region after splitting:
#ALIAS {split} { #SPLIT 5 5; #BUFFER end; }
Draw Stuff
Second, you can draw tiles or boxes of data into your split region, using the coordinate system.
- Coordinate System
- The coordinate system is "Row Col Row Col" with the first Row-Col pair being the 'upper left' point of box, and the second Row-Col pair being the lower right corner of the box.
- Negative values can be used to mean 'rows from end'. This is used by the #draw command to either "#draw box' or "#draw tile".
- Boxes vs. Tiles:
- Tile: Can be a single space, one character high/wide. If you have data that is exactly 2x3 characters, you can draw a 2x3 tile for example. If your data exceeds that tile space, it is truncated.
- Box: Can be a large space, typically good for drawing lists into, like affects or communications lines, etc. Lines that may vary in size so you don't know the exact required space and wouldn't want to use a tile.
Example: 1 1 -5 -5
- Box will be from the upper-most left corner (row 1 column 1) to the point 5 rows from the right end of your screen, and 5 rows above the bottom row on your screen)
- To learn how these work, I would suggest just playing around with them in a blank tintin session, you don't even have to be connected to a mud.
- You can do #screen clear all to wipe the screen after each command to wipe the slate
#draw box 1 1 -10 -10 hellooooooo #draw box 10 10 25 25 hellooooooo (So box starts upper left corner row 10 down from the top, column 10 in from the left side. Goes to row 25, column 25 for lower right corner). #draw tile 30 20 30 25 123456 (tile drawn on the 30th row, from columns 20 to 25 (so 6 spaces). If you try to draw 1234567 you'll see it gets wrapped/truncated and only prints '7')
You can also play with lots of colors and formatting options. See #help draw.
Here we are printing the room/area name on line 3 (down from the top) and it will go the upper left corner (
#ALIAS {draw} { #DRAW red tile 3 2 3 44 $msdp_info[ROOM_NAME]; #DRAW blue tile 2 2 2 44 $msdp_info[AREA_NAME]; }
To clarify, the coordinates are <row> <column> <row> <column> and set the upper-left point, and lower-right point.
You'll have to read #Help draw to understand all your options, and get good at the coordinate system to place those into exact positions on screen. You'll also want to learn #FORMAT so you can add additional controls and style to those.
Format Tiles
Using #format we can set more colors, and more importantly lengths/aligns to your tiles. Here, we format the msdp vars into our own stylized vars first, then draw those.
#ALIAS {draw} { #FORMAT {room_string} {%c%.44s} {<acf>}{$msdp_info[ROOM_NAME]}; #DRAW tile 3 2 3 46 $room_string; #FORMAT {area_string} {%c%.40s} {<ffa>}{$msdp_info[AREA_NAME]}; #DRAW tile 2 2 2 46 $area_string; }
The format commands are saying we want to format a new variable named "room_string" that will be comprised of an rgb color code (%c), and then a 44 character string (%.44s). We then define the color code as the <acf> color (blue) and the string as the room name we get from msdp.
So, first we format the room name string to be exactly 44 characters. Then we draw a tile of the exact size to contain that 44 characters (between columns 2 - 46 in this example).
However - having a singular alias like this 'draw' example can become a problem when it comes to auto-updating the screen however. It works well for updating one tile or box, but, you don't want to be re-drawing your entire gui every time any part of it needs updating. Bear that in mind. Maybe make an alias like draw_area_info to draw the room/area/geo and that's it. Make several commands to draw different parts of your gui, and trigger each individually, not the whole screen all at once.
Draw Lists
Instead of drawing individual tiles, you can also generate a list and draw that all at once.
For example:
#list example add example text blablabla stuff
Looks like:
#VARIABLE {example} { {1} {example} {2} {text} {3} {blablabla} {4} {stuff} }
Can use #draw to print that all inside a box like this:
#draw box 10 10 20 40 $example[1..-1]
If you set those coordinates into a SPLIT region, the box will remain in place until it is redrawn at some point (perhaps by an alias you have, or scripted #event or #action).
If you set those coordinates into the scrolling region, the box will scroll away with the rest of the game text.
Note that when using a list, you can choose which list indexes (lines) you want to draw with the numbers inside the brackets. So 1..-1 is the first var (1) to the one before the end of the var (i.e. the last thing in the list) (-1), if you only want the last 5 you would just use -5..-1, etc.
If you capture all speech/tells/etc to a list, you can see the last 10 things sent to you with values like -10 -1 for example.
Format a List
We can also of course use #format to stylize the contents of our list. This alias takes your full affects list from msdp, and sets a color based on how many ticks remaining the spell is.
#alias get_affects { #list affects clear; #foreach {*msdp_info[AFFECTS][]} {affect} { #if {$msdp_info[AFFECTS][$affect] < 50} {#var Color {<dbb>}}; #if {$msdp_info[AFFECTS][$affect] > 49 && $msdp_info[AFFECTS][$affect] < 99} {#var Color {<ffd>}}; #if {$msdp_info[AFFECTS][$affect] > 99} {#var Color {<ddd>}}; #format {affect_line} {%c%+15.15s %c%-4s%c} {<bbb>}{$affect}{$Color}{$msdp_info[AFFECTS][$affect]}{<ddd>}; #LIST {affects} {add} {$affect_line}; }; #unvar Color; #unvar affect_line; };
That will generate a var named $affects. Type "#VAR affects" to see what it looks like. Once you get that looking how you want, you can draw that list anywhere.
For example, here we can just print it into a box in the scrolling region:
#draw box 10 60 50 90 $affects[1..-1]
If you have short lists, those could probably fit in your top/bottom split. For long lists, you'll probably want to use #split to add a sidebar and draw it there. See my other sidebar script.
Auto-Updates
Now, let's say you want some of these tile or list draws auto-update as those vars update. Can use an #event for that, like:
#EVENT {VARIABLE UPDATED msdp_info[ROOM_NAME]} {RE-DRAW RELEVANT TILE!}
However, instead of writing the re-draw code right into that event, I prefer to write those as aliases and have the event fire the alias. That way, other things/scripts can also re-draw those tiles, and you don't have to keep rewriting the code for each one, they can all just call the alias.
#ALIAS {draw_room_tile} { #FORMAT {room_string} {%c%.44s} {<ddd>}{$msdp_info[ROOM_NAME]}; #DRAW tile 3 2 3 44 $room_string; }
#ALIAS {draw_area_tile} { #FORMAT {area_string} {%c%.40s} {<bbb>}{$msdp_info[AREA_NAME]}; #DRAW tile 2 2 2 43 $area_string; }
Then have an event to update each one:
#EVENT {VARIABLE UPDATED msdp_info[ROOM_NAME]} {draw_room_tile} #EVENT {VARIABLE UPDATED msdp_info[AREA_NAME]} {draw_area_tile}
How you manage your vars, and how/when to draw/update them is up to you. I've experimented with a few approaches, and have found that handling each screen element as its own small tile, with its own draw alias, with its own event, runs quite efficiently so I'm only ever drawing tiny tiles, and not redrawing the whole screen and doing unnecessary computation to generate parts of the screen that haven't changed. You can still have a 'draw everything' type alias that may need to run sometimes, but that would just be a string of all the little tile draw aliases.
Conclusion
The concepts here are just the tip of the iceberg. You'll run into a lot of headscratchers along the way as far as how to properly set up your gui so it doesn't have conflicts, or draw things redundantly, and auto-updates, and doesn't fight with other sessions. Also, you'll have to put a bit of effort into how to actually integrate it into the rest of your system.
For me, I load my gui script after mud connection (as a module in my tt5 suite). I have some additional triggers firing in my connection script that then push gui re-draws upon things like session activation (changing characters), msdp reception updates, other variable updates, and code to limit when/where I draw to only work upon the active character session. This is kinda where things really get into the weeds, and you'll have to spend some time and thought on how best you want to handle all that sort of stuff. Session management is a bitch, you'll want to become familiar with the #events for session connection/activation/deactivated, as those are good times to draw your gui stuff, or wipe it out.
General advice:
- The simpler you can make each gui element, the better. You should be able to get very specific about what you want to draw, or redraw, so that the rest of your scripting can easily update your screen without too much work.
- As a beginner at this, I would suggest just trying to get one split region working and printing some info, for example, just set a bottom prompt and try to start putting your basic character info there, similar to your prompt, see if you can get that working. Before you draw out your entire screen in some elaborate fashion like I have, start small, one bar, and get that all working before you expand.