Version 2.3

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

Gameplay

 * You can disable the game pausing on unfocus.
 * The music now pauses when you unfocus the game. An option was added to let you revert this.
 * A scripting command was added to allow level creators to control this option, with.
 * Glitchrunner mode, a mode which un-fixes glitches used in speedrunning, has been added.
 * There's no longer one frame of input delay, however this can be changed back.

Visual

 * The game now has an option to render at higher framerates than 30fps.
 * There's now an option to give all text a black outline. This is off by default.
 * You can now press ACTION to skip the fake loading screen.
 * The fake loading screen can now be toggled.
 * There's now an option to have a translucent roomname.
 * If your custom level has a custom minimap.png, it'll be used as the map in your level.
 * There is now an in-game timer, which is off by default.
 * now fades out after a few seconds.
 * Terminals can now have any sprite.
 * Cursor visibility is now automatically toggled.

Custom Levels

 * You can now left-click on script boxes to change their script.
 * There are now 7x7, 9x9, full horizontal and vertical brush sizes.
 * The game now loads per-level custom assets from folders.
 * The game now loads levels from zip files.
 * Editor playtesting ghosts were added.
 * You can now use the Warp Zone gray tileset in the editor.
 * You can press G to go to a room in the editor.
 * One-ways are now recolored to fit the rooms' colors.
 * If you're using custom graphics, you need  in the level file in order to re-enable it.
 * Shift+F1/F2/F3 now exist which let you cycle backwards for tilesets, tileset colors and enemy types (F1/F2/F3) respectively.
 * In the level editor, pressing F9 reloads resources.
 * There's now an open level folder menu option in the play levels menu.
 * Space station 1 tilecol -1 can be used in the editor.
 * You can now select any song in the editor.
 * There's now a previous song option to editor music screen.
 * You can now access options from the editor.
 * There is now an option to delete quicksaves for custom levels.
 * You can now delete all custom level save data.

Scripting

 * The  command has been added to let player levels control audio pausing when you unfocus the game.
 * now functions on the player, and can unflip crewmates.
 * works in custom levels, and is automatically saved to quicksaves.

Technical

 * Symlinks are now supported.
 * Unicode text is now supported.
 * Instead of failing silently (or crashing the game), lots of error screens have been added. This includes attempting to load a level that doesn't exist, saving a level you can't save to, data.zip missing, etc.
 * Lots of command line arguments were added.
 * You can now specify the base user directory with the  flag.
 * You can now specify your data.zip with the  flag.
 * You can now directly launch a level with the  flag. If you input , the game will read the level from standard input.   can be used instead of.
 * You can pass in  to select which assets you would like to play with.
 * ,,  , and   are to set the player's X, Y, room X and room Y.
 * is the player's gravity.
 * lets you specify the music which the level should start with.
 * XML forwards compatibility has been added.

General

 * Pressing N now mutes the music only.
 * Pressing enter to open map and enter to interact are now separated. By default, it's the same behavior unless configured otherwise.
 * Resize to nearest graphics option added.
 * You can now press ESC to return to the previous menu.
 * In-game music and sound volume sliders have been added.
 * A previous page option has been added to the levels list.

Gameplay

 * You can no longer press R in no death mode.
 * is now saved to main game save files.

Visual

 * The elephant is no longer flashy if screen effects are disabled.
 * In the final level, the tile animations are disabled if screen effects are disabled. The colors will still change.
 * The menu in flip mode is now upside-down.
 * The hardest room name is now Dimension VVVVVV if the roomname is blank.
 * If a roomname is empty and the room has a hiddenname, then it's used for the hardest room.
 * All rooms get explored when you enter the secret lab.

Custom Levels

 * The trinket and crewmate limits were raised to 100.
 * All collectable slots are now reset when returning to the menu.
 * Sheets no longer have a max width or height.
 * You can no longer roll the credits while in the editor.
 * Only inbounds trinkets and crewmates are counted in custom levels.
 * The level list loading has been optimized.
 * Crewmates can now be cyan when initially placed down.
 * Enemies, platforms and conveyors in Warp Zone gray tileset are now gray.
 * Locked gravity/warp lines are now respected and not immediately reverted when the room is loaded in the editor.
 * All music file headers are now parsed.
 * The check which prevents both warp lines and the bgs in the editor has been removed.
 * Duplicate player entities are now destroyed when returning to the menu.

Scripting

 * Removing lines in the script editor is no longer instant. Prior to this change, pressing backspace to remove a line would have no cooldown, possibly leading to a line being removed every frame.
 * and  now work.
 * You can no longer type pipes in the script editor.
 * now has its last four arguments exposed to scripting. They default to 0, 0, 320 and 240.
 * There's no longer a two-frame-delay when entering a room with an "init" script.

Technical

 * All settings have been moved to.
 * The game now uses TinyXML-2.

General

 * The next/previous page options in the level list are no longer shown if there's only one page.
 * The menu layout has been completely changed.
 * Your stats are now saved immediately when you set a new super gravitron record.
 * F11 (and RCommand+Enter/F on macOS) now toggle fullscreen.
 * Presing Alt+F4 now saves your settings.
 * You can now press ESC to go to the quit menu from the teleporter menu.
 * You can now access the options from the escape menu.

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 has been 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.
 * Softlock from touching trinkets or crewmates on the same frame as a script box with a text box in it no longer happens.
 * Moving platforms and teleporters will no longer be rendered weird if they go above or to the left of the screen.

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 has been 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 crewmates in flip mode.
 * Time trial results no longer displays 00:60 instead of 01:00.
 * 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 menu up in tower 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) has been 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.

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 has been 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 has been 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 from uninitialized memory.
 * This memory 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 off of 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 has been compensated by Terry for her work.