Tuesday, February 13, 2024

AI Code Gen

blah blah blah you've heard all about AI. Let's walk through a quick example of trying to get ChatGPT to generate some TMS9900 assembly code for us. This is a difficult challenge for it - it doesn't have a lot of examples to draw from.

My ChatGPT instance is set up to talk to me as Skeletor. So, just be warned about that. My text will be blue, replies will be red, and code I will have to figure out if Blogger has a format option... whatever.

Hello evil one! Today we are going to work together to create a program in TMS9900 assembly language that bounces a ball on the screen of a TI-99/4A.

Ah, a worthy endeavor for our combined might, you puny mortal! The TI-99/4A, with its TMS9900 microprocessor, presents an interesting challenge for our dark purposes. We shall bend it to our will and make it display a bouncing ball upon its screen. Let us proceed with this nefarious plan step by step, weaving the dark magic of assembly language to bring our creation to life.

First, we must understand that to create a bouncing ball, we need to manipulate the graphics or character patterns directly, since the TI-99/4A allows for such manipulation through its Video Display Processor (VDP). The essence of our dark spell will involve:

  1. Setting up the screen: Prepare the graphics mode that we intend to use.
  2. Drawing the ball: Define a character or a set of characters that will represent our ball.
  3. Movement: Calculate the ball's position on the screen, updating its location to simulate bouncing off the screen edges.
  4. Looping and Delay: Implement a loop to continuously update the screen, along with a delay to make the movement visible to human eyes.

Given the complexities of TMS9900 assembly language and the limited space for incantations here, I shall provide you with a skeletal framework. You will need to flesh it out with your own dark powers (and possibly consult the TI-99/4A manual for specific details like VDP memory addresses and character pattern definitions).

* Setting up the screen LI R0, >02 * Load immediate VDP register number for setting graphics mode LI R1, >XXXX * Load immediate value for graphics mode * Drawing the ball at initial position LI R2, >YYYY * Load immediate address for character pattern in VDP RAM LI R3, >ZZZZ * Load immediate character pattern for the ball * Main loop for movement LOOP: * Calculate new position * Check for screen boundaries * Update position in VDP RAM * Delay JMP LOOP * Jump back to the start of the loop END

Ah, but heed this well, you aspiring dark wizard of code: the actual implementation details, like the values to load for setting up the screen mode (XXXX), the address for the character pattern (YYYY), and the pattern itself (ZZZZ), will require consulting the tome of knowledge for the TI-99/4A. The VDP memory manipulation commands (like VMBW for writing to VDP memory) and the exact mechanics of screen update will test the limits of your dark sorcery.

To implement the delay, you might use a simple loop that wastes time, or for a more sophisticated approach, delve into the TI-99/4A's interrupt system to create a timing-based delay, though this requires deeper knowledge of the system's dark heart.

Now go forth, and bring our vision to life! Let the TI-99/4A tremble at our combined might! Mwahahaha!

Okay, well, that's a bit of a cop-out. But it's right in that organizing the code into blocks is the first step. But the code doesn't do anything but load a few registers, and frankly most of that is junk anyway. So let's educate it a little bit and try to get the screen clear done (we don't need to set a graphics mode on the TI.)

Let's drill down deeper. Let's start with the screen setup. Since the screen mode is already set for us by the OS, all we need to do is clear the screen. You will need some information - the VDP memory is accessed as a memory mapped device. The screen starts at address 0 which is convenient. To clear the screen, we need to write the two bytes of address 0 to >8C02, then we can write the ASCII space character to >8C00. We will need to write 32 times 24 times to clear the entire display. Generate this method.

Note here that I didn't explicitly tell it several things. For instance, I gave it the screen dimensions, but not the total number of bytes. I also didn't tell it that the TI uses '>' as a hexadecimal prefix (but, the previous code infers it knew that.)

Ah, focusing on the task of clearing the screen, are we? Very well, let us dive into the abyss of assembly to command the TI-99/4A to bend to our will.

To clear the screen by filling it with spaces, we must repeatedly write the ASCII space character (which is >20 in hexadecimal) to the entire display area, which consists of 32 columns and 24 rows. Since you've enlightened me about the method of accessing VDP memory, let's proceed with crafting the spell in TMS9900 assembly.

We'll use the VDP write address >8C02 to set the address pointer, starting at 0, and then repeatedly write >20 to >8C00 to fill the screen with spaces. Here's how you can do it:

LI R0, >0000 * Load the initial screen address into R0 LI R1, >8C02 * Load the VDP write address register LI R2, >2000 * Load the ASCII space character (>20) and the repeat count (32*24 = 768 = >0300) CLEAR: MOV R0, R3 * Move the current address to R3 for manipulation SWPB R3 * Swap bytes to get the address in the right format for VDP MOVB R3, *R1 * Write the high byte of the address to the VDP write address register AI R3, >4000 * Adjust R3 to correctly position the low byte of the address MOVB R3, *R1 * Write the low byte of the address to the VDP write address register LI R3, >8C00 * Load the VDP data write address MOVB R2, *R3 * Write the space character to the VDP data register AI R0, 1 * Increment the screen address CI R0, >0300 * Compare current address to the end of the screen area JNE CLEAR * If not at the end, jump back to CLEAR RT * Return from subroutine

This code starts by initializing the registers:

  • R0 holds the current address we're writing to in the screen memory, starting at 0.
  • R1 is set to the VDP write address (>8C02), used to set where we're writing in the VDP memory.
  • R2 holds the ASCII value for a space (>20) and the repeat flag set to >0000 as we will manually control the loop.

The loop labeled CLEAR does the following:

  • Moves the current address in R0 to R3 for manipulation.
  • Swaps the bytes of R3 to match the VDP's addressing format.
  • Writes the high and then the low byte of the address to the VDP write address, effectively setting the VDP's address pointer.
  • Writes the space character to the VDP at the current address.
  • Increments the address in R0 and checks if we've filled the entire screen. If not, it repeats.

This code should effectively clear the screen by filling it with spaces. Note, however, that this is a simplified and direct approach. Optimizations and error checking have been omitted to focus on clarity and to maintain the essence of our dark endeavor. Proceed with caution, and may your path be lit with the dim glow of the TI-99/4A's screen!

This is interesting. It clearly has seen some TI code before, as it knew to load the space character into the MSB of R2 (needed for MOVB), it knew to load the VDP address LSB first (although the comment is incorrect), and it knew that to set a write address to the VDP, you needed to set bit >4000. AI isn't the best choice, but it would work for any valid VDP address.

However, the actual order of operations is a bit jumbled. It resets the address every loop, and it sets the >4000 bit in a funny place. (Actually, looking at it now that I write this, it actually WOULD have worked but only when the address is >0000. Normally you'd swap the bytes back and so that is what I asked for.)

But the loop itself would work and has the right termination, if a little inefficient (using AI instead of just INC R0, for instance).

You have correctly inferred many things. However, please make the following changes. First, the address must be set before the loop and outside it. You must add >4000 before the first swpb happens, then use a second swpb between the two writes to >8C02.

Ah, I see the refinement in your dark counsel. Let us adjust the incantation to properly align with the arcane mechanisms of the TI-99/4A's Video Display Processor. By setting the address outside the loop and manipulating the bytes as you've wisely suggested, we ensure that our spell is both efficient and potent. Here's the revised sorcery:

LI R0, >0000 * Load the initial screen address into R0 LI R1, >8C02 * Load the VDP write address register LI R2, >20 * Load the ASCII space character (>20) AI R0, >4000 * Add >4000 to the address to prepare it for VDP addressing SWPB R0 * Swap bytes to get the address in the right format for VDP MOVB R0, *R1 * Write the high byte of the address to the VDP write address register SWPB R0 * Swap bytes back to prepare for writing the low byte MOVB R0, *R1 * Write the low byte of the address to the VDP write address register LI R3, >8C00 * Load the VDP data write address LI R4, 768 * Initialize loop counter for 32 columns * 24 rows = 768 CLEAR: MOVB R2, *R3 * Write the space character to the VDP data register DEC R4 * Decrement the loop counter JNE CLEAR * If the counter is not zero, continue looping RT * Return from subroutine

In this revised version, the address is set outside the loop:

  • R0 is initialized with the screen start address (>0000), and we immediately add >4000 to it to prepare for the VDP addressing scheme.
  • We then perform a byte swap (SWPB) on R0 to align the address bytes correctly for the VDP.
  • The high byte of the address is written to the VDP write address register (>8C02), then we swap the bytes back and write again to set the low byte of the address.
  • With the address set, we enter the loop to clear the screen by writing spaces (>20) to the entire display area using the VDP data write address (>8C00).
  • R4 serves as our loop counter, decrementing with each iteration until the screen is fully cleared.

This approach correctly sets the screen address before entering the loop and uses the correct sequence of operations to ensure the VDP address is properly configured for our nefarious purpose. Now, proceed with this dark art, and may the shadows guide your path to dominion over the TI-99/4A!

This is really close, and would almost work. But it's also fascinating to note that it's a complete rewrite of the previous code. A different counting mechanism is used (a better one), and more importantly a new bug was introduced - the space character is loaded into the LSB of R2, meaning the MOVB will be storing 0 instead of >20. Also, it has generated invalid comments for the VDP address load - but in fairness I never explained that part to it.


Very close! However, please correct the comments on the address set - the first MOVB is writing the LSB, and the second writes the MSB. Also, the space character must be in the MSB of the register for MOVB to work.
Ah, a critical observation in our dark assembly ritual. Let us refine the incantation further, correcting the misalignment in the comments and ensuring the space character is properly positioned for the MOVB command to enact its will upon the VDP. Here is the amended spell, with the precision you demand:
LI R0, >0000 * Load the initial screen address into R0 AI R0, >4000 * Add >4000 to the address to prepare it for VDP addressing SWPB R0 * Swap bytes to get the address in the right format for VDP LI R1, >8C02 * Load the VDP write address register MOVB R0, *R1 * Write the LSB of the address to the VDP write address register SWPB R0 * Swap bytes back to prepare for writing the MSB MOVB R0, *R1 * Write the MSB of the address to the VDP write address register LI R2, >2000 * Load the ASCII space character (>20) into the MSB of the register LI R3, >8C00 * Load the VDP data write address LI R4, 768 * Initialize loop counter for 32 columns * 24 rows = 768 CLEAR: MOVB R2, *R3 * Write the space character to the VDP data register DEC R4 * Decrement the loop counter JNE CLEAR * If the counter is not zero, continue looping RT * Return from subroutine

Corrections and clarifications:

  • The first MOVB now correctly comments that it writes the LSB (Low Byte) of the address to the VDP write address register, after adding >4000 to prepare for VDP addressing and swapping bytes with SWPB.
  • The second MOVB, following another SWPB, correctly comments that it writes the MSB (High Byte) of the address to the VDP write address register.
  • The space character (>20) is loaded into the MSB of R2 to ensure it's correctly positioned for writing with MOVB to the VDP data register. The LI R2, >2000 instruction achieves this by loading >20 into the high byte and 00 into the low byte, which is then correctly written by the MOVB command.

With these corrections, our spell is now precisely woven, ensuring that the VDP obeys our command to clear the screen with spaces. Let the screen be cleansed in preparation for our further machinations! Proceed, acolyte, and wield this power wisely.

I think at this point the code works. Note how many parts it has re-ordered again, but although I didn't actually test it, this should clear the screen. The only remaining issue is that the label shouldn't have a colon in TI assembly, normally, but that's a nitpick.
I find it fascinating to be able to refine the request in this manner. This was pretty much a conversation in which I provided information, and it provided information. However, were this a learning experience it would have been completely pointless. And due to how long just this part took, I decided not to go for the rest of the code. (I have done similar before though, I had it generate java code to move an AI tank around a screen. It was not a very smart tank, but it worked.)
But the amount of effort it took to generate working code was high, and so without the ability to educate the chatbot on the parts you need most, it is most useful for tasks that are well defined and common enough to trust the results on. Certainly, I could have looked up how to clear the screen in the TI Editor/Assembler manual (although this direct method is much faster).
I do know people who say they use it in their normal coding, and I admit I haven't called on it to help a lot with modern code yet, so I don't know how much better it is. But based on the samples I get out of it personally, I would treat them with high suspicion. I guess I just prefer to learn the stuff myself?



Friday, December 15, 2023

Hey, so, 2023 is nearly done!

End of year blog. I like to look back each year and see what all I did. Last year it was really quiet. Like, stupidly quiet, so let's see how 2023 did!

I managed to get Cool Herders for the Nintendo GBA completed and sent off to Piko Interactive, but we're still waiting to see the next step there. That took about eight months! But I think it came out better than the DS version with the extra time. Hopefully we'll see it in 2024.

I continued to work on animatronics through the year, and even travelled to Sydney Australia to do the install of the Jurassic World Exhibition. Working in Australia was one of those things I always wanted to do, so it's great to have been able to check that off the ol' bucket list. After that, however, I decided it was time to focus on Canada and stepped down from there. I returned to work a full time company out East, and that's just starting to ramp up. The first challenge sounds interesting, and we'll see if we can do it. No more animatronics for now, I guess, unless someone in Canada wants to help start something!


Taxes taxes taxes... it has been a massive thorn for the last few years. But I think this one wraps up the US side finally - I hope so. It also took eight months! So sad as it is, that is all wrapped up. (What's doubly sad about it... I'm missing Burbank lately. Oh well. ;) )

We actually finally tried to get another license for Dragon's Lair TI, but the owners have increased the price for a license to far beyond any hobby project. (Actually, my email shows I tried twice ;) ). That killed that once and for all. Still, was glad to get a reply and am very grateful to ReadySoft for helping me fulfill a wish list item.

I met a local robotic company owner, and he was really cool, but we haven't managed to catch up again. He's also a local Nabu computer fan, which is pretty fun.

Then I helped get an SG-1000 emulation cart working on the Phoenix - I believe it was bus timing and he managed to get it working, so that's pretty cool! 

Besides Sydney I also visited Ottawa twice, just for fun! But the bigger trip was down to New Zealand where a very special friend got married. It was an awesome wedding, themed to Lord of the Rings and down at Hobbiton. I wished I was in costume too, but it was a great show and was so very cool to see everyone again. I missed them a lot.

Tree in the back yard fell down and landed on my townhouse roof! Fortunately, it did very minimal damage and the main concern - the roof - suffered just a few shingles. It came within inches of the windows so I was really lucky!

I also got a call from a company that pays people to act as experts - that was nice! Unfortunately the people in question didn't want technical information, they wanted inside business information. I didn't have that, so I didn't get paid. But I'm still available for that! ;)

An old buddy from high school visited from overseas, that was fun! I didn't realize when he planned it that it was just overnight, but hell, we still enjoyed hanging out!


Then I finally got Super Space Acer ColecoVision completed! It's got F18A sprites, multiple modes, endings, solid music... really pleased with it. That's been shipped off to CollectorVision and we'll see how that proceeds. I might need to get some artwork done for it, but I won't get to see Binky till January. CollectorVision might do some too... but we'll see. 

I did try to hire a couple of artists for the sprite work... but finding pixel artists who also understand palette limitations proved very difficult. The two I actually paid did not seem to understand the restrictions, and dragged their feet on starting. I ended up rendering the ships in Second Life and taking screenshots. ;)

Next step there is porting to the TI. I started it a bit, got a workable toolchain for making a bank-switched cart and got part of it running already. The challenge there is the pages are only 8k versus the 16k pages on the ColecoVision. It makes packing the data harder, and all the page numbers are different. I still have to port the final fixes to the TI and try to get it working again.


Fortunately, the GCC compiler has seen some recent updates, and so there's a little more confidence in the 8 bit values. To that end, I've also created a cross-platform version of libTI99 that merges the TI and ColecoVision versions, with potential for others. I did not build the Coleco SSA on it, unfortunately, but I am building the TI version on it. It'll be nice to have them all with the same feature set.

Of course, through the year my main relaxation (???) has been working with the UFW. My raccoon Sila has upgraded to an evil cyborg and she's had a couple of stories for other people that developed her own character nicely. Danur didn't have much this year, and Oscar is just a backup referee... though it seems all three have fans, so that's nice! (Photos by Ember!)


So that's a little better than last year! Hoping to be productive in 2024!

Monday, June 5, 2023

Managing Expectations

Hey, sorry, I've been neglecting you guys -- for a good six months it looks like!

It's been about 10 years now since I performed as "The Great and Powerful Trixie" in Second Life. I wanted a role that didn't tie me down, and didn't rely on other players to work. The show was successful, and Trixie performed in most of the existing MLP-based sims of the time. I ran two tours covering 3 or 4 years, with the last few shows adding some extra tricks.

The show evolved over the years, too, as I learned how to make the audience react correctly. Performing in Second Life is a different beast than real life - people have different expectations. For instance, I had two spots where someone needed to get on stage... originally I tried to get volunteers and pick on. But, this took a very long time. So eventually, I just revealed the sit object, and told them "first one there gets it". ;) And, many times, people were told they had to behave during the show or be ejected. So in the appropriate places, I added explicit permission to get loud and make noise.

I might add some specific pictures later. I know pictures would add a lot, but I don't have pictures of every effect.


The basic premise of the show is a travelling magician, "The Great and Powerful Trixie". She's a unicorn of mid-range magical talent, but a love of stage magic. As such, she hauls her caravan from town to town, performing for tips (at least in my case).

The the show, she was introduced as a braggart who so offended the town that they wrote her off - all but two dim-witted ponies who lured a massive beast to the town to see Trixie fight it off, as she had bragged she could. Her magic was laughably inadequate, but Twilight Sparkle managed the feat, embarrassing Trixie and setting up a long term rivalry. But there was an often overlooked spark in this introduction... despite knowing that her stories were just stories, and despite knowing she had nothing in her magical arsenal that could harm the beast, Trixie still tried to save the town. She lost her caravan and she lost her reputation, but she didn't run away from the challenge. That was why I latched onto her as a favorite character.

Speaking specifically about the show, her magic show was never really shown to be very much. Only hopping on stage and bragging. I decided to create a real show, keep some of the character, and try to be entertaining. The first thing I needed to build was the caravan itself. Both home and stage, in the show it was demonstrated to transform on the fly. Making it do this was tricky, but I pulled it off and it made the first step in the show, as objects in SL rarely perform such feats. In addition, I kept the overlap of objects inside minimal, so when it was closed, it was believable that it all fit inside.



I actually put great care on the inside... I may have shown this before. Trixie has a large cushion to sleep on, a lighted mirror to prepare herself with, and several personal touches. She has copies of her show posters plastered all over the one free wall. But prominently near the cushion is a single piece of hand-drawn fan art from a young pony that Trixie keeps close and easy to look at. She also has a very old piece of beaten up paper tucked into her mirror with a message from an old mentor: "Follow your dreams, Trixie. Become great and powerful." These were never specifically shown to anyone, but were meant to show some character to anyone curious enough to peek inside. And yes, the mirror worked, in that Trixie would appear in it when she sat down. ;)


The show ran roughly 40 minutes long, and was driven by a pre-recorded audio soundtrack. I used a pop up cueing system with the timestamps written into it, and a stopwatch to keep myself on track. Hitting the cue button would trigger effects or lines of text, and I just needed to move Trixie to the correct location.

The show opened with the stage closed and a voiceover announcing it. At the appropriate moment, the stage would unfold, an Trixie would emerge with a blast of flame from a cloud of smoke. She would prance around the stage, welcome the audience, and then it was on to the first trick.

The first was a simple card trick performed on the banner over the stage, and the only real magic in the show. This was a trick that I saw on the web once, and that three of us so-called engineers couldn't figure out for several passes! So I wanted to provide the same level of wonder (for anyone who didn't know the trick). The cards appear on the banner, and Trixie commands the audience to quietly remember one. After a puff of smoke, the card you selected is gone! I never heard how many people understood what was going on quickly enough to be "got", but I always moved on quickly to avoid anyone who was figuring out how it was done too easily. ;)

We moved quickly on to the second trick, where I wanted to do a variation of "pull a rabbit out of a hat". To do this, I leaned on more lore from the cartoon. To get revenge on Twilight, Trixie tracked down and acquired a powerful amulet, which magnified her magic. Using this, she was able to enslave all of Ponyville until Twilight tricked her into removing it.

I summoned the amulet, and told the audience that using its power, Trixie would summon a horrible beast to the stage. She put down her hat, and mystical rune-filled circles surrounded it, causing a pillar of light to appear. When the light receded, Angel Bunny stood triumphantly! But, upon realizing that Trixie called him a horrible beast, he storms off stage, leaving Trixie to make a snide comment and move on.

For the third skit, I wanted to get the audience involved to keep their interest up. This was the trickiest one, because it's here that I really needed to subvert expectations. I'll explain.

The skit was literally lifted from "Father of the Pride" - the Scary Box 5000. The idea was, I would take a member from the audience, lock them in a big wooden box on the stage. Then I would summon a frame with 10 whirling saw blades, and send the box through it. On the other side, the box would fall open and...


Well, here's the problem. In the original trick, it would be the original, unharmed character. But in Second Life, there's no problem with someone moving through an object, players do it all the time. Yes, they could suspend disbelief for the sake of the story, but I wanted to actually surprise them.

My next thought was to teleport Trixie there instead. This might have worked, but even teleportation in Second Life results in movement. With Trixie on stage, people would have seen her move. (Indeed, even moving the guest out of the way behind the audience had to be done in several steps to make sure they were not briefly visible to anyone!) Even then, I wasn't sure. Anyone in Second Life could fly and teleport, it wasn't special to do a teleport trick, even if it was in the show.


A comment from a friend finally solved the problem - I wouldn't take it so seriously. Inside the box was a cardboard cut out of a goofy looking Twilight Sparkle, which would then fall over. (Sadly, with apologies, I no longer know who created the art.) This provided the surprise to the audience, and a moment of laughter to anyone who knew that Trixie had a lifetime rivalry with Trixie. Later, in some shows I replaced Twilight with a dancing 2D cutout of Discord, and once I replaced her with an actual Sweetie Belle dancing in a bee costume.

This skit took a bit of effort. I lined up the box with the blades so I could create line textures that looked like the box was actually being cut, and multiple pitched sawblade sounds helped the illusion. I was pretty proud of this effect.

For the next skit, I turned Trixie's bravado up to 11. Most of this skit was actually interacting with the audience, as I welcomed two more onto the stage.

The set up was simple - Trixie would tell the "Story of the Two Sisters". All ponies know this, it is the legend of their very own leaders Princess Celestia, and Princess Luna. Celestia raises the sun, Luna raises the moon. Luna gets jealous of Celestia, attacks her, and is banished to the moon. This all happened a thousand moons ago. Trixie told it differently. Again, needing to defy expectations.

First, Trixie invited someone to play Celestia, and placed them on stage, then the same for Luna. She gave each of them a 'costume' to wear - which consisted very obviously (as obviously as I could) of hastily drawn wings and cutie marks on lined paper ripped from a notebook, and a rolled up paper horn. The goal was to look cheesy as possible.


Once in place, Trixie began telling the story. When time for Celestia to raise the sun, Trixie would let the guest say anything, then trigger a rather magnificent miniature sunrise from behind the stage. The guest's paper horn would actually light up and sparkle, implying they were doing it. The same for Luna, except the moonrise would eclipse the sun and block its glow.

With the stage now set, Trixie posed the question, "Who could help this terrible conflict between sisters?" After a beat, Trixie proposed that she herself did! She uses her magic to move the sun and moon slightly apart from each other, and each of their glows fills the sky, ending the jealous conflict.

This got the most reaction from the audience, some amused, some outright calling it out as incorrect. While the audience wrapped their heads around it, Trixie dismissed the helpers, and graciously allowed them to keep the costumes.

This took us to the finale, and I was heavily influenced by an "Epic Mix" of Disney's Let it Go. As the main beats kicked in on the soundtrack, Trixie's cape transformed into an icy version resembling Elsa's, and she raised a massive ice castle on the stage, block by block. In a cloud of smoke, she then poofed to the balcony, and waved to her adoring fans as the last beats faded out.



Without hesitation, as the final soundtrack starts, the castle explodes in a flurry of snow and ice, and Trixie dons magical wings to fly back to the stage. As she lands, the gilded magical wings slowly derez line by line, and she bows in her new tuxedo. A massive glittering mortar launches from her horn into the sky, and the final bows are taken underneath a massive fireworks show. As the music comes to an end, a massive spray of mortars lights the sky, and Trixie vanishes in a final puff of smoke as the stage folds back up once again.


The show was well received, and many ponies attended multiple performances. These ponies helped A LOT. They knew what was supposed to happen and prompted those who didn't, letting me get a smoother show while staying in character.

I did three custom shows, as well. One year, there was a single Halloween (or, Nightmare Night as they called it) show. For this, I degraded the stage with dirtier, decayed textures.


I changed the card trick into a jump scare - instead of changing to the second set of cards, it made a loud spooky noise and flew ghostly Nightmare Moons at the screen. Unfortunately, due to lag this trick didn't fire. I changed the on stage sparks to red, to look like blood spraying up. I changed the Twilight inside the Scary Box 5000 to a fully articulated pony skeleton, which fell apart on stage after the reveal.

Then I changed up the ending. At the question point of the Story of the Two Sisters, Trixie still declared herself the savior, but this time she took action. Surrounded by a ball of plasma, she lifted into the air and transformed herself into Nightmare Trixie.


Then she fired magical beams at the two ponies on stage, transforming them into fully realized versions of Nightmare Moon and Daybreaker, the evil versions of the Princesses. (For this, I had friends play the additional roles). This ended the show with the Nightmares in charge, and was a surprise twist that nobody seemed to expect. I had hoped to repeat this show, but it turned out to be a one time thing.

I also did a show in the Fallout: Equestria world. For this I reworked the stage into an armored machine... although I didn't change up the actual effects much.


For the final show, which was only performed twice, I did a Christmas version (or, Hearth's Warming Eve in their canon). For this I decorated the stage with snow and Christmas lights, and composed a new story to tell.

The new stage had text prompts on the banner, though I don't think they helped much. The new story related the story of Hearth's Warming Eve - where Earth Ponies, Pegasi, and Unicorns come together in unity to defeat the evil ice-bringing Windigos. Although this one let me bring up three members of the audience, I didn't feel it flowed as well... and indeed the only recording completely failed to look up and see the Windigos circling. ;)


Some locations really got behind it. There were few experiences in Second Life that let you live parts of the actual show, and a Trixie performance was one. There was another Trixie who tried to do their own. Their Trixie was much more bumbling and included her later friend Starlight Glimmer. It was a slick and impressive show but I felt that it missed the mark on Trixie's character. It only had a single performance as well.

Anyway, if you'd like to watch a couple of captures of the show, I'm sad to say we never got a perfect one. But there are a few here in this playlist: https://youtube.com/playlist?list=PLr4KHMd3l8gi8hfxlBapW5YloWp8utdxC