Overview
Now-a-days, saving cell space isn't as big a concern as it use to be, thanks to the introduction of mega and ultra cell space features and workaround methods. This guide is probably only going to be of interest to Alphaworld builders, as virtually all other populated worlds have at least mega cell space to work with. Still, some techniques are a "might as well" sort of a thing, as it involves no extra effort.
Cell Space Explained
A cell is a 10x10 meter area (and infinitively vertical), bordered off using the world's coordinate system. You can view the cell layout by pressing F10. Each cell can only store so much data, as set in the world settings. There are 5 tiers of cell space.
Cell space tiers as of January 2nd, 2007:
- Normal: 1650 bytes (~39 objects)
- Large: 2750 bytes (~65 objects)
- Huge: 4400 bytes (~104 objects)
- Mega: 5500 bytes (~130 objects)
- Ultra: 11000 bytes (~260 objects)
*object count based on max potential
What uses up cell space?
- The object's metadata, such as its ID, coordinates, the object's filename, and owner. This uses 45-55 bytes normally, average of 49.
- Longer object filenames use more space. For example, p1cyl0025d.rwx is 14 characters, using 14 bytes, whereas aw4.rwx is only 7.
- The object's description and action fields. Each character is one byte.
- V4 objects are a special case. All their numeric fields are stored in 4 bytes each, with the string fields (like urls, asset lists, etc) added ontop. Below are the minimum uses of each v4 type, without any string fields in use:
- One particle emitter uses at least 242 bytes + strings (about 4.9 objects).
- One zone object uses 90 bytes + strings (about 1.8 objects).
- One mover object uses 129 bytes + strings (about 2.6 objects).
- One camera object uses 60 bytes + strings (about 1.2 objects).
Code Optimization
AW's action code language is already pretty large, so anything you can shave off helps. Here are some tips, in no particular order:
- Do not use spaces after commas and semicolons.
- Use on and no for true and false flags, as they are the shortest. For example
create visible no
and create visible on
- Do not include https:// in urls.
- For time= arguments, such as in move and rotate, do not use a long number if you want it to be virtually infinite. AW accepts exponentials, so use 9e9 instead. For example
create move 0 1 1 time=9e9
which equals 9000000000. On the opposite side of the spectrum, you can also use 1e-9, which equals .000000001.
- For timings, such as times in particle emitters, or delays in astart/astop animations, you can shave off 1 byte by using timings such as 999 instead of 1000, as it's virtually the same.
- Omit extra variables from move commands. AW will default to 0. For example
create move 10
is the same as create move 10 0 0
. Note you can also do this for rotate commands, but not all the time. The extra zeros sometimes alters its rotation.
- For color commands, hex colors are often shorter than written out colors. For example
create color 0
is the same as create color black
, but 4 bytes less. You can also omit leading zeros in hex colors. For example create color 000250
is the same as create color 250
.
In some cases, written out colors are shorter than hex colors. create color white
is one byte less than create color ffffff
.
- Be sure not to type out code that's already included by default. For example, signs already use white font text by default, so you'd never use
create sign color=white
.
- In signs, you can place the sign's text in the action field or the description. Tests have shown that description based text uses less cell space.
- Instead of using
create sound blah.wav
, you can use sound:blah.wav
.
- For hidden objects only used for remote code, use an object with a short filename such as aw4.rwx
- For worlds without registries, and will never have a registry, omit the .rwx or .cob extension from objects.
- When texturing objects, remember that stock textures may already be in use. For example do not texture a pp01.rwx metal1 since pp25.rwx uses metal1 by default.
- Do not remove filename extension from urls to save cell space! For example do not remove the .jpg from
create picture www.blah.com/pics/blah
. While it may work for you, it will likely not work for others. This will only work if the user has seen and downloaded an object with the extension first. Only remove the extensions if you be absolutely sure that visitors will see an object using the extension first.
- All actions are applied to the object the action was written on unless otherwise specified, so do not use name commands unless needed. This is something I often see in astart/astop scripting.
Planning Ahead
If you are expecting to build something that is dense with objects, like a vehicle construct, you should plan its placement before getting started. This is done by splitting the construct across multiple cells (press F10 to enable the cell grid).
Build Efficiently
If you run out of cell space, there's a few things you can do.
- Most importantly, always be sure you're using the largest objects possible to get the job done. This mostly involves just memorizing the OP and their dimensions.
- In some cases you can use the scale command to make an object larger, replacing an array of smaller objects. Just be careful not to do this for ground cover because scaled ground cover does not protect against encroachment. Also note that some objects support different levels of texture scaling. For example, two w1pan_1000g.rwx objects could be replaced with one w2pan_1000f at scale 2. This trick applies for many object sets. Try it out!
- Move in the objects. This is done by using insta'moves. For example, move an object 10 meters to the east (which puts it in a new cell), and use
create move 10 time=0 wait=9e9
. The object will move back to where you had it, but since cell storage is based on an objects true position, it's using cell space from another cell.
If you are dealing with objects at all various angles, you'll notice they don't move along the world grid straight when your trying to relocate them to another cell. To compensate, the easiest way to do this is to build a temporary object and press NumPad 5 (with NumLock disabled). Then select your objects you wish to relocate, and select the temporary object last. Then group of objects will then move on a straight line.
- Offset particle emitters, if you're using them. Particle emitters use a lot of space (about 6 objects worth), so it's best to keep them outside of buildings. You can build a particle emitter 10 meters to the east for example, and then set its Volume X to 10-10, which offsets its emission point 10 meters west, essentially putting it back where you had it.
- In some cases, you can rotate an object around so it's axis point is in another cell, but it's geographic position looks the same as before. For example, say you have a cylinder object, like a log, laying down on the ground. It's axis point is on the west end of the cylinder. The axis point is in a full cell. Simply rotate the log end-to-end so the axis point is on the east side.
Remote Commands
Using remote commands means to name your objects, and have another object apply commands to it such as a texture. However, this is a dieing method in most communities as the most feasible method of doing this is significantly laggy. Back when Alphaworld had only tier 1 cell space, and lack of workaround alternatives, remote texturing was the norm. Remote texturing is not recommended, but it still works, and because of that it will be included in this guide.
First, to answer a question: Why do it? There's two reasons.
One, create name __ is shorter than create texture _____. The difference adds up when used in large scale, meaning more objects per cell. The difference between a single character name (create name b
) and a 6 character texture (create texture flame1
) is 8 bytes. If used to max efficiency in a world with huge cell space like Alphaworld, it could mean an additional 12 objects. However this is just one example. Due to many many factors, you can expect anywhere between 6 and 16 additional objects using naming.
Second, naming whole sets of objects allows you to easily retexture them all at once, which is handy in the design phase.
There are three ways to do it.
Method 1: Non-Looping Texturers obsolete with AW 4.1
The easiest way to do is to name everything, then on a remote object use create texture ____ name=__
. This method is a double edged sword though, because this is known as non-looping texturer. Once it applies the textures to the named object, it doesn't do it again. Translation? If it loads before the named objects load, the named objects won't get their texture. There were 2 workarounds to this.
- Build many of them so that they're more likely to be loaded after the named objects do. While this usually works for revisits, it's a risky system for first-time visitors, because the cells AW choses to download is seemingly random. Also adding multiple copies somewhat defeats the purpose of saving cell space.
- Only build it in the cell with the names applied. When AW 3.6 loads a cell, it loads all objects at the same time. The remote texture would then safely apply its command to all objects in the cell. However, this would only be feasible if the commands are being applied to enough objects to break even with the amount of space the texturer itself is using up.
AW 4.1's new cell loading sub-system does not load all the objects in the cell at exactly the same time, at least not behind the scenes. Because of this, this method no longer works reliably.
Method 2: Looping Texturers
This method is the common approach to remote texturing. Unlike method 1, this technique restarts the texturing code over and over so that the load order doesn't matter. For example, say you named your walls b and wanted to texture it wood7. You'd build a remote object somewhere and give it this code:
create animate me 1. 1 1 999,astart;adone texture wood7 name=b,astart
It is outside the skope of this guide to explain astart/astop scripting, but what this basically does is play an animation for 999 milliseconds, and when it's done, to trigger the adone section of the code, which contains all the texturing commands to apply to the named objects. Unfortunantly the act the having a running code loop over and over, applying a texture to multiple, sometimes hundreds of objects, is laggy on the browser. Hence, while this may work good for small scale applications, all in all it's recommended to simply use direct texturing instead of this technique.
Important: The 999 in the sample code is the delay. This number should never be 0, or anywhere under 100 for that matter! A delay of 1000 (1 second) is the fastest it should go. For dense areas, a delay of 2 or 3 seconds is recommended.
Method 3: Delayed Non-Looping Texturers
This method is the 4.1 compatible version of method 1's second application. It involves placing a remote texturer in every cell which wants to use it. The texturer uses a delay, giving AW enough time to load the cell before applying the actions. The advantage is that it's not laggy, unlike method 2.
The code of the remote texturer is the same as method 2, except it uses a shorter delay and doesn't loop:
create animate me 1. 1 1 99,astart;adone texture wood7 name=b
Once again, the remote texturer has to be in every cell using it since it doesn't loop. Due to it being in the same cell, and the length of its code, the texturer has to be applied to at least 15 objects of a single texture to break even in its cell space consumption. For every additional texture applied, it needs to be applied to at least 3 objects. In a best case scenario in a huge cell spaced world, one could only hope to save enough room to add another 5-9 objects.
Activated Non-Looping Texturers
This technique only applies to a small number of projects. If you have an interior that's unseen from the outside (like an underground room, or a windowless room), you can have everything inside textured upon entering the room. For example, name the walls b and the furniture c. Place this on the entrance door:
activate texture wood7 name=b,texture wood34 name=c
and then add any other commands to physically open the door (see: interactive doors)
When the user clicks the door, the code textures all the objects. Alternatively you could create an invisible bump trigger to do this instead. Just remember the user has to always properly enter the room to hit the triggers first.