Version 2.3



Version 2.3 is a major update to VVVVVV, starting development on January 10th, 2020, when the game's source code was released on GitHub. It was released on 31 August 2021.

Gameplay

 * An option to disable pausing when the game loses focus was added.
 * Music now pauses when the game loses focus.
 * An option was added to disable this feature.
 * Glitchrunner mode - a mode that reintroduces glitches used in speedrunning - was added.
 * Input delay was reduced from one frame to zero frames.
 * An option was added to revert this change, in case the player's muscle memory would be broken.
 * Time trial results and Game Complete learned to show the centiseconds of time taken.

Visual



 * The game now has an option to render at framerates higher than 30 frames per second.
 * A VSync option was added. It defaults to being on.
 * An option was added to give all text a black outline. This is off by default.
 * ACTION can now be used to skip the fake loading screen.
 * The fake loading screen can now be disabled.
 * An option to have a translucent room name was added.
 * If a custom level has a custom, the image will be used as the map in the level.
 * An in-game timer was added.
 * It is disabled by default.
 * now fades out after a few seconds.
 * The option to give terminals any sprite was added.
 * Automatic toggling of cursor visibility was added.

Custom Levels

 * The ability to left-click on script boxes to edit its associated script was added.
 * 7x7, 9x9, full-horizontal and full-vertical brush sizes were added.
 * Functionality for loading per-level custom assets from folders was added.
 * Functionality for loading levels from zip files was added.
 * Editor playtesting ghosts were added.
 * The Warp Zone gray tileset was added to the editor.
 * Space Station 1 tilecol -1 was added the editor.
 * The Lab rainbow background was added to the editor (available only if Direct Mode is enabled).
 * The ability to press G to go to a room in the editor was added.
 * One-ways were changed to recolor themselves to fit the current room's colors.
 * If custom graphics are in use,  is needed in the level file to re-enable recoloring.
 * It is now possible to press Shift+F1/F2/F3/W to cycle backwards tilesets, tileset colors, enemy types, and warp dirs (which are F1/F2/F3/W).
 * The option to press F9 in the editor to reload resources was added.
 * A menu option to open the levels folder was added to the levels menu.
 * It is disabled if unavailable (e.g. in Steam Big Picture mode).
 * The ability to select any song was added to the editor.
 * An option to select the previous song was added to the editor music screen.
 * The ability to access settings from the editor was added.
 * An option to delete quicksaves for custom levels was added.
 * An option to delete all custom level save data was added.
 * The ability to use  and   colors in   boxes was added.

Scripting

 * The  command was added to let player levels control audio pausing when the game loses focus.
 * It can be used by doing either  or.
 * The  command was changed to act on the player, and to unflip crewmates.
 * The  command was changed to work in custom levels.
 * It is also automatically saved to quicksaves.

Technical

 * Support for symbolic links was added.
 * Support for Unicode text was added.
 * Instead of failing silently (or even crashing the game), several error screens were added. This includes attempting to load a level that doesn't exist, saving a level to a location that cannot be saved to,  missing, etc.
 * The Linux and macOS binary names were changed to simply be . Additionally, you no longer need to run the game specifically from the directory containing the directory containing the binary, on Linux and macOS.
 * Several command-line arguments were added.
 * The option to specify the base user directory with the  flag was added.
 * The option to specify the  location with the   flag was added.
 * The option to directly launch a level with the  flag was added. If the filename   is passed, the game will read the level from standard input.
 * The option to pass in  to select assets to use was added. This would be useful if a level is passed in through standard input, as otherwise the game wouldn't know which assets to load.
 * The flags,  ,  , and   were added to set the player's X, Y, room X, and room Y.
 * The flag  was added to set the player's gravity.
 * The flag  was added to specify the music which the level should start with.
 * XML forwards compatibility was added.

General

 * The ability to press N to mute only music (as opposed to all game audio including sound effects) was added.
 * An option was added to separate the bind for opening the map from the bind for interaction.
 * It is off by default.
 * The graphics option to resize the window to the nearest multiple of 320x240 ("resize to nearest") was added.
 * The ability to press ESC to return to the previous menu was added.
 * In-game music and sound volume sliders were added.
 * A  icon file was embedded into   on Windows.

Gameplay

 * Pressing R was changed such that it does not kill the player in No Death Mode.
 * Targets (question marks on the minimap) are now guaranteed to be saved to save files when unlocked after completing Space Station 1. Else, a player could unlock them, but not talk to Violet, quit and load the game again, and have their targets be gone.
 * It is now always possible to bring up the pause/map screens and press R during cutscenes, in case the player gets softlocked.
 * Vertically-moving platforms were fixed to give the player two frames of edge-flipping, instead of only one (due to an oversight).
 * Flip tokens and  were counted towards the total number of player flips.

Visual



 * The elephant was changed such that it will not flash if screen effects are disabled.
 * Tile animations in The Final Level were changed such that they will be disabled if screen effects are disabled.
 * While the texture is static, the colors will still change.
 * The hardest room displayed in the ending sequence was changed to use the room's hidden name if it's blank.
 * As an example, if the hardest room is in the Overworld, the text will read  instead of being blank.
 * All rooms are automatically marked as explored when the Secret Lab is entered through the epilogue cutscene.
 * Previously they would only be explored if the Secret Lab was entered through the main menu.
 * All rooms in the Secret Lab (including the Super Gravitron) were given hidden names (names that show up on the map screen).

Custom Levels

 * The trinket and custom level crewmate limits were raised to 100.
 * Word forms of numbers (used in the trinket and custom level crewmate collection dialogues) from Fifty One to One Hundred were added.
 * Additionally, trinket and custom level crewmate collect statuses above ID 19 were changed to now be reset properly when exiting to the menu.
 * The max width and height was removed from all tilesheets.
 * Because of this, tilesheet sizes are no longer assumed in the Direct Mode tile tray.
 * The ability to roll credits while in the editor was removed.
 * Trinkets and crewmates in custom levels were changed such that they will only be counted if they are in-bounds.
 * Loading of the level list was optimized.
 * Enemies, platforms and conveyors in Warp Zone gray tileset were changed to appear gray.
 * Locked gravity/warp lines are no longer reverted when the room is loaded in the editor.
 * Parsing of all 128 music file headers was added (for both  and  ).
 * The (buggy) check which prevented having both warp lines and a warping background in a room in the editor was removed.
 * Duplicate player entities were fixed to be destroyed when returning to the menu.
 * Custom level stats were no longer limited to 199 level stats at a time.
 * Supercrewmates now collide with more entities.

Scripting

 * and  were fixed.
 * was changed to expose its last four arguments for scripting.
 * They default to 0, 0, 320 and 240.

Technical

 * The game was upgraded to SDL 2.0.16.
 * All settings were moved to.
 * For backwards compatibility with previous versions, settings are still duplicated in  in case the player were to change some settings in 2.3 and then go back to playing 2.2.
 * The game was changed to use TinyXML-2.
 * Gravitron RNG was changed to be deterministic regardless of screen effects.
 * Official binaries for 32-bit Linux and macOS were abandoned. Users will need to compile from source if they want such binaries.
 * This is technically not a change with VVVVVV per se, but due to an upgraded SDL_mixer version, loop points were made to now work in music (via  and  /  metadata tags).

General

 * The next/previous page options in the level list were changed such that they do not appear if there is only one page.
 * The menu layout was completely changed.
 * The ability to press F11 to toggle fullscreen was added.
 * On macOS, the ability to use RCommand+Enter/F alongside Command+Enter/F to toggle fullscreen was added.
 * The ability to press ESC to go to the quit menu from the teleporter menu or Super Gravitron quit menu was added.
 * The Super Gravitron quit menu was fixed to be able to be brought up immediately upon entering the Super Gravitron, without having to wait for  to show up.
 * The ability to access the options from the escape menu was added.
 * Flip Mode was made always accessible in Make & Play.
 * Flip Mode was made accessible in the in-game options menu if available.

Fixes
Due to 2.3 having so many changes, there are quite a lot of fixes that are not mentioned here. If you see one missing, please contribute.

Gameplay

 * The teleporter prompt no longer disappears when dying.
 * The Prize for the Reckless quicksand fix kludge now only happens in the correct room, and not in Boldly To Go, or custom levels.
 * Tower respawning is now less buggy.
 * The player spawning in is no longer offset by two pixels.
 * Starting from a checkpoint in the editor now spawns Viridian in the correct location.
 * Platforms, conveyors, and teleporters will no longer be rendered weird if they go above or to the left of the screen.
 * Gravitron squares were made to still move offscreen on death even after the Gravitron ended. Otherwise, the player could keep continuously dying in a Gravitron square after the Gravitron finishes (archive).
 * Quitting to the menu was fixed to no longer be interruptible, unless glitchrunner mode is re-enabled.
 * Quitting to the menu was fixed to be faster (regardless of glitchrunner mode).
 * The clock no longer ticks up when the game is in an unfocus pause (it would tick up, but about 3 times slower, when paused).
 * The clock no longer ticks up while a time trial countdown happens, which made it possible to play the cry sound effect every frame if the time ticked up past the par during the countdown (via pausing the game).
 * Clipping inside a wall inside towers (which is possible without hacks or invincibility) no longer kills the player (previously, it killed the player even if they were invincible!).
 * Tower spikes are now solid in invincibility mode, consistent with all other spikes being solid.
 * The tower camera in invincibility was made more smooth when pushed around, and can now be moved downwards in ascending towers. Here is a demonstration video (archive).
 * In the main game, music per area was made more solid (via an area map) and it is no longer possible to mismatch music with the area.
 * Rescuing Violet was fixed to not reset crewmate progress (which would lead to an unwinnable save).
 * Rescuing Violet last was fixed to lead to the Final Level, instead of canceling the sequence (which would lead to an unwinnable save).
 * It is no longer possible to softlock from touching trinkets or crewmates on the same frame as a script box with a text box in it.
 * It is no longer possible to softlock by using a teleporter and teleporting to another teleporter, while inside the teleporter hitbox, after returning from rescuing a crewmate or an intermission.
 * It is no longer possible to softlock by being stuck on a text box waiting for an ACTION press without having a  prompt.
 * General anti-softlock measures were added. The game is guaranteed to return player control if there is no script or gamestate running.
 * It is no longer possible to go into an infinite loop (which would require force-killing the game) by opening a teleporter with only one teleporter unlocked and then pressing left or right.

Visual



 * Translucent pixels of tiles drawn outside towers were fixed to be drawn correctly.
 * A wrong tile in the top-left of Do Try To Keep Up was fixed.
 * Entities are now drawn in the same order as the rest of the game in towers and in the editor (backwards according to entity index).
 * Entities warping in Flip Mode are no longer discolored.
 * Crewmate-found text boxes no longer overlap each other in Flip Mode.
 * The menu in Flip Mode was changed to display upside-down.
 * If the player finishes a time trial in 1 minute, it is now displayed as  instead of.
 * There's no longer a seam when entering a new room with a horizontal or vertical warp background.
 * The screen now renders screen effects in towers.
 * The map now renders screen effects (shaking, flashing etc.).
 * Bringing the menu up in towers no longer brings it up against the wrong background.
 * The capitalization of all songs were made consistent.
 * "Passion for exploring" or "Passion For Exploring" -> "Passion for Exploring"
 * "Pushing onwards" -> "Pushing Onwards"
 * "Positive force" -> "Positive Force"
 * "Potential for anything" or "Potential For Anything" -> "Potential for Anything"
 * "Predestined fate" -> "Predestined Fate"
 * "ecrof evitisoP" -> "ecroF evitisoP"
 * "Piercing The Sky" -> "Piercing the Sky"
 * "Warpzone" was corrected to "Warp Zone".
 * "Exausted?" was corrected to "Exhausted?".
 * "You can unlock each time trial seperately" was corrected to "You can unlock each time trial separately". ("seperately" was misspelled.)
 * "seperate" at the end of the epilogue cutscene was corrected to "separate".
 * "Rebind your controllers buttons and sensitivity" was missing an apostrophe, and was corrected to "Rebind your controller's buttons and sensitivity".
 * The Viridian squeaks played when pressing ACTION in menus were made consistent across all menus.
 * The final stretch color cycling no longer gets faster after you enter a tower.
 * Disappearing platform animations during final stretch are no longer glitchy if they disappear while the room color changes.
 * Pushing the tower camera with invincibility mode no longer smears the background.
 * Quitting to the menu at the right time in a tower no longer mismatches the title screen text and background colors.
 * Entities creating during a complete stop will no longer have their sprite offset set to 0 (making all sprites look like the player and all platforms be invisible).
 * Translucent pixels in the font were fixed to not keep being drawn on top of themselves on the map screen.
 * The right-side corners of the menu bar on the map screen were fixed to not be visible if the corners had custom textures.

Custom Levels

 * Custom levels can no longer modify or overwrite main game telesaves, quicksaves, or highest scores, or unlock any game modes or achievements.
 * It is no longer possible to lower a two-star custom level score by replaying it but beating it without full trinket completion.
 * The hardcoded all-sides warp in (19,8) no longer happens.
 * The Prize for the Reckless moving platform kludge no longer happens in custom levels.
 * Enemy type room properties in the editor are now reset when creating a new level.
 * The Make & Play edition no longer contained room data for the Final Level, Lab, Overworld, or Tower in its binary.
 * Enemy movement types 10 and 12 no longer cause memory leaks when spawned as either a custom enemy ( entry 56), or spawned outside of the rooms they spawn in in the main game.
 * The hardcoded no-follow rule of scripting crewmates in (10,5) was removed in custom levels.
 * You can no longer make zero lines in the script editor.
 * Activating and loading scripts no longer causes undefined behavior.
 * Moving platforms warping no longer causes a memory leak.
 * The game no longer attempts to spawn main game crewmates/activity zones (which would happen if you used ) in custom levels.
 * You can no longer destroy the main player entity. Duplicate player entities can be destroyed by using  on them, and entering a different room (or reloading the current one).
 * Direct Mode is now reset correctly when making a new level.
 * The two-frame-delay when entering a room with an "init" script was fixed.
 * The possibility for crewmates to be cyan when initially placed was re-added. (It previously was not possible due to an oversight.)
 * The bug where enemy and platform bounds wouldn't be drawn in the editor if any one of their bounds touched a screen edge was fixed.

Scripting

 * The script editor no longer lets you type on a non-existent last line.
 * Pressing M to mute no longer happens in the script editor.
 * The process of removing lines in the script editor was changed to be non-instanteous.
 * Prior to this change, pressing backspace to remove a line would have no cooldown, possibly leading to a line being removed every frame.
 * Typing pipes (line separator character) was disabled in the script editor.
 * Closing a script with any lines ending in a colon (thus inadvertently creating a new script) was fixed by putting a space after each offending colon when closing said script.
 * now sets the right background regardless of which tileset is in use.
 * warp lines now work even without a placed warp line already present.
 * ing to the same room no longer restarts the horizontal/vertical warp background animation.
 * Centering text with x=-1 was fixed. Prior to this, it would center the textbox based on the first line alone.
 * Warp directions set with  are now reset when exiting playtesting.
 * size is now reset properly upon death and exiting to menu, unless glitchrunner mode is enabled.
 * no longer ignores the height of the textbox.
 * It is no longer possible to get in an infinite loop in the scripting system (which would require force-killing the game).

Technical

 * and  are now reset properly.
 * Superfluous whitespace in entity XML data in level files was removed.
 * The game no longer attempts to position cyan text boxes above horizontal warp lines.
 * A bug with Windows usernames containing Unicode was fixed.

General

 * The Alt+Enter Glitch is fixed, but can be re-enabled with glitchrunner mode.
 * Pressing ESC now works better in roomtext/script text input.
 * In the main game, songs 0 and 7 no longer loop and fade if you're using PPPPPP while  is present.
 * Holding X or Z while spikes are selected no longer increases the size of the eraser when using the spike tool.
 * Stats are now saved immediately when a new Super Gravitron record is set, or a new highest main game trinket count is set.
 * Additionally, the game was changed to always save your stats and settings upon closing the game (e.g. pressing Alt+F4), even if not closed by using the "quit game" option on the title screen.
 * Ethan Lee (the developer who worked on 2.2 and wasn't credited) was added to credits.
 * Various typos, memory leaks and less-important bugs have been fixed.

Undefined Behavior Fixes
All undefined behaviors have been fixed. This is a list of undefined behaviors in previous versions that no longer exist in 2.3.

Uninitialized memory

 * Playing music for the first time (i.e. pressing ACTION on title screen) reads from uninitialized memory.
 * Basically... you weren't able to even launch the game without causing undefined behavior!
 * Processing music reads from uninitialized memory until a 'nice fade' is queued.
 * Checking for collision for the first time reads from uninitialized memory (twice).
 * Drawing entities for the first time reads from uninitialized memory.
 * Saving the game reads from uninitialized memory until a 'nice fade' is queued.
 * Loading a quicksave inside a tower without ever having respawned in a tower before in the game process reads a variable from uninitialized memory.
 * This variable controls how long the game will wait before moving the camera, and if it's an absurdly high value, this results in the tower quicksave (semi-) softlock bug.
 * An internal function named  would return uninitialized memory if given an empty string, and it is used for parsing numerical script arguments; thus using a script command that has an argument that expects numbers and either leaving it out and having a blank previous argument or explicitly setting it blank (by adding argument separators) will result in reading from uninitialized memory.
 * An example is level makers using  with only 2 arguments instead of 3, which caused undefined behavior if you were unlucky (depending on which scripts the player executed) and was just unpredictable in general.
 * Calling  always reads from uninitialized memory.

Out-of-bounds indexing
The game was originally ported from the original ActionScript in the Flash 1.x versions. Ported, not rewritten. Thus previous versions shared many (poor) ActionScript coding standards (namely indexing an array in ActionScript grows it), which resulted in all these arbitrary limits. Going past them would result in undefined behavior (out-of-bounds indexing).


 * Creating a text box with more than 10 lines (this despite the simplified /  taking in a maximum of 50 lines).
 * Separate from the above, making a  box that takes in more than 40 lines.
 * Having 30 consecutive or concurrent text boxes.
 * Having a script line (simplified or internal) with more than 40 parameters (the command counts as one parameter).
 * Entering a room in a custom level with more than 50 script boxes.
 * Entering a room in a custom level with more than 100 room text.
 * Having more than 200 entities existing at once.
 * Having more than 500 blocks existing at once.
 * Running a custom script through the simplified-to-internal parser that outputs more than 500 internal lines.
 * Opening a custom script with more than 500 lines in the script editor.
 * Loading a custom level with more than 500 scripts.
 * Even loading a custom level with exactly 500 scripts.
 * Loading a custom level with more than 3000 placed entities.
 * Calling,  ,  ,  , or   with an X or Y which, after both are combined to a room index, is less than 0 or greater than 399.
 * Calling  with a trinket index less than 0 or greater than 99.
 * Creating a trinket, coin, or crewmate with an ID less than 0 or greater than 99.
 * And collecting a trinket, coin, or crewmate with an ID less than 0 or greater than 99.
 * Calling  or   with a flag number less than 0 or greater than 99.
 * Surprisingly enough,  actually did have a bounds check, and could never commit undefined behavior.
 * Calling  with a number less than 0, if you don't have an , or if you do have an   but have your soundtrack switched to MMMMMM.
 * Calling  with a number less than 0 or greater than 27.
 * Drawing a  or   tile number less than 0 or greater than 1199 (can be done in custom levels by entering a room containing such a tile number).
 * Drawing a  tile number less than 0 or greater than 899.
 * Drawing an  tile less than 0 or greater than 719 (can be done by placing a checkpoint on a disappearing platform right above some spikes, then spawning on the checkpoint and keeping dying on the spikes, and letting the tile in the platform increment until the game crashes, which can take several minutes or half a minute depending on which tileset and tilecol your room is).
 * Drawing a sprite with a sprite number less than 0 or greater than 191.
 * Loading any custom level file (because the XML buffer is not null-terminated).
 * Because of this, even merely loading the levels list results in out-of-bounds indexing.
 * On top of that, starting a custom level from the beginning also commits out-of-bounds indexing when finding the start point.
 * The start point is still unnecessarily searched for when loading a quicksave, so loading a quicksave still commits out-of-bounds indexing...
 * Only starting a level from the editor doesn't do this.
 * Left-clicking in the editor at all.
 * Pressing backspace with no custom scripts in the script list.
 * Having any blank lines in any script in a loaded custom level will cause out-of-bounds indexing, in one case after unloading said level (by loading any level), and in another after loading a script with such a blank line.
 * Dying in Outside Dimension VVVVVV in a room that's outside the array that keeps track of your room deaths in Outside Dimension VVVVVV.
 * Speedrunners have ran into the effects of this many times... (archive 1, 2, 3).
 * Having no player entity existing (can be done by doing the Gravitron fling glitch).
 * Having no teleporter existing when the game expects it to.
 * Having no companion existing when the game expects it to.
 * Loading a level with a map size less than 1x1 or greater than 20x20. The undefined behaviors here would happen basically everywhere.

Version 2.3.1
This was a bug fix update released on 1 September 2021 fixing some issues found after 2.3's launch.


 * VSync was made now enabled by default when starting 2.3 for the first time
 * Fixed not-Flip-Mode flag turning off when returning from options menu
 * Minor fixes were done for the official build systems

Trivia

 * On 30 March 21, a beta based on intermediate commits of 2.3 was released on Steam, and was updated periodically as 2.3 development continued.
 * Version 2.3 is the first major version to be released in 7 years, where 2.2 was released on 11 June 2014.
 * Version 2.3 is the first version to have its source public, with most changes being made by contributors on GitHub.
 * Info Teddy has contributed the most to Version 2.3, at a total commit count of 1,472 commits on 31 August 2021.
 * Due to doing most of the work, she was compensated by Terry.