TesterTron3000
May 02, 2015
In Friday's podcast, I mentioned that I'd implemented an autoplay mode for Thimbleweed Park, where the game could play itself.
I can't remember if it was for Last Crusade or Monkey Island when Aric Wilmunder and I wrote the first autoplay scripts for the SCUMM games and they were invaluable.
Aric and I were in Chicago at CES (the Consumer Electronics Show) where Lucasfilm Games was showing their latest wears. CES was a loud, noisy, crowded spectacle of a show that would - at least for games - be replaced by E3, a new loud, noisy, crowded spectacle of a show.
Lucasfilm Games had a booth with several PCs connected to monitors, keyboards and mice, and we would stand around and ask passers-by, "Would you like to see Maniac Mansion or Monkey Island?" Lucasfilm Games was small back then and everyone pitched in. Designers, Programmers, Artists, we were all expect to stand around for 8 hours and demo the latest games.
It was grueling.
Demoing adventure games is especially hard. They're about thinking and pondering and enjoying a good conversation. They don't demo well.
So, Aric and I got to talking about implementing a self-play mode, where we could just stand around at the booth and the game would play itself and you could take over if someone wanted a demo. Most people are happy to just watch a game being played, even if completely randomly, so this would take a lot of pressure off the poor person on booth duty. Some movement, even random movement, was better than a idle screen with a completely still and slowly pulsing crosshair cursor. The arcade games called this attract mode.
Aric and I spent the evening in our hotel room banging out SCUMM's first autoplay mode. It wasn't sophisticated. It randomly picked an object in the room and then randomly picked a verb and then did that. It didn't need to be smart, it just need to do something that looked interesting.
We would later expand on the autoplay scripts, and they would use inventory items with other items and even do rudimentary dialog choices. All with the unblinking precision and determination of rand().
During Monkey Island, I would leave autoplay running overnight and the next morning I'd come in and see where it crashed, or got stuck in a walk box gap, or be amazed at how far it got just picking random objects.
Autoplay was great for finding "one frame bugs", where you'd click on something and then something else one frame later. They are the kind of bugs human testers don't find, but robots do.
So last week I implemented testerTron3000, the autoplay script for Thimbleweed Park. Much like the fist SCUMM autoplay scripts, it just randomly picks stuff and does stuff to that stuff.
It's already found several bugs and it's amazing how far it gets when I check it in the morning. It keeps a log of every action it preforms and the time it did it.
At the 30 second mark, I pressed the 'f' key and put the game into fast mode. Please keep in mind this is all wire frame art and no where close to final.
Still a lot of changes to make, like limiting the amount of time spent in each room, not always leaving a room and next click after entering. These should still happen, just not as often as they do. What I've always found important in these autoplays is not to guide them too much. The inclination is to have them run a test plan, but the whole point of these is to just randomly do shit we haven't thought of. You can guild the autoplay in the right direction, but let it do it's thing.
Here is the code:
breaktime(1.0);
while(YES) {
// Find on object in the Room
foreach (obj in currentRoom) {
// Is this an object
if (isObject(obj)) {
// If there is no valid usePos, it's probably an inventory object.
if (objectValidUsePos(obj)) {
// Might be dependent on another object, or just untouchable
if (objectTouchable(obj)) {
if (randomOdds(0.20) && objectValidVerb(obj, VERB_WALKTO)) {
logInfo("Walk to "+obj.name)
pushSentence(VERB_WALKTO, obj)
break
}
if (randomOdds(0.20) && objectValidVerb(obj, VERB_LOOKAT)) {
logInfo("Look at "+obj.name)
pushSentence(VERB_LOOKAT, obj)
break
}
if (randomOdds(0.20) && objectValidVerb(obj, VERB_PICKUP)) {
logInfo("Pick up "+obj.name)
pushSentence(VERB_PICKUP, obj)
break
}
if (randomOdds(0.20) && objectValidVerb(obj, VERB_OPEN)) {
logInfo("Open "+obj.name)
pushSentence(VERB_OPEN, obj)
break
}
if (randomOdds(0.20) && objectValidVerb(obj, VERB_CLOSE)) {
logInfo("Close "+obj.name)
pushSentence(VERB_CLOSE, obj)
break
}
}
}
}
}
local time = gameTime()
while(YES) {
breaktime(1.0)
if (!actorWalking() && !actorTalking()) {
break;
}
if (gameTime() > time + 30.0) {
logWarning("Time Out")
break;
}
}
}
}
- Ron
A simple password is usually used for games where a few quantities are memorized, and perhaps what level someone is on. They don't hold a ton of information, such as where you've been, which dialogue choices you've made, item combinations you've made, and exactly where you're standing in the world.
E.g. they allow you to start at a specific location in game with a specific set of inventory items.
In SCUMM this was called boot params, see this page for a detailed list: http://wiki.scummvm.org/index.php/Boot_Params
And then there are also traditional cheat codes like Ctrl+W in Monkey Island 1 and 2 for instant win!
Of course they cannot replace proper saves.
By the way I've still got some floppy disks in my cellar, bearing the inscription "savegames".
This MUST be in the game. If you include it, I'll make a Twitch channel called "Thimbleweed Park plays Thimbleweeb Park" and see if the game can finish itself in automatic-random mode!
XDDDD
The other option would be to have a map view (or birds-eye view of the area). This would be my preference, unless there are objects or puzzles that occur on the streets themselves (e.g. drop something into a mail slot, examine sewer drain or manhole, climb light pole, etc.).
If there are street puzzles, maybe Ron can somehow implement a "run" option- which possible would introduce the need for a run anim.
I'd like to hear Ron's take on this- if the street room will stay mostly as-is, or if it's just a placeholder of sorts.
http://www.mobygames.com/game/atari-st/zak-mckracken-and-the-alien-mindbenders/screenshots/gameShotId,438562/
And here a large area with a super small actor running super fast (speed in pixel/s is actually about the same as with normal scaling!):
http://www.mobygames.com/game/dos/zak-mckracken-and-the-alien-mindbenders/screenshots/gameShotId,267696/
*twitch*
Best comment yet!
Thanks for sharing!
I am the worst programmer; i totally would just fix the code and annotate it in the comments. Terrible practice.
(Yeah, I know that the analysis of this script is probably worth more time than it took to write the script. And I know it is likely FineTM for large enough number sets. .. just ... ~twitch~)
Which, on the whole, seems very enthusiastic.
-dZ.
:)
Thanks!
I personally like both 16 and 256 colors. I got to know MI on a grayscale display, so 16 colors are quite luxury to me.
Wire frame art = rooms drawn very simplistically and with little to no detail, textures, variety of colors, shading, etc etc . That stuff Gary will add to the rooms later when him, Gary and David know that they want to keep the rooms that he's doing early wireframe art for in the game. It doesn't make sense for Gary to fully draw art for a room only to have the room get cut from the final build of the game. Right now the guys just want to put together a very early beta build of the game that they can have the characters walk around in, in order to test out Ron's game engine and figure how to best do the puzzles, the story, etc. etc.
What was this originally intended for?
Say, for example, there's an item on a table and you trigger the "pick up item" action. The game then flows through the following actions:
1. Say "Thank you."
2. Add item to inventory
3. Remove item from table
While the game goes through that sequence, imagine if a new "pick up item" action is triggered right after step #2. The item is still registered as available on the table, so the action is valid but there's only one of it. How will the game react to this situation?
Regular humans may not be as quick to trigger these situations reliably, but an automatic robot player can.
Where it gets more difficult is if we had a script running that did these things, waited for the Say text to vanish, and then did something else. We'd have to either turn off the UI (making it a mini cut-scene) or make sure whatever happened later could be interrupted.
Shouldn't it be "The Thimbleweed Park developement blog has been updated!" in the ThimbleMail™ Update? There's also an
superfluous "e" in "developement" that should be "development". I'm sorry but I have nothing better to do now (that I care to
admit).
Typing regards, Grammar Commie :P
Free font: http://opendyslexic.org/
Fixed that for you.
Had no clue that the tester thing was implemented during the early days already. It's actually hauntingly creepy how fascinated one can get over following some fairly simple random procedures being automatically executed by a machine. But in a fun way. I actually genuinely chuckled a bit when the character couldn't get enough of the lovely clock, playing with it like a kid or teenager might do.
"All with the unblinking precision and determination of rand()"
Loved this one. Maybe kids and teenagers are powered by that one too, along with many adults.
Wow, so there is an Arcade Room (at most in this demo!) with the poster of myself attached to the wall!! :-D :-D
I apologize, everyone, I've not had my coffee today.
s Vimeo page, but this video isn't there for some reason. Maybe Vimeo's having problems.
Awesome video by the way. This is our first look at a great deal of rooms and connectivity in the game all at once. Wow. I love this testing concept. Does it also allow for character interaction, and swapping active characters (maybe that's not coded yet)? I didn't notice any in the video, but I might have missed it.
Love the animated hot dog flies.
Felt like a sibling piece so had to link it here :)
Felt like a sibling piece so had to link it here :)
one of my former colleagues did something similar for So Blonde and wrote an article about it:
http://www.gamasutra.com/view/feature/134893/automated_testing_building_a_.php
The nice thing, if I remember correctly, was that it was running without the rendering and therefore was able to play thousands of games overnight (so it would also find puzzle flaws where you could get stuck)
I can't stop reading this blog and watching all the videos from Ron & Gary...
It's such a good idea.
Hope it won't spoil the surprise.
A demo: https://www.youtube.com/watch?v=b13ZXUOULJY
It supports:
- Stay in a room for a specified time
- An exclude list of forbidden objects. Useful if you don't want to exit from a zone
- A flag to never leave the current room
- A flag for walking to allow the bot to trigger player walking
- Chances tuned for more actions and less lookat and combine objects in inventory
Thank you for this blog. Really inspiring for me. I am working for 2 years in an Adventure Engine and I enjoy to see how you resolve the same problems that I found.
I've a question, it has been in my head for a few days now, I think that you made choose to use a scripting language (e.g. SCUMM, Squirrel) is to have portability(script stays the same and only modify the bindings if needed) and/or flexibility(swap code on real time)? (or maybe I'm wrong on this).
If so, how do you decide when to start using the scripting language and when to write on a compiled programming language (e.g. c++, c, asm, etc)? Also, did you build for SCUMM a debugger? I''ve tried to use an engine with javascript support, and it was a hell of a time and effort when i have a bug in my js.
Aside from that, thanks for having a development blog and showing us all those great advances.
http://ataripodcast.libsyn.com/antic-interview-104-aric-wilmunder-star-raiders-ii-temple-of-apshai