Be warned, I'm not sure how much time I'll have to finish that, but I'm going to attempt a repeat of what I've done years ago with the Nox Wizard emulator.

Nox was a total nobody until our team did not just do what every emulator should do (write code and fix bugs regularly) but because I (not a programmer by any education) made sure we had an up-to-date and actual USER-oriented manual for scripting and how-to's. In lay man's terms. We became pretty well known after half a year of work in the community, user base growing, but we all had too much real life going on to keep it up and after 2 years Nox disappeared again. I still consider it the most user-friendly (easy to use, very well documented and thus easy to customize) emulator that was out there, but the main reason for its quickly rising popularity was the focus on communication with people who were users and had no programming background, teaching them how to work it.

In my opinion RunUO has always lacked that, it became better when it got open source, but there was never a good communication established to connect and empower users. RunUO ruled through its features and good developers, not through a user based the same as even Sphere did. ServUO isn't very actively developed currently but I think it has enough going already from core etc that it can be very powerful and actively used if only the education/introduction side of things was better.

I've been on vacation now for a few days, which is the reason I've had time to look into UO again. Work starts Monday again and I'm usually extremely busy. So this might quickly dry up. But here is to a start ...

For the sake of readability I would like to ask everyone to not ask question in here or make general comments but make new threads in general discussion liking here.
But: Since I'm not a programmer and literally learning while I go, I'll make mistakes. If you find one, please comment THAT in here.
 
Basics
Before you start programming/scripting anything ... internalize the golden rule: documentation is EVERYTHING. Programming is like a form of math: it is very logic, it can be simple like 1+1=2 ... but it can become extremely complex too and if there is a small error, the logic falls apart and everything crashs or gives very wrong results. A script can be simple and still in the large picture of the server code cause insane havoc. Documentation of your code is the only way of saving you horrible headaches and lots of time searching for the failure. To document your code easily and generate automatic handbooks/manuals from what you’ve done, I recommend you use Doxygen (http://www.doxygen.org/ ). It contains something like “comments” you write in your code with all kinds of explanation what something does - which the server ignores but the Doxygen program will recognize, extract and put into a website/html or text manual.

Next you need a decent editor which helps you work efficiently and keep track of things through highlighting code in certain ways, offering auto-fill for commonly used things etc. You can use Visual Studio Express from Microsoft if you look for the professional version of things (costs money) or you can use Notepad++ ( http://notepad-plus-plus.org/ ) if you want to use a pretty powerful free programming/text editor.

Now to the actual coding. RunUO and ServUO and related emulators are all written in C#. C# (pronounced “C Sharp”) is a programming language that is written in plain text and then upon server start compiled into a more compressed “language” that allows a server to run more efficiently. C# is object-oriented, which means it separates into objects (data packages so to say) and modifiers.

Objects & Types
Objects contain data (hair color, strength, a number counter, a sentence, index positions etc etc), which are then manipulated through modifier. Objects come in certain types. C# has three basic types: Value types, Reference types, Pointer types.

From the Microsoft C# reference (https://msdn.microsoft.com/en-us/library/618ayhy6(v=vs.110).aspx) "Variables that are value types store data, and those that are reference types store references to the actual data. Reference types are also referred to as objects. Pointer types can be used only in unsafe mode. It is possible to convert a value type to a reference type, and back again to a value type, by using boxing and unboxing. With the exception of a boxed value type, you cannot convert a reference type to a value type."

To use types correctly, you have to understand that C# is rather compulsive obsessive about you telling it what exact sub-type it is. Data can’t just be contained in a type, C# wants to have a definition if it is going to be a number (and what kind of number, does it have digits after a dot?), a word/text, a “judgment/test” (true or false?) etc etc. So you have to understand and get used to the categories inside the three main types.

The advantage of this is that C# can quickly figure out if you use a wrong type (put a text inside a number type? Error message!) or you trying to do something to some data which can’t be done (subtract a word?) and tell you that precisely in an error message. Which in turn helps you find errors in your programming. And since writing code is mostly about data and wrong data handling causes problems the initial headache of learning the types and sub-types and becoming familiar with that kind of thinking is very well worth it to write better code and avoid or find problems much easier!
 
Last edited:
[H="3"]Value Types[/H]
Value types contain … values (Doh). A value is a type of data that is on its own, it just exists. To explain what I mean with that: a Reference type always points to something else, it is NOT on its own. But value types are just that – a value. Value types can be converted into each other and one Value type object can be assigned the data of another Value type object for example. Meaning: you can define a Value type called "hair" which contains a hair color name (text!), then convert hair into a Value type for numbers and have it now contain the number you get when a server translates text into numbers (ever tried in Excel to turn a text cell into a numeric cell? Yes, every text can be translated into a numeric value). Now as I said C# is very obsessive about data types and because of that there are tons of sub-types and sub-sub-types and you should understand each of them to use them properly …

TL DR version: For number values, always use numeric value types. If you have a variable that will contain small numbers, use byte or sbyte. If you need large numbers (above 255), you will likely end up with int. If you need a variable with a very wide range of values/large numbers both positive and negative AND you need digits beyond the dot, float is what you will most likely need. And if you need to handle letters or symbols or numbers as part of a text/sentence, char is your value type - but char allows only ONE letter/number digit/symbol. If you need more than one, you have to move on from Value types to the Reference type "string".
And if you need to count something (and not just store a single number), use enum, that is easiest for the server to digest.

Here is an overview over the Value type hierarchy:
  • Structural
    • Numeric
      • Integral
      • Floating-point
      • Decimal
    • Bool
    • User-defined
  • Enumeration
I think the above (while true and basic theory information) is not going to help for beginners much so we’ll ignore it for now – but if you want to go deeper in these terms, the list and hierarchy will help you to google information about C# and learn more! For the time being let’s just explain all of them as if they were the same hierarchy level

1. bool

Bool types contain the result of a very simple test/judgment: is something TRUE or is something FALSE (Is that hair color red? Is that speech the same as the previous? Do we have a certain property or event happening?). Every time you want to do that kind of test and store the result as data, you must define a bool type.

2. byte
A number between 0 and 255 (aka the possible values of a computer byte), but not stored as a regular number (2 … 5 … 10 etc) but converted into binary code, the way a computer counts, using only “0” and “1” and 8 positions for it. Why does that matter? A byte can contain the number between 0 and 255 while using MUCH less memory than having to actually store the number. That is because a computer does not count like human beings, so every time the actual number needs to be put in memory, it needs a rather lengthy “translation instruction” for the computer what that is and how to handle it. A little bit like explaining a blind and death man with extremely bad memory a color: you have to include all the information what color was again and what that color means and how writing that color in letters would be done etc etc. It is very inefficient.

On the other hand the byte storing way of numbers is extremely efficient for a computer. Byte storing of numbers is based on counting “electricity on” or “electricity off” states-of-being. And that is what a computer naturally works with, no translation needed. So this is how storing numbers in bytes works: you have a row of 8 positions, the bits. And every bit has ONE of two options: it can be switched off (0) or switched on (1). The bits each have values assigned to them. And the computer sums up the value of every bit which is switched on (1). The values assigned to each bit are: 1-2-4-8-16-32-64-128. You see the pattern? Always the double of the previous bit.

Now if the bit 1 is switched on (1) and all other bits are switched off (0) what value does that give the whole byte? Well, since the value of bit 1 is the only one that is on/1 and it has a value assigned of 1", we have a total byte value of 1. That means a byte of writing 0x1000000 (0x plus 8 bits, the 1st is on/1, the other bits are off/0) has a value of 1. Yes, that is very different from how humans count (from left to right and each an additional digit) but essential to understand when writing code.

Let’s try another example: We want to store a value of 50 in our byte. How would we do that? Well we can sum up the bits with the values 16 and 32 (bits 5 and 6), then we have already 48, if we add to that the bit with value 2 (position 2) we have a total sum of 50. So the byte would look like … 0x01001100. Bits 2, 5 and 6 are on/1 and thus summed up. Makes sense?

Now the good news: you don’t need to do these calculations every time to figure out how the byte looks, simply declaring the byte as having that value is enough. The server handles the rest (figuring out how the byte looks like). But you should understand how that work for the use of your types. And if you have to handle values in your scripting which will not go above 255 (which is the total sum of every bit switched on) you now know to use a byte type because it only needs a memory space of 1 byte, the minimal data type size C# has.

3. sbyte
Same as byte, but the range is shifted, instead of 0-255, it is -128 to +127. sbyte ... like "shifted byte". Does that number range ring a bell? Yes, it is the Ultima Online minimal/maximum z value for the map/building, so obviously that value is defined by an sbyte.

4. ushort
Same as byte, but now double the amounts of bits (basically 2 bytes after each other now used to store a single number/sum). Because it is two bytes instead of one it needs the double amount of memory. The range of possible values stored in a ushort type is numbers between 0 to 65,535.

5. short
The same as ushort but - similar as sbyte is a byte shifted for half of its value range into negative numbers - short is the same as ushort shifted by half of its value range into negative numbers. In other words: instead of a range of numbers from 0 to 65,535 it contains a numbers range between -32,768 and 32,767. Again of course two bytes memory used to store that.

6. uint
Same as ushort, just again the double size (4 bytes) to store a single number. The range of possible values that one can store is 0 to 4,294,967,295.

7. int
Same as uint (4 bytes for one number stored) but shifted into the negative range for half of the numbers range again. So the range of possible stored values is between -2,147,483,648 and 2,147,483,647.

8. ulong
If you’ve followed me until here you can guess what that is … yes, 8 byte (double size as uint). The range of possible values is between 0 to 18,446,744,073,709,551,615.

9. long
You can guess it … yes that one uses 8 bytes too but is shifted half its range into the negatives. The range is between -9,223,372,036,854,775,808 and 9,223,372,036,854,775,807.

10. float
Now we leave the normal numbers and enter the realm of numbers who are having digits after the dot. The first value type for that is called “float. The float is your usual bet for number handling when you need your value to contain digits after the dot. The range is 1.5 x 10-45 to ±3.4 x 10 38 and float value types store 7 digits after the dot. Float needs 4 bytes for storage.

11. double
Similar to float, that one allows even larger numbers to be stored and has a higher precision (more digits after the value stored). The value range for double is ±5.0 × 10−324 to ±1.7 × 10308 and it stores 15 digits after the dot. Double needs … double the storage space of a float, 8 bytes instead of 4.

12. decimal
Decimal is again more precise and allowing a larger number to store than double. The range of possible values lies between -7.9 x 10 to the 28 and 7.9 x 10 to the 28 … have fun. Use a decimal for extremely large positive or negative numbers where you need 28-29 digits after the dot. Which means very likely: never. Usually decimal is only needed if working with certain math or physics science equations. A decimal needs 12 byte to be stored.

13. char
A Char type contains text. It is the most alien version of data to a computer which naturally only handles bytes, nothing like a letter at all, at least numbers are somewhat familiar to it. So storing text takes the most memory and processing power for a server. The important point is that for a computer “text” is so alien, that it can contain anything, even special signs (exclamation marks!) or NUMBERS. The server will treat anything inside a char pretty much like “that unintelligible stuff”. So yes, you can put anything into a char, you can’t do math with it and you are limited to how you can manipulate it, because the server is essentially quite “blind” to anything defined as a Char.

Now the crucial part: A Char type is very comfortable; it allows you to avoid any headache about the Value type selection if you just use Char types for everything. But not only does that mean lots of memory use and performance loss and being limited to how you can manipulate the contained data – but it allows you to break the main advantage of having these Value types in the first place … avoiding coding errors. The server will not be able to track if what you do to this is wrong, if you are producing garbage and feeding failures into the whole system. Any manipulation you do, will be followed blindly no matter what it produces as result. To put it blindly: you are going to waste resources and likely end up working like a butcher instead of a surgeon at least some places. So use Char types only if really necessary please!

Usage/memory: A char is really only a SINGLE letter/sign/symbol/number. You can extend a char to contain more than one “position” – called a “string” - but each position needs 2 byte to be stored. So basically a sentence of 16 positions including letters/empty space/punctuation etc. means already 32 bytes used!

14. enum

15. struct


Short version of Value types
(courtesy cds333 at https://social.msdn.microsoft.com/F...imal-vs-double-difference?forum=csharpgeneral):


C# Type|.Net Framework (System) type|Signed?|Bytes Occupied|Possible Values
sbyte|System.Sbyte|Yes|1|-128 to 127
short|System.Int16|Yes|2|-32768 to 32767
int|System.Int32|Yes|4|-2147483648 to 2147483647
long|System.Int64|Yes|8|-9223372036854775808 to 9223372036854775807
byte|System.Byte|No|1|0 to 255
ushort|System.Uint16|No|2|0 to 65535
uint|System.UInt32|No|4|0 to 4294967295
ulong|System.Uint64|No|8|0 to 18446744073709551615
float|System.Single|Yes|4|Approximately ±1.5 x 10-45 to ±3.4 x 1038 with 7 significant figures
double|System.Double|Yes|8|Approximately ±5.0 x 10-324 to ±1.7 x 10308 with 15 or 16 significant figures
decimal|System.Decimal|Yes|12|Approximately ±1.0 x 10-28 to ±7.9 x 1028 with 28 or 29 significant figures
char|System.Char|N/A|2|Any Unicode character (16 bit)
bool|System.Boolean|N/A|1 / 2|true or false

Edit: the table command seems to be broken in the forum?
 
Last edited:
[H="3"]Built-in Reference types[/H]
Reference types are a bit more complicated than Value types. As mentioned, they always refer to some other data, they don’t just contain data without connection to anything (Value types). There are 3 build-in Reference types: string, object, dynamic.

1. “string” Reference
String references are the main reference type you will use. A string is nothing else but a collection of char Value types. Same as chars, the data content of a string must be provided in quotation marks. While a char can contain only one letter/number/symbol etc., a string is theoretically infinite in length (as long as you have enough memory to store it).

Now if a char Value type contains a single Unicode symbol (letter, one digit of a number, exclamation mark, whatever) and a string is a collection of chars - why is a string not a Value type but a Reference type?

Because the Unicode symbols all make no sense to the computer anyway it stores each in its own data unit (the char), for which it needs a lot of memory (remember the blind and deaf man and the color information). The computer would go crazy by having to generate that mass of information-related-to-store-that-unintelligible-symbol every time a single letter or sign needs to be handled. So to prevent that waste of memory the computer basically has a table in its memory with every possible Unicode sign (letter, single-digit number, punctuation sign etc etc). It needs to save that whole table only once. And each symbol in Unicode is a data point (char Value type). If a string would be a Value type then every possible word, sentence, number-stored-as-Unicode in any language needed to be an extra entry into that table! The memory would explode; you would need to have a Value type for each word, sentence, text ever possible, even every book ever to be written!

So a string does not contain the data itself (Value type). Instead it refers (Reference type!) to the positions in the Unicode table needed to build its content. It basically says (invisible to you): position 0 of the string use the char at Unicode table position A, position 1 use the char at table position X etc etc. Which in turn means that each position of the string can be addressed/isolated as a “char[…]” where … is the position in the string.

Example:
Code:
string str = "test";
char x = str[2];  // x = 's';
That script basically says “the string called ‘str’ refers to Unicode content of ‘test’ and now the char called ‘x’ should receive the Unicode symbol from position 2 of the ‘str’. The counting for string positions starts at 0, so position 2 is ‘s’.

The next advantage is not just saving tons of memory from strings you don’t need to store currently, but you can start manipulating text in an almost mathematical way.

Examples:
Code:
string a = "good " + "morning";

This will create a string with name “a” that refers to Unicode content of “good morning” (pay attention to the empty space after good!).

2. “object” Reference
Object is a Reference type that can refer to any kind of Value type.

An “object” Reference can be “boxed”, meaning it will now contain the data of a Value type. And Value type can then later be extracted again from the object reference (unboxing). Now this boxing and unboxing both need quite some processing ressources, so why do it? The reason for boxing/unboxing is basically moving data around in the memory of the computer to make it available for later use. A modifier/script claims - when it s started - a certain space of the computer memory. This is called the stack. Everything the script does will go into the stack. And once the script is finished, the stack will be emptied and the memory space is free for grabs again by other scripts.

But sometimes you want to keep the data and use it for something else at a timepoint you don’t know yet. This is where boxing/unboxing is used: Boxing a Value type/data somewhere in the script tells the script to move it out of its stack into a special second space in memory called the heap. The heap is shared by all the scripts/server and survives the end of the script run time. So through Boxing the data survives the “death” of the script and can still be used by other scripts (once it is unboxed inside that other script and thus turned back into a Value type inside the scripts own stack).


3. “dynamic” Reference
Dynamic references break the rule of a basic property of C#: everything is tested upon compilation for its correct types. Instead the type with dynamic references is only checked when the script that contains it actually runs. Isn’t that a risk for coding errors only to be found late, while the server runs? Yes! So why do it? Well, dynamic programming allows one a lot more freedom in establishing some functionality, you can move types around all the time and it doesn’t matter what type they are until they are used by a specific script. So you save memory by converting a type of the same name into others depending what you need it for right now. A lot about programming is optimization to yield minimal processing time and memory use after all. Which is why there are a lot of coding languages out there which work “dynamic” all the time, especially in conditions where there is little CPU power or such available, tasks are rather small and things should be done quickly. For example Python or Javascript are such dynamic languages. And sometimes people want to integrate scripts from these into something written in C#. So for example you have a web application written in Javascript which you want to integrate into the server. In that case you need a “gateway” from a static language (check when compiling) to the dynamic language (check only when running). That gateway to exchange data between the static language of C# and the dynamic language Javascript would be the Reference type “dynamic”.


And similarly to dynamic languages you can now code “dirty” (some disagree with that choice of word and call it flexible), have a data object first defined as numeric, use it as such, then convert it into a char and use it as that. C# won’t check anymore, it will just do whatever you tell it. And it won’t be stopping with a critical error at compilation time if a line later the Dynamic Reference type is suddenly assigned a text value, saying “Wait a minute, that is a numeric type, you can’t put text into that!”.


There is much to be learned about dynamic but I must confess I don’t get it really and this is a rather advanced concept, so I’ll not dig further into it.
 
Last edited:
[H="2"]Self-defined Reference types[/H]
Those are different from the build-in ones as they can handle data referencing in much more flexible ways. Again there are three types: class, interface, delegate.

“class” Reference type & “interface” Reference type
A class is like a branch on a tree: directly before it there can only be a single other branch (or the tree trunk). One follows a single previous one – or it is on its own entirely. The previous branch/class, called the “base class”, is handing all its properties into the following class. We say the new “class member” inherits the properties of the base class. A class member does not just inherit the properties of its base class (if it has a base class), but it usually adds extra ones. This hierarchy is strict and means you need to plan ahead very well which class at which step of the hierarchy contains which properties.

Additionally – same as a branch on a tree again - each class can act as base class for several other sub-classes. In other words classes and their members are linear in structure, hierarchical and they can branch off. For example in RunUO/ServUO one of the very first classes is called “Object”, which is the base class for “Item” (among others), “Item” is the base class for the “BaseWeapon” class, which is the base class for the “BaseMeleeWeapon” class, which in turns is the base class for “BaseAxe”, “BaseKnife”, “BaseBashing” etc etc etc.

The big advantage of the “class” Reference type is that it contains instructions for changes to every existing sub-class downstream of the branch. Change one at the top and you have the effect all through the hierarchy. But the hierarchy of classes should be carefully defined, because classes and their members should be of similar functionality. For example a knife is a melee weapon, is a weapon, is an item etc. – they make sense inside a class hierarchy. An NPC and a knife don’t really, except that they are both object for the server, so they should branch off very early in their classes. So if you define something and its behavior further – use a class/sub-class to inherit the properties of the more general, higher hierarchy. But if you want to inherit properties of a very different nature into your new class - let’s say you have an NPC who should have some of the properties of an explosive potion - it is better to move on to the Reference type “interface”.

The “interface” reference type is similar to a class as a class can inherit from an interface too. An interface is not so hierarchical; it is used to connect classes of very different functionality. One could say that interfaces make cross-connection between class branches - but their information/inheritance again flows only in one direction, the connection remains linear. And while the class will inherit along its line downstream into its last member, an interface only inherits its property directly; there is no downstream hierarchy of members automatically affect as well. For interfaces the inheritance has to be re-defined for every class/step along the line again if you want to affect sub-classes. And as I mentioned before: A class can only inherit from one class - but a class can inherit from several interfaces. Plus you can always mix the two as well.

So the options are that a class can inherit from
  • nothing at all
  • one base class (then it is called a “derived” class)
  • one or more interfaces (then it is called an “implemented” class)
  • one base class plus one or more interfaces (then it is both a derived and an implemented class)

The code how this inheritance is written looks like this (https://msdn.microsoft.com/en-us/library/0b0thckt(v=vs.110).aspx):

Code:
class ClassA { }
class DerivedClass: BaseClass { }
class ImplClass: IFace1, IFace2 { }
class ImplDerivedClass: BaseClass, IFace1 { }

Summary: classes establish a hierarchy among of similar functionality with more and more details added the further along the class hierarchy one goes. Everything is linear like tree branches, one class can inherit only from one other class, not several classes. And every inheritance “flows” into its lowest level member. Changes in on higher up class are inherited automatically along the branch. Plus classes are fast in processing.

Interfaces connect over class hierarchies of very different functionality and generate a net. They break the linearity because several interfaces can feed into/be inherited by one class. Furthermore interfaces can’t enforce modification on sub-classes. Whatever you do to an interface, stays in the interface and is inherited only by the class that inherits directly from it, not the sub-classes. So changes can’t be fed directly along the hierarchy of class members. Last but not least interfaces need longer in processing.

“delegate” Reference type
The “delegate” Reference type is similar to the string: it points to one or several values, how many and which they are we can define. Now as I mentioned, the string always contains Unicode, with the server only really perceiving “so many positions, that and that and that etc is at each of the positions”. The delegate refers to any kind of Value type, as many as we need or want, and makes their content available. One could say that what the string is for char – the collection of multiple Unicode symbols – is the delegate for any Value type. Same as the string it refers to a method/modifier. But in case of the string the method is “go into the Unicode table at these positions and string up all the symbols you find in the correct order” and we don’t write all that, the method is in-build/hidden from us. But the delegate method we are allowed to define our self, it can be anything from modifying numbers, combining numbers and text etc etc.

Warning: I'm writing that while I go, I'm not a programmer, I'm literally just going through tutorials etc and writing down what I THINK I learn. It might be faulty and corrections or additions are very welcome!
 
Back