#world-persistence

1 messages · Page 6 of 1

agile coral
#

I haven't played much with player objects yet

sturdy veldt
#

I have a very very thicc playerobject with lots of stuff in it lol

agile coral
#

Peak

sturdy veldt
#

I haven’t coded my mobs yet but planned to pool their prefabs since they’d need to sync so much data they probably shouldn’t be instantiated

#

That will need grief prevention

agile coral
#

Oo what are they gonna do

dense owl
#

Destroying all mirrors would be enough backfire to cause mental damage to some users...an adequate punishment! <w<

#

As for the PlayerObject solution to prevent forced ownership...
Does that mean if I wanted a menu whose variables have to be read by the network for other mechanics to know the current "player stats", but interactions themselves are local...
I should make the menu a PlayerObject, then locally turn off the copies that arn't owned by the local player? (so they don't overlap)

I'm stil new to this "coding defensively" thing, no idea what are the actual good practices aside of the underscore thing (that I always forget to use...)

wary summit
#

The only time I'd put a menu inside a player object is if I wanted the ability to view the menu connected to someone else.

agile coral
#

Although

#

I could make it turn on a bunch of mirrors vrcAevSip

#

Ya know to uhhhhh, symbolically let them "reflect" on how their actions affect others and how it casts shame onto themselves

carmine belfry
#

Hey uh
Where would I go to ask / look for worlds? (Idk where to ask this at 😭)

sturdy veldt
carmine belfry
#

Well that's the thing
I'm trying to find this certain world that I forgot the name of that im not sure if its still up

light laurel
#

does it matter whether i use Manual or None syncing on a persistent script that won't have any synced variables?

sturdy veldt
#

None = no network id

light laurel
#

i'm just wondering if the playerdata still saves and loads fine if the sync behaviour is set to none

#

i would think it does but i never actually checked

sturdy veldt
#

Ohh good question

#

Is it storing data for a synced behavior to retrieve?

light laurel
#

in this context, it's just for a local world toggle

#

so no

amber agate
#

anyone had a problem where sometimes when quest user's network lags or they come back from sleep mode, it calls OnPlayerRestored with null data, potentially resetting their save?

subtle quest
wary summit
light laurel
#

that’s what i figured

noble nova
#

So am thinking of migrating all of my separate persistence bools into one string for scalability of my project but I'm worried about the size cost. Is it not worth it and it wouldn't even be scalable because it would quickly hit that cap

#

How much is 1 char on persistence

#

Pretty much

#

Also I know there's that compression how does it compress and what are the benefits from it

visual cargo
#

we don't really have any documentation on how exactly the compression works. In my testing though, it would compress by about 30%-80%

#

I've seen most people pack bools into bytes, not chars

#

which does tend to save space if you have a lot of bools, since 1 bool and 1 byte are both 1 byte each when synced

wary summit
noble nova
#

Should be much more preformant then my current system too

sturdy veldt
#

I’m not very familiar with bit shifting or converters so I don’t really understand the value of packing into byte arrays vs strings?

#

And I currently have two different scripts wrapping some network data into strings so >.>

visual cargo
#

you can save a significant amount of space by packing bools into bytes though

noble nova
visual cargo
#

right, due to 1 bool taking up a full byte when networked

noble nova
#

Or 4 double digit integers for arrays and whatnot

#

Wait no nvm thinking of something else

sturdy veldt
unique rune
#

it's a classic computer science thing, you're likely to find lots of posts on it, but I'd be surprised if there's anything vrchat or U# specific.

sturdy veldt
#

Yea don’t need u# specific at all

#

I’ll give it a google later, thankies ^-^

unique rune
#

might try "bit fields" too maybe

visual cargo
#

There's probably a C# tutorial out there on it

unique rune
#

probably is

meager spoke
#

for PlayerData does the Key count towards the data limit or just the value?

meager spoke
# wary summit It does

is there any specifics on how the data gets compressed? and does the key get saved as a string always or if it just numbers then it optimizes to int or uint or something like that?

#

or does the key string get hashed?

#

sorry to be more specific, i wanna know how many Bytes the key takes up

raw sigil
meager spoke
visual cargo
# meager spoke nice data although it does mention persistence, it doesent take into account the...

I tried to do some testing to figure this out.
It seems like VRChat no longer logs the detailed persistence info, like the compressed amount, but we do have new functions to get the current amount of saved persistence data
with 1 int, I got:
key "a" : 364 bytes
key "aaaaaaaaaa" : 366 bytes
since it's just one key, most of this is probably header, but it seems like the name of the key directly contributes to the size, but is compressed along with the rest of the data

wary summit
# meager spoke nice data although it does mention persistence, it doesent take into account the...

It's difficult to give precise estimates for persistence because the number that matters is after compression. It depends not only on the type of data, but the content of the data. For example, "aaaaa" will take up less data than "abcde". The more repeating patterns in your data, the easier it is to compress. The more randomness in your data, the less it will compress and the more data it will take up. Ultimately, that's why those functions to check the size of persistence data exist - you have to run them in your own environment to see the real numbers

#

You can have a 100k length byte array but if it's all zeros, it will compress down to less than 1% of that. If it's pure random data, it won't compress at all. If it has large chunks of similar data but still with some variety, it will be somewhere between

meager spoke
#

okay so with this little test of ~2k values stored it... seems to work but uhh i dont really get the math, uncompressed it's i think over 300k and compressed 70k while on raw data i'm only storing 2048 uint all the remaining is key or other database stuff

spring fossil
#

Im wanting to make a game world with persistence but have zero idea how to set up one. Can anyone help teach me?

sturdy veldt
visual cargo
sturdy veldt
#

I have two different game worlds (almost 3) and no persistence in any of them because I’m lazy 😂

visual cargo
#

depending on the game it can easily not be necessary at all

#

just doesn't make sense as part of the game design

sturdy veldt
#

It just feels like ass to give people settings to customize and not save them >.<

#

anything that takes a moment of UI navigation feels worth saving for them after the first time

visual cargo
#

it's probably easier than you might expect to set that up to work with persistence

sturdy veldt
#

It is but the only time I’ve tried I didn’t like having to wait for player to restore before applying variables because there were other things that were also time sensitive (like string loading patron state) and I didn’t know which should trigger first

visual cargo
#

ideally you'd design it so it's not that sensitive to timing

#

for UI it'd just auto-move or change the UI element when the data is loaded in

spring fossil
#

Im wanting to make an idle world where people can pick herbs and plant a garden and a few other things. I just need help in general with it. I want to make a ui menu where tools can be bought and skins and areas for the items to be collected. I would like a backpack they can upgrade to hold more items

visual cargo
# spring fossil Im wanting to make an idle world where people can pick herbs and plant a garden ...

you'll want to plan out each feature that you'll need to make, ideally break it up into little things that all add up to be the entire game.
Breaking it up into little pieces is crucial in turning a big, difficult task, into a handful of easy tasks.
you've already got, in no particular order:

  1. UI Menu
  2. Plant growing system
  3. player inventory
    From these broad pieces, you then pick a piece. Could be any piece, or the part that makes the most sense to do first, like if one part depends on another part already existing.
    So I'd start with maybe... the plant growing? Up to you what makes the most sense
spring fossil
#

how do i set up a ui menu? how do i make it where plants grow? how do i set up a player inventory?

spring fossil
visual cargo
#

right. So, you'd just pick one of those questions and then go from there

#

UI Menu: pretty easy, in theory. Right click the hierarchy > UI > Button - TextMeshPro (VRC)

unique rune
#

The Unity documentation will help a lot here, most of the UI stuff is just Unity, not VRChat-specific.

amber agate
#

anyone had a problem with player data randomly fully/partially resetting on quest?

sturdy veldt
amber agate
#

it's rare too, like no way to reproduce

sturdy veldt
amber agate
#

but i'm just tired of players approaching me with that problem and having to restore their stuff

#

really hoping to find a fix

wispy latch
#

It's kinda unfortunate

#

But of course, there is always a chance your persistence setup has issues too. I personally simply use one PlayerData slot and put in a json into that. So usually it's impossible for the data to get lost in any way.

#

Another thing I've done recently that might help: I paste the encrypted save to their log when they join. Some people just give that to me and I just can paste that into the recover system.

#

(but obviously a lot of people have issue getting to the logs as well)

amber agate
amber agate
amber agate
dense owl
#

Most of the persistance is "on player join (then node to check the data), if bool is true, send custom event" tho...And turning the key on condition met. The rest is just normal world making really (at least for PlayerData)

wispy latch
meager spoke
#

does vrc update/upload all of the persistence data when updating a single value? because i had heaps of performance difference at ~100 keys and ~1000 keys, when i try to update a single value with 1000 key/values in the database it would give a lag spyke / frame drop, also network suffering increases a waaay lot

meager spoke
#

💀

#

any good reason?

visual cargo
#

networked data is serialized per-object; so if you have 100 separate objects, and tell one to sync, it'll sync all data on that object together, even if you only changed one value.
PlayerData, however, is essentially one object. So changing one value, all data must be serialized together and re-sent

meager spoke
#

kay.. i understand what you mean but i feel like playerdata, the way it works, it should be it's own database then that allows for single value changes, i dont see how uploading all the data for playerdata on a single value makes much sense, i mean other than reusing the same system from player objects?

visual cargo
#

it's because it has to all be serialized together, due to how VRChat does its networking

#

and "reusing the same system from player objects" is almost exactly what it's doing. Even further, just how objects themselves are networked. both PlayerObjects and PlayerData network the same way as normal networked scripts do

#

it's not really an entirely separate thing

#

Should it work how you describe? Maybe, yeah. Is it how persistence currently works? no

meager spoke
visual cargo
#

it would certainly be a useful upgrade, but I don't see it happening anytime soon

#

they'd essentially have to rework both persistence and the network stack from scratch

meager spoke
#

i guess i'll have to figure out some other way for frequent updates of small values on larger data pool

visual cargo
#

your answer to that would be using PlayerObjects

#

PlayerData is not at all designed for data that you'd be updating often, that should be in a PlayerObject instead

#

additionally, you can make multiple PlayerObjects and separate the data if needed, so that not all of the data is being sent all at once

meager spoke
visual cargo
#

that's safer to do with PlayerObjects than with PlayerData

meager spoke
#

yeah but i feel like i'd reach the data limit quicker, rn i'm at about ~2000 objects stored using 8% of the storage limit

visual cargo
#

PlayerObjects is a whole, separate limit, and has the same capacity as PlayerData

meager spoke
#

yeah but a key already takes a lot of bytes from the limit, how many bytes does an object take with a stored int?

visual cargo
#

you wouldn't store the object, just the data

#

it might take even less even, since you don't need to store the key name

meager spoke
#

hmm, i'll look into it

meager spoke
#

can i instantiate player objects in runtime and/or can i destroy them aswell?

visual cargo
#

no

#

they already intantiate themselves, one for every player

meager spoke
#

i mean make new ones

visual cargo
#

well, you can technically instantiate anything, yes. but you can't have networked scripts on instantiated objects

#

you can have as many PlayerObject templates in your scene as you want though

meager spoke
visual cargo
#

with an editor script yeah you can make as many as you want, just can't really make new ones at runtime

meager spoke
#

guess an editor script it will be then to preload the objects, good idea, didnt think about that

meager spoke
#

okay it still is very proportional to how many values per key/objects i got but i got now 2048 values stored in player objects down to just a little less than 10% with 32 objects and an array of 64 uints per object

sturdy veldt
#

thx 💜

prime granite
#

there are workarounds for instanced objects to do networking

sturdy veldt
#

Yep, I use one all the time

subtle quest
#

it's very possible to design lightweight, generic, networking-only objects and use those to give networking to instantiated objects; very useful if you have different objects that work similarly (for example different pickupable items in a game that you want networked)

smoky mural
#

im trying to make a item unlock system for a Project im working on and i tried searching up Videos and Guides and i can't find anything about it i tried using the example but it not the way i want it to be

narrow tree
smoky mural
#

Like when you find a serect or item and when you click on the item you unlock a reward for it that what is trying to figure out

twilit meteor
#

There is sorta a prefab in VRChats home central thing

visual cargo
smoky mural
#

Yeah I tried the example already but it didn’t seem to work for me what I needed for

unique rune
#

Often you can't find a thing that fits your needs exactly

visual cargo
#

the idea would be to take that example and then modify it for what you want, or at least pick it apart to get a better understanding

#

just checked again and there still isn't really any video tutorials on persistence, best you've got will be reading the docs

timid drift
#

I was actually interested in asking, the documentation kinda lists a limit of like 100kb if i remember correctly, for player data, is the limit for playerobject the same? And if so, for stuff like world settings or even save files is it better to use playerdata or playerobject data for persistence?

#

For like preformance or general use i mean

visual cargo
# timid drift I was actually interested in asking, the documentation kinda lists a limit of li...

both systems have a separate limit of 100kb each, so it's 200kb (compressed) total persistence data overall.
Which you use heavily depends on what you're saving, how much, and most importantly how often.
saving in PlayerData is often more convenient, but a drawback of PlayerData is that all of the data must be sent over the network. So if you have a large amount of data in PlayerData, and you update just one value, all of that data gets sent again. If it's updated often, you could potentially clog the network
PlayerObject data is easier to break up, since you can have multiple PlayerObjects. You can split up any values that are being changed frequently from the ones that aren't, giving you room to optimize it

#

So for your case, if it's just a couple of world settings, PlayerData should work fine

timid drift
#

Can you control how often or when playerdata gets updated? Like having a button that uploads the data when pressed

visual cargo
#

definitely

timid drift
#

Awesomeeee

#

Thank you

subtle quest
#

You actually can't delay syncing PlayerData; if you change any value it internally makes a network sync request

edgy salmon
#

Where do we go for World SDK bugs?

I have a bug when using ulong as a persistence field data type. Persistence data get serialized as JSON then reloaded to give you persistence. JSON doesn't officially support ulong so you get a truncated value like 1.84219742784434E+19 and converted to double for the ulong value of 18421974278443368513.

Not sure if this reproduces on live, but does happen in Unity and super annoying to deal with and test locally. 🙁

unique rune
#

You submit bugs on canny, but here's a good place to discuss them

visual cargo
#

I don't think that's technically a bug, that's just a drawback of converting to JSON

#

but.... persistent data doesn't get converted to JSON though.

unique rune
#

yeah don't expect math to be very accurate if you convert it a bunch of times

sturdy veldt
visual cargo
#

it's only JSON for ClientSim

sturdy veldt
#

Oh weird

spice tendon
#

Hey! Is there any good persistence examples out there? Im really just looking to get examples on how data gets stored/accessed for different data types such as lists/arrays/maps

twilit meteor
spice tendon
#

So I am trying to wrap my head around the documentation for playerdata, but for something like this PlayerData.SetInt(POINTS_KEY, points); it seems as if this doesn't target a specific player? does this only target the local player? And what if I were iterating through all players in a world and I wanted to update a "win" or "lose" value?

visual cargo
#

correct; it does not target a specific player because you can only save the local player's data

Use these methods to save PlayerData for the local player. It is not possible to set a remote player's data.

#

if you want all players to update a PlayerData value, you'll have to send an event to the other players so they can run it locally

spice tendon
#

I think that makes sense! so for example if I wanted to reward the team, or a specific player, I would want to store them, or the team, in some sort of variable, then run an event that checks if (player.isLocal) then from there modifiy the respective PlayerData?

visual cargo
#

mmm kind of. It's more important that the function to set the PlayerData runs for all players

#

you might not need to check for the local player, because the methods are only going to apply to the local player anyway

#

it's likely your game management script is being executed by just one player, I assume. So whenever the game "ends" or whatever, they could call SendCustomNetworkEvent and target All players; then you'd have that function update the PlayerData

spice tendon
#

I think that makes sense. Ill have to play around with some ideas I have and see how everything works. I appreciate the help!

viral linden
#

Wouldnt OnPlayerDataUpdated be more suitable? since it is the OnDeserialization equivalent for manual sync

#

…equivalent for PlayerData, you know what i mean

visual cargo
#

that runs after a player's data has been changed

#

so you could use that to possibly update a UI with the counts for all of the players

#

that doesn't get around the initial issue of, you can only set the local player's PlayerData

viral linden
#

Oh right

spice tendon
#

if it does help to have some context, essentially what I am trying to make is a tcg. The player obviously will have a card inventory along with their deck, so updating the players owned cards and wins/losses, along with other misc values I don't want to super dive into. So a lot of the data will be important to keep per player rather than EVERYONE in the world

#

so something like:

Networking.LocalPlayer;
        if (!PlayerData.HasKey(player, INITIALIZED_KEY)) {```

everything in the if statement woud ONLY run for the local player correct?
visual cargo
#

it will only apply to the local player, yes

subtle quest
#

A psudocode way of writing that if statement would be "If I don't have the INITIALIZED_KEY in my PlayerData then I should"

spice tendon
#

is there a good way to save a sort of "community" leaderboard/stats across ALL instances?

bronze acorn
twilit meteor
#

I wouldn't say good... But you can store a leaderboard outside of the game and grab it via string loading

Users would need to self submit, one of the main tycoon guys has a system for that

spice tendon
spice tendon
bronze acorn
#

Ah, then as @twilit meteor mentioned then
In this example such things are stringloaded:

twilit meteor
#

IDK if the systems are public but you could follow a similiar setup

viral linden
#

Alternatively Japan Street has a nice demo of a "contagious" leaderboard that is updated with everyones data and is persistent across instances and rejoins

#

Stored in persistence

pale lava
twilit meteor
#

its the tycoon guy!

#

(Ik you do other stuff, just what I am most familiar from your works)

cursive barn
#

Sorry, doing some self-learning on how to make worlds... is player persistence (like.. level, score, vip, etc) stored in the cloud or locally?

sturdy veldt
cursive barn
visual cargo
cursive barn
#

👍🏼

foggy mason
#

My thinking is that the ToS for Udon-powered world moderation as currently written was well-suited before worlds could have persistence, but now that worlds can be powered by persistence, it is time to re-evaluate the ToS and create rules that account for cheaters able to misbehave in one instance and carry that result with them into new instances where the ToS does not currently allow creators to do anything about it.

#

Thoughts?

visual cargo
#

I don't think persistence warrants any change to the TOS

foggy mason
#

What is the best ToS-complaint way of keeping cheaters from ruining a competitive game's community/economy/high scores/rankings via hacked save data or modded clients (cheated item equipment, currency etc)

#

I do think VRChat is a good place for these kind of experiences, but there's really not a good way of maintaining good game integrety, as written.

#

Traditionally, it would just be "ban cheaters" , but, this seems to not be allowed

visual cargo
#

right, due to the common misconception that you as the world creator also have the authority to globally moderate your world

#

the most you can do is just make it harder to cheat, and to punish cheaters in a specific instance, but it will never be foolproof

#

I've seen strategies to obsfucate the data in the variable that holds the value of things like currency

foggy mason
#

Well that's why I think there needs to be a fundamental change in the TOS, essentially what's being said is you cannot use VRChat as a platform for the types of games that require the ability to designate specific users as no longer welcome in the game's global community

#

There needs to be a VRChat-sanctioned way to remove bad actors from ruining the global experience, not just from specific instances

visual cargo
#

there already is; you report them to moderation and they get banned

foggy mason
#

I don't think VRChat's T&S team can handle or understand all the individual little made up rules and codes of conduct that a game may have, understanding if they are legitimately broken or not, and banning VRChat accounts wholesale for violating any one of them.

#

Perhaps then, a world creator could create world-specific report categories to be sent to the T&S team?

#

And those categories populated into VRChat's own reporting system

foggy mason
#

But you can't expect a general VRC T&S member to understand the nuances of every contrived game mechanic in every game world to determine if the report is legitimate or not. It does not scale.

visual cargo
#

I mean, you can also already just report someone under the category "Client Modding / Hacking"

unique rune
#

breaking arbitrary game rules doesn't seem like a T&S issue to me

foggy mason
foggy mason
daring hull
#

We can't have world creators making user "blacklists" because that will inevitably lead to the very worst kinds of discrimination. However, we also can't be flooding T&S team with "User cheated at Game" requests because its not scalable and a waste of their time. The best moderation we have right now is Group instances where the group moderator can directly kick players who are cheating. But if the player has already made whatever gains, and those gains persist across instances...now we have a corner case where cheating has little consequence and there's no clear way to solve it.

hardy onyx
#

So like, listed name auto kick from the world is a tos no no but invalid cheat data make the experience awful a yes yes?

visual cargo
#

you are definitely allowed to have some sort of detection saying "woah you have an absurdly high amount of currency/you just gained way more currency than is normally possible. Set currency to 0"

foggy mason
#

Cheat detection is an arms race, and manual review will always be needed to fix what you can't catch

daring hull
# visual cargo you are definitely allowed to have some sort of detection saying "woah you have ...

Essentially, the status quo is world creators are going to have to get creative with how they detect cheaters and what they choose to do about them - but whatever they do must stop short of fully locking them out of the world/game altogether. Which opens up a can of worms of "following the letter of the law, but not the spirit of it". Also, its kind of a burden on world creators who want to you know create a fun game, to spend much of their resources combatting cheaters instead.

visual cargo
# daring hull Essentially, the status quo is world creators are going to have to get creative ...

yeah that's the entire point of the rule; it is not, and should not, be your burden as a world creator to moderate your world. Your world isn't really "yours" in the sense that you are supposed to boot out cheaters from every instance; rather, other people are just borrowing your world in their own instance and can do what they want within it as they see fit.
VRChat deliberately wants the burden of moderation to be on themselves

#

As a world creator at most you should be developing tools to punish cheaters on a per-instance basis, but are not permitted to develop systems to moderate in a global scope

daring hull
# visual cargo yeah that's the entire point of the rule; it is not, and should not, be your bur...

If it's truly the case that VRChat wants the burden of moderation solely on themselves, then perhaps we should have some Udon calls to report suspicious behaviour to VRChat in an automated way? That...seems like a big ask to me, and a large burden on T&S team. But who knows, perhaps VRC would be game for it. Some automated reporting tools I think would be welcomed by the creator community, I simply have no concept how expensive a system like this would be to implement

foggy mason
#

If this really is The Way VRChat Wants It To Be™ then world creators should be able to specify their own custom report categories to be populated on the report menu. But like I said, I don't believe this can scale. No T&S Team member is going to know the rules of 7D Multi-Dimentional Calvinball and be able to tell if a player actually cheated.

viral linden
#

In the ideal world, world authors are just designers, and VRChat Inc. ban all cheaters with cheat detection.
But evidently, VRChat Inc. is not effective nor efficient at policing cheaters. Perhaps because VRChat itself takes a fairly lenient approach to cheat detection (e.g. multiboxing is allowed lol) due to it being fundamentally a chat room with a fancy 3D interface rather than a serious game engine.
Imo it should be entirely VRChat's responsibility to up their cheat detection standard and treat their game more like a game.
User level moderation should be moderating user level problems, like someone pisses someone off, or breaking some social rules in the lobby.
User level moderation (or Udon moderation tools) should never have to tackle program level or hacking related problems, because that is a program level violation that is VRChat Inc.'s domain.

raw sigil
#

not on quest🤷‍♂️

dark quartz
# foggy mason My thinking is that the ToS for Udon-powered world moderation as currently writt...

I've been doing some thinking on this, and my feelings I think can be summarized thusly:

The fact of the matter is that persistence has introduced a very important change: instances are no longer entirely self-contained. The consequences of actions from one instance can carry directly into another. The Terms, and our ability to respond to this as a community, have to be updated to reflect that change. Regardless of what those updates might look like, they are in fact necessary.

I don't feel like that's probably something most people would disagree with?

#

Also hi I don't hang out here normally but I've been trying to branch out

terse juniper
#

persistent data can travel from instance to instance, but not from player to player (unless the world is programmed to do so). So I don't get how cheated persistent data can ruin a game, even if the game is direct PVP, unless a player with enough time (who doesn't cheat) can also ruin it, by doing the same thing, except obtaining any resources/currency legitimately by investing time.

sturdy veldt
#

So you don’t think in an rpg forcing yourself to max level and having all the quest items without any work wouldn’t ruin the game for anyone he kills?

#

Cuz I’d be upset if I found out a cheater didn’t work for any of the shit they had after they fucked me up 😂

wanton leaf
#

If you have a very powerful one use item that is intended to be seen used rarely, and then someone can instantly buy up thousands of them and spam them endlessly. One way to determine sure-fire that it is almost certainly a cheater is to have a currency cap, so that at best the average player can only buy (and probably hold) one or two at a time.

subtle quest
#

You'd have to worry about avoiding false positives and it would probably be really easy to get around (only spawn up to the cap; and then spawn more as needed while keeping within the cap)

wanton leaf
subtle quest
#

Well that would depend on how they're cheating or exploiting; exploiting is itself the game working as it was coded, even if the consequences weren't intended

stable slate
#

Was wondering if anyone could help fix this code. Im using a text mesh pro ui button to toggle an object on and off but I want it persistent and can't seem to make it work. I have no idea what im doing. ive gotten non persistant toggles to work fine

stable slate
#

nvm i think I got it to work, I just need to figure out how to have it start as on the first time you ever join. if anyone knows how to do that, i would be very greateful

stable slate
#

Messed with it all yesterday and still couldnt figure it out

stable slate
#

I figured it out finally!!! I was putting a unary negation in the wrong spot. It goes between the playerdata get bool and the game object set active incase anyone runs into the same issue

raw sigil
#

what. but it is supposed to go between get and set

ebon timber
#

I’m trying to create a fully-functioning Chao Garden system in VR Chat. I want to allow other worlds to participate, such as allowing players to summon their chao into the world, race their friends’ chao in the world, and even find up to 3 animals in each world

The best system I’ve found so far is just to save chao data as a text file and have players copy/paste the data into each world. With some encryption and a check to make sure that ChaoID matches PlayerID, to prevent cheaters from copying each other’s chao

Is there a better way to do this? The VRC website says there’s no way to program Persistence between worlds 🙁 But is it possible to set up my own server to store chao data? Or is multi-world persistence coming sometime soon?

viral linden
#

Multi world persistence is not coming anytime soon, the single world persistence is janky as is and there is no sign they will fix it

visual cargo
ebon timber
# visual cargo Your current plan isn't a bad idea since yeah, cross-world persistence is not pl...

Ah… Yeah I don’t think that’ll work then 🥲 Since the games I’m making are kinda geared towards kids…

My main goal is to create a game series called SPEED: Self-Paced Education for Expedited Diplomas. I could go on for hours about what makes it unique, but… Yeah… It’s meant to help teach Math, Physics, and Chemistry to people of all ages, and I don’t want to encourage children to turn off the safety settings 🥲

visual cargo
#

Sounds like a very noble thing to make. I'd imagine you could still make the idea work, you'd just have to reduce the scope so that progress only needs to be saved in one world

#

Personally, I wouldn't call the current persistence implementation "janky". I have not had any issues with it. I have a world from a year ago that still has my data saved and it loads it just fine.
Persistence is known to be exploitable by malicious clients at the moment, though. It is currently possible for cheaters to reset other players' data

sturdy veldt
ebon timber
ebon timber
ebon timber
#

I asked the VRC Help Desk if it’d be possible to set up an external server and get the URL added to the whitelist of trusted URLs

Their AI suggested that I just use github JSON strings since Github is already a trusted URL

Is this true? Would this work? Could github be used to send and receive chao data without a user changing their settings?

visual cargo
#

As with any AI suggestion.... it's half true

What it's referring to is String Loading, you can download data from the internet as a string and do whatever with it. It is technically only download/receiving data, you can't use it to properly upload/send data.
However, if you have your own webserver, there are ways to configure it so that when it receives a "download" request, the server just pretends it's actually an upload. Udon still treats it as a download, but the webserver just does its magic on the backend to save the data instead.
I hope that makes sense. I've never done it myself so I don't know the specifics, but there are a handful of worlds in VRChat that have set up something like this

ebon timber
#

Ahhh icic~ o,o May I know the names of these worlds? I’d love to talk to the creators and replicate that method~

elfin wren
#

(Looking at you fish devs)

ebon timber
viral linden
#

Prevent, no.
Minimize impact, yes.
"Networked" normally means networked events, but I dont know if that is what is in FISH that got exploited, I dont even know if non-networked methods can be called via network calling

sturdy veldt
#

I am about to start writing a new persistence script and will try this

viral linden
#

how do you even call any arbitrary public method? is it some third party hack tool? (mod this is a valid question of actual Udon security, we have to know the common points of attack in order to defend them)

#

if it is third party stuff, then shouldn't anti-cheat be catching them? (and shouldnt the Udon VM have some basic checks to prevent random methods being called?)

raw sigil
#

@viral linden quest has no anticheat

#

afaik its mostly coming from them

elfin wren
#

So there's nothing to catch

#

Its correct behaviour for the input state

#

Udon has very primitive networking

#

Anything not marked as private is assumed to be public networkable

elfin wren
#

Hmm it seems there were some changes a few sdks back too

hardy onyx
#

Cant expect anybody to fully understand the vaguely synced multiverses that is multiplayer games

ebon timber
#

Ahhh I think I understand what mistake they made. It sounds like they made their variables Public so they could adjust their variables directly from Unity’s interface. Instead of using the optimal [SerializeField] private variable type

#

I’m still fairly new to C# though so I could be totally wrong about that

sturdy veldt
#

Hackers/clients can still change private variables soo

twilit meteor
#

YL gl with any proper security

wary summit
#

The key to security is recognizing that hacked clients can do anything they want to your world on their computer. If you have private methods, private variables, disabled gameobjects, honeypot udonbehaviours, whatever - they can all be manipulated and you can't stop them.

However, what you do have control over is how other clients in the instance respond to what a hacked client is doing. If you really want to do everything you can about security, you have to assume that all incoming synced data can be compromised.

An example of this might be if you have an admin panel that can teleport other people around. VRChat clients do not have the built-in capability of teleporting other clients, so the only way to do this is with networking. You have to have some mechanism where the admin client communicates with the target client and tells them to teleport themself. However, if you implement it without the target running any verification, you are leaving it wide open for anybody to send the network event that makes it happen. It doesn't matter if the admin panel is locked behind a gameobject that is only enabled for admins. You have to assume that hacked clients can always break into your systems and enable it on their end. They can even pretend to be a username they're not. But they can't extend that same control out to other clients, so whenever they send a network event, your other clients will always be able to verify the name of the sender and see that they're not an admin, so they ignore it.

Similarly, any local setting like mirror toggles shouldn't have any networking connected to them.

You shouldn't leave holes for people to control other's persistence data - PlayerObjects and PlayerData have strictly controlled ownership and cannot be stolen by hacked clients, but if you have some other synced behaviour or network event that can lead to affecting someone's persistence data, that's still a backdoor. You need to ensure that you close all your backdoors.

sturdy veldt
#

Great write up, thank you 💜

spare smelt
#

Someone smart should make a tool that obfuscates your scripts and game objects when you upload to vrchat. Either when you click the upload button or just a script you run that creates a duplicate scene and temp folder that changes and scrambles all game objects names, method names, custom event names etc to random text that way it would make it harder for client users to mess with stuff.

viral linden
#

or Udon VM should do it natively

#

although, debugging will never be possible

#

if everything is scrambled

sturdy veldt
#

An on build script so it’s random each upload and you don’t have to ever read the jank

#

If you didn’t want debugging to be as hard you could probably also give it the ability to spit out the seed so you can use that to interpret logs vrcAevSip

terse juniper
#

name obfuscation of gameobjects that doesn't really help against hacked clients. Even without names, a gameobject's function can rather easily be identified by how it looks in game, and it's fairly simply to highlight any gameobject of your choosing (with a hacked client or the debug view, if the latter is enabled) to find out where it is in the world.

sturdy veldt
#

On the flip side, if a singular hacked client user wrote a hack for a specific world and handed it out, any update or change to any gameobjects in said hack would become unusable until the OP wrote a new one- this paired with daily or weekly uploads could completely throttle 90% of a world’s hack problems if there’s only a handful of folks who know what they’re doing

spare smelt
terse juniper
# sturdy veldt On the flip side, if a singular hacked client user wrote a hack for a specific w...

hence such a world specific hack would not rely on the randomized names staying the same, but the non-randomized metadata surrounding it. (gameobject positions, components attached to game objects, the udon instructions of behaviours [in case your obfuscation tool also randomizes variable offsets])
Sure, if you know exactly what the hack relies on to find what it needs you can break it, but most often the world author does not. And the names of the native unity functions udon calls cannot be randomized, and those will stand out like a sore thumb in most cases.

ebon timber
# wary summit The key to security is recognizing that hacked clients can do anything they want...

Imma be honest… I’m mostly familiar with Javascript and I’m still very new to C#, so all this private/public synced networking stuff is going way over my head @.@;

I think my strategy going forward will be to start off super simple and then work my way up once I get more familiar with C# and its vulnerabilities. And I’ll also leave a lot of room for power creep in my game to make any vulnerabilities obsolete… Like, if a hacker finds a way to give themselves 9999 pokemon, but all the pokemon are Magicarp, it won’t help the hacker in the long term + it’ll teach me a vulnerability for me to patch out

I’ll save this post and come back to it later once I understand the terminology better ^^’ Thank you~ 💛

subtle quest
# sturdy veldt I think the problem is anything public can be networked, so you’d have to make a...

@sturdy veldt @viral linden Bit of a late response, but any public method that starts with an underscore (for example _MyMethod) cannot be called over the network. ([NetworkCallable] might override this but I have not tested this). https://creators.vrchat.com/worlds/udon/networking/events/#legacy-events-and-security

To simplify what I know of how it works, a hacker can effectively send a SendCustomNetworkEvent to any or all players in an instance. That means any public method that doesn't take parameters is a valid target (they might also need to return void, but I am unsure of that). The underscore is how you protect from this vulnerability. Note that while VRC can't fix this issue in Udon without breaking backwards computability in countless works, Soba will likely (hopefully) fix this issue, where methods will need to be explicitly marked as networkable to be called over the network.

Network events allow simple one-way network communication between your scripts. When a script executes a network event, it executes the event once for the target players currently in the instance.

subtle quest
elfin wren
viral linden
#

Its a really obscure workaround to something that people shouldn't have to worry to begin with, why is udon so burdened with unfixable legacy stuff and why cant they just fix it and keep the old stuff running with old vm

visual cargo
#

Soba methods will be non-networked by default, and will require [NetworkCallable] in order to be networked, just like how events with parameters work currently

viral linden
#

Well i dont have very high hopes, we dont even know when it is coming out

marsh rover
#

Can someone help me out
I've been trying to learn persistence and I kind of got it working but I have no idea why the object is turning on for everyone else whenever somebody is joining. I've tried several workarounds but haven't figured it out yet.
the object is disabled in unity and the boolean isnt on by default either so i have no idea why it turns on

sturdy veldt
#

so a new player joins, they're restored, and you run your code again

#

you need to check if the player that was restored is equal to the local player reference

marsh rover
#

I'm still looking for a solution
I've tried a few variations of this but it either doesn't change the outcome or makes it worse.

#

Like it does work, it'll fix itself when they finish joining but during that time I have 0 clue why it bugs out and appears. it fires twice but shouldn't it still be using the localplayer anyways?

#

That's what I'm confused about, even if the player joining's data hasn't loaded yet when it fires the first time why would it affect other people when it's using the localplayer's bool. And why would the object turn on, Isn't the default bool value false? And if It did nothing the object is turned off by default in unity.
I really wanna figure this out

lyric kraken
#

it's kinda hard to tell what your exact situation or aim is, but you're using the local player's bool on someone else's object from what i can tell (when you see player restore fire for anyone, you're reading your local player bool for every playerobject of this type)

#

i suppose the equality check means it will only fire when you restore, but you probably want to read the owner's bool; by checking if it's the owner of the object being restored

marsh rover
#

I simply only want this gameobject to be active for people who have the boolean

lyric kraken
#

is the intent that everyone gets one of these objects? because playerobjects are created for every player that joins

marsh rover
#

Not necessarily, The object wouldn't be something you pick up and move around, more like an achievement that would only be visible to you.
But it wouldn't work without it having persistence enabled.

#

And I can't have it enabled without it having the playerobject comp

lyric kraken
#

playerdata is actually independent of that component to add persistence to the object; it's not necessary if you read/write with playerdata

if it's a single object you want visible/hidden, you may want to just remove these two components

#

the persistence component there only adds persistence to the player object itself for synced vars on it, playerdata can be read separately and persists regardless

marsh rover
#

Ah okay

#

I removed them but now the gameobject doesn't turn on at all

lyric kraken
#

you might want to log out the results of the bool and see if it's actually retrieving it with the TryGet as well

marsh rover
#

How could I do that?

lyric kraken
#

it's the Debug.Log node i believe; you can probably apply the bool as the message directly; i'd consider logging the bool to retrieve it (to see if it succeeds or fails), then the resulting value

#

it'll appear in the console, you can probably even test it in clientsim (in editor)

marsh rover
#

I might not be seeing it,
Is this right?

lyric kraken
#

you'll need to connect the impulse arrow

#

it's sort of an active process to log it

marsh rover
#

oh right

#

I still don't think I see it

#

Am I routing this right?

lyric kraken
#

i believe so, i'd probably have to check myself because i don't work with graph often

marsh rover
#

would any of this help?

lyric kraken
#

i'm seeing it log false for me (which is expected) here

marsh rover
#

Can you show me what the log looks like

lyric kraken
#

by default it's a lower tab near project

#

and you'll want the exclamation point toggled on, on the right hand side

marsh rover
#

Yeah I have everything toggled on, I'm looking there I just dont see anything

#

(toggled just the warnings on for this)

#

I looked through the log and there wasn't anything.
Searched through all the false flags and nothing there either.

#

it should be returning true

#

I don't know why but It's just straight up not logging it

lyric kraken
#

is the object inactive in scene?

marsh rover
#

Yes it was

#

okay

lyric kraken
#

ah it'll need to be active to fire restore

#

you may want to decouple the script as a parent above the visual if you want the visual to start off

marsh rover
#

Interesting, It didn't need to be when it was a playerobject

#

but anyways

lyric kraken
#

the playerobject instantiates it as a new active object for every player

marsh rover
#

ahh okay

#

So that's why they were on by default, I still don't know why other people could see it maybe it spawned before assigning it to the other person but that's just my guess

lyric kraken
#

your own restore wouldn't fire again when theirs spawns in

#

so it'd just spawn it

marsh rover
#

Ohh so then when they finished loading, it would hide it but there would be 2 hidden ones not a singular object thats being hidden and unhidden

#

New issue, now it's not turning off

lyric kraken
#

when you toggle it with interact? or when you restore?

marsh rover
#

oh wait

#

okay nevermind I just had it not routed to the setactive

#

Let me test this rq

#

YAAAAY
It work's now.

#

Hopefully with no issues

lyric kraken
#

just bear in mind if it's like an achievement people can acquire during play you'll need to enact the setactive at that point too

marsh rover
#

Yeah I was just waiting til this worked to iron it out

#

Otherwise they won't see it til' they rejoin

#

Tysm!

#

Now I understand a bit more about how persistence and playerobjects work and that's all I wanted.

marsh rover
#

Here's my graph code for a simple persistence object
Make sure to add GameObject and String as public variables to edit on the object itself

Use either the trigger or Interact version to set the bool
Then use that same bool name on Active on join to enable that object when you load in to the world.

I hope this can help somebody 💜

bronze acorn
#

So has anyone looked into the cross-world persistence for into the [un]known
Or know how it was done etcetc

viral linden
#

It has to be another VRChat secret beta testing round

bronze acorn
#

Yea, I'd be down with that
I think it's something that's been requested for a whileeeee(?)
So I just hope it's not gatekept

visual cargo
#

from what I've been told, it's not a secret feature, it's some trick that has to do with shader globals

bronze acorn
#

I see
So two world lines

  • Feature testing
  • Officially endorsed hack of requested feature
    Let's hopee it's not the latter
subtle quest
#

Although with the mention of "shader globals" it might not be persistence at all, but rather one or multiple flags being set that persist through world change (although I imagine they'll be lost on game reload)

bronze acorn
#

Persistence is persistence is persistence
Whether thru shader or other means
The data has persisted sorta deal
The method is in question
No URLs loaded

#

To answer your first question
When you exit the world, complete a world made by another
And come back (immediately)
Progress for completion is tracked in this "hub"

#

On some crash bandicoot hub world schnizzle

viral linden
#

How can shaders persist data across a scene load?

#

At the very least they need to persist an int or a float to carry across at least 13 different flags because there are 13 linked worlds to complete

bronze acorn
visual cargo
bronze acorn
#

Questioning the open air is kinda silly
These people are here and currently just exist to be silent
I don't even know if it unlocks a tape but @velvet barn your world was a part of this
Do you have any input or were you told anything

velvet barn
# bronze acorn Questioning the open air is kinda silly These people are here and currently just...

I can confirm it's not some hidden beta persistence feature provided by VRChat as people had speculated (like Fish! has for the anti-flying mechanic) since that much has already been stated elsewhere. But I'm not really at liberty to speak more about it at least at present. It's not something I came up with, was only shared with me in confidentiality as part of this project, and it's the sort of unintended mechanic that could theoretically be patched out by VRC.

visual cargo
#

hence why I was theorizing testing it.... because this^ is pretty much the only answer I've gotten so far every time I ask about it

bronze acorn
#

Cool beans
Thasall I needed to know

velvet barn
#

I promise we're not trying to be gatekeepy about it arbitrarily. I'd love for VRC to have cross world persistence broadly. This just exists in a weird gray area, and until told otherwise it's not something at least myself and many others involved can speak on right now 🙁

bronze acorn
#

Sigh
Just means I need more notoriety to be in the in-club one day with my awesome sauce world building skills
I'll get there one day

viral linden
#

Official event! Theme: VRChat cannot patch things because UGC is built on hacks and exploits. In both the fictional universe, and the actual execution of the event!
I don't mean to bash on anyone but at a more basic level, while the Jank gives birth to some amazing hacks (like this one) it is ultimately detrimental and an obstacle to UGC.
Imagine a world where flying is a well made mechanic, where stations just works, and where persistence works across worlds, that is the condition where UGC can flourish. These collider flying hacks, and shader based multi-world persistence hacks, while creative and impressive in their own right, are not true indication of a platform that fosters creativity, but the opposite of it.

#

I fear that VRChat Inc might be mistaking Jank workarounds as expressions of creative freedom hence not willing to patch things or implement things/tools properly. That would not be a correct path in my opinion.

visual cargo
#

VRChat is usually very vocal about patching such things, and tends to offer an alternative to the same feature when it's patched out

bronze acorn
#

Yea, that's fine
World line two still marks this as a bad ending
Despite anything else

velvet barn
# viral linden *Official event! Theme: VRChat cannot patch things because UGC is built on hacks...

Did UGC have something taken away from it, or have the existing conditions made it incapable of flourishing for the past 10 years?

I like new things too, and I do agree VRC is quite often conservative on their restrictions and slow to implement new things. But we also finally got built-in persistence at all just a year ago. To suggest the platform is incapable of flourishing unless it has everything everyone asks for immediately feels a bit dramatic.

bronze acorn
#

Yeah tbh the fish thing is way crazier
This at-the-top gatekeeping thing is just only nasty/mini-corrupt

velvet barn
#

I'm fine with that one if once testing concludes they proceed to roll it out broadly, or otherwise roll it back.

bronze acorn
#

Actually, that's my bad
Did they actually announce it anywhere in any official channels
I'll roll back my fish statement

#

"We're testing X/Y/Z for Fish" sorta deal

sand lantern
#

iirc it was on last week's dev stream they commented on it

#

I don't have a timestamp bc I missed it but I think it was pretty early on

visual cargo
#

for the Fish stuff?

#

I wrote a summary for what they said on it

velvet barn
#

Yeah. They have mentioned it on official channels, just not in a mass VRC discord announcement or the dev posts. Which is okay by me, I don't think it applies to most people.

bronze acorn
#

I guess I can give it to them if it was unprompted
And not a "what's going with fish sorta deal" in which they then had to answer on it during a q&a or w/e

#

I could barely give them that though if "World A" is being tested with "Feature A" and it's not on dev forum, channels, or other
That's baarreeelly a give

#

Esp for such tunnel visioning for something at the top

visual cargo
bronze acorn
#

I can't grant popularity as if the sample size for the popular worlds that came before it collectively didn't already surpass its numbers today
Especially over X duration for however long they've been wanting to test it
X duration over Y popular worlds already gives more data

#

At this rate
If numbers were the goal
Get as many large worlds as you can including Fish
What r we saying tbh

#

I think it's healthier to just say they sortakinda forgot about it and when fish blew up they threw it in as a test
Not because they were thinking about any optimal methods or a chance for popularity
Likely because Fish just had a higher demand to disable flight across an open area

visual cargo
#

it was also Godfall who submitted the Canny suggestion to disable flight colliders in the first place

bronze acorn
# velvet barn Yeah. They have mentioned it on official channels, just not in a mass VRC discor...

I missed this message btw
It's kind of a crazy one
Don't all anti-cheat measures apply to all world creators whether or not they want to use them
All new world features apply or relate to the set of all world creators which is why they make roadmaps or announcements
Not that it had to be an announcement when they decided to do it
But maybe as a mention in any announcements thereafter or sooooomeeething
I will never endorse such arbitrarily low communications about the platform I want to make things for

visual cargo
#

that's the entire point of enabling it only for Fish, they're still testing the system and figuring out what will work best

#

currently how it works would not be ideal for everyone

bronze acorn
#

Just to be clear
This is only about communication
Not about what it means for everyone else

viral linden
# velvet barn Did UGC have something taken away from it, or have the existing conditions made ...

I guess i was looping in stations and collider flying to illustrate the point of janky chairs and janky wings makes it harder and arguably impossible to design or creative maps with them, and the loss would be measured in years of lost UGC due to poor implementations (or non-fixing of a bug). If station worked at some point it would have became a more common feature thus more variety of maps. If the collider flying was fixed years ago creators would have the drive to innovate world based flying where flying is less jank. Arguably persistence (the multi-world version) would follow the path of the latter. My argument is bad tools only benefits a contorted and less accessible expression of creativity.

#

One can say, yes nothing is perfect and can always be better, but cmon, jank is jank, i'd say, and call it what it is, and that we can all use a bit of less jank

#

VRChat is fixing things, sure, but it seems they can never get rid of jank, almost at a religious level they must include jank in their execution, but can the devs simply make things just work?

#

Can VRChat transition away from its humble and janky origins and become something a bit more... polished at its core?

#

I am rambling at this point but jank is jank

lofty wharf
#

give it time to finish adding cross world persistence and ugc-ifying the shop

#

xd

bronze acorn
#

Valid
Though everything that it's not isn't helpful
After already being told it was under NDA

#

I don't really need more info

junior goblet
#

How is persistance data linked to player GOs? More specifically, does it have anything to do with the network ids?
Im curious if regarating the newtwork IDs for a scene would break all of the current persistance data.

raw sigil
#

@junior goblet yes it absolutely would for player objects. wont for player data

#

ofc depends on it actually getting a different network id

junior goblet
#

Hmm yea i assumed it was networkID based. Alright. 👍

sturdy veldt
#

Where do you go to delete persistence data from clientsim again?

visual cargo
#

VRChat SDK > ClientSim PlayerData/PlayerObjects

sturdy veldt
#

Huh, I checked there and didn’t see anything, guess guess I just wrote bad code and it’s not the data 😂

visual cargo
#

keep that window open while in Play mode, should be able to refresh and see it update live

#

worse case you can hit the folder button and see if a JSON file is getting created

fervent geyser
#

Excuse! Is oversized player data associated with endless 'Vrchat transmit important data'? Or a playerdata will continuously get larger as the game goes on?

light laurel
#

so i have a world with about 120 objects, and each one has a bool for whether it's been discovered, and a string for it's name saved in persistence. right now they're all separate keys and are saved separately, but i figured it's probably ridiculous to have so many separate keys and values, so is there a better way to save all that data?

#

can i persist a JSON or a data dictionary maybe?

visual cargo
#

You could save a data dictionary as a string, but it's going to take up more space than if it was just the bools

light laurel
#

that's what i was wondering mainly, is 120 bools and strings more or less data than if i use some other data type to save it all

#

i don't think there's any noticable performance impact for loading all of the bools and strings anyway

#

(i'm just activating or deactivating gameobjects or setting the text of a Text component)

visual cargo
#

With them being all bools, if needed you could save space by bit packing them together

light laurel
#

is there a way to see how much space my playerdata takes up? would the clientsim JSON file be accurate? (not if it gets compressed by VRC)

visual cargo
#

Yes you can, but I know the ClientSim and Build & Test values are inaccurate
There's a function in Player data for it

light laurel
#

ah okay, i see

#

thanks

visual cargo
#

Bit packing could be worth it for you to do, theoretically could turn 120 bools + strings to just 15 bytes + strings

sturdy veldt
#

Bit packing would be a lifesaver for this ^^

#

why have 120 bools if you could just do 120 bits in a few ints instead yepyepyep

#

32 (or 31?) bits per int means what, 4?

light laurel
#

so uh, how would i do bit packing? i’ve only heard of it, never done it

sturdy veldt
visual cargo
#

hm maybe

#

well...

#

I mean if it's all bools then what are you gonna do with the enum

visual cargo
# light laurel so uh, how would i do bit packing? i’ve only heard of it, never done it

I forgot to get around to answering this
so I get the concept of bit packing, but never actually had a reason to do it in Udon, it'd be one of those "figure out as a go" type deals. There's probably C# tutorials out there for it too

but you get that 1 bool should theoretically only take up 1 bit of space right? It's just a 0 or 1. But in C#, and when a bool is networked in Udon, it takes up a full byte instead, either 00000000 or 11111111
That's a lot of wasted space for something that's essentially just a 0 or a 1 in the end.
So, if you've got 8 bools or less, you can "pack" them into one single byte instead. Potentially turning 8 bytes of data, down into just 1 byte
You'd decide a certain spot in the byte for each bool, then just set the individual bits as a 1 or a 0 depending on the value of the bool

#

you pack them up in OnPreSerialization, then unpack them and assign out the bools in OnPostSerialization and OnDeserialization

#

how you pack them I guess would be the fun part. You'd probably make use of the bitwise operators, like bit shifting or bitwise logical operators

sturdy veldt
#

Interacting with ints and flag-enums is the same since it’s just bit shifting, which is why I suggested that since an enum is basically a preset “one string per bit” stuffed into an int, which is exactly what is needed rn

#

But internally idk if an enum has a bigger overhead or jack all about that, and if this needs to be udonsynced idk if you can sync an enum

visual cargo
#

you can't sync an enum, no

#

not directly at least

#

I don't even know if Udon lets you use one like this

sturdy veldt
#

It does cuz I’ve been using it for the past few weeks now

#

I made a tag based furniture browser UI with it

subtle quest
#

you can't sync an enum, but you can convert it into a syncable value in OnPreSerialization

#

just a heads up that directly casting an enum into anything that isn't an int will either cause a runtime exception in Udon or silently break networking in the background; you'll need to cast and assign it it to an int variable and then cast that int variable into your desired data type

#
public override void OnPreSerialization()
{
    // directly converting an enum to a byte here silently breaks the object's Udon networking
    int golfBallStateInt = (int)golfBallState;
    golfBallStateByte = (byte)golfBallStateInt;
}
coarse vale
#

I tried to add a second PlayerObject to my game but it always errors out with the message:
Network ID 117 for [POTemplate name] [1] does not match desired ID 115
This is when trying to access it with Networking.FindComponentInPlayerObjects in OnPlayerRestored

Right before that, I access the first PO I had added and it's never given me a problem.

Regenerating network IDs only changed the number in the error.
I upgraded the SDK from 3.10.1 -> 3.10.2 and that didn't fix it either.

Edit: Fixed by removing the VRC Player Object & VRC Enable Persistence components and then re-adding them.

visual cargo
#

can you show that error fully in the console? Seems like an odd one

coarse vale
#

Well I just inadvertently fixed it by removing the VRC Player Object and VRC Enable Persistence components and re-adding them. Guess some bug during creation of the PO left it in a weird state.

coarse vale
#

Added a third PlayerObject and the second one is throwing an error again in the editor, but this time it's functioning anyways (previously I would get this error twice and the object would never show in the ClientSim PlayerObjects).

UnityEngine.Debug:LogError (object)
VRC.SDK3.ClientSim.ClientSimMain:FindComponentInPlayerObjects (VRC.SDKBase.VRCPlayerApi,UnityEngine.Component) (at ./Packages/com.vrchat.worlds/Integrations/ClientSim/Runtime/System/ClientSimMain.cs:508)
VRC.SDKBase.Networking:FindComponentInPlayerObjects (VRC.SDKBase.VRCPlayerApi,UnityEngine.Component)
VRC.Udon.Wrapper.Modules.ExternVRCSDKBaseNetworking:__FindComponentInPlayerObjects__VRCSDKBaseVRCPlayerApi_UnityEngineComponent__UnityEngineComponent (VRC.Udon.Common.Interfaces.IUdonHeap,System.Span`1<uint>)
VRC.Udon.VM.UdonVM:Interpret ()
VRC.Udon.UdonBehaviour:RunProgram (uint) (at ./Packages/com.vrchat.worlds/Runtime/Udon/UdonBehaviour.cs:1156)
VRC.Udon.UdonBehaviour:RunEventAdvanced (string,bool,bool,System.ValueTuple`2<string, object>[]) (at ./Packages/com.vrchat.worlds/Runtime/Udon/UdonBehaviour.cs:1801)
VRC.Udon.UdonBehaviour:RunEvent (string,System.ValueTuple`2<string, object>[]) (at ./Packages/com.vrchat.worlds/Runtime/Udon/UdonBehaviour.cs:1759)
VRC.Udon.UdonManager:RunEvent (string,System.ValueTuple`2<string, object>[]) (at ./Packages/com.vrchat.worlds/Runtime/Udon/UdonManager.cs:1222)
VRC.SDK3.ClientSim.ClientSimUdonManagerEventSender:RunEvent (string,System.ValueTuple`2<string, object>[]) (at ./Packages/com.vrchat.worlds/Integrations/ClientSim/Runtime/System/ClientSimUdonManagerEventSender.cs:16)
VRC.SDK3.ClientSim.ClientSimPlayer:CheckPlayerRestored () (at ./Packages/com.vrchat.worlds/Integrations/ClientSim/Runtime/Player/ClientSimPlayer.cs:368)
VRC.SDK3.ClientSim.ClientSimPlayer:OnPlayerDataDecoded (VRC.SDK3.ClientSim.ClientSimOnPlayerDataDecodedEvent) (at ./Packages/com.vrchat.worlds/Integrations/ClientSim/Runtime/Player/ClientSimPlayer.cs:381)
VRC.SDK3.ClientSim.ClientSimEventDispatcher:SendEvent<VRC.SDK3.ClientSim.ClientSimOnPlayerDataDecodedEvent> (VRC.SDK3.ClientSim.ClientSimOnPlayerDataDecodedEvent) (at ./Packages/com.vrchat.worlds/Integrations/ClientSim/Runtime/Events/ClientSimEventDispatcher.cs:62)
VRC.SDK3.ClientSim.Persistence.ClientSimPlayerDataStorage:LateUpdate () (at ./Packages/com.vrchat.worlds/Integrations/ClientSim/Runtime/Player/PlayerPersistence/ClientSimPlayerDataStorage.cs:864)```
viral linden
#

do the gameobjects have the same name?

coarse vale
#

Nope, different names, created from scratch separately, nothing connecting them. Now it's just randomly selecting one to complain about each time 🤷‍♀️ another random bit of log spam to add to the pile

sturdy veldt
#

I have a player persistence object as a child of my playermanager playerobject, with a reference to the persistent object built into my playermanager script so I can pull my save data with the manager

#

Is this allowed?

#

Or is my pre-set reference making it so all players get a reference to the disabled, original persistence obj?

#

Because rn I can't load any persistent data and Idk if this is the culprit or if I need to look somewhere else

#

I was under the impression this would be ok 😅

viral linden
#

are the variables synced variables?

#

looking at the docs your setup should be fine

sturdy veldt
#

yeah they're all synced, I actually got it to load partway by delaying my playermanager with execution order 🙏

#

I was already bumping persistence up but I apparently had to specifically knock playermanager back

viral linden
#

Use the OnPlayerRestored to detect that a PlayerObject has finished loading User Data. This event is executed once for every player in the instance, including the owner of the PlayerObject.
?

sturdy veldt
#

yeah I'm doing that already, really confused why it's seeing null values

#

ok it only worked once lmao

#

And now it's again not working on rejoin

viral linden
#

hard to say without seeing the full codes, are you writing stuff before OnPlayerRestored?

sturdy veldt
#

I don't have any time to investigate any more today, just gonna have to blow another day on this at some point ig

#

So weird that it worked once tho, and specifically someone else was in the instance at the time. Like re-opening the instance loads differently than joining an existing or something.

viral linden
#

what is the null for? just one variable?

sturdy veldt
#

no it's all of them, all my true/false are read as false, all my arrays are read empty

#

like the entire persistence doesn't exist

#

but I added a function that loops every 5 frames until a flag that's set at the END of persistence is true, so the fact that it's even putting me in a room (which it does) means it's getting the OK that persistence is done

#

then it checks the data and sees nothing for some reason

#

Even persistence direclty setting the settings board is setting it to false in its own restore

#

Like it's just seeing a stock version of persistence for no reason smh

#

and they're all synced public variables

#

When you're in-game and you place any furniture, it adds to your persistence and runs a networked event to ask all players in that room to check your persistence

#

everyone can place, remove, and watch others do the same perfectly fine

#

there's literally no reason that I shouldn't be seeing the data on persistence when I load in after doing allat

#

this the type shit that makes people give up on VRC I swear xD

viral linden
#

um, if it is synced variables, you don't need to ask other player to check your persistence, because the synced variables should already be synced, they are ready at OnDeserialization like normal synced variables... wait, are you using the VRCEnablePersistence component?

sturdy veldt
#

I'm fucking not

#

thank you uzer

viral linden
#

i was under the impression you have a VRCEnablePersistence component on a child object

sturdy veldt
#

nope I definitely didn't enable persistence on my persistent save object facepalm

viral linden
#

then... it has nothing to do with PlayerObject really

sturdy veldt
#

Thank you, people leave VRC because they're dumb like me 🙃

unique rune
#

ooh, there's a classic

viral linden
#

i cant tell if this is /s

sturdy veldt
#

It's a classic cuz everyone's been there for sure 😭

twilit meteor
#

🐥🚬

lunar isle
# sturdy veldt and they're all synced public variables

I don't know if this is an issue in practice but shouldn't you not set a variable to an initial value like this because it's synced? I'd worry about the playerSeed getting picked up early by something before the value is restored and causing some problem with my code later on, or maybe the variable gets overwritten despite having a persisted value.

I create my persisted variables then set them on restore if they don't exist already, but maybe it's really not an issue and I'm just overthinking it.

sturdy veldt
#

sounds like overthinking 😂

viral linden
#

And as far as whether to initialize the value before OnPlayerRestored, I think all persistence data are value types so they cannot be null, they will have some sort of default value

lunar isle
ebon timber
#

I think I’ve finally found a workaround to create cross-world data persistence

Please let me know if there’s an easier method because this current method is soul-sucking

weak venture
#

this is so cursed and cool

viral linden
#

Doesnt avatars get reloaded upon entering a new world? Would bone positions persist?

terse juniper
#

you could also use contacts to transfer data to an avatar, which uses a parameter driver to set synced and saved parameters (which will persist upon entering a new world), and then use contacts again to read the data out.

twilit meteor
#

I didn't play the latest event that sparked this cross-world persistence, but was everyone required to wear a specific avatar?

visual cargo
#

no, that wasn't necessary for VITU

subtle quest
#

From what I heard it required you to directly travel from one world to the other, right?

visual cargo
#

not directly, just has to be done at some point in your current VRChat session

#

so the data is stored "persistently", but only while you have the game open; if you close the game, you have to revisit the world to get the values it's looking for saved again, then you could go to the hub to permanently save it

#

for example, I took a friend through, he did the first world without going to the hub after, just went straight to the second world. but after returning from the second, it saved the progress that he did the first two

#

I also went and 100%'d it by speedrunning all of the "Discovery' worlds in a row, and only had to return to the hub once at the end when I finished them

subtle quest
#

there's no way for Udon to access to logging menu or file, right?

subtle quest
ebon timber
raw sigil
#

contacts would be a new thing but still do require for a certain avi to be worn. still no idea how physbones/bones would work beyond figuring out furry bases via bone position proportions (or a custom avi to be worn so back to a pre persistent days). am i missing smth?

#

ie i dont think physbones or any of that kind are persistent between instances

hardy onyx
#

Has the clipboard copy/paste method been brought up yet. Idk anything about it personally but ive seen worlds that let you save to your windows copy button

subtle quest
#

I'd be a bit converned if they had the ability to read your clipboard without you knowing

fresh mica
#

Not how that works

#

You paste the generated code into a textbox

ebon timber
# raw sigil ie i dont think physbones or any of that kind are persistent between instances

My understanding of it (I didn’t write the software) is that it adds & deletes particles which interact with the physbones. But the software was written like 5 years ago, before single-world data persistence was a thing, so the project has largely been abandoned and is probably outdated. Hence I’m looking for other ideas

I’m really curious what avatar contacts are 👀

#

And forcing players to wear a certain avatar is totally fine for me. My game, Pokemon SPEED (self-paced education for expedited diplomas), is meant to be PG-13, so I was planning on forcing players to wear SFW avatars anyway

subtle quest
ebon timber
#

Thank you! ^.^ 💛

#

Quick question. It says an avatar can only have 256 contacts. And that contacts can only have 16 tags. Does this mean I can have 16 tags total? Or 256*16=4096 tags total?

ebon timber
#

Did some studying using kapa ai. It seems that Contacts can send some data, but not a lot

ebon timber
ebon timber
unique rune
#

have you tried the VRChat docs?

ebon timber
unique rune
#

feel free to ask for clarification in here, you'll probably get better results than an AI

ebon timber
#

If I make a fully-functional Pokemon game in VR Chat, how likely is it to actually get taken down? ||I.e., how likely is it to persist through moderation?||

#

In that same vein of questioning, how often do worlds actually get taken down for copyright infringement?

craggy obsidian
ebon timber
#

How likely is VR Chat to take down a game like that? @.@;

cobalt hatch
#

if they get a DMCA, yes

craggy obsidian
ebon timber
#

Icic @.@; So very likely…

craggy obsidian
ebon timber
#

Unless I could somehow get permission from Nintendo… But I’d be more likely to win the lottery 😞

subtle quest
#

While I will not comment on the specifics of VRC's rules and ToS, I will point out that VRC's design largely obscures worlds from outside view and that getting attention from IP owners enough for them to care is going to be very hard to accomplish. I'll also point out the existence of games recreated in VRC and that while a significant amount of content in VRC may or may not be copyright infringement, I've never heard of any DMCA takedowns for generic stuff.

The biggest consequence will likely be the VRC devs giving your world zero official acknowledgment no matter how popular it gets, and also the world never getting approved for the creator economy.

sturdy veldt
#

I have seen VRC cancel their own planned events after asking creators about them, because the world in question felt “too copyrighted”

#

even when it actually had no copywritten content, it was just heavily inspired by something

sturdy veldt
upbeat dagger
#

Worlds have been taken down because of DMCA's in the past. The moment you use someone else's IP without their permission, you run the risk of action against you.

ebon timber
sturdy veldt
#

idk if anyone would actually issue a takedown / dmca. the only dmca I’m aware of ever happening was for someone pirating movies for their site and posting it all over / heavily associating it with their world.

#

which is to be expected 😅

upbeat dagger
#

Ace Combat DMCA's a couple flight worlds because they were using their jet 3d models

visual cargo
# ebon timber I’m getting two conflicting messages x.x The Pokemon Fusion people are telling m...

think of it this way.... technically, every time you upload a world or avatar to VRChat, you check a little box and agree that you own the rights to everything you're uploading.
So, do you own the rights to Pokemon? No.... so you're technically lying when checking that box. According to VRChat's TOS, you are not allowed to upload that content

however
There is no automated system in place that checks your world for IP infringement. That isn't really possible, really. For your world to be sanctioned for IP infringement, the owner of the rights would have to submit a DMCA request to VRChat asking to take it down. As in, they actually have to care enough to feel like that's worth doing.
If you search VRChat worlds for "Pokemon", you find hundreds of worlds based on Pokemon. Even worlds with straight-up illegally obtained assets!
The thing is though, Nintendo has to care to go in and request these to be taken down. None of these worlds are doing any significant harm to their image or profits.... so it quite literally costs them less money not to care. And so, all of these worlds stay up

So in summary, if you wanted to make your own world, based on Pokemon, or Mario, or Sonic, or whatever? Use your best judgement. The most likely scenario is Nintendo will not care, and not bother you. But that risk will technically always remain.

upbeat dagger
#

Law language is very specific for a reason. Over general answers from people will never really give you the true answer. You'd need to look into the exact wordings of all the statements from all sources to build the proper picture. Aka what lawyers are paid to do.

unique rune
#

Nintendo is quite... litigious

viral linden
#

So when people make "Pokemon stuff" on VRChat these are known as derivative works, which the "new parts" are copyrightable. However the original copyright owner The Pokemon Company (which Nintendo owns partially) has exclusive rights to prepare derivative works based upon the copyrighted work, subject to fair use. So unless your world or avatar is firmly in the realm of fair use (which is a test of several factors like commercial/non-profit and transformative and fiction/non-fiction and substantiality and effect upon work's value) then you are infringing the copyright of The Pokemon Company, who can DMCA you and sue you.
But since you are unlikely to make any substantial commercial profit and have much effect on the IP of Pokemon, you are not going to be a big enough fish for Pokemon Company to spend money/attention on. Unless, of course if you somehow make it a super profitable world and is attracting massive viral attention, that changes the risk/reward equation for Pokemon Company.
So it can be a grey area, the original copyright owner may or may not DMCA and/or sue you for infringement (regardless of whether it may or may not be actual infringement or fair use, which is decided by the court), depending on what you create, and how other people react, and how these change over time as well.
Most likely outcome is Pokemon Company is not going to care. But that does not automatically mean it is not an infringement. It is entirely your risk and it is really a case-by-case situation.

ebon timber
viral linden
#

That alone would not be enough to make it fair use, it would not even be enough to make it to the grey area... you are hinting at some level of transformativeness, but arguably that is not transformative at all, actual copyrighted Pokemon can learn new moves all the time in all sorts of combination, you are not changing anything really

#

And it can be a matter of opinion, and it also depends on what your new features and abilities are really

#

But if you have to ask, it most probably is not fair use. If it is not quite obviously fair use, it is entirely your risk

ebon timber
#

The new features would be a fusion mechanic, where each fused pokemon would have 2 models (the models of the two input pokemon) and then allow the player to lerp the values such as vertices’ positions and color palettes. So like, if I wanted a fire/ghost Ninetails with Ghastly’s color scheme, it would 100% Ninetails on all of the Legs/Arms/Torso/Head vertices and 0% Ninetails on all of the color palettes. Similar to Pokemon Infinite Fusion but in 3D

#

The same system that Chao Gardens used in the Sonic Adventure games

viral linden
#

Arguably, Pokemon Infinite Fusion creates new and unique pokemons by mixing two together ~50/50. Mathematically, you lerping between two existing pokemon make a sort of bell curve of "newness", with only the middle part is more unique, and either ends are close to straight copies of an existing pokemon.
So while you are in a similar boat of Pokemon Infinite Fusion (which is not risk-free), allowing it to slide between the two actually decreases the overall proportion of arguably original content, if that makes sense. Mathmetically speaking if you average a bell curve you end up having only 50% of your originality. So you are really only on a same boat with one leg, and the other leg in hot water so to speak.

#

It gets even worse if you slide on two axis.

#

That is, even if mixing two pokemon is even considered new. Arguably it is still derivative work. Pokemon Company choosing to ignore it, is their choice.

#

But again, it is a matter of opinion, fan games and fan content are made all the time. And again, they probably won't go after you if you are just making a fan game and not really making any profit.

#

Like LEGOS has pointed out there are hundreds of pokemon worlds already. You are not making any super revolutionary content, you are probably fine.

ebon timber
#

Nice~ But I’ll still make my own models just to be sure

twilit meteor
#

I met this guy who made avatars. He has pokemon trainers and each one can summon a pokemon and you can kinda fight.

That is a bit harder to detect, compared to a world, but I don't think they are taken down.

Also, maybe Nintendo has bigger issues now, since they lost their patent or whatever VS Palworld

#

Honestly it's always gunna be a coinflip in regards to this stuff.
Just don't paint a target on your back by profiting off of the content.

ebon timber
#

I found a solution but it’s TL;DR:

  • 3 versions of the game; two versions are legally distinct
  • Games can share data with each other thanks to the cross-world data persistence thing
grizzled depot
#

hey how do i fix my world popping this up and just not going away

sturdy veldt
#

I’ve never seen that before in my life

#

I wonder what you did to your persistence setup for that to happen

#

unless it’s just waiting to pull it from the servers and won’t for some reason

subtle quest
#

@ebon timber using the Pokemon name alone could run afoul of trademark laws

viral linden
#

maybe the network is clogged and the world is trying to save

grizzled depot
grizzled depot
ebon timber
# grizzled depot wait how does cross-world data persistence work?

It’s very janky. You literally have to:

  • Force your users to wear a NUSS avatar
  • Save the player’s data onto the NUSS avatar by changing avatar parameters that add particles that alter the rotation of the avatar’s physbones
  • Now your next worlds are able to read their save data by interacting with the avatar to read the rotation of the physbones
#

||Or you can just force your users to copy/paste their save data between worlds like in Bullet Time Agent||

grizzled depot
ebon timber
#

Frfr. That’s what I’m going to start with on my game, then move on to NUSS later

grizzled depot
#

yea fair

grizzled depot
#

could it be because the world is private?

light laurel
#

no

#

no idea why it happenes, but no, persistence works in private worlds

#

have you had anyone else besides yourself join to test it?

grizzled depot
#

could it be the save code file is too big?

light laurel
#

what are you saving?

#

the limit is 100kb so it’s not like you can save a ton of data

grizzled depot
#

hmmm

#

that might be why

sturdy veldt
#

seriously think you could block “bro” with 4 images and wouldn’t effect a single human post

weary quest
#

So tired of the creative channels being targeted.

#

At some point I'd hope the creative channels split into a VRC creator's space away from the chaos of the main VRC discord.

#

Would be nice.

twilit meteor
#

yeam it pmo that the bots keep hitting these channels cause them im wasting all these click for no new messages 😡
why are these hackers so selfish and eating up my precious seconds

sturdy veldt
weak venture
#

well well well speaking of
lmao

twilit meteor
#

No the easiest addition would be dont let people post photos in here if they have never sent beyond like 10+ messages in these channels

#

So then if people are explaining issues, we will try a bit and then eventually get photos, 10 may not be right

#

proibablyt can just do 1 tbh

#

since there are only so many brave souls that step into this domain. IDK if this is even doable to setup but maybe a helper can pass the idea along?

ebon timber
#

I’ve found a way to store nearly 33kb of useable data per avatar. Each avatar can have up to 8192 avatar parameters. If updated locally, each avatar parameter can store a 32-bit float. But those 32-bit floats get turned into 8-bit floats if synced with the server and other players. So now I just need to:

  • Find a way to read & write all data locally to maintain the 32-bit floats
  • Find a way to read & write data in a way that’s actually fast and doesn’t require 10,000 physbones (probably easy, but I have skill issues)
  • Then I’ll finally have cross-world data persistence by storing 33kb of data onto an avatar
  • MMORPG in VR Chat
sturdy veldt
#

I gave him that a week ago and he ended up not using it

#

I have no idea why he’s reinventing the wheel tho

fading totem
#

Why do you even need to store that much data

ebon timber
# sturdy veldt I have no idea why he’s reinventing the wheel tho

NUSS has an upper limit of 8kb / avatar. And after talking to the creator, he recommended I re-write a lot of the code to implement VR Chat’s new features, which can make the read/write processes a lot faster and can store 4x as much data per avatar as before. Or, alternatively, could store the same amount of data with only 25% of the physbones

Technically, if a player keeps their data at <2304 floats, they wouldn’t need any physbones whatsoever and could just use avatar contacts instead

#

Like, NUSS is awesome, but it was created 5 years ago so there’s a lot of potential to optimize its design

ebon timber
twilit meteor
#

So how does this work at a big picture? Its not persistence?

#

Or would it be a combination of using this technique for data storage and saving to persistence?

#

oh wait u gave it at a big picture got it

ebon timber
# twilit meteor Or would it be a combination of using this technique for data storage and saving...

It would have to be both tbh

Avatars could store a maximum of 33kb if fully optimized, but avatar data is stored on the user’s device. So there’s 2 issues there:

  1. If the user plays on 2 or more devices, they’ll have 2 or more sets of avatar data, which will need some way to sync up
  2. If the game is competitive, there needs to be encryption on the data to prevent cheating. But VRC doesn’t provide Udon# with UserIDs, so we have to use DisplayName as the primary encryption key. But DisplayName can be changed once every 90 days (or 30 days with VRC+), so if that’s our only key, players would lose access to their data when changing names

So single-world persistence must be used to provide:

  • A secondary storage so that multiple devices can be synced up
  • A secondary encryption key to authenticate users when they change their DisplayName

I don’t want to get too technical, but TL;DR, an MMO in VRC would need to use single-world data persistence and avatar storage to shore up each other’s weaknesses

twilit meteor
#

I do agree we need user ids in the API or whatever. It is super frustrating dealing with the names changing. People love these pointless shape that they probably don't even know the key combination to send em.

ebon timber
#

Frfr encryption would be 100x easier if VRC would let us access UserIDs. But I also understand that they don’t want automated systems being able to catalog visitors and access their data on the website

twilit meteor
#

Yeah I get it for privacy

#

maybe a diff key

visual cargo
#

you could always just save your own generated ID into persistence

twilit meteor
#

that we can tell who its for

#

but they have the private key to use it idk

#

Ah yeah that works too

#

Sounds like more work VRC should let us access but that's my opinion. Or maybe just an example of it for advanced persistence saves in example central. Either or

ebon timber
twilit meteor
#

I def tried the IDs for persistence that wipes on diff IDs generated based on the users stored ID

#

That is a really good point

#

damn

#

It would allow for cross world saves, like u could go catch in kanto and then goi somewhere else (dont sue me nintendo)

#

sounds cool

#

That could ALSO be resolved if

#

worlds could share the same table too

#

but idk, give us some ids. even if its anonymous to the world creator. Like public private keys kinda, idk tho

ebon timber
#

Frfr this would be 999999x easier if worlds could just share their persistence

twilit meteor
#

Udon please 🙏

#

or what is it

#

soba

ebon timber
#

But opening databases up to multiple worlds would either:

  • Create a massive security threat if the databases allow any worlds to read & write to them
  • Create an extra layer of complexity and confusion if the creators have to configure security on their databases
twilit meteor
#

Def yeah

#

hit one mole and another pops up, classic

ebon timber
#

Frfr but I think I can create a solution that keeps things simple for everyone (except me). My end goal is to create a system that:

  • Can store up to 20kb per avatar
  • Can rip all the data & functionality
  • Can combine that cloned avatar with the 20kb storage system, so now the players can use their preferred avatars for storage
  • A system that automatically translates any data you feed it into the optimized floats to be stored within the avatar parameters, and vice-versa for getting the data back out again
  • Create an SDK where this is all already set up, and creators can place SaveBlocks and LoadBlocks wherever they want in their worlds
  • A customizable encryption algorithm so that different creators’ worlds won’t read & write with other creators’ storage avatars

If I could accomplish this, every creator would effectively have access to cross-world data persistence. But I’m probably being a bit too ambitious tbh

twilit meteor
#

So would we like equip a specific avatar to do this?

#

and then join the next instance

#

so say u enter a portal (not a VRC instance portal), swaps avi and then u go to the next instance?

#

Also excited to see it. Would def open the potential of worlds to a far far bigger way

ebon timber
#

Sort of. The creators’ game would need to have a hub world, and that hub world would:

  • Take the data from the player’s storage avatar and save it to world persistence as a sort of backup save file
  • Have the option to create new avatars for the player based on their favorite avatars. I.e., I could create a clone of my chao avatar
  • Cram the player’s save data into the cloned avatar’s parameters
  • Now the player can use their favorite (cloned) avatar, with their save data, without actually bloating their (original) favorite avatar
#

-# Knowing my luck, VRC will release proper cross-world data persistence just as soon as I finish this system

twilit meteor
#

Try interpreting it as they are scared of you

ebon timber
#

Could the new Raycast feature be used to read data out of an avatar’s parameters? I.e., could an avatar’s parameters influence the raycasts to transmit different data to Udon#?

subtle quest
#

the only new thing is that the avatar can use a raycast now, right?

#

you could already utilize raycasts in world

zenith hemlock
raw sigil
#

og question was about reading avi data. and the answer is no, i dont see how it changes anything

ebon timber
#

Sadge. I was hoping Udon# might have some way to detect raycasts, but it seems to be done completely through avatars with no Udon interaction

sturdy veldt
ebon timber
# sturdy veldt udon does have its own raycast support via physics.raycast tho 👌

True, but it’d be really difficult to use the Udon#-spawned raycasts to read data out of avatars. I’m trying to see if we could transmit data from Avatar Parameters to Udon# through raycasts. And if so, would it be faster and more-reliable?

I’ll still use NUSS ofc but I want to have a fallback option in case VRC changes something and breaks NUSS

#

So far I know of 2 methods:

  • NUSS (max of 8kb per avatar)
  • Contacts (max of 2304 floats, not sure how many bytes per float)

Both of which fall short of the 33kb theoretical maximum that avatar parameters should be able to provide

#

It’s also generally good practice to have 3 methods of data transfer so that, if one method breaks and starts sending jumbled data, the other 2 methods can overrule it and the system can distinguish the good data from the junk data

lyric kraken
#

cycling data on to contacts is probably the way you'd have to do it, but you're going to be waiting a lot of time to read across frames and the setup isn't trivial on avatars

ebon timber
#

Like I know that the animator uses avatar parameter values to change a change object to change the scale, rotation, etc. of the contact but it sounds like there’s a lot of room to make mistakes in such a convoluted process

lyric kraken
#

i've done it with osc to push data to a world via contacts, automating it from an avatar to udon doesn't sound especially fun. i'd much sooner use strings

ebon timber
# lyric kraken i've done it with osc to push data to a world via contacts, automating it from a...

Is OSC easy for the player to set up, though? I haven’t actually used OSC

For context, the game I’m making is called VRmon SPEED, self-paced education for expedited diplomas, a pokemon-like MMORPG that teaches Math & Physics k-12. So any solution I implement needs to be simple enough for even literal children can do it

Ideally, of course, I’d just have an avatar. The players clicks on the avatar once and everything happens automatically

Luckily, all players will be using the same avatar (the games must be PG-13, so my scripts will automatically kick anyone who changes out of the game’s avatar) so the parameter names etc. will be universal across all players

lyric kraken
#

osc is just driving the data, it's avatar contacts -> world udon for what's actually happening. if you used osc for it, it'd require people to install some osc solution you make

in your case it sounds more like you want it to be solely avatar and world interaction, the state machine to write and read from an avi would be extremely convoluted

it'd be magnitudes easier to just provide players with their save/load string data for input fields

#

with contacts it would also likely take minutes to transfer the data in either direction and be very brittle

lyric kraken
#

i consider origin contact reading brittle and it'd need to recover if they change avis, though you intend to "kick" them if they change avis i guess? i imagine you mean removing them from the play area or disabling scripts

#

brittle being something that is easily broken or prone to error is what i mean

ebon timber
# lyric kraken i consider origin contact reading brittle and it'd need to recover if they chang...

That’s correct. If they change avatars mid-game, they’ll automatically be teleported 999999m into the sky and set to a nearby respawn point so they can’t come back down

Ahhh icic~ Yeah, that’s why I’m trying to look for 3 different solutions. So far I have 2:

  • NUSS uses physbones to transmit data while the player is in a designated VRC Station
  • Contacts transmit data somewhat continuously

But if either method breaks and starts sending junk data, then the worlds will be receiving one set of good data and one set of junk data; and won’t be able to tell which data to load. So I need a 3rd data transmission method so that the good data will always have a 2/3rds majority

#

-# I was hoping to use raycasts but that turned out to be a dead end

lyric kraken
#

raycasts don't transfer data; i really think you should consider string copy/pasting as it's very easy in comparison to avatar data and it's easy for anyone to understand how to copy/paste a string. it does require they keep track of the string themselves though

ebon timber
lyric kraken
#

avatar data isn't stored server-side

#

if they lost their device, avatars have the same issue

ebon timber
#

Luckily that can be mitigated a bit with single-world data persistence. I.e., each world would save a player’s most-recent progress and could re-generate their string for them. But having to explain that 1000x sounds like a pain

ebon timber
visual cargo
#

you could have both the string method and persistence

#

have it update and save itself while you're in one world, then require players to "export" their savefile when they want to play in a different world with the same data

ebon timber
#

True. But then there’s one glaring issue with that (and it’s the main reason I’m trying my best to avoid it):

  • In case the player starts a new save file on a different device, I need to know which save data is their main save data. Otherwise their fresh save file could overwrite their main save file in the single-world data persistence, which is the opposite of what we want
  • Therefore, each save file will have several bytes dedicated to the “Playtime” variable. I.e., if there are 2 conflicting save files, the one with the higher Playtime will overwrite the one with less playtime
  • But if students have access to their encrypted data, obviously they’re going to try tampering with it to see if they can cheat. And this is going to result in save files with tampered data having massively higher Playtimes than their actual data and then overwriting their actual data
  • Alternatively, if someone tries to plug in someone else’s encrypted data, the decryption process will yield the same result

It’s honestly just better to not give the players easy access to their data

#

Keeping a player’s save data stored only on their device, encrypted, unable to be shared, but able to spread to their new devices, is the only reliable way to preserve data and prevent cheating

lyric kraken
#

avatar data is quite easily accessible, perhaps one layer removed, but it's not safe from tampering by any means if someone intends to cheat

ebon timber
#

Even so, it’d be very difficult for a player to read my code (I deliberately write it so that only I can read it), and even more difficult for them to actually decrypt it themselves. At that point, cheating becomes harder than beating the game normally

ebon timber
#

Just to double check, Disbridge only allows for one-way communication, right? From Discord -> VRC?

finite fulcrum
plucky kite
#

Hello I had a question...
Why does this stay on for over 10 minutes? Going close to 15 minutes now......

#

The craziest thing is I went to go cook mac and cheese and it's still doing it..... 😞

#

Update: The instance I tried to join prior to leaving the fishing world has recently closed and they said I didn't have permission to join that instance.
Essentially the instance was closed.
It's been that long, I'm now eating my macncheese
Yes it finally finished
15:24 on timer

ebon timber
#

Yeah, VRC’s built-in persistence is pretty buggy tbh x.x

glossy belfry
#

Is there a way I can test my persistance stuff with out uploading to the public version?

zenith hemlock
raven tundra
#

two questions:

  1. Should I use persistence to save if someone clicked Accept on a disclaimer like this? (should as in, I think I do want to so people dont have to click on it every time, but should I only show this popup once? or is it better to show it more often?)
  2. How should I go at this, if I should.
lyric kraken
#

just my take/opinion, but i think vrc views sessions as the boundary for accepting rules or enforcing anything. i think it's probably safer to have them accept every time. possible someone could come back x amount of time later and now have issues they didn't have before. or creator side, someone could change their disclaimer without proper versioning and it'd skip past without them accepting the updated text

unique rune
#

optionally you could add a "remember my choice" checkbox

raven tundra
unique rune
#

Sorry, I really don't do Graph, I'm not the one you want to ask for help with it

raven tundra
#

Also is there a good way to like clear persistance if data of user older than a month?

raven tundra
unique rune
#

don't do it for me, I don't need such a thing 🙂

raven tundra
#

no worries

raven tundra
lyric kraken
raven tundra
#

Was already working on that. This graph is getting a bit out of hand. Might need to rewrite it to U# anyways

lyric kraken
#

GetNetworkDateTime()

raven tundra
#

and then .Ticks?

lyric kraken
#

yeah i'd probably use ticks

#

also you shouldn't do it on start, you should do it on player restore for the local player being passed in

raven tundra
#

like this?

(and yeah I optimized the code by just using one variable and checking if it even exists)

lyric kraken
#

yeah that restore looks correct for a non playerobject

fading hawk
#

I'm confused about the storage limit. It is 100 KB for PlayerData and peristence enabled PlayerObject in total right?
Not 100 KB for PlayerData and a separate 100 KB for PlayerObject?

sturdy veldt
#

most folks talk about it like they’re separate

#

their storage limits*

fading hawk
#

;\ that doesn't answer it does it

#

It does not seem separate from my experiments. Saving persistence enabled PlayerObject and PlayerData occupy the same storage when calling GetPlayerDataStorageUsage() and GetPlayerDataStorageLimit()

wary summit
fading hawk
#

and that would mean users don't have an API to tell apart which is which for GetPlayerDataStorageUsage()

#

^ that is false because I didn't try Networking.GetPlayerObjectStorageLimit

#

Actually that was super strange because I had been testing persistence enabled PlayerObject and this would fill up the PlayerDataStorageUsage. Or should this be the expected behaviour?

#

Here's 1000 manual synced objects that are a child of a persistence enabled PlayerObject. Each with saved position, rotation, various IDs and states.
I'm not sure where the PlayerData usage is coming from in this case, could it be that it's overflowing PlayerObject storage? I don't understand

lyric kraken
#

it might be that they store the playerobject keys on playerdata or something, i'm seeing a small amount of playerdata usage without any calls to it in my playerobject setup

fading totem
lyric kraken
#

🐈

hardy narwhal
fading hawk
#

I'm experimenting with cases such as adding more UdonSynced variable to a persisted object

#

it knows that there are 8 synced variables and I tried to add a 9th

fading hawk
lyric kraken
#

using one blob over many objects is the best playerobject of all 📗

fading hawk
#

that sounds very plausible

alpine wadi
#

SaveLoad holds my player data

lyric kraken
#

i was more referring to the idea of holding one persisted object with a block of data on it; as opposed to many objects with udonsync across them

#

if SaveLoad is the only point where udonsync lives it may fit that idea

lyric kraken
#

yeah; i'd advocate for versioning at least and packing it rather than parallel arrays, but if your layout is very rigid then parallel arrays are okay too

alpine wadi
#

but yes, they're rigid, the item id is linked to the position and rotation

lyric kraken
#

packing to a single unit, like a byte array or string. if you ever need to introduce a new field or fields it becomes easier to maintain if you're not operating across multiple data structures. usually you'd pack your working/intermediate data from local to the udonsync side on save and unpack when loading (going from a byte array to your working arrays or data structures)

i'm not sure it'd be worth it for what you're doing at this point though

alpine wadi
#

hmm... so if I'm understanding you correctly, you'd save multiple fields into 1 byte array, save it, then on load put it into a local script?

#

I feel like that'd be harder to maintain though

lyric kraken
#

maybe it is easier to reason about in your case, idk. it involves serializing your data into the byte array yeah. i feel it's easier to reason about when managing migration or upgrading your scheme in a central place and i prefer to separate the concern of saved/packed data from the working data. in your case if the working data and save data are at parity there's probably not much benefit

alpine wadi
#

I like having the data put into the udonsynced the way it is so that it can be saved when something is placed

#

and since it's not constantly syncing - I use manual serialization - it should save data (I hope)

lyric kraken
#

you can achieve the same with packing, there's not really a difference between packing upon change and requesting to serialize it like you're doing, but it probably requires thinking about it a bit differently

alpine wadi
#

packing seems interesting though, so I could use it for a future project if I ever have an idea to make a different game world, would you mind providing a sample of it as I could probably get a better idea

lyric kraken
alpine wadi
#

I see, so you unpack it in the same order you pack it