Merge branch 'PretendoNetwork:dev' into dev
171
blogposts/12-25-25.md
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
---
|
||||
title: "Christmas Progress Update"
|
||||
author: "Jon"
|
||||
author_image: "https://www.github.com/jonbarrow.png"
|
||||
date: "December 25, 2025"
|
||||
caption: "Internal changes, Juxtaposition, 3rd party servers and more"
|
||||
cover_image: "/assets/images/blogposts/december-25-2025/banner.png"
|
||||
---
|
||||
|
||||
These last few months saw a large focus on internal changes to our systems, internal gRPC services, and improvements to Juxtaposition, amongst others!
|
||||
|
||||
# Animal Crossing: New Leaf
|
||||
|
||||
As I’m sure you all remember, on July 24th of this year, we made the unfortunate announcement that we were taking our Animal Crossing: New Leaf servers offline, indefinitely. This was in direct response to reports of an RCE exploit being actively used in the game.
|
||||
|
||||
To reiterate, this is an exploit *within the game itself*. It was not caused by our servers, and in fact can be exploited when not online at all via local wireless play. Even still, we felt it best to take the servers down to limit the impact while we investigated.
|
||||
|
||||
After several months of testing, research, and talking with famous Animal Crossing content creator [Hunter R.](https://www.youtube.com/@Hunter-R.), a working patch for the exploit was made. Animal Crossing: New Leaf is back online for ALL users as of December 8th! We would like to thank everyone for their patience, and thank all of our testers for helping with the process.
|
||||
|
||||
For a deeper explanation of what the exploit is, how it worked, and how we are patching it, see [Hunter R.’s breakdown video on YouTube](https://youtu.be/pV0xnIsgGXE).
|
||||
|
||||
# Technical Updates
|
||||
|
||||
## Account Server
|
||||
|
||||
When logging into your account, the server issues 2 tokens:
|
||||
|
||||
1. A short lived access token
|
||||
2. A long lived refresh token
|
||||
|
||||
The access token is used by the console/games to identify your account with the account server, for reasons such as querying for user data, requesting additional tokens, etc. These tokens are short lived, forcing a client to reauthenticate after they expire. In order to skip the normal login flow, the client may send the refresh token to the server to "refresh" the login session, getting back a new set of access/refresh tokens.
|
||||
|
||||
One of the biggest long-standing bugs with our account server is that it issued "useless" refresh tokens, which were unable to actually refresh the session. This was because refresh tokens were expiring at the same time as the access tokens! Refresh tokens now properly expire and are actually usable.
|
||||
|
||||
At the same time, we also changed how service tokens are handled. A "service token" is a token issued by the account server for an "independent service". An "independent service" is essentially any server a game needs to operate which is not a game server written using the NEX library. These are most commonly used by 3rd parties to implement their own servers (RPG Maker FES, Colors! 3D, etc.) or to add supplementary servers that assist the main NEX game server (Super Mario Maker's bookmark site, Pokemon legality checking, etc.). These service tokens are requested using the accounts access token and provide developers a way to ensure a user passed the normal authentication checks to obtain the token, as well as a read-only way to interact with user data.
|
||||
|
||||
Initially, we treated service token expiration the same way we treated all token expiration. The token has an associated "expiration time" and, when used on the account server, it would validate that time, rejecting any tokens that had expired. However, this was later found to be inconsistent with how we observed some services operating. [Dani](https://github.com/DaniElectra) noticed some time ago that there are references to [local expiration on the 3DS](https://github.com/PretendoNetwork/juxtaposition/pull/114#issuecomment-2863503035). We also noticed that the request to WaraWara Plaza data seems to always use the same token, no matter how much time has passed. These 2 things, when combined, seem to indicate that service tokens, officially, either did not ever expire, or the expiration was ignored when the independent service validated the token with the account server, presumably allowing each independent service to decide how long a token should be "alive" for.
|
||||
|
||||
In light of these observations, we have now also changed our service token handling to be more accurate to the behaviour we observed. Rather than tracking an "expire time", service tokens now track an "issued time", allowing each independent service to pick the length of time a token should be valid for. This marks the first step in our larger plans for a total overhaul of how tokens/account data is processed.
|
||||
|
||||
## Account Deletion
|
||||
|
||||
Until recently, the only ways to delete your account were using a console or by requesting a deletion via our support forums. We have now updated our account server's internal gRPC service to allow for account deletion requests. This uses the same mechanism under the hood as used by the on-console “Delete Account” button, but now allows us to trigger an account deletion from anywhere we choose. This has allowed us to add a “Delete Account” button to both the website, for you to delete your own accounts without needing a console, and to our admin panel, for moderators to take immediate action in extreme cases.
|
||||
|
||||
Additionally, deleting your account will also automatically delete personal data from supported services, such as the forums and Juxtaposition.
|
||||
|
||||
***NOTE: DELETING YOUR ACCOUNT WILL NOT FREE YOUR USERNAME FOR REUSE. USERNAMES CAN NEVER BE USED AGAIN ONCE ASSIGNED TO AN ACCOUNT***
|
||||
|
||||
## BOSS (SpotPass)
|
||||
|
||||
BOSS is a system Nintendo provided to allow titles to request/store data (called objects) using background tasks. This is most commonly used for the SpotPass feature, but is also used to deliver data like system notifications, Splatoon rotations, etc. Over the past few months, we have been working on improving our BOSS server both in terms of developer usability and its general operations. The BOSS server received several upgrades to both how we store and process SpotPass files, our internal gRPC service for managing files, as well as improving our data storage and transport systems. All of these combined should provide a much better SpotPass experience for both users and our team, allowing us to more easily ship data like in-game content, console notifications, etc.
|
||||
|
||||
## gRPC
|
||||
|
||||
As mentioned in [Account Server](#account-server), we have begun making some updates to our internal [gRPC](https://grpc.io/) services. We use gRPC for [interprocess communication (IPC)](https://en.wikipedia.org/wiki/Inter-process_communication) as a way to communicate and request/send data between services as it is fast, lightweight, strongly typed, and allows services to be easily defined via [protocol buffers](https://protobuf.dev/). [Quarky](https://github.com/ashquarky) recently added the ability to [request device information](https://github.com/PretendoNetwork/grpc/pull/3) for devices linked to a user's account, and we have also begun adding a way to [exchange service tokens for account data](https://github.com/PretendoNetwork/grpc/pull/6). Additionally, we have also begun exploring a brand new [NEX gRPC service](https://github.com/PretendoNetwork/grpc/pull/5). This service would live inside game servers and allow us to interact with them more efficiently, for features such as:
|
||||
|
||||
- Moderation. Having a link to the game servers will allow us to kick existing clients from games in instances like account/device bans
|
||||
- Live notifications
|
||||
- Pulling server statistics like player counts, multiplayer match data, information about UGC, etc.
|
||||
|
||||
## Misc
|
||||
|
||||
These are some smaller changes compared to the ones above, but still deserve mentioning
|
||||
|
||||
- [Will](https://github.com/binaryoverload) upgraded our [BOSS server to Express 5](https://github.com/PretendoNetwork/BOSS/pull/22). While not a huge change by itself, Express 5 brings in many [new features and improvements](https://expressjs.com/en/guide/migrating-5.html) that we can take advantage of
|
||||
- [Dani](https://github.com/DaniElectra) has updated our documentation wiki both with [the latest upstream changes](https://github.com/PretendoNetwork/nintendo-wiki/pull/43), as well as [new additions to some older NEX protocols](https://github.com/PretendoNetwork/nintendo-wiki/pull/44)
|
||||
- The account server received some minor bug fixes. Those being a bug with the 6 digit email codes which would incorrectly block registration if a code was in use by another account already, as well as a bug where 3DS devices would not be properly linked to an account when using the NNAS service, and some updates to token validation
|
||||
- Various research into many games (including those not on the Wii U/3DS) continues to drive our understanding of these games forward, and continues to be documented on our wiki. We now have documentation for [several previously undocumented protocols](https://github.com/PretendoNetwork/nintendo-wiki/pull/52)
|
||||
- [JVS](https://github.com/mrjvs) made a new [SMTP relay server](https://github.com/PretendoNetwork/smtp-relay) that has been introduced for use on the forums. Our forums are powered by [Discourse](https://discourse.org/), which requires that *all* accounts have a unique email address. NNIDs, and subsequently PNIDs, do NOT require unique email addresses. As a workaround for this, every forum account is assigned a fake email address using each account's unique PID value. This lets us link PNIDs to the forum, but breaks email support. This new SMTP relay runs alongside the forum and maps the fake email address back to the account's real email address, allowing for email notifications to finally work on user accounts
|
||||
- Splatoon rotations are now fully automated. Previously, we were working with [OatmealDome](https://github.com/OatmealDome), who used his [Rotationator](https://github.com/OatmealDome/Rotationator) tool to generate our Splatoon rotations every few weeks, which we would then manually upload. Utilizing the new updates to the BOSS server, we were able to [fork OatmealDome’s tool](https://github.com/PretendoNetwork/Rotationator) and completely automate the process
|
||||
|
||||
# Juxtaposition
|
||||
|
||||
Juxtaposition has received a large focus over the past few months. Many hands touched these changes, thank you to [Jemma](https://github.com/CaramelKat), [Quarky](https://github.com/ashquarky), [jvs](https://github.com/mrjvs), and everyone else on the team, as well as all of our outside contributors! There are too many individual changes to list here, so only the biggest changes/PRs will be listed. To get a full breakdown of all the changes, please see the official [Juxtaposition GitHub repository](https://github.com/PretendoNetwork/juxtaposition/) and the [`#github` channel on Discord](https://discord.com/channels/408718485913468928/473698995286573066)
|
||||
|
||||
Ingest and processing of images has been overhauled, making more compressed and thumbnail versions of uploaded paintings and screenshots. On pages with lots of images, this makes Juxtaposition load dramatically faster and reduces memory load on 3DS systems especially.
|
||||

|
||||
*Screenshots like these used to be quite a problem for 3DS users. The full-size version of this image, as uploaded by the Wii U, is 88KiB. The new thumbnail version shown on 3DS is 12KiB - an 80% improvement!*
|
||||
|
||||
These changes also include aspect ratio tracking for uploaded images, in case.. future changes involve uploading screenshots of other aspect ratios, for some reason. :) Tracking aspect ratio also helps improve content shift on load.
|
||||

|
||||
*The layout used to move around a lot while the images loaded. Now, everything maintains its proper size during loading. (Load times increased for clarity)*
|
||||
|
||||
Banners for 3DS communities can now have a small background area behind the community info. We’ll be steadily updating communities to take advantage of this design.
|
||||

|
||||
*Splatoon is one of the communities featuring the new design.*
|
||||
|
||||
On 3DS, Juxtaposition now calls for manual garbage collection after each page load. This helps clean up unused memory and free it up for the new parts of the page. On the Old 3DS, this appears to have nearly completely eliminated the “blue screen” out of memory issues.
|
||||

|
||||
*The blue background is always there, you just can’t see it. We hope.*
|
||||
|
||||
On 3DS, Juxtaposition’s design assets have been optimised and re-encoded - things like the background pattern, coloured headers, and tab background. Combined with JavaScript delivery improvements, page sizes (excluding images) have dropped by 60%.
|
||||

|
||||
*Juxtaposition on the 3DS uses this spritesheet for the bulk of its design assets to reduce load times. This way, the console only has to load one large image and show different portions of it. Compression makes this more efficient than loading a dozen smaller images.*
|
||||
|
||||
Some quick-fire updates:
|
||||
- The [logic for creating a new post has been updated](https://github.com/PretendoNetwork/juxtaposition/pull/129) to fix several bugs and "smelly" code
|
||||
- A new [audit log has been implemented](https://github.com/PretendoNetwork/juxtaposition/pull/136) to track actions performed by moderators
|
||||
- A new [JSX-based rendering system](https://github.com/PretendoNetwork/juxtaposition/pull/132) is being worked on
|
||||

|
||||
*Message threads are one of the pages on the new JSX renderer.*
|
||||
- Updates to [the new token format](https://github.com/PretendoNetwork/juxtaposition/pull/131) are being worked implemented
|
||||
- Several parts of our build system have been improved and the UI portions of the applications are slowing being ported to TypeScript
|
||||
- An [experimental new framework for structuring Wii U/3DS web applications](https://github.com/PretendoNetwork/Yeah/pull/1) is being worked on. This framework is intended to help modernize the development/workflow of Juxtaposition, making it feel more like a modern web application built with frameworks like [Nuxt](http://nuxt.com/)/[Next](https://nextjs.org/). However this should be usable by anyone wanting to make a web application compatible with the Wii U/3DS
|
||||
|
||||
## Juxtaposition on Cemu
|
||||
|
||||
While not something we completed ourselves, we felt this to be news worthy enough to be included here. Back in 2023, I began looking into getting the Wii U Miiverse app to run in Cemu. Doing so would solve a pretty big pain-point: lack of a full functional web version of Juxtaposition. We do have a read-only website available right now, however it needs some UI updates and lacks the ability to create posts.
|
||||
|
||||
With a few tweaks to Cemu, some patched system files, and a couple of server-side patches, I was able to get the [Miiverse app to load without much issue](https://github.com/PretendoNetwork/Martini/issues/13#issuecomment-2544470882). However there were a number of issues with my approach, namely the fact that it required patched system files. Due to these issues, I shelved the idea indefinitely, telling myself I would pick it back up eventually.
|
||||
|
||||
Thanks to the dedicated work by developer [Arian Kordi](https://github.com/ariankordi), Cemu now has the ability to [launch the Miiverse app into Juxtaposition](https://github.com/cemu-project/Cemu/pull/1747) without ANY patched system files! This has not yet made it into an official Cemu release, however the changes have been merged and can be used today if compiled manually.
|
||||
|
||||
# Game Servers
|
||||
|
||||
While the last few months had a lot of focus on internal changes and Juxtaposition, game servers also saw a lot of attention!
|
||||
|
||||
- [Dani](https://github.com/DaniElectra) has begun implementing the [`MessageDelivery` and `Messaging` protocols into our "common" module](https://github.com/PretendoNetwork/nex-protocols-common-go/pull/54). Once complete, these protocols should be widely available to all games
|
||||
- [Dani](https://github.com/DaniElectra) Has begun [implementing the `MatchmakeExtension::GetPlayingSession`](https://github.com/PretendoNetwork/nex-protocols-common-go/pull/55) NEX method for use in multiplayer games
|
||||

|
||||
*Splatoon, for its part, calls GetPlayingSession every time you enter the multiplayer lobby.*
|
||||
- [Trace](https://github.com/TraceEntertains) updated [Yo Kai Watch Blasters](https://github.com/PretendoNetwork/yo-kai-watch-blasters/pull/5) to the latest server libraries, including the above mentioned changes by [Dani](https://github.com/DaniElectra). With this update friend rooms and trading are now functional
|
||||
- A proposal for updating several areas of state tracking in our underlying PRUDP server [has been created](https://github.com/PretendoNetwork/nex-go/issues/87)
|
||||
- Puyo Puyo Tetris neared completion, with replay upload and club matchmaking - which previously didn’t work - now implemented. There’s one issue left where you can’t always see other people’s replays.
|
||||

|
||||
*There should be more than one replay listed here. Still, one is better than before!*
|
||||
|
||||
## Super Smash Bros. 4
|
||||
Ever since the games launch, Super Smash Bros. 4 has had an issue where only one lobby can be active at a time for a given game mode. This has been often dubbed the “One True Lobby” bug. Trying to fix this bug has been a priority, and we are happy to announce that we now understand why the bug occurs.
|
||||
|
||||
When a client wants to join a multiplayer game, it has 2 options to do so:
|
||||
|
||||
1. Searching (internally called “browsing”) for active sessions to join manually
|
||||
2. “Auto matchmaking”, which automatically puts you into a session
|
||||
|
||||
In both options, the client sends the server various details about the kind of session it wants (called [“search criteria”](https://nintendo-wiki.pretendo.network/docs/nex/protocols/match-making/types#matchmakesessionsearchcriteria-structure)) and the various settings/capabilities of the game (such as how many players are joining). If no active sessions exist that match what the client wants/needs, the server creates a new one for the client and automatically assigns them as the host/owner.
|
||||
|
||||
The key difference between the 2 matchmaking functions is that “browsing” can return a list of candidate sessions the client can pick from manually, whereas the “auto matchmaking” functions will always automatically join and return the 1st session possible, without user input.
|
||||
|
||||
The “One True Lobby” bug occurs due to a previous misunderstanding of 2 of the search criteria settings:
|
||||
|
||||
- `m_VacantOnly`
|
||||
- `m_VacantParticipants`
|
||||
|
||||
Through past testing prior to the official servers shutdowns, we knew that these 2 settings controlled whether or not sessions should be considered “invalid” for joining based on the number of current participants. The `m_VacantOnly` controlling whether or sessions with full lobbies are valid, and `m_VacantParticipants` controlling the number of empty slots in the session.
|
||||
|
||||
Previously, we misunderstood in which contexts these settings are actually used, and when to ignore them. The `m_VacantOnly` setting has always existed (since NEX v1), however the `m_VacantParticipants` setting was added 2 major and 4 minor versions later (in NEX v3.4). Due to this, it seemed like `m_VacantParticipants` *replaced* the original `m_VacantOnly` setting. We also believed that these settings were treated the same in both matchmaking functions.
|
||||
|
||||
We now know this to be incorrect. In reality, `m_VacantOnly` and `m_VacantParticipants` are both still used. `m_VacantOnly` is also only used when using the “browsing” matchmaking function, whereas `m_VacantParticipants` is used in all functions. Logically, this also makes sense. Allowing a game client to see full lobbies may be useful in certain contexts, but would not be needed when “auto” matchmaking, whereas checking the number `m_VacantParticipants` *is* required at all times.
|
||||
|
||||
This was confirmed through a mix of previous testing/notes, and by decompiling various titles to inspect their implementations. These decompilation efforts also extend past the Wii U/3DS, as NEX is used in various Switch titles as well, and NEX itself is based on an existing library known as Rendez-Vous which is seen in many non-Nintendo titles. This fix for Super Smash Bros. 4 was helped by decompiling Splatoon 2 on the Switch, as it was the only game we could find that still implemented a mix of both `m_VacantOnly` and `m_VacantParticipants` being used at the same time (confirming that one did not replace the other), highlighting how important research is to improving accuracy and why certain updates may take more time than others.
|
||||
|
||||
A temporary fix for the bug is already deployed to production, while a [proper implementation is currently in the works](https://github.com/PretendoNetwork/nex-protocols-common-go/pull/59).
|
||||

|
||||
*Image demonstrates 2 lobbies active in 1v1 mode, with 3 users!*
|
||||
|
||||
# 3rd Party Integrations
|
||||
|
||||
Historically, there has always been some confusion as to what the goals/scope of the project actually are. This is not helped by Nintendo’s often confusing branding of “Nintendo Network” on certain games. Many people, understandably, assume that our goal is to provide servers for *all* games on the Wii U/3DS. This is, in fact, not the case. Our scope has always been limited to supporting games which use Nintendo’s 1st-party networking library called NEX. At times, we may provide replacement servers for games whose original servers are trivial to implement, but that is not the standard we hold ourselves to. Those are exceptions. If a game did not use NEX, it should always be assumed that we will not provide servers for it.
|
||||
|
||||
This confusion often comes from a mixture of word-of-mouth rumors, and due to Nintendo’s questionable Nintendo Network branding/developer usage, especially in relation to the name we chose for the project. All games which have any online capabilities and/or make use of your system/network account are branded with the Nintendo Network logo, *even if that game uses its own online servers*. This is because all games on the Wii U/3DS first must go through Nintendo’s own account servers for account/device authentication (this server is called NASC on the 3DS when not using a NNID, and NNAS when using a NNID on either console). These account servers authenticate your device/account and then issue the game tokens that can be used to identify the user. After this initial authentication, the developer is *free to do anything they wish* with the game. However, since the game DID use Nintendo’s account servers, the game receives the “Nintendo Network” branding.
|
||||
|
||||
Games such as WATCH_DOGS are prime examples of this. They authenticate your NNID, get the identity tokens, and then use those tokens to link your NNID to your Uplay (now Ubisoft Connect) account. After that, the game uses servers entirely ran by Ubisoft for games *actual* online features.
|
||||
|
||||
These games are *not* within our projects scope, and we have always felt that the best course of action was to leave those games to their own dedicated teams to revive, as they often require expertise specific to said games which we do not have, and do not wish to add onto our ever growing work load.
|
||||
|
||||
That being said, it has always been difficult to accomplish this without potential fragmentation in the community. How could someone make their own WATCH_DOGS servers without an accessible NNAS server, and while ours does not support the game? Requiring these 3rd party teams to run portions of the Nintendo Network infrastructure adds unnecessary load onto them and potentially creates fragmentation in the community.
|
||||
|
||||
Because of this obvious issue, we are excited to announce that we have begun the process of allowing 3rd parties to register themselves with us, and providing tools for them to use to officially integrate into Pretendo Network *the exact same way Nintendo did*! Right now we are still in the planning stages, but once completed anyone making servers for games that are out of our scope (or even stand-alone applications that wish to integrate with our services), will be able to do so seamlessly.
|
||||
|
||||
For details on how 3rd parties operated officially, and for our current plans to support them ourselves, see [this GitHub feature request](https://github.com/PretendoNetwork/account/issues/202).
|
||||
BIN
public/assets/images/blogposts/december-25-2025/banner.png
Normal file
|
After Width: | Height: | Size: 411 KiB |
BIN
public/assets/images/blogposts/december-25-2025/image1.png
Normal file
|
After Width: | Height: | Size: 293 KiB |
BIN
public/assets/images/blogposts/december-25-2025/image2.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
public/assets/images/blogposts/december-25-2025/image3.png
Normal file
|
After Width: | Height: | Size: 201 KiB |
BIN
public/assets/images/blogposts/december-25-2025/image4.gif
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
public/assets/images/blogposts/december-25-2025/image5.png
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
public/assets/images/blogposts/december-25-2025/image6.png
Normal file
|
After Width: | Height: | Size: 755 KiB |
BIN
public/assets/images/blogposts/december-25-2025/image7.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
public/assets/images/blogposts/december-25-2025/image8.png
Normal file
|
After Width: | Height: | Size: 286 KiB |
BIN
public/assets/images/blogposts/december-25-2025/image9.png
Normal file
|
After Width: | Height: | Size: 729 KiB |