feat(nfc): NFC tags from the player's own dumps, with an NFC tab in the Insert menu #280
No reviewers
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/upscaling
good first issue
gpu/amd
gpu/igpu
gpu/intel
gpu/nvidia
help wanted
kind
bug
kind
chore
kind
docs
kind
feature
kind
performance
kind
question
needs measurements
platform/linux
platform/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!280
Loading…
Reference in a new issue
No description provided.
Delete branch "airdamien/Longshot:feat/nfc-tags"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
Where the game asks for a figure's NFC tag, nothing happens in Longshot: the console's NFC library (
nn::nfp, 23 functions the game imports) is not there. This gives the game that library on tags of the player's own: dump files in a folder, chosen and "tapped" from a new NFC tab in the Insert menu, and real tags on a Switch 2 Pro Controller's reader.What changed
host/nn_nfp.c(new):nn::nfpon a pretended reader. The tags are files in the player's NFC folder (hos_nfc_dir:%LOCALAPPDATA%\Longshot\nfc,$XDG_DATA_HOME/longshot/nfc, orLONGSHOT_NFC_DIR): an NTAG215's 540 bytes (.bin) or a Flipper Zero NFC file (.nfc), checked inload_tag. Only the tag's ID and the figure's model are read from one (both plain on a tag): no key is needed or used. What the game writes to a tag (its application area) is kept in a file beside the saves (area_load,area_save), and no tag is written. The device's states follow what the game polls (GetDeviceState: searching, found, mounted).reader_main,reader_read,scan_run, Windows, over the controller pull request'shos_switch2_command): while the game waits for a tag and none of the files is held to the reader, a real tag on the controller is read and, when it is a figure's, given to the game; a scan copies one into the folder. The reader's commands are in the file's comment as the controller answered them.host/nn_os_sync.chos_event_init(an event of the OS layer's own making);host/rx_backend.candgpu/vk/vk_api.h:MkwVkHostgetsnfc_count,nfc_name,nfc_tap,nfc_state,nfc_dir,nfc_scan,nfc_scan_name(MKWVK_API_VERSION22).gpu/vk/vk_menu.cpp: an NFC tab: the NFC tag row (the folder's files by name, listed again each time the menu opens:refresh_nfc), Tap tag, Remove tag, Scan tag on controller (nfc_press,nfc_scan_says).docs/nfc.md(new), README (the tab's rows and a paragraph),docs/development.md(three switches).tests/test_readme_menu_rows.pycovers the NFC tab's rows;tests/test_menu_keys.pygets a stub forrefresh_nfc.Flags and settings
nfc_tag), Tap tag, Remove tag, Scan tag on controllerLONGSHOT_NFC_DIR=<folder>HOS_NFP_TRACE=1HOS_NFP_SEARCH=1Measurements
main:
fbd42024(2026-11-13)this PR: feat/nfc-tags @ 1dd5ec73 (the measured commit;
b99145e0after it added only the row in docs/tested-configurations.md)Hardware: NVIDIA GeForce RTX 5080 (Vulkan driver 0x93cec000), Windows 11; a Switch 2 Pro Controller (firmware 1.1.5) plugged in over USB
Scene: the save's load point, Link standing still; 3840x2160 output, DLSS, frame generation 3x, the game's frame rate cap 60
Method: 150 s runs, the first 60 s left out, two interleaved runs each (main, this PR, ...). The numbers are
RX_VK_FRAME_LOG's frame times, a line per present (made frames included); the game's own rate islongshot_log.txt'svi:line.How to reproduce: the builds from the same dump with
nx2/make_game.py, the samelongshot_options.iniand save,HOS_INPUT_SCRIPT=12:A,15:A,...,42:A HOS_INPUT_SCRIPT_BACKGROUND=1 RX_VK_FRAME_LOG=<csv>.fbd42024The measured build was made before the branch was put on the controller pull request's last commit (a docs row); its code is the same.
Rebased since onto main @
514591a3(the branch's head is nowea2cbd4b) and not measured again: main's ten commits sincefbd42024are the website, docs, the forge script, a Damage taken row, an HDR route for FSR 4 that is opt-in, occlusion query numbering, quick pipelines and two input fixes; none is in this change's path, and the rebase of this pull request's own commit had no conflict. The rebased branch was built whole (nx2/make_game.py) and its checks run.Testing
Tested:
python -I -B tests/run_all.pyon Windows 11 (llvm-mingw): 454 passed, 7 failed, at the rebased head. The same 7 fail onmain@514591a3on this PC (test_bake_portability,test_fpx_sticky,test_spawn_emit,test_nup_paths,test_check_third_party,test_release,test_menu_i18n): local tools and packages, and one text of main's without its translations, not this change.RX_VK_ONLY=1 nx2/build.py --standalonecompiles and linkslongshot_vk.so;host/nn_nfp.c,host/nn_os_sync.c,host/rx_backend.ccompile (-fsyntax-onlywith the build's includes).nfp: the game uses NFC tags: ...); the NFC tab lists the folder's files; Tap tag holds one to the reader (nfp: the NFC tag "..." held to the reader (model ...); the game is not asking for one now), Remove tag takes it away.HOS_NFP_SEARCH=1) and from the Scan row (nfp: scan: the tag (UID ...) was read, but it is not a figure's tag: not saved).nfp: the game waits for an NFC tagsix times, each followed bynfp: the game reads the NFC tag "..."andnfp: the game stopped waiting for an NFC tag; oncenfp: a tag read on the controller (model 0105000003580902): given to the game, a figure's real tag on the Switch 2 Pro Controller; tags tapped both ahead (... the game is not asking for one now: it stays there until it does) and while it waited (... the game was waiting for one). Nonn::nfpimport was left unimplemented and nothing crashed.nfp: scan: waiting ten seconds for a tag on the controller, thennfp: the tag on the controller was scanned into the folder as "Scanned <ID>" (model 0105000003580902); the 540-byte file is in the folder.Not tested:
Needs other testers:
Screenshots
The NFC tab, this PR @ 1dd5ec73, on pretended tags (
mainhas no such tab):Risk and rollback
nn::nfp::InitializeandAttachAvailabilityChangeEventat start before (logged as unimplemented imports, returning as they were); now they do something: a reader that is always there. A game path that waited on the reader's event now goes on.MKWVK_API_VERSIONgoes to 22: the exe and the renderer must be of one build, as at every bump.nfc_tag=<its place in the list>, as any row's; it means nothing to another build.Reviewer notes
#dev-workbeforehand.Issues
None.
Checklist
For everyone
type(scope): description).main.python -I -B tests/run_all.pyrun and passing (any failure that also fails onmainis named above).third_party/untouched (a new folder with aPROVENANCE.mdinstead).If applicable
Assisted-by:/Co-Authored-By:trailers.docs/tested-configurations.mdfor each measured run.MKWVK_API_VERSIONbumped (gpu/vk/vk_api.h'sMkwVkHostorMkwVkRendererchanged).tests/that reads changed source updated in this PR, not weakened.🤖 Generated with Claude Code
Tested in play by the author: at the game's NFC screen the game read six tags in one session, from the Insert menu's NFC tab and, once, a figure's real tag on the Switch 2 Pro Controller's reader (the log's lines are in the description). The two requests that asked for that (T-3UQZ, T-LHBX) are withdrawn; one for Linux is open (T-KZYU). Marking it ready.
WIP: feat(nfc): NFC tags from the player's own dumps, with an NFC tab in the Insert menuto feat(nfc): NFC tags from the player's own dumps, with an NFC tab in the Insert menub99145e0baea2cbd4bb9Rebased with the controller pull request onto main @
514591a3(headea2cbd4b), no conflict in this one's own commit. Built whole and the checks run. Also tested since, by the author: Scan tag on controller saved a figure's real tag into the folder (nfp: the tag on the controller was scanned into the folder as "Scanned <ID>").View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.