-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
The original crazythings implementation stored every phone, contact, and message ever sent, in every
conversation, forever, in one SavedData blob - and broadcast the entire thing to every online player
on every login and every message sent. History was never pruned, so the payload only grew across the
server's lifetime; that's what eventually crashed the server on player connect.
This rewrite splits that blob by purpose:
| Data | Storage | Sync behavior |
|---|---|---|
| Phone registry, contacts, mayor state | PhoneRegistrySavedData |
Small by construction, still synced in full on login |
| Conversation messages (incl. voice audio, images) |
ConversationSavedData, one bucket per conversation |
Never broadcast; fetched on demand when a conversation is opened, capped and trimmed on write |
A new message now notifies only the participants who are online, instead of the whole server, so payload size stays bounded no matter how long the world has run or how much history has accumulated. The same principle carries through the voice features added later, and through the native photo pipeline: call audio, voice message audio, and photo bytes are only ever sent to the players who actually need them, on demand, never broadcast.
One shared src/main/java tree, preprocessed per target by Stonecutter
(//? if fabric / //? if neoforge, plus per-version checks) into 5 build targets. NeoForge 1.21.1 is the
primary development target; everything else is kept in sync with it.
| NeoForge 1.20.4 | NeoForge 1.21.1 | NeoForge 1.21.10 | Fabric 1.20.1 | Fabric 1.21.1 | |
|---|---|---|---|---|---|
| Phone, messaging, contacts, groups | ✅ | ✅ | ✅ | — | ✅ |
| Mayor election | ✅ | ✅ | ✅ | — | ✅ |
| Native camera (capture/viewer/photo item/My Photos) | ✅ | ✅ | — (pending) | — | ✅ |
| Sneak-presenting (hold a photo up, two-hand grip) | ✅ | ✅ | — (pending) | — | ✅ |
| Voice calls & voice messages | ✅ (SVC) | ✅ (SVC) | ✅ (SVC) | — | — |
| Soulbound enchantment | — | ✅ | ✅ | — | ✅ |
| Runtime-configurable settings | ✅ | ✅ | ✅ | — | — |
- NeoForge 1.21.10's camera and sneak-presenting features compile but don't work yet: Mojang reworked both item rendering and the screenshot/texture APIs the native pipeline uses on that version, and porting to the new APIs is a separate, tracked follow-up.
-
Fabric 1.20.1 is a walking skeleton for now - the item exists and registers, but the phone's
networking layer needs an API (
CustomPacketPayload) that doesn't exist before 1.20.5, so none of the screens/messaging/camera work yet on that specific version. - Fabric 1.21.1 has the core feature set, the native camera pipeline (including punch-to-shoot, standalone capture, and My Photos), sneak-presenting, and the Soulbound enchantment - but no voice calls/messages, since Simple Voice Chat integration hasn't been ported to Fabric yet.
Stonecutter splits the codebase into a shared source tree and one subproject per target version/loader:
CrazyPhone/
├── src/main/java/fr/lordfinn/crazyphone/ Shared source tree - every target compiles from here
│ ├── client/gui/ Screens (one per phone page) + shared widgets
│ ├── client/picture/ Native screenshot capture + texture cache, shared by both loaders
│ ├── command/ /crazyphone command tree
│ ├── data/ SavedData + player attachments (the crash fix lives here)
│ ├── enchantment/ Soulbound enchantment (≥1.20.5 only)
│ ├── fabric/ Fabric entrypoints + per-loader registration glue
│ ├── init/ Item/menu/screen/tab/sound/permission registration
│ ├── item/ The Crazy Phone item and photo item, vanilla item models & inventory capability
│ ├── mixin/ Cross-loader mixins (capture overlay input/rendering, sneak-presenting pose/hand-grip)
│ ├── network/ Client-server packets
│ ├── procedures/ Gameplay logic (ported from the original mod, adapted to the new data layer)
│ ├── utils/ Shared helpers (contacts, screen navigation, NBT/registry compat)
│ ├── voicechat/ Optional Simple Voice Chat integration (NeoForge only)
│ └── world/inventory/ Container menus backing each screen
├── versions/ One Stonecutter subproject per build target (1.20.4, 1.21.1, 1.21.10,
│ 1.20.1-fabric, 1.21.1-fabric) - each has its own gradle.properties pinning
│ that target's Minecraft/loader/dependency versions
├── build.gradle.kts Default build script - NeoForge targets
├── build.fabric.gradle.kts Build script used by the two "-fabric" subprojects (Fabric Loom)
└── stonecutter.gradle.kts Wires up the //? if fabric / //? if neoforge / //? if >=X.Y preprocessor
Per-loader and per-version differences in the shared tree are handled with Stonecutter comment directives
(e.g. //? if fabric { ... }, //? if >=1.20.5 { ... }) rather than separate source sets or an
abstraction layer - most files are identical on every target; only the files that genuinely differ
(registries, networking, attachments, a handful of NeoForge/Fabric API divergences) carry any gating.
Every piece of UI text (button labels, tooltips, placeholders, headers) is routed through the lang files, no hardcoded strings:
src/main/resources/assets/crazyphone/lang/en_us.json
src/main/resources/assets/crazyphone/lang/fr_fr.json
Want to add another language? Copy en_us.json to <your_locale>.json and translate the values; the keys
must stay identical between files.
- Simple Voice Chat by henkelmax: the voice engine calls and voice messages are built on top of (NeoForge only).
- Original
crazythingsproject: source of the feature set and assets this mod ports and rebuilds.