Development:Psychonauts/Scripts
This is a sub-page of Development:Psychonauts.
The full uncompiled Lua code of the game can be found within the February 2013 Steam build, revealing tons of developer comments, commented out and old code and unused entities.
Even unused dialogue can be found in these files - the developers typically annotate line IDs with their corresponding dialogue, so even if a line of dialogue's sound file was removed, it's still possible to see what the cut line was.
Contents
Levels
The scripts and folders for the levels in the game contain all sorts of goodies.
ActionLand
A script for the night variant of a general test level named "ActionLand". While no other remnants of this level besides this script and the lightmaps exist here, the PlayStation 2 port of the game mistakenly included the level scene.
The script is fairly simple:
On initialization, the level prints "in actionland night" to debug output. It then sets up two rail objects ("splRail0" and "splRail1"), making it possible to switch between them when riding and setting both their minimum and maximum speed to 700. When it's done setting up the rails, it prints "Ready to go"
Afterwards it creates a trampoline object at the coordinates -1000, 250, 1300 and a canoe at -200, 550, 11000. It then calls a debug function to grant the player all powers.
The level also has an option for the debug menu (set up using a method that's supported but not used by any other levels) that would apparently spawn a rock above the player. The entity it tries to create is TEST_Rock, the script for which unfortunately no longer exists.
Milla's Dance Party
The script for the dancers in Milla's dance party makes references to an entity named 'Lucifer' and contains state handlers for states that never come in to play. Namely, the dancers have variables "bCondemned", "bDoomed", "bSaved" and "bGoneToHell", with comments alongside the variables indicating that at some point some kind of demonic enemy would've attacked the dancers by dragging them to hell, and allowed Raz to save them with the unused levitation psi popper. Even the message handler function for the act of getting grabbed (function Ob:onDemonArmGrab) remains, alongside the state handler for getting pulled to hell (function Ob:statePulledToHell). Unfortunately the script for the 'Lucifer' entity is completely gone, which means that the context of the behaviour cannot be extrapolated from what's left.
Of note is that the nightmares the player faces in The Milkman Conspiracy, alongside the ones found in the secret in Milla's Dance Party are both internally referred to as "demon" and "demonchildren", respectively. These script leftovers, alongside with the unused voice lines found in the soundbanks may be indicative of some narrative rewrites for the level throughout development.
Black Velvetopia
Cut Wrestler Dialogue
The wrestlers in Black Velvetopia originally had additional dialogue in their intros, but it was cut. While the sound files are gone, the lines are still noted in the scripts.
Dialogue used in the game, provided for context, is shown in bold.
Speaker | Line |
---|---|
Raz | Alright, I get it. Just shut up and let's go. |
Tiger | Perhaps Wee Lord Puny would like to make me shut up? |
Raz | I'm - |
Tiger | It occurs to me that I'd like to see someone so tiny make me shut up. |
Raz | Well - |
Tiger | Honestly, you and what Lilliputian army could even - |
Raz | Look, if you'd shut up for a second, I'm gonna start the making you shut up phase. |
Tiger | Then I will shut up, but only so I can enjoy the microscopic spectacle of your attempts to make me shut up. |
Raz | Fine. |
Tiger | Yes, it is fine. |
Speaker | Line |
---|---|
Dragon | That's sulfur. It's part of the dragon costume. |
Raz | Oh man. |
Dragon | Enjoy it while you can, kid. The next odor you smell is gonna be all FEAR! |
Raz | Whatever you say, stinky. Let's get this over with. |
Speaker | Line |
---|---|
Cobra | Well since you'd have to break my concentration to even touch me, and since you can't break my concentration, I guess you won't be too disappointed then. |
Raz | Alright, jerk, we'll see who loses focus first. |
Cobra | Hey look Smeglee - a girl! Why don't you curl up and have yourself a good cry? |
On a related note, while Eagle's intro doesn't have any unused lines, there is a commented out line of code at the top of his intro script which would have Raz play the animation BVDI013RA. The comment next to this line says that the animation "Doesn't exist!", though the animation does exist, and is used for the line of dialogue where Raz gets punched in the head, meaning this comment is probably from an older iteration of the scene.
Lungfishopolis
Original Kochamara fight
Tons of unfinished code scattered around Lungfishopolis' script files reveals that the Kochamara fight was originally a much more complex puzzle sequence rather than a direct fight. The code is clearly WIP and some parts of it are missing, making certain details unclear, but much of the fight's progression can be gleamed from what remains.
This early iteration is split into various steps. To begin, progress on Kochamara Island would be prevented by a series of barriers. A zealot would be present to hack them to allow you to progress, however an orbital laser satellite would also be active and attempting to fire on the zealot. To prevent the laser from killing the zealot you would have needed to use the scrapped PSI poppers (specifically, shield poppers) to protect him from the laser when it is about to fire. After a certain point (the exact circumstances are unclear due to the incomplete and partial nature of the code) the player would gain control of the satellite (it would target what the player is looking at, with a special HUD and all used to display its current target and how close it is to firing). The final objective in this part of the sequence is using the laser to destroy a battery that is powering a final shield wall. After that's done, you would be able to progress to the confrontation with Kochamara himself.
The Kochamara fight was different to the final version in that it would involve using the satellite on him. He can be damaged 3 times using the satellite before the next phase begins.
In the next and final phase, Kochamara wisens up and begins shielding himself when the satellite attempts to fire on him, making it impossible to hit him with it. However, at the start of this phase a zealot dressed as a bunny would spawn (unfortunately the script class for this NPC is missing, so its exact behaviour cannot be determined). The bunny zealot would be targetable using the satellite and this would open the way to defeating Kochamara once and for all. By trying to shoot the bunny zealot with the satellite instead of Kochamara himself, Kochamara will rush to float above the bunny at the last second and take the hit for it, finally defeating him.
Meat Circus
Unused Butcher Attack
The butcher has a somewhat unusual unused attack where he brings his right hand cleaver down near Raz and then scrapes it along the ground in a sweeping motion a single time. The attack is incredibly unfinished and even once all the associated code is uncommented, the cleaver isn't able to do a great deal of pushing things around as it seems to have been intended to do (at most, it'll move the object slightly before the object warps behind the cleaver). In additional, the sounds the cleaver calls on result in the butcher making censor sounds, as he doesn't have the appropriate overrides set.
The attack is unusual because it's not clear what it was intended to do beyond pushing things and the nature of it hardly seems like it'd have made sense for it to do damage. The move is derived from his overhead swing attack and the code to decide when he should perform it is exactly the same, making it difficult to gauge its purpose. However, it's possible that it was intended for phase 3 of the fight where Raz's dad throws flaming clubs. It seems like the butcher may have been intended to use this "attack" to scrape the clubs out of the way and make it more difficult to reach them (and potentially dragging them into Raz). Indeed, at certain angles the attack is capable of pushing the clubs around slightly.
Unused Global Entities
Emotional Roadblock
Some simple, unfinished code for the scrapped Emotional Roadblock enemy can be found, grouped with many other very old scripts. It doesn't seem like the roadblock was developed very far before being cut.
It has 5 states: WHIMPER, BURNING, DAMAGE, DEATH and BLOCKING
BURNING, DAMAGE and DEATH are, as expected, generic functions for handling those events.
Its default state is the whimper state. It stays in this state so long as Raz is more than 1500 units away, or invisible (it seems intended to also ignore Raz if he's moving slowly, but the code for checking this seems to be incorrect). Once Raz is less than 1500 units away, it enters a the "BLOCKING" state.
The blocking state doesn't seem to do anything unique (besides likely having a different animation) other than checking Raz's distance so that it can switch out of the blocking state once he's out of range. The game does have a second check to see if Raz is less than 1000 units away, but if it passes, it just sets the roadblock into the blocking state again. It's likely that another state was intended to go there that was never created and given that the variable used to set this range is called "saferange", it's possible that the roadblock would've started attacking once the player entered this range.
Finally, if interacted with, the roadblock prints "Get Away Little Boy!" and "Grrrr" to the log.
Besides this barebones behaviour, the only remaining notable thing about the entity is that it has a message handler for receiving a "Set" message, which causes it to print "Received BVLL Message that I'm SET". This is notable because BVLL is an early Black Velvetopia level that no longer exists, suggesting the roadblock played some specific role in that level at some point.
Psi-Poppers and the Psi-Popper Generator
Before being repurposed for the fast travel system, Oatmeal's model was originally use for "Psi-Popper generators" which would grant the player "Psi-Poppers". The code for both of these can be found in the February 2013 Steam build, and remains partially functional.
Psi-Poppers are inventory items that resemble balloons filled with a particular psychic power (or filled with nothing at all). They each have special effects when used and even allow the player to use powers that normally directly affect Raz (such as levitation) on other entities. They were likely also a predecessor to the confusion grenade.
Psi-Poppers would be obtained in mental worlds by stealing them from psi-popper generators. Two kinds of generator exist, one that grants empty poppers and one that grants poppers pre-filled with specific powers. They're identical in almost every way except visually as popper generators are intended to have have different textures based on the power they grant (though, only the texture for confusion generators in Black Velvetopia was completed).
Generators can only grant a set number of Psi-Poppers (by default, 1). After they hit the max, they go to sleep and can no longer be interacted with until one of the previously granted powers is used up, though the existing code has a bug where the popper will not notify the generators that it was used unless the popper was actually used on an object. Attempting to interact with a generator while it is asleep causes some voiceless dialogue from Raz to appear, first remarking on how the generator "looks beat" and then shouting at it to wake up. While not implemented, temporary voiceovers for these lines can be found in the soundbank for Black Velvetopia.
Each popper type has different effects:
Power | Effect | Intended Effect |
---|---|---|
None | Empty Psi Poppers do nothing when used. When held though, they can be filled up by using a PSI power. Strangely, only specific powers work. They can be filled with shield or pyrokinesis without issue, but attempting to fill them with levitation or telekinesis will play a failure sound and open the power quickswitch menu. Any other power does nothing and uses the power as normal. | |
Levitation | Attempts to launch most entities upwards. Has a unique interaction of lifting the Black Velvetopia bull into the air for a moment, and was also to be the intended method of saving the dancers in early versions of Milla's party. | Would have also caused damage to the target and nearby enemies when used on hostiles |
Telekinesis | Crashes the game | Would hold the target in place using the TK claw/hand for a while, interacting with the target while they are in this state would have TK'd them as normal. |
Invisibility | Makes the target see-through | |
Pyrokinesis | Doesn't appear to do anything, though there is code for it | AoE fire bomb |
Clairvoyance | Does nothing in release builds of the game, though is intended to display "Clairvoyance popper not implemented." in debug builds. Based on some older debug code, clairvoyance poppers were to appear in The Milkman Conspiracy as part of the keypad puzzle. | |
Confusion | Confuses the target, exactly like a confusion grenade | It seems that confusion was originally a targeted ability, and the mechanism of confusion poppers was likely repurposed into the final game's confusion grenades. |
Shield | Does nothing. Intended to have special interactions on certain entities in Lungfishopolis | Would have immobilised the target for a short time, but also made them invulnerable. |
Psi-Blast | Just makes a sound or crash the game | Would have launched a PSI-blast at the nearest enemy, from the landing point of the popper. |