RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

New Shard Owners: Future Development Tips

Vorspire

Knight
New Shard Owners: Future Development Tips

Save yourselves hours of work by consolidating your multiple Item and Mobile scripts into one, easy-to-edit custom parent class...

  • Guide: Consolidate Your Future Edits (BaseItem, BaseMobile)
  • Author: Vorspire
  • Date: 5:25 AM, Saturday, August 7th, 2010
  • Version: 1.0.A
  • Content: Create, Open, Edit and Save multiple cs script files.
  • Support: N/A
  • Difficulty: 4/10 - Intermediate
Note: If you are not a new shard owner (IE: You already have a player-base) then this post doesn't really apply to you unless you're prepared to wipe all Items and Mobiles from your World Saves!

If you're still interested in making development life easier for yourself in the long-run, follow these simple steps.

=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=

ITEMS - Derive BaseWeapon, BaseClothing, BaseJewelry, etc. from one manageable class...

  1. Create a new cs file and name it BaseItem.cs
  2. Move BaseItem.cs to your /RunUO/Scripts directory.
  3. Open BaseItem.cs with the text-editor of your choice.
  4. Copy and Paste the code below into BaseItem.cs - Make sure you select it all!
    Rich (BB code):
     using System;
     using Server;
     using Server.Items;
     using Server.Mobiles;
     
     namespace Server
     {
          public abstract class BaseItem : Item
          {
               public BaseItem(int itemId) : base(itemId)
               {
                     //Name = "Base Item";
               }
     
               public BaseItem(Serial serial) : base(serial)
               { }
     
               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( ); //Version #
     
                    switch( version )
                    {
                         case 0: { } break;
                    }
               }
          }
     }
  5. Save BaseItem.cs and close the text-editor.
Inheritance

Editing the Base Item scripts is very simple, all you have to do is change one single reference in each of the Base*.cs files related to Items, like BaseWeapon.cs, BaseArmor.cs BaseJewelry.cs and BaseClothing.cs.
In the steps below, BaseX will represent the Base Item class you are currently editing.

  1. Open your BaseX.cs file with your preferred text-editor.
  2. In the class declaration, you must change the inheritance from Item to BaseItem (See example below).
Class declaration modification example. - DO NOT copy and paste this code, just replace the blue text with the red text...
Rich (BB code):
using System;
using Server;

...

     public class BaseX : Item  -->  BaseItem
     {
          ...
     }
}

After you have finished editing all of your BaseX scripts, boot up your shard to check for errors.
(Visual Studio users can use F5 to debug the code)

If everything is working fine, congratulations, you're done...at least with Items anyway.

Now in the future, if you ever need to make a custom edit to BaseWeapon, BaseArmor, etc. and you find yourself duplicating the code, you should edit your BaseItem.cs file with the edits, they will be applied to anything that inherits BaseItem (Any classes you edited in the Inheritance steps).

Usually you would have to edit Item.cs in the Core to make global edits to all Items, now you don't have to.

=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=

MOBILES - Derive BaseVendor, BaseCreature, PlayerMobile, etc. from one manageable class...

  1. Create a new cs file and name it BaseMobile.cs
  2. Move BaseMobile.cs to your /RunUO/Scripts directory.
  3. Open BaseMobile.cs with the text-editor of your choice.
  4. Copy and Paste the code below into BaseMobile.cs - Make sure you select it all!
    Rich (BB code):
     using System;
     using Server;
     using Server.Items;
     using Server.Mobiles;
     
     namespace Server
     {
          public class BaseMobile : Mobile
          {
               [Constructable]
               public BaseMobile( ) : base()
               {
                     Name = "Base Mobile";
               }
     
               public BaseMobile(Serial serial) : base(serial)
               { }
     
               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( ); //Version #
     
                    switch( version )
                    {
                         case 0: { } break;
                    }
               }
          }
     }
  5. Save BaseMobile.cs and close the text-editor.
Inheritance

Editing the Base Mobile scripts is very simple, all you have to do is change one single reference in each of the Base*.cs files related to Mobiles, like BaseVendor.cs, BaseCreature.cs and PlayerMobile.cs.
In the steps below, BaseX will represent the Base Mobile class you are currently editing.

  1. Open your BaseX.cs file with your preferred text-editor.
  2. In the class declaration, you must change the inheritance from Mobile to BaseMobile (See example below).
Class declaration modification example. - DO NOT copy and paste this code, just replace the blue text with the red text...
Rich (BB code):
using System;
using Server;

...

     public class BaseX : Mobile  -->  BaseMobile
     {
          ...
     }
}

After you have finished editing all of your BaseX scripts, boot up your shard to check for errors.
(Visual Studio users can use F5 to debug the code)

If everything is working fine, congratulations, you're done!

Now in the future, if you ever need to make a custom edit to BaseCreature, BaseVendor, PlayerMobile etc. and you find yourself duplicating the code, you should edit your BaseMobile.cs file with the edits, they will be applied to anything that inherits BaseMobile (Any classes you edited in the Inheritance steps).

Usually you would have to edit Mobile.cs in the Core to make global edits to all Mobiles, now you don't have to.

=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=#-#=

If you find any problems with this guide, please post your feedback here so I can make adequate corrections.

Haven't been on here in a while so I thought I'd bring you another 5-AM rambling, hope this helps and good luck :)
 

Jeff

Lord
You say Consolidate... but this is not the right word. This word assumes you are moving all the code from BaseVendor, BaseCreature, etc into the new BaseMobile class. I suggest you use the words "Create a new BaseItem Subclass and inherit BaseWeapon, BaseClothing, BaseJewelry from it".

Also, your BaseItem, BaseMobile classes should be abstract, and NOT [Constructable]
 

Murzin

Knight
i prefer the term parent class :p

thats what you are doing, you are creating a shell parent class for everything to inherit from

when going up the tree its a parent

when you go down the tree its a derived/child
 

Vorspire

Knight
Consolidate
–verb (used with object)
1. to bring together (separate parts) into a single or unified whole; unite; combine: They consolidated their three companies.

- This guide enables the user to consolidate future multiple edits into one single edit, so it is actually the right word, just the wrong context, so I will update that ;)

I can understand why the BaseItem class should not be constructable, but this can not be said for BaseMobile, simply because the BaseMobile, when created, allows the user to create "mock" NPC's that don't have AI and don't move at all, making them useful for manikins and displaying equipment in show-rooms, which is why I chose not to add abstraction. -However I will change the BaseItem code to comply with your suggestion.
 

Murzin

Knight
isnt there an aitype.none for no AI that is what you use for a manequin??

vorsp, i was not saying the term consolidate was wrong, but in the context of programming, its parent/child/derivitive/source/root are usually how you refer to the class tree afaik.
 

Pure Insanity

Sorceror
I like the tip, works on some edits. But I imagine most edits to armor/weapons for shards, are minor ones that would be edited on the item script it's self, not the parent class that it derives from. Which is how most people end up doing their stuff. Even so, this is still the best way to do it.

If used properly, you can make an armor suit that derives from one base class. Which defines what type of resource it would use, weight, rarity, anything that will be the same for all of the parts of the suit. Then the script that makes the constructable item, would be rather short and simple. Only defining specific attributes to each piece, to make them unique.

Doing it this way, you could set things such as luck as a default value in the parent class. And then if you decide you didn't want that much luck, say more. You can easily override them or hide them with the new constructor.

If people start their projects like this, it will save them time and trouble later if they decide to change things. It's a lot easier making a couple of edits to one file, then it is to edit 7 files for a whole suit or w/e it is you're working on.

Oh, and kinda off topic. There isn't an AI_None. The Mannequin I use, uses the default.
 

Vorspire

Knight
Murzin;848048 said:
isnt there an aitype.none for no AI that is what you use for a manequin??

Yes, but that is irrelevant because you don't have to set extra properties my way, thus reducing the amount of time overall that you spend setting up the manikins. You're just picking at pointless bits here.

Murzin;848048 said:
vorsp, i was not saying the term consolidate was wrong, but in the context of programming, its parent/child/derivitive/source/root are usually how you refer to the class tree afaik.

I never said you said it was wrong, in fact, I wasn't even replying to you.
I know how inheritance works...
 

Tabain

Sorceror
This is a great idea, but the way the scripts stand right now, every item that doesn't have a name assigned will be called Base Item. In the Distro scripts, this is A LOT of items. You may want to comment out the name part of the code unless you want to go through your scripts and assign each item it's own name property.
 

Vorspire

Knight
Tabain;848251 said:
This is a great idea, but the way the scripts stand right now, every item that doesn't have a name assigned will be called Base Item. In the Distro scripts, this is A LOT of items. You may want to comment out the name part of the code unless you want to go through your scripts and assign each item it's own name property.

This is a very good point, thanks for pointing that out.

Item.Name is never null on my server, which is why I forgot about this :p

Will update the main post, thanks.
 

Tabain

Sorceror
As I just did this for a new project I started, I noticed that items and mobiles aren't saving on worldsaves.

I had to add base.Serialize and base.Deserialize to make items and mobiles persist.
 

Kerwin

Sorceror
Jeff;848007 said:
You say Consolidate... but this is not the right word. This word assumes you are moving all the code from BaseVendor, BaseCreature, etc into the new BaseMobile class. I suggest you use the words "Create a new BaseItem Subclass and inherit BaseWeapon, BaseClothing, BaseJewelry from it".

Also, your BaseItem, BaseMobile classes should be abstract, and NOT [Constructable]

I've been playing around with this idea in the back of my head. It seems like alot of more or less static code is being used where some sort of data management system should be used instead.

Example: Each weapon and item has it's own class. Why not instead make a single class that returns the various data points and pull that information from the database on construction?
 

Murzin

Knight
kerwin, that idea is used in non-object oriented languages

in an object orientated language like C#, while you CAN do that, it is horribly unwieldy and can overwhelm the novice programmer/scripter/coder very quickly

by breaking things up it makes them much easier to deal with on an individual basis.
 

Kerwin

Sorceror
Murzin;848546 said:
kerwin, that idea is used in non-object oriented languages

in an object orientated language like C#, while you CAN do that, it is horribly unwieldy and can overwhelm the novice programmer/scripter/coder very quickly

by breaking things up it makes them much easier to deal with on an individual basis.

What I mean is this- There is a TON of of rewritten code for Items, weapons, and such. The only difference for a large number of these items are pretty much just data.

(Generalization that is not completely accurate)
Example: Sword A Inherits Swords, which inherit Weapon , which inherits Item.

In a case like this, I would suggest stopping the inheritance tree at "Weapon", as after that the differences are very minute. A few methods may be the only substantial difference, in which case the extra code shouldn't overwhelm the base "Weapon" class.

Add a class that Inherits "Weapon" that initialized the actual weapon from the database. (Doesn't have to be SQL, but someplace where you store the weapon information) Each time the weapon is constructed, just pull the information out of the database and you would have a much, much easier time making changes to weapons and items. This would also potentially allow you to make changes to these on the go so you could more quickly develop new items, or have a much easier time balancing new weapons and changes made.

I would almost say this is more OOP oriented then the current setup, as it conserves reused code so that you only need to write the basic data in, instead of making a whole new class just to add a single new item.
 

Jeff

Lord
Kerwin;848547 said:
What I mean is this- There is a TON of of rewritten code for Items, weapons, and such. The only difference for a large number of these items are pretty much just data.

(Generalization that is not completely accurate)
Example: Sword A Inherits Swords, which inherit Weapon , which inherits Item.

In a case like this, I would suggest stopping the inheritance tree at "Weapon", as after that the differences are very minute. A few methods may be the only substantial difference, in which case the extra code shouldn't overwhelm the base "Weapon" class.

Add a class that Inherits "Weapon" that initialized the actual weapon from the database. (Doesn't have to be SQL, but someplace where you store the weapon information) Each time the weapon is constructed, just pull the information out of the database and you would have a much, much easier time making changes to weapons and items. This would also potentially allow you to make changes to these on the go so you could more quickly develop new items, or have a much easier time balancing new weapons and changes made.

I would almost say this is more OOP oriented then the current setup, as it conserves reused code so that you only need to write the basic data in, instead of making a whole new class just to add a single new item.

Clearly you are not a developer. The only reason this is something that should be done is because Item and Mobile in compiled into an assembly, and we use C# scripts outside of the assembly... In an ideal situation, everything would be compiled into the same assembly, making this completely useless... you would just add your edits to Item and Mobile instead.. or use 'partial' classes, but unfortunately this is the way it has to be done, in order to allow a "scriptable" version of RunUO.
 

Kerwin

Sorceror
Jeff;848558 said:
Clearly you are not a developer. The only reason this is something that should be done is because Item and Mobile in compiled into an assembly, and we use C# scripts outside of the assembly... In an ideal situation, everything would be compiled into the same assembly, making this completely useless... you would just add your edits to Item and Mobile instead.. or use 'partial' classes, but unfortunately this is the way it has to be done, in order to allow a "scriptable" version of RunUO.

All my suggestion does is add in the ability to quickly edit items. It is useful, as you don't need to recompile everything just to make an adjustment to a katana's speed. The issue is just an idea, and there are a few initial problems you would have to find a solution too, but it is not an uncommon solution in the development world to push data out to a layer designed for it. I think I can understand why RunUO is the way it is, but the way the items and weapons are designed make things a big pain to change.

Also, I would imagine that as a developer, one would rather make the need for copy/paste programming go away. If someone wants to make a flaming sword of tasty goodness, I don't see the need to make a new file if the only difference between the flaming sword of tasty goodness and a generic broadsword is art, damage, and speed. The design also does not completely preclude making a new class if functionality needs to be added. It just makes it easier for people to add stuff, fix stuff, and change stuff.

Also, I am 99.999% certain that that suggestion is far from unique in any game engine or MMO. The data layers are most likely different(Many are XML, some use SQL, and at least one I know of uses MySQL.) Not to mention the many WoW servers that also use some form of SQL for the items and loot. ;)

Also, that is the best way to enter a discussion. Stick to the point and attack that instead of trying to assert dominance by insulting people. Act more professional, it helps to keep people on topic and helps to avoid people from reacting emotionally.
 

Jeff

Lord
The problem is, XML/SQL solution is not something available to everyone... (well XML is, but XML is slow). Hot-loading is something that was discussed when RunUO was being created, but it allows for huge serialization issues. RunUO is made to to be extended, if you have an idea for a system, by all means create it. Keep in mind, RunUO was built for performance, and adding systems that allow hot-loading, or even what you explained take away from that performance. On my own server (back in the day) I setup a system like you stated, only it was coded. I had a table that stored all weapon/spell/armor damange/values, and created gumps that could modify them live. This was effective, but I still preferred the coded solution vs, a config file solution. Lazy programming is great, many new technologies come from it, but it has NEVER proven to be better then hard coding when it comes to performance. If you ran a server like UOGamers: Hybrid, you would understand where I'm coming from.
 

Kerwin

Sorceror
Jeff;848560 said:
The problem is, XML/SQL solution is not something available to everyone... (well XML is, but XML is slow). Hot-loading is something that was discussed when RunUO was being created, but it allows for huge serialization issues. RunUO is made to to be extended, if you have an idea for a system, by all means create it. Keep in mind, RunUO was built for performance, and adding systems that allow hot-loading, or even what you explained take away from that performance. On my own server (back in the day) I setup a system like you stated, only it was coded. I had a table that stored all weapon/spell/armor damange/values, and created gumps that could modify them live. This was effective, but I still preferred the coded solution vs, a config file solution. Lazy programming is great, many new technologies come from it, but it has NEVER proven to be better then hard coding when it comes to performance. If you ran a server like UOGamers: Hybrid, you would understand where I'm coming from.

See! When you reply to the subject, it reads much nicer, and you get a better response, thank you! ^_^

The performance issue was one I was alluding too, as well as at least one other that comes to mind having to do with items not being in sync with the data layer when you do hot-load. As far as accessibility, the data layer by it self isn't completely accessible, but you can always make a toolset for making the items. I actually have pondered on something that uses the art files so you can see what you are making. (plays animations, and has numbers and names and such that you can edit.)

Also, there is a point where Optimization is not needed. For a server like Hybrid, I do imagine it is greatly needed to deal with the load. Most servers I know of have never seen even 100 players, much less 7,000. In a case like that, you have a system that is hard to manage. Though, if I am understanding what I am seeing correctly, you might be able to come close to Hybrid's speed by making a Hash table in memory of the values from the database for the weapon system. If the Id's go straight to where they would be on the table, then all you would do is fill the tables in memory before De-Serializing everything. All it is then is pulling data out of a place in memory. (a tad slower, how much slower I am uncertain but I don't think it would be too bad as long as you don't have millions of coded items.)
 

Jeff

Lord
There are tools (possibility out of date now) for making weapons/mobs/etc, they are here somewhere on the forums. But to be quite honest, coding a weapon from scratch takes about the same amount of time (probably even less) then the tools. If you have the right applications to do it, and are smart enough to sit and learn Visual Studios short cuts. I'm a really fast developer, been told that by several ppl, but its mostly because i physically type less characters then you see on the screen. Look into Snippets, you can build a snippet for an item/mobile in 10 minutes, then apply it to a new class and have a complete mob made in 20 seconds, pretty easy. Lazy development isn't always about creating new, easy to use ways to make a piece of software to work, its better to create new, easy to use ways to write the software....

Seriously look into Snippets....

P.S. Spending a shitload of energy, to make a utility to do code generation, takes about the same amount of energy to just code it... Zippy had a great quote awhile back that said "As a matter of principal, code generation is stupid" and over the years of learning how to develop and honing my skills, I'd have to agree... The easy route will most likely bite you in the ass some day....
 

Kerwin

Sorceror
Jeff;848562 said:
There are tools (possibility out of date now) for making weapons/mobs/etc, they are here somewhere on the forums. But to be quite honest, coding a weapon from scratch takes about the same amount of time (probably even less) then the tools. If you have the right applications to do it, and are smart enough to sit and learn Visual Studios short cuts. I'm a really fast developer, been told that by several ppl, but its mostly because i physically type less characters then you see on the screen. Look into Snippets, you can build a snippet for an item/mobile in 10 minutes, then apply it to a new class and have a complete mob made in 20 seconds, pretty easy. Lazy development isn't always about creating new, easy to use ways to make a piece of software to work, its better to create new, easy to use ways to write the software....

Seriously look into Snippets....

P.S. Spending a shitload of energy, to make a utility to do code generation, takes about the same amount of energy to just code it... Zippy had a great quote awhile back that said "As a matter of principal, code generation is stupid" and over the years of learning how to develop and honing my skills, I'd have to agree... The easy route will most likely bite you in the ass some day....

It depends on what your end goal is. If you are just slightly modifying an end product like RunUO, I wouldn't see too much need to add in a system like this, unless you plan on doing a large update in the near future. It other cases, if you are planning on stripping down a good amount of functionality and rebuilding the system to be fairly different, then you could see time savings in a system like what I suggested. While the time to make the items are equal, where you really see the saving will be in the debugging and balancing.

Also, a quote like that, without context, could also be making suggestions down to the point of needing to generate code. In my experience, I have found that it is usually time to fix problems when you find yourself copy-pasting too often.
 

Peoharen

Sorceror
And I have found copypasta prevents MovetoWorld/MoveToworld/MOveToWorld errors. However I know of this method and how to use it because I didn't use a generator.

Once upon a time, back when Dreamweaver 6.4 or so was out I claimed to know how to build a webpage, hey dreamweaver/fireworks does the work for me and I had a copy of it. Yeah I was lucky I could explain what the hell a tag was and living in a dream world. Fast forward a bit, and I learned, not mimiced, not code generated, I learned stylesheet. The skill came into use recently when I converted Blue Magic's readme into an html file, I wanted it to look like how I designed the in game menus and I did exactly that. I didn't skirt around and not do it from a lack of my own limitations (admirably I was cursing css, they should support images with border).
 
Top