feat: phone battery system - #151
Open
Github-Samuel wants to merge 11 commits into
Open
Conversation
…ke lb battery exports real
…arning and dead screen
…ss around the logo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the cosmetic battery with a real, persistent, configurable one. Ships disabled (
configs/battery.luaEnabled = false), so nothing changes for existing installs until they opt in.What was already there
This finishes an existing seam rather than adding a feature from scratch:
client/main.lua:667drained 1% per 30s while open, never persisted, and never recharged (it hit 0 and stayed there)BatteryPage.tsxhad a Low Power Mode toggle wired to nothing, plus invented "Battery health / Maximum Capacity 100%" rowsDesign
The charge follows
DataOwner.session.identity(source) or player.getIdentifier(source)resolves to the device/SIM profile under unique phones and the citizenid otherwise, so it is correct in all four ownership configurations with no second concept.Client simulates, server checkpoints. No server threads and no per-percent writes. The client owns the tick (it is the only side that knows if the phone is open); the server stores
level/charging/updated_atand derives on demand for exports and item handlers. Checkpoints happen on transitions plus a slow safety flush, roughly one write per player per few minutes rather than ~9 writes/second at 500 players.A live client is authoritative;
derive()is the fallback for owners with no live client. Without that rule a power bank used on a player who never opened their phone would write drift back into their row.lb-phone compatibility
All 8 exports implemented plus the
lb-phone:phoneDiedevent. Three deliberate divergences, each fixing a defect in lb's own bundle:battery === 20, soSetBattery(25 → 15)silently skips themCharging
lb ships no chargers at all, so enabling battery there gives players a phone that dies and never recovers. Three affordances ship here, each independently switchable: a power bank item, a cable item plus ox_target props and radius zones, and vehicle charging. All are thin callers of
chargePhone/toggleCharging, which are also exported for server owners.Verification
lua tests/lua/run.lua: 301 passed, 0 failed (27 new assertions coveringderiveprojection, clock skew,DrainWhileOffline/DrainWhenClosed,ownerKeyacross all four modes, rate selection, and threshold crossing)npm run build(tsc + vite),lint(0 errors),test(163 passed),knip(clean)luac -pon all 16 touched Lua filesTest files are intentionally not committed per repo convention.
Notes
config.StatusBar.BatteryStartis still read as the fallback forBattery.StartLevel, mirroring howSimTrayhonoursUseContainers.AllowEmergencyCallsneeded anEmergencyNumberslist because no emergency-number concept existed; it only bites underDeadBehaviour = 'noservice', since under'dead'the phone will not open to reach a dialler. Documented in the config comment.🤖 Generated with Claude Code