OpenPerpetuum / OpenPerpetuum/PerpetuumServer2
Assembled robots in corporation hangars at PBS bases are altered by a server restart ("Peanut Plague")
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 1
- Forks
- 2
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 2
Description
Status: TODO — Priority: HIGH — Area: Corporations / Containers / PBS
Reported by the lead developer on Discord, 2026-08-15. Filed here so it has a thread; the matching backlog entry is ISSUE-040 in docs/backlog/issues.md.
Problem
Storing assembled (non-repackaged) robots in a corporation hangar hosted on a PBS docking base leaves them in a wrong state after a server restart. The failure is known internally as the "Peanut Plague". Reported from live server experience; previous attempts were made to address it and none is confirmed to have fixed it. Not reproduced in a development environment.
No reproduction steps, affected-robot list, or exact post-restart symptom have been recorded. The whole of the current description is that a restart "makes funny things with them", so establishing what state the robots actually end up in is the first task, not the fix.
Where an investigation would start:
PublicCorporationHangarStorage(src/Perpetuum/Containers/PublicCorporationHangarStorage.cs:13) is, in its own words, "the parent of every corporate hangar, one per base". On a PBS base the entire hangar tree therefore hangs off an entity owned by that base.PBSDockingBase(src/Perpetuum/Zones/PBS/DockingBases/PBSDockingBase.cs:27) andExpiringPBSDockingBase(src/Perpetuum/Zones/PBS/DockingBases/ExpiringPBSDockingBase.cs), which callsKill()when its lifetime runs out. What happens to the hangar subtree, and to assembled robots inside it, when the parent base expires or is killed is worth establishing early — a PBS base is not permanent, and an ordinary docking base is.Robot.IsStackable(src/Perpetuum/Robots/Robot.cs:87) isbase.IsStackable && IsRepackaged. An assembled robot is an entity subtree — components, modules and its ownRobotInventory— while a repackaged one is a plain stackable item. That difference is the reason the assembled case is the one that breaks, and it is what makes a restart, which rebuilds every entity from the database, the point where it surfaces.Container.cs:394already special-casesCorporateHangarandCorporateHangarFolderduring item movement, so the hangar types are known to need their own handling elsewhere.
Impact
Player property, without any player action, repeating on every restart. Robots are among the most expensive assets a corporation owns and corporation hangars at player-built bases are where they are kept. Whatever the concrete symptom turns out to be, the affected items were paid for.
Proposed fix
Investigation first, fix second:
- Reproduce locally — place an assembled robot in a corporation hangar on a PBS base, record the full entity subtree from the database, restart the server, and diff the subtree.
- Derive the mechanism from that diff rather than from a hypothesis.
- Cover it at the integration tier once the mechanism is known. This is the shape of defect that tier exists for: it is about what survives a real load from a real database, which no faked data layer can answer.
Notes
- Priority is a judgement made when filing; the report did not assign one. HIGH because it destroys or alters player assets and recurs, against a report that carries no measured frequency.
- Every line number above was checked against
4e6d697and is anchored to it. Line numbers drift.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the restart with an assembled robot in a PBS corporation hangar and recording the entity subtree before and after. Read PublicCorporationHangarStorage.cs, PBSDockingBase.cs, ExpiringPBSDockingBase.cs, Robot.cs, and Container.cs around the mentioned locations, then derive the mechanism from the database diff. Done means the behavior is fixed and covered by an integration test that verifies the subtree survives a real reload.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100