Updating critters/items/etc. With Versioning in the Script

TheArt

Squire
Oct 21, 2018
108
57
28
Shard Name
Planes of Etria
So, I wanted to share this with everyone because it's been something I've been using to update my creatures on my shard as well as other little things. I'm sure some of you already know this, and I'm sure some of you don't. This is for those who are updating graphics in their client, or some other little thing that inevitably makes it so some of your creatures don't have the right graphics or what have you.

That being said, this also helps with making it so you don't have to respawn the world all the time. It's such a simple easy little fix that you might be facepalming when you see this.

Wherever in your script that has the serialization/deserialization for the creature/item/mob/etc.

C#:
public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );

            writer.Write( (int) 1 );
        }

        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );
            int version = reader.ReadInt();

            switch ( version )
            {
                case 1:
                {
                    //insert whatever it is here that's going to be changing.
                }
            }
If you have to change some things about it again, change the write version number to the next level, add the switch with the version, and the next case.

That would look like this:
C#:
public override void Serialize( GenericWriter writer )

        {

            base.Serialize( writer );



            writer.Write( (int) 2 );

        }



        public override void Deserialize( GenericReader reader )

        {

            base.Deserialize( reader );

            int version = reader.ReadInt();



            switch ( version )

            {

                case 1:

                {

                    //insert whatever it is here that's going to be changing.

                }

            }
            switch ( version )

            {

                case 2:

                {

                    //Second fix! Woooo

                }

            }
 

GoldDraco13

Squire
Aug 1, 2014
415
261
63
48
Canada
mycy4.com
Donate
Donate money to this user
You have a double switch statement? Also goto is needed unless each case is its own new load but then you'll be reusing code! I'm not sure if this is the best example of using versioning in the Serialize Methods!

Not to hinder your attempt to help others but this might cause problems!
 

TheArt

Squire
Oct 21, 2018
108
57
28
Shard Name
Planes of Etria
You have a double switch statement? Also goto is needed unless each case is its own new load but then you'll be reusing code! I'm not sure if this is the best example of using versioning in the Serialize Methods!

Not to hinder your attempt to help others but this might cause problems!
I've had it work with a few scripts this way, it's why I figured I'd share this. I've fixed control slots, body types, bag limits, etc. this way, so I just figured I'd share it. If you know there's a better way to make an instance of a creature version, could you please share it?
 

GoldDraco13

Squire
Aug 1, 2014
415
261
63
48
Canada
mycy4.com
Donate
Donate money to this user
The point of versioning is to be able to load objects that were saved without the new values effecting them, if you do not use versioning, you'll need to delete all existing instances of the object that were saved and it could even result in a corrupted save/load as the method cancels out before all the files are created which ruins the save folder.

So to avoid this we add the new values to a version, which basically is saying, load these older objects(Mobiles/Items etc etc) without the new data field, but when saving them add the field and update the version so next time they load they will load the new data! So say we then make another change and add more fields, we will repeat the process but the thing to remember is that previous changes should apply. Using a switch case statement, you want to use goto or forego the break; so they flow, or you could use a compare operation, which is what I prefer ie if (version > 0){new field} and keep incrementing as per new update to the save/load. You can also use the Deserialize to load timers, reset/set fields etc etc. It is not just for loading saved values, it initializes the instance too! Take a look at the Playermobile..cs overtime they keep adding to it and they used the switch case with goto new case and even used versioning to separate things like stabling a tame, under version 26 it does something different then above version 25.

I'll say it took me awhile to get my head around all of this and I'm sure I still have more to learn but this is what I know to date, hope it helps!
 

TheArt

Squire
Oct 21, 2018
108
57
28
Shard Name
Planes of Etria
The point of versioning is to be able to load objects that were saved without the new values effecting them, if you do not use versioning, you'll need to delete all existing instances of the object that were saved and it could even result in a corrupted save/load as the method cancels out before all the files are created which ruins the save folder.

So to avoid this we add the new values to a version, which basically is saying, load these older objects(Mobiles/Items etc etc) without the new data field, but when saving them add the field and update the version so next time they load they will load the new data! So say we then make another change and add more fields, we will repeat the process but the thing to remember is that previous changes should apply. Using a switch case statement, you want to use goto or forego the break; so they flow, or you could use a compare operation, which is what I prefer ie if (version > 0){new field} and keep incrementing as per new update to the save/load. You can also use the Deserialize to load timers, reset/set fields etc etc. It is not just for loading saved values, it initializes the instance too! Take a look at the Playermobile..cs overtime they keep adding to it and they used the switch case with goto new case and even used versioning to separate things like stabling a tame, under version 26 it does something different then above version 25.

I'll say it took me awhile to get my head around all of this and I'm sure I still have more to learn but this is what I know to date, hope it helps!
That doesn't really.... help with what I was asking. I was asking if you could show us an example for some of the other people out there that know next to nothing about coding. Instead you're boasting about what you know. That doesn't really help fix the mistakes you see that are obvious to you. If you're wanting to help, why don't you show changes in what I've shared so the class knows what I did wrong?


Also - I'm the sort of person who learns from full on examples given, not the sort of person who can learn from listening to a lecture, so what you just said goes so far above my head, I'm just going to assume you know what you're talking about and then wonder how the heck I can fix what I'm doing since you didn't give me an example.
 

GoldDraco13

Squire
Aug 1, 2014
415
261
63
48
Canada
mycy4.com
Donate
Donate money to this user
I'm not boasting, I am trying to help!

Here is an example of the process over a few edits, this is how I see using it but others may know a better way, like switch case could work better depending on the needs of the script, I find this simple and useful and helpful to understand!

lets start with a fresh setup

Code:
        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
say this is on a creature and we add a bool for IsHungry and we want saved but we already have these spawned in the world

Code:
        public bool IsHungry { get; set; }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)1); // version

            //version 1
            writer.Write(IsHungry);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();

            if (version > 0)
                IsHungry = reader.ReadBool();
        }
A few weeks pass and we want to add another bool for IsSleep and we want that saved plus we want them to all be set to a new hue 1234, which Hue is already an existing field!

Code:
        public bool IsHungry { get; set; }
        public bool IsSleep { get; set; }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)2); // version

            //version 1
            writer.Write(IsHungry);

            //version 2
            writer.Write(IsSleep);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();

            if (version > 0)
                IsHungry = reader.ReadBool();

            if (version > 1)
                IsSleep = reader.ReadBool();

            Hue = 1234; //new hue applied on loading mobiles
        }
 
Last edited:

TheArt

Squire
Oct 21, 2018
108
57
28
Shard Name
Planes of Etria
I'm not boasting, I am trying to help!

Here is an example of the process over a few edits, this is how I see using it but others may know a better way, like switch case could work better depending on the needs of the script, I find this simple and useful and helpful to understand!

lets start with a fresh setup

Code:
        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
        }
say this is on a creature and we add a bool for is they are hungry and we want saved but we already have these spawned in the world

Code:
        public bool IsHungry { get; set; }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)1); // version

            //version 1
            writer.Write(IsHungry);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();

            if (version > 0)
                IsHungry = reader.ReadBool();
        }
A few weeks pass and we want to add another bool for if they are asleep and we want that saved plus we want them to all be set to a new hue 1234, which Hue is already an existing field!

Code:
        public bool IsHungry { get; set; }
        public bool IsSleep { get; set; }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)2); // version

            //version 1
            writer.Write(IsHungry);

            //version 2
            writer.Write(IsSleep);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();

            if (version > 0)
                IsHungry = reader.ReadBool();

            if (version > 1)
                IsSleep = reader.ReadBool();

            Hue = 1234; //new hue applied on loading mobiles
        }
Thank you! ^_^ Much appreciated!