Adding Gradual Typing + Old TV Stuff
What’s happening everyone! I’m writing to you at 5AM on November 17th, 2023 in order to give you the latest news on a local man who has become engrossed by a quest to make good textboxes. I am that local man.
This post’s update covers another improvement in the world of textboxes. We now have our text gradually typing into the textbox, rather than all appearing at once. Observe!
So there’s two new bits of functionality to see here. First, the text gradually appears like I mentioned before. The second bit of functionality is that if you click while the text is typing, it skips the text appearing animation and shows you the completed textbox. Another click will start the gradual typing of the next line, where you’re free to skip ahead again.
One way to accomplish the gradual typing part is to notice that the Label class has a property called “visible_ratio” (the RichTextLabel class also has it). Visible ratio is a number from 0 to 1 that represents what percentage of the text is showing. Being aware of the existence of this is half the battle. When I first started implementing this, I was creating an array of all the letters in the upcoming message and adding the next letter onto the displayed string one at a time. You can do that obviously, but visible ratio can do the heavy lifting for you.
A Godot rule of thumb: once you know that you have a property you want to change over time, it’s a good indication that you’re in Tween Territory. A Tween is a class that can “lerp” (linear interpolation - gradually change a value from A to B over a specified time). It also has built in functionality that enables it to assist with animations. Here, our tween is changing the visible ratio property of the label over a time interval. The time interval I chose is calculated based on the length of the string being printed, so lines of all lengths will print at the same speed.
For the second bit of functionality - skipping ahead in the text if you click while the textbox is typing - we’re crossing over into the world of input management. Like, players pressing buttons and what they do.
The situation with the textbox is basically such that what an input does is based on what is happening with the textbox. If the textbox is still printing, clicking skips the printing. If the textbox is done printing, clicking takes you to the next line of dialogue.
Another Godot rule of thumb: if you find yourself in an input management situation like this, you’re in finite state machine’s neighborhood. If you’re not familiar with FSMs and you want to implement one, googling the term will get you plenty of good info. At a high level though, a FSM is a setup where you can be in one of many different states, but you can only be in one state at a time. What state you’re in affects what parts of your code run. It’s useful for separating your input management into distinct categories. Without an FSM, you’ll instead start putting if statements or other conditionals into your _input() function that always start out manageable, but quickly turn into chaos once your objects can do more (e.g., when the textbox features a text selection for the user, what a click does will become further complicated).
So for our purposes here, our textbox can be in the “awaiting input” state, or the “reading” state. If we click while it’s awaiting input, the textbox will check to see if there’s another line to print, and print it if there is (and exit if the dialogue is over). If we click while the textbox is in the reading state, the previously-discussed Tween gets cancelled, and we just show all of the text.
And that’s all the game updates I have for you today!
New Stream Setup: Moving to S-Video
Forget about 4k! Let me tell you about S-Video.
So first to recap my stream history, I streamed on Twitch for the first time in the summer of 2016. Since then, I’ve had several periods of consistently speedrunning DKC2. These periods always eventually end, and then half a year later I’ll pick it back up again.
My stream has gotten consistently better over the years. At first, it was just a live video feed of me playing the game. Granted, just getting a live video feed of a video game so old (released in 1995) is already an undertaking. Super Nintendo games are played on CRTs (the old style of television with the huge back that weigh a ton). You could use converters to plug the SNES into a more modern television, though I choose not to do this. Playing the SNES on a modern TV can come with input lag, though honestly the main reason I don’t do it is nostalgia. CRTs are what I’ve always played these games on. The CRT is part of the experience!
Anyway, so how do you digitally stream and record Super Nintendo footage from a CRT? The way that seemingly everyone accomplishes this is to buy this one Japanese product called the GV-USB2. Here is a photo of my box:
Then, if you poke around online you’ll find a translated guide on how to install the drivers for this device. You need a translated guide because the site is in Japanese, as are all of their manuals.
As the box indicates, the product is marketed for transitioning your VHS tapes to DVD. Here’s a picture of the actual device, the GV-USB2.
One end is a USB that I plug into my desktop computer. The other end has two audio cables - the red and white plugs. You’d always use both of these. The last two plugs are competing video inputs - the S-Video (black plug) and the more-common composite video plug (the yellow plug). You would only use one of these two.
So basically, under normal circumstances your Super Nintendo would plug into your CRT. To live stream and record it digitally, the Super Nintendo needs to plug into the CRT and into the GV-USB2. To enable the SNES to send its data to two sources at once, you use a splitter, pictured here:
So all told, the Super Nintendo’s red / white / yellow plugs go into the splitter, and then half the splitter output goes to the CRT, and the other half goes into the GV-USB2, which in turn goes to your computer.
You might notice that the splitter only accommodates the yellow “composite” plug. It doesn’t have an S-Video plug. More on that later!
So anyway, the technology solution outlined above is what I’ve used throughout my whole speedrunning career to date. I’ve used a couple different TVs over the years, but they were all very similar. This is a photo of the CRT I’ve used the last few years.
It’s a pretty good TV. It has a headphone jack, and it’s nice to have the red / yellow / white plugs facing forward. Any memories you may have of plugging something into the back of a CRT are not good memories.
Enter the present, late 2023. I’m getting the familiar itch to live stream some DKC2 speedrun attempts, so I figure, “you know what? this year I’m going to actually do research and improve my stream quality.”
This led to a lot of learning about old TVs and how they receive and use information. I think the easiest way to understand TV technology of the age is via the information they use to show you a picture. These are the key pieces of information:
Luma - this is the only value you need to get a black and white picture. There’s an amount of light, and adding or subtracting from it is how you shade things and form pictures. This value is affecting that.
Red, blue, green - these are the values that describe the color of this location on the TV in the RGB color space. The way the RGB color space works, if you have two of these numbers, you can calculate the third, so you really only need two of these.
Left and right audio
For each of these key pieces of information, the quality of your audio and video will be better if that piece of information is transferred along its own channel. Keeping each of these channels separate wasn’t trivial at the time though - each time a channel was able to be transferred separately, it represented a new, higher level of overall output quality. That higher output quality would also require a new cable, and that meant that TVs then had to come prepared to handle that new cable.
So the oldest, and worst quality output is radio frequency output, or RF output. The original Super Nintendo came with an RF output by default, though it also supported other outputs as we’ll see momentarily. The NES also used an RF output. Here’s a picture of the RF switch that connects my NES to a CRT.
One side plugs into the NES (or SNES), and the other side plugs into the RF cord slot on a CRT (some people call it a coaxial cord you might know it as that).
I don’t know a lot about how radio frequencies work, but I do know that all the video and audio is being transmitted through this one cord. If you remember how back in the day games would always ask you if your setup was “Stereo” or “Mono” - this is an example where Mono is all that’s available. Since all the sound is one cord, the left and right distinction isn’t available.
A step up from this would be to use the red / yellow / white plugs that I think the most people are the most familiar with. With these plugs, one is for left audio, one is for right audio, and one of for video. With these output plugs, you could play a game in ‘stereo’. The video quality would still be about the same as it was using the RF output, though. All of the video data is still consolidated to one plug. When all of the video data is on one plug on its own like this, it’s called composite video.
A step up from composite would be S-Video. The S in S-Video stands for ‘separate’ - you can see what’s going on here. With S-Video, the video data is broken up into the luma data, and the color data (red, blue, green). This separation causes a massive uptick in picture quality.
The next step up from S-Video, is component video. It’s very easy to confuse “component” and “composite” - note they’re different! Component takes that final step that S-Video didn’t. While S-Video split its data into Luma on one channel, and red/blue/green on a second channel, component puts Luma on one channel, red on a second channel, blue on a third channel, and dynamically calculates green based on the values of red and blue. This results in the best possible picture quality you can get on a CRT. It’s notable though that the gap between component and S-Video is much, much smaller than the gap between S-Video and composite. Each advancement in technology didn’t bring equally large advancements in picture quality.
So, in short, the hierarchy of quality starts with RF output, moves next to composite video which splits audio into left and right, moves next to S-video which separates light and color from each other, and finally moves to component video which separates the red blue and green from each other.
Now, the CRT that I have been using these last few years unfortunately only came with a composite video output. Because of this, one step of my ongoing stream upgrade was to track down a new CRT. I got this one for free from someone who was throwing it out, and I have to say she’s a real beauty.
This TV comes with both S-Video and component outputs, so at this stage of the process, I actually had my choice between which avenue to go down. I wound up choosing to implement S-Video, despite the fact that component video is slightly higher quality. My main reason is because I already own the GV-USB2 - the capture device that translates analog data into digital data and plugs into my PC. The GV-USB2 also supports S-Video, so by using S-Video instead of component, I can keep using that same recording device. If I implemented a stack that focused on component video, I’d need to buy a converter that could handle the component data.
Another thing that can change if you move from composite to either S-Video or component, is the way you split the signal changes. Recall that in my current stream setup, I was using this splitter to send the Super Nintendo data to both the CRT and the GV-USB2 (which then goes to my computer):
One thing that tripped me up while setting this up was I assumed that S-Video data would be split in this same way. However, if you search the internet for S-Video plugs with one female and two male ends, you won’t find any. Eventually I found out that this is because unlike the composite data, the S-Video data isn’t strong enough to split and send two places. Instead of a splitter like the one shown above, you need an S-Video amplifier and distributor. The only website I found that sold these amplifiers is called ShowMeCables dot com, so if you get this far into the process, yes, you’re officially in the trenches.
And by the way, if you do decide to use a component setup, Retrotink is a small shop that makes devices analogous to the GV-USB2, but for component. Look them up if you need a solution.
Finally, the Super Nintendo itself that you need can change if you decide to upgrade your setup from composite to either S-Video or component. Mine did.
Unlike your CRT, where the newer your CRT, the more likely it is to have the better outputs, it’s actually the older Super Nintendo consoles that have the best output. Here’s a picture of the SNS 101 I own - the second design of the Super Nintendo that came out a few years after the original.
This model actually doesn’t output in S-Video. It only outputs in composite video, which is why it has been fine for my streaming purposes up until this point. Only the older version of the console outputs S-Video, but actually even that will likely require you to find a SNES S-Video AV plug. The original Super Nintendo consoles came with an RF cable, but somewhat secretly could output S-Video. Back in the day you had to write to Nintendo and ask them to specifically send you an S-Video Super Nintendo AV cable. Nowadays you’ll find them on electronic bay dot com. Mine is on its way in the mail as I type.
The Super Nintendo never actually supported component video at all, but if you have all the other equipment to enable it, you can buy original SNES consoles that have been modded to output in component. What a time to be alive.
Hopefully you enjoyed that trip down CRT memory lane. Have a great day!