Welcome, all! This release contains all the changes in the main branch of pygame/pygame from October through early February, mainly written by pygame-ce contributors, and of course all the pygame-ce progress in the past month!
Thank you to the community for all the support since the last release!
Because this contains so many months of changes, the release notes are quite long, so prepare yourself before reading further :).
What's Changed
Enhancements
* Starbuck5 and oddbookworm worked on features to make font rendering better than ever before!
- Multiline text! You can set a pixel limit and do automatic line wrapping, and you can align text left/right/center. Additionally, `Font.render` will respect explicit newlines in the text. https://github.com/pygame-community/pygame-ce/pull/1898
- Internationalization! We can now render non-latin alphabets much better with new `Font.set_script(...)` and `Font.set_direction(...)` methods. For example, to render Arabic, you'd load a font that supports Arabic, `Font.set_script("Arab")`, and `Font.set_direction(pygame.DIRECTION_RTL)`. https://github.com/pygame-community/pygame-ce/pull/1956, [upstream #3330](https://github.com/pygame/pygame/pull/3330)
* Matiiss added `pygame.mixer.music.get_metadata()` to potentially grab title/album/artist/copyright metadata from music files. https://github.com/pygame-community/pygame-ce/pull/8
* ScriptLineStudios added `transform.grayscale` and `Color.grayscale` (in case you're feeling gray). https://github.com/pygame-community/pygame-ce/pull/1907
* itzpr3d4t0r dug into the source to optimize overhead on `mouse.get_pos()`, `mouse.get_rel()`, `Rect.colliderect()`, `Rect.collidepoint()`, `Rect.collidelist()`, `Rect.collidelistall()`. These functions don't usually bottleneck people's code, but regardless, a 30-40% speedup on them is a cool thing to have. [upstream 3424](https://github.com/pygame/pygame/pull/3424), [upstream #3322](https://github.com/pygame/pygame/pull/3322), https://github.com/pygame-community/pygame-ce/pull/1832, https://github.com/pygame-community/pygame-ce/pull/1905
* PurityLake optimized blit mode code, achieving a 15-20% speedup while using blit blend modes for computers without AVX2 support. [upstream 3370](https://github.com/pygame/pygame/pull/3370)
* MightyJosip optimized pygame.draw.circle's with width (I saw a 300% performance boost in one case). [upstream 3550](https://github.com/pygame/pygame/pull/3550)
* itzpr3d4t0r added `Surface.fblits()`, which achieves faster speeds than `blits` by being slightly less flexible about input, as well as being highly optimized code itself. https://github.com/pygame-community/pygame-ce/pull/1831, https://github.com/pygame-community/pygame-ce/pull/1965
* Matiiss added `__round__()` method for pygame.Vector(2/3). [upstream 3559](https://github.com/pygame/pygame/pull/3559)
* avaxar implemented `pitch` argument for `pygame.image.frombuffer`, `pygame.image.from(string|bytes)`. https://github.com/pygame-community/pygame-ce/pull/1863
* Matiiss replaced an unclear hardcoded error message with the value of `SDL_GetError()`. [upstream 3641](https://github.com/pygame/pygame/pull/3641)
* yunline add `IS_CE` constant to test for running on pygame-ce, i.e. `if getattr(pygame, "IS_CE", False): print("Running pygame CE")`. https://github.com/pygame-community/pygame-ce/pull/1900
* yunline added a "window" attribute DROPFILE and DROPTEXT events. [upstream 3568](https://github.com/pygame/pygame/pull/3568)
* oddbookworm made every dependency version getter work the same way, and return linked version vs compiled version. [upstream 3379](https://github.com/pygame/pygame/pull/3379) and [upstream #3567](https://github.com/pygame/pygame/pull/3567)
* PurityLake added aliases to common objects. E.g. `pygame.Joystick(...)` instead of `pygame.joystick.Joystick(...)`, `pygame.Font(...)`, `pygame.Clock(...)`, `pygame.Event(...)`, `pygame.Channel(...)`. https://github.com/pygame-community/pygame-ce/pull/1854
* oddbookworm added a debug method to print out tons of pygame details. https://github.com/pygame-community/pygame-ce/pull/2
* avaxar implement `draw_triangle` and `draw_quad` in `pygame._sdl2`. https://github.com/pygame-community/pygame-ce/pull/1876
* MyreMylar added a way to premultiply a Surface's alpha, starting on a track towards optimized alpha blits via premultiplication. [upstream 3276](https://github.com/pygame/pygame/pull/3276)
Bugfixes
* ankith26 fixed the "MacOS font rendering bug" that shall live in infamy-- where MacOS < 12 macs couldn't render fonts at all. https://github.com/pygame-community/pygame-ce/pull/1922
* zoldalma999 made sure updating a Texture with a Surface takes into account pixel format. [upstream 3548](https://github.com/pygame/pygame/pull/3548)
* ankith26 fixed a regression where `camera.list_cameras()` would be empty on Linux. [upstream 3594](https://github.com/pygame/pygame/pull/3594)
* ankith26 fixed several memory leaks in the math module. [upstream 3590](https://github.com/pygame/pygame/pull/3590)
* oddbookworm fixed potential segfaults in `PixelArray`, `Surface`, `draw`, and `transform`. [upstream 3666](https://github.com/pygame/pygame/pull/3666), https://github.com/pygame-community/pygame-ce/pull/1940
* ankith26 fixed a bizarre bug where fast mouse scrolls would have a bogus `.button` attribute. [upstream 3642](https://github.com/pygame/pygame/pull/3642)
* yunline fixed reversed `Window.borderless` in the _sdl2 module. https://github.com/pygame-community/pygame-ce/pull/1869
* Temmie3754 ensured toggle_fullscreen works for maximized window. https://github.com/pygame-community/pygame-ce/pull/4
Deprecations, Potential Breaking Changes, and Removals
* Python 3.6 support has been dropped. Thanks yunline for implementing that in https://github.com/pygame-community/pygame-ce/pull/1896 and https://github.com/pygame-community/pygame-ce/pull/1936
* `pygame.display` "gamma" functionality has been deprecated as it has been removed in the upcoming SDL3. Thanks SSS-Says-Snek for implementing that in [upstream 3622](https://github.com/pygame/pygame/pull/3622)
* `pgScancodeWrapper` now raises `TypeError` when you attempt to iterate over it, since iterating it is a footgun. Thanks to PurityLake for implementing that in https://github.com/pygame-community/pygame-ce/pull/1855
Docs, Examples, and Types
* pgattic, winterhazel, CodeMaster7000, chimosky, and IlmastroStefanuzzo fixed typos and grammar mistakes. [upstream 3554](https://github.com/pygame/pygame/pull/3554), [upstream #3562](https://github.com/pygame/pygame/pull/3562), [upstream #3625](https://github.com/pygame/pygame/pull/3625), [upstream #3694](https://github.com/pygame/pygame/pull/3694), https://github.com/pygame-community/pygame-ce/pull/1879
* Matiiss and novialriptide polished up `PixelArray` and `math` docs. [upstream 3544](https://github.com/pygame/pygame/pull/3544), [upstream #3581](https://github.com/pygame/pygame/pull/3581), [upstream #3574](https://github.com/pygame/pygame/pull/3574).
* Linkid fixed several links in the docs. [upstream 3549](https://github.com/pygame/pygame/pull/3549)
* zoldalma999 documented `SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS`. [upstream 3546](https://github.com/pygame/pygame/pull/3546)
* Starbuck5 added a pygame quickstart section to docs front page. [upstream 3541](https://github.com/pygame/pygame/pull/3541)
* SmashedFrenzy16 updated README to replace a list with a table. [upstream 3638](https://github.com/pygame/pygame/pull/3638)
* novialriptide, yunline, PurityLake, and khiaxeng worked on enhancements throughout the docs. [upstream 3684](https://github.com/pygame/pygame/pull/3684), [upstream #3558](https://github.com/pygame/pygame/pull/3558), https://github.com/pygame-community/pygame-ce/pull/1916, https://github.com/pygame-community/pygame-ce/pull/1920, https://github.com/pygame-community/pygame-ce/pull/1964
* pycoinfu overhauled the "stars" example. https://github.com/pygame-community/pygame-ce/pull/1909
* ankith26, Matiiss, and yunline fixed typestub related errors in [upstream 3395](https://github.com/pygame/pygame/pull/3395), https://github.com/pygame-community/pygame-ce/pull/1885, https://github.com/pygame-community/pygame-ce/pull/1
Cleanups and Robustness
* yunline, MyreMylar, Koswu, and Starbuck5 removed unused and obsolete code from the codebase. https://github.com/pygame-community/pygame-ce/pull/1895, https://github.com/pygame-community/pygame-ce/pull/1904, [upstream #3563](https://github.com/pygame/pygame/pull/3563), [upstream #3553](https://github.com/pygame/pygame/pull/3553), [upstream #3618 ](https://github.com/pygame/pygame/pull/3618), [upstream #3617](https://github.com/pygame/pygame/pull/3617)
* ankith26 and Starbuck5 worked to make the SIMD code (low level code for blitting) simpler and emit better warnings. [upstream 3501](https://github.com/pygame/pygame/pull/3501), [upstream #3588](https://github.com/pygame/pygame/pull/3588)
* ankith26 worked to make the key compat table more robust. [upstream 3426](https://github.com/pygame/pygame/pull/3426)
* MyreMylar, Matiis, itzpr3d4t0r, Starbuck5, and TheVroum worked to simplify and spruce up code throughout the codebase. [upstream 3530](https://github.com/pygame/pygame/pull/3530), https://github.com/pygame-community/pygame-ce/pull/15, [upstream #3655](https://github.com/pygame/pygame/pull/3655), [upstream #3633](https://github.com/pygame/pygame/pull/3633), https://github.com/pygame-community/pygame-ce/pull/1938, [upstream #3577](https://github.com/pygame/pygame/pull/3577), [upstream #3620](https://github.com/pygame/pygame/pull/3620), [upstream #3595](https://github.com/pygame/pygame/pull/3595)
* avaxar changed `pygame.time` to use `SDL_GetTicks64` when possible, which stops `pygame.time` from having a 32 bit rollover ~days~ into program runtime. https://github.com/pygame-community/pygame-ce/pull/1873
Operations
* ankith26, MyreMylar, Starbuck5, yunline, and novialriptide all helped keep the CI running and up to date and passing, which is hugely important. Special kudos to ankith26 and MyreMylar for their amount of work on this. [upstream 3611](https://github.com/pygame/pygame/pull/3611), [upstream #3647](https://github.com/pygame/pygame/pull/3647), [upstream #3698](https://github.com/pygame/pygame/pull/3689), [upstream #3695](https://github.com/pygame/pygame/pull/3695), https://github.com/pygame-community/pygame-ce/pull/790, https://github.com/pygame-community/pygame-ce/pull/1838, https://github.com/pygame-community/pygame-ce/pull/1849, https://github.com/pygame-community/pygame-ce/pull/1852, https://github.com/pygame-community/pygame-ce/pull/1882, https://github.com/pygame-community/pygame-ce/pull/1888, https://github.com/pygame-community/pygame-ce/pull/1867, https://github.com/pygame-community/pygame-ce/pull/1891, https://github.com/pygame-community/pygame-ce/pull/1899, https://github.com/pygame-community/pygame-ce/pull/1901, https://github.com/pygame-community/pygame-ce/pull/1946
* cgohlke Fixed build errors on win_arm64. [upstream 3583](https://github.com/pygame/pygame/pull/3583)
* Starbuck5, oddbookworm, Mega-JC, Matiiss, gresm, and novialriptide all helped get pygame-ce set up as its own independent project. https://github.com/pygame-community/pygame-ce/pull/6, https://github.com/pygame-community/pygame-ce/pull/7, https://github.com/pygame-community/pygame-ce/pull/13, https://github.com/pygame-community/pygame-ce/pull/10, https://github.com/pygame-community/pygame-ce/pull/1921, https://github.com/pygame-community/pygame-ce/pull/1914, https://github.com/pygame-community/pygame-ce/pull/1858, https://github.com/pygame-community/pygame-ce/pull/1865, https://github.com/pygame-community/pygame-ce/pull/1871
* MyreMylar added a CODEOWNERS file to set up our review structure. https://github.com/pygame-community/pygame-ce/pull/14
* pmp-p continued work on improving pygame wasm CI, and making runtime behavior more optimal. [upstream 3593](https://github.com/pygame/pygame/pull/3593), https://github.com/pygame-community/pygame-ce/pull/1861, https://github.com/pygame-community/pygame-ce/pull/1948
* novialriptide renamed a folder, and Starbuck5 added a folder to the gitignore, https://github.com/pygame-community/pygame-ce/pull/1925, [upstream #3587](https://github.com/pygame/pygame/pull/3587)
* yunline added 'stubcheck' into setup.py. https://github.com/pygame-community/pygame-ce/pull/1866
* Ritikkhulbe, novialriptide, and oddbookworm made sure our README badges were in tip-top shape. https://github.com/pygame-community/pygame-ce/pull/1893, [upstream #3599](https://github.com/pygame/pygame/pull/3599), https://github.com/pygame-community/pygame-ce/pull/1880, https://github.com/pygame-community/pygame-ce/pull/1872
New Contributors
* pgattic made their first contribution [upstream in 3554](https://github.com/pygame/pygame/pull/3554)
* winterhazel made their first contribution [upstream in 3562](https://github.com/pygame/pygame/pull/3562)
* Koswu made their first contribution [upstream in 3563](https://github.com/pygame/pygame/pull/3563)
* yunline made their first contribution [upstream in 3568](https://github.com/pygame/pygame/pull/3568)
* CodeMaster7000 made their first contribution [upstream in 3625](https://github.com/pygame/pygame/pull/3625)
* SmashedFrenzy16 made their first contribution [upstream in 3638](https://github.com/pygame/pygame/pull/3638)
* TheVroum made their first contribution [upstream in 3595](https://github.com/pygame/pygame/pull/3595)
* chimosky made their first contribution [upstream in 3694](https://github.com/pygame/pygame/pull/3694)
* IlmastroStefanuzzo made their first contribution in https://github.com/pygame-community/pygame-ce/pull/1879
* Ritikkhulbe made their first contribution in https://github.com/pygame-community/pygame-ce/pull/1893
khiaxeng made their first contribution in https://github.com/pygame-community/pygame-ce/pull/1964
**Full Changelog**: https://github.com/pygame-community/pygame-ce/compare/2.1.3...2.1.4.dev2
And finally...
It is time to officially open contributor nominations for the Pygame Community Edition "Steering Council" who will guide the Community Edition of pygame for the next year. The steering council concept is modelled after the similar governance structure for Python itself, and the structure of other large, community driven, open source projects. You can read more about [the steering council here](https://github.com/pygame-community/pygame-ce/wiki/The-Steering-Council). If you are [an official contributor](https://github.com/orgs/pygame-community/teams/pygame-contributors/members) and want to nominate yourself for election then send an email to [danintheshedgmail.com](mailto:danintheshedgmail.com) and you'll be added to the candidates list.
Due to the small size of the electorate this year, nominations will be open only for a week from this release and then we will do the voting after that for a week, or until everyone has had a chance to vote. Voting will be done via the [Helios Voting](https://vote.heliosvoting.org/) platform.