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.

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.
 * A scripting command was added to allow level creators to control this option, with.
 * 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.

Visual

 * The game now has an option to render at framerates higher than 30 frames per second.
 * 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 roomname 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 option to left-click on script boxes to edit the 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.
 * The option 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 to cycle backwards tilesets, tileset colors and enemy types (which are F1/F2/F3).
 * The option to press F9 in the editor to reload resources was added.
 * A menu option to open a level folder was added to the levels menu.
 * It is disabled if unavailable (e.g. in Steam Big Picture mode).
 * Space Station 1 tilecol -1 was added the editor.
 * 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.

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.
 * The rebind slot for opening the map was separated from the slot for interacting.
 * 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.

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.

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 menu in flip mode was changed to display upside-down.
 * 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.

Custom Levels

 * The trinket and crewmate limits were raised to 100.
 * Collectable slots were changed to reset when returning to the menu.
 * The max width and height was removed from sheets.
 * 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.
 * The option for crewmates to be cyan when initially placed was added.
 * Enemies, platforms and conveyors in Warp Zone gray tileset were changed to appear gray.
 * Locked gravity/warp lines were change to be respected rather than reverted when the room is loaded in the editor.
 * Parsing of all music file headers was added.
 * The (buggy) check which prevented both warp lines and the backgrounds in the editor was removed.
 * Duplicate player entities were fixed to be destroyed when returning to the menu.

Scripting

 * 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.
 * and  were fixed.
 * Typing of pipes was disabled in the script editor.
 * was changed to expose its last four arguments for scripting.
 * They default to 0, 0, 320 and 240.

Technical

 * All settings were moved to.
 * The game was changed to use TinyXML-2.
 * Support for 32-bit Linux was abandoned.

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.
 * Stats are now saved immediately when a new super gravitron record is set.
 * The option to press F11 to toggle fullscreen was added.
 * Presing Alt+F4 was changed to save the current settings.
 * The option to press ESC to go to the quit menu from the teleporter menu was added.
 * The ability to access the options from the escape menu was added.

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 custom levels.
 * Tower respawning is now less buggy.
 * Quicksaving in towers was fixed for all operating systems.
 * 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.
 * 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 have been added in. The game is guaranteed to return player control if there is no script or gamestate running.

Visual

 * The capitalization of some songs have been fixed.
 * Editor entities are now drawn according to in-game order.
 * Transparent pixels are now drawn as you'd expect.
 * "Warpzone" was changed to "Warp Zone".
 * A wrong tile in the top-left of Do Try To Keep Up was fixed.
 * Entities are now drawn backwards in towers (to match with the rest of the game).
 * Entities warping in flip mode is no longer discolored.
 * Crewmate-found textboxes no longer overlap each other in flip mode.
 * 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.

Custom Levels

 * Custom levels can no longer modify or overwrite main game telesaves, quicksaves, or highest scores, or unlock any game modes or achievements.
 * You can no longer lower your custom level score by replaying it.
 * The hardcoded all-sides warp in (19,8) no longer happens.
 * The Prize for the Reckless quicksand fix kludge no longer happens in custom levels.
 * 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.
 * M&P no longer has the final level/lab/overworld/tower room data.
 * Enemy movement types 10 and 12 no longer cause memory leaks when spawned as either a custom enemy (createentity 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.

Scripting

 * The script editor no longer lets you type on the non-existent last line.
 * Pressing M to mute no longer happens in the script editor.
 * now sets the right background regardless of which tileset is in use.
 * warp lines now work even without an edentity 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.

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 textboxes above horizontal warp lines.

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.
 * 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.

Trivia

 * On 30 March 21, a beta based on intermediate commits of 2.3 was released on Steam, and has been updated periodically as 2.3 development continues. It can be enabled by going to Game Properties -> Betas, then selecting.
 * 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,444 commits at August 20th, 2021.
 * Due to doing most of the work, she was compensated by Terry for her work.