Browse by type
Author: AlienMajik
Feel free to open issues or pull requests to improve this plugin or suggest new features. Enjoy leveling up your Pwnagotchi!
Version 5.2.0 · MIT · by AlienMajik
A narrative-driven progression plugin for Pwnagotchi. It tracks how long your unit has lived, how hard it's been working, and what it has captured — then wraps all of it in titles, lore, cheeky quotes, random events and a prestige/rebirth cycle.
Tested against Jayofelony Pwnagotchi 2.9.5.8. Works on 2.9.3 and later; see Compatibility if you're upgrading from an older image.
Counts the epochs your Pwnagotchi has lived through, and awards a title at each
threshold — "Baby Steps" at 100, "Neon Spawn" at 1,000, "Data Raider" at 10,000, all the
way to "Intergalactic" at 111,111. After a rebirth every title gains a Reborn prefix.
Reflects training effort. On images with the AI removed (which is all current Jayofelony
releases) strength accrues passively at passive_train_rate per epoch — 0.1 by default,
so one strength point per ten epochs. If a fork does emit AI training steps, the plugin
switches to counting real steps automatically, and falls back to passive accrual if those
steps stop arriving.
Titles run from "Sparring Novice" (100) through "Deauth King" (2,000) to "Kuato" (11,111).
Earned per handshake, scaled by encryption strength and your prestige multiplier:
| Encryption | Base points |
|---|---|
| WPA3 | 10 |
| WPA2 | 5 |
| WPA / WEP | 2 |
| Open / unknown | 1 |
Bettercap reports encryption as strings like WPA2 CCMP PSK, so the plugin normalizes
whatever it gets into one of those families before scoring.
Points decay during long stretches of inactivity, and there's a streak bonus of +20% once you've captured five in a row without a decay event.
Three traits grow from how you actually play:
| Trait | Grows when |
|---|---|
| Aggro | +3 per handshake (aggro_per_handshake) |
| Scholar | +1 every 10 epochs |
| Stealth | +1 per 5 consecutive quiet epochs (stealth_quiet_epochs) |
The dominant trait can be shown on screen with show_personality.
Max out both the age and strength title tables and a rebirth becomes available. Taking it
resets epochs, strength, points, streaks, personality and the current handshake count, and
grants a permanent +10% point multiplier per prestige level (1.1×, 1.2×, …), tunable
with prestige_bonus.
Your lifetime handshake total and your unlocked achievements survive rebirth.
By default rebirth triggers automatically on the next epoch. Set auto_rebirth = false
to hold it, then spend it from the web UI when you're ready.
Every event_interval epochs (100 by default) there's a random_event_chance roll for one
of:
| Event | Effect |
|---|---|
| Lucky Break | Double points, next 5 handshakes |
| Overclock | Triple points, next 3 handshakes |
| Signal Noise | Half points, next handshake |
| Hacker's Block | Zero points, next 3 handshakes |
| Windfall | +50 points instantly (scaled by prestige) |
| Time Warp | Strength grows 2× for 100 epochs |
| Ghost | Swaps your aggro and stealth scores |
Events persist across reboots and expire cleanly.
Milestones fire off your lifetime handshake count, so they aren't lost to a rebirth: First Blood (1), Double Digits (10), Century Mark (100), Thousand Claps (1,000) and Legend (5,000) — each worth +50 points.
Two are hidden: Night Owl (10 handshakes between 2am and 4am) and Crypto King (capture WPA3, WPA2, WPA and WEP).
Copy age.py into the custom plugins directory:
sudo scp age.py pi@<pwnagotchi_ip>:/tmp/
sudo mv /tmp/age.py /etc/pwnagotchi/custom-plugins/
Then add the config below to /etc/pwnagotchi/config.toml and restart:
sudo systemctl restart pwnagotchi
Bracketed form, recommended:
[main.plugins.age]
enabled = true
# UI positions. Keep every y below your panel height — a Waveshare 2.13 is
# only 122px tall, and anything at or past that gets clamped with a warning.
age_x_coord = 101
age_y_coord = 80
strength_x_coord = 160
strength_y_coord = 80
points_x_coord = 10
points_y_coord = 60
progress_x_coord = 10
progress_y_coord = 100
personality_x_coord = 10
personality_y_coord = 20
age_status_x_coord = 10
age_status_y_coord = 110
# Which elements to draw
show_personality = false
show_points = true
show_progress = true
show_status = true
# Decay
decay_interval = 50
decay_amount = 5
# Events and prestige
random_event_chance = 0.05
event_interval = 100
prestige_bonus = 0.1
auto_rebirth = true
Flat main.plugins.age.<key> = <value> form works identically if you prefer it.
| Option | Default | What it does |
|---|---|---|
decay_interval |
50 | Epochs of inactivity before points decay |
decay_amount |
10 | Points lost per decay interval |
random_event_chance |
0.05 | Probability of an event at each interval |
event_interval |
100 | Epochs between event rolls |
prestige_bonus |
0.1 | Multiplier gained per prestige level |
auto_rebirth |
true | Spend a pending rebirth automatically |
passive_train_rate |
0.1 | Strength gained per epoch without AI |
ai_idle_epochs |
20 | Epochs without a training step before passive accrual resumes |
stealth_quiet_epochs |
5 | Quiet epochs per stealth point |
aggro_per_handshake |
3 | Aggro gained per capture |
repeat_ap_penalty |
false | Diminishing returns for re-capturing the same BSSID |
takeover_status |
true | Briefly borrow the main status line for new messages |
max_status_len |
40 | Characters before a message is truncated |
msg_hold |
3 | UI refreshes a queued message stays up |
save_interval |
60 | Seconds between disk writes |
log_max_bytes |
524288 | Rotate the points log past this size |
show_personality |
false | Draw the dominant trait |
show_points / show_progress / show_status |
true | Draw those elements |
data_path |
/root/age_strength.json |
Stats file |
log_path |
/root/network_points.log |
Points log |
handshake_dir |
auto | Override the handshake directory |
age_titles / strength_titles |
built-in | Custom threshold → title maps |
points_map |
built-in | Custom per-encryption scores (merges with defaults) |
Bad values are logged and replaced with the default rather than crashing the plugin, and a
partial points_map merges with the built-in one instead of wiping the entries it didn't
mention.
Live stats at http://<pwnagotchi_ip>:8080/plugins/age/ — titles, points, prestige,
lifetime handshakes, streak, personality breakdown, encryption families seen and unlocked
achievements. When auto_rebirth = false and a rebirth is pending, a link there triggers
it.
| Image | Status |
|---|---|
| Jayofelony 2.9.5.5 – 2.9.5.8 | Supported |
| Jayofelony 2.9.3 – 2.9.5.4 | Supported |
| Older / evilsocket | Should work; handshake paths and faces are probed defensively |
Two things changed in the Jayofelony line that this plugin now accounts for:
.pcapng as of the 2.9.5.5+ images. The initial scan counts both
.pcapng and .pcap. If you're carrying over old captures, note that Jayofelony's own
advice is to rename .pcap to .pcapng so the rest of the tooling still sees them./home/pi/handshakes in 2.9.3. That path is probed
first, then /root/handshakes for older images. Override with handshake_dir if yours
lives elsewhere.Because pcapng files are appended to rather than recreated, a single network can raise
on_handshake more than once. If one router at home ends up dominating your score,
repeat_ap_penalty = true applies diminishing returns per BSSID.
The AI is gone from current images, so strength accrues passively — that's expected, not a fault. Nothing here depends on the AI being present.
/root/age_strength.json — all persistent state: epochs, strength, points, current and
lifetime handshakes, prestige, personality, achievements, active events and event
progress. Written atomically (temp file, fsync, rename) at most once per save_interval,
so a power cut can't leave you with a truncated file. If it ever is unreadable it's moved
aside to .corrupt rather than silently zeroing your progress.
/root/network_points.log — one CSV line per handshake: timestamp, quoted ESSID,
encryption family, points awarded. Rotates to .1 past log_max_bytes.
Drop in the new age.py and restart. Your existing age_strength.json is read as-is and
new fields are filled with sane defaults.
Expect your points total to change on first run. v4 applied the prestige multiplier
twice (once when earning, once when displaying) and mis-rendered any value under 1,000 —
100 points showed as 1. The number you see now is the correct one.
Two balance changes worth knowing about: stealth no longer gains a point every single quiet epoch, so the dominant trait will stop defaulting to Stealth; and handshake milestones now key off your lifetime total, so several may unlock at once the first time you capture something.
A plugin that captures ADS-B data from aircraft using RTL-SDR and logs it.
A RTL-SDR Dongle is required to run this plugin.
First, connect your RTL-SDR dongle to one of the USB ports on your Raspberry Pi (the hardware running Pwnagotchi). Ensure the dongle is properly seated and secure.
To configure the RTL-SDR and test rtl_adsb, you'll need to access the terminal on your Pwnagotchi. You can do this in several ways:
Once you're in the terminal, you'll likely need to install the RTL-SDR drivers and the rtl_adsb utility. Pwnagotchi is based on Raspbian, so you can use apt-get to install these packages. Run the following commands:
sudo apt-get install rtl-sdr
After installation, verify that the RTL-SDR dongle is recognized by the system:
rtl_test
This command checks if the RTL-SDR dongle is properly recognized. You should see output indicating the detection of the dongle. If there are errors or the dongle is not detected, ensure it's properly connected or try reconnecting it.
Now, try running rtl_adsb to see if you can receive ADS-B signals:
rtl_adsb
This command starts the ADS-B reception. If your RTL-SDR is set up correctly and there are aircraft in range, you should see ADS-B messages appearing in the terminal.
Add adsbsniffer.py to /usr/local/share/pwnagotchi/installed-plugins and /usr/local/share/pwnagotchi/available-plugins
In /etc/pwnagotchi/config.toml file add:
main.plugins.adsbsniffer.enabled = true
main.plugins.adsbsniffer.timer = 60
main.plugins.adsbsniffer.aircraft_file = "/root/handshakes/adsb_aircraft.json"
main.plugins.adsbsniffer.adsb_x_coord = 120
main.plugins.adsbsniffer.adsb_y_coord = 50
The ADSBSniffer plugin ("the Plugin") is provided for educational and research purposes only. By using the Plugin, you agree to use it in a manner that is ethical, legal, and in compliance with all applicable local, state, federal, and international laws and regulations. The creators, contributors, and distributors of the Plugin are not responsible for any misuse, illegal activity, or damages that may arise from the use of the Plugin.
The Plugin is designed to capture ADS-B data from aircraft using RTL-SDR technology. It is important to understand that interfacing with ADS-B signals, aircraft communications, and related technologies may be regulated by governmental agencies. Users are solely responsible for ensuring their use of the Plugin complies with all relevant aviation and communications regulations.
The information provided by the Plugin is not guaranteed to be accurate, complete, or up-to-date. The Plugin should not be used for navigation, air traffic control, or any other activities where the accuracy and completeness of the information are critical.
The use of the Plugin to interfere with, disrupt, or intercept aircraft communications is strictly prohibited. Respect privacy and safety laws and regulations at all times when using the Plugin.
The creators of the Plugin make no warranties, express or implied, about the suitability, reliability, availability, or accuracy of the information, products, services, or related graphics contained within the Plugin for any purpose. Any reliance you place on such information is therefore strictly at your own risk.
By using the Plugin, you agree to indemnify and hold harmless the creators, contributors, and distributors of the Plugin from and against any and all claims, liabilities, damages,
$ claude mcp add pwnagotchi_plugins \
-- python -m otcore.mcp_server <graph>