PlaceholderEntity dont think this is what would work, its still hackable cuz the logs are local.
What would work is to have some kind of decentralized ledger that you update or something.. could crypto give what you want without investing in centralized server?
i would like to know a solution to this problem.. i was thinking about similar way to persist the data and not having the centralized server..
So far i havent looked into it more than surface level
EDIT:
OK blockchain requires someone runing node and keeping it synced up 24/7.. it would be easier to have server validate that thing..
AI says this:
Secure SP+MP inventory (P2P Godot 4, no server):
Run everything as host mode (singleplayer = local host).
Authoritative data lives only in memory on host. Save file is encrypted + checksummed.
# Host-only (works in SP and MP)
const SAVE_PATH = "user://inventory.dat"
const HASH_PATH = "user://inventory.hash"
var inventories: Dictionary[int, Array[Item]] # authoritative
func save_inventory():
if not multiplayer.is_server(): return
var data = FileAccess.open_encrypted_with_pass(SAVE_PATH, FileAccess.WRITE, "your_secret_pass")
data.store_var(inventories) # or JSON
data.close()
var hash = FileAccess.get_sha256(SAVE_PATH)
var hfile = FileAccess.open(HASH_PATH, FileAccess.WRITE)
hfile.store_string(hash)
hfile.close()
func load_inventory():
if not FileAccess.file_exists(SAVE_PATH): return
var stored_hash = FileAccess.open(HASH_PATH, FileAccess.READ).get_as_text()
if FileAccess.get_sha256(SAVE_PATH) != stored_hash:
push_error("Save tampered! Resetting.")
inventories.clear() # or delete file
return
var data = FileAccess.open_encrypted_with_pass(SAVE_PATH, FileAccess.READ, "your_secret_pass")
inventories = data.get_var()
data.close()
# Pickup / trade (same as before)
@rpc("any_peer")
func pickup_item(item_type: String): # only host runs
if not multiplayer.is_server(): return
# create unique item, add to host's inventories
rpc("sync_inventory", inventories) # overwrite all clients
@rpc("any_peer")
func trade_item(item_id: String, to_id: int):
if not multiplayer.is_server(): return
# validate + move atomically on host only
rpc("sync_inventory", inventories)
Result:
Singleplayer: your local host = ledger. Tamper = detected on load.
Multiplayer: whoever hosts loads their save as truth. All trades go through host RPC only.
Dupes impossible: item exists once on host, synced by overwrite.
No blockchain needed. Works instantly.
Change password per game or derive from hardware ID for extra hardness. That's the max security possible in pure P2P.
Derive key (no hardcoded secret):
var secret = OS.get_unique_id() + ProjectSettings.get_setting("application/config/name")
var data = FileAccess.open_encrypted_with_pass(SAVE_PATH, FileAccess.WRITE, secret)
Checksum still catches any edit.