1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
Love makes the world go around. Though in this case, it's the name of
the world server, the module that directly controls what happens to the
content of the virtual world.
The love world server that deals with changing the world. It manages
the on disk representation of the world, and lets others screw with it
via nails pumps. Love also sends nails events on changes.
World server vs local world.
----------------------------
Extantz defaults to running a local world at start up. Lspace serves
the content for a networked world. They may be the same world if the
local world is also networked. Nails pumps commands to and from the
world.
Lspace just serves the results as a web server. The love world server
changes on disk content, Lspace checks on disk modified time stamps to
deal with "do you have a newer version" HTTP requests. Standard web
server stuff really, though a mod_nails might be useful to catch events
in order to invalidate any internal web caches.
For networked worlds, Extantz fetches new content from Lspace, and hooks
up to the nails pump of the love server for changes. For local worlds,
extantz would basically BE the world server? No, that duplicates
things, it can just run a local love server, then connect to it like
every one else. No need to connect to a local Lspace server, just deal
with the file system direct.
The local love server would be configured to listen on 127.0.0.1, and/or
the outside IP address. Extantz checks to see if there's one running on
127.0.0.1 first before starting one if needed.
Separate vs combined.
---------------------
There's two ways of doing this. The world server could be part of
Lspace, or they could be separate modules. What we really have is a web
server, backing store, and command pump. The command pump is nails, and
should be a library that is shared, since both ends of the protocol
would be needed by most modules.
Combined might be useful to conserve resources. They both need to deal
with the contents of the world. Lspace just serves it to the outside
world via HTTP, but needs to track changes. Love makes those changes,
and also sends changes via nails to every one. Keeping the current
working set in memory only once saves a lot of memory.
The down sides of combined is that one might bog down the other, and it
gets harder to use standard web servers.
Separated is good coz Lspace might just be any ordinary web server.
They already have mechanisms in place to serve dynamic data, and even
deal with changes to the files. This is the whole point of basing the
major asset shifting part of the protocol on the web, people can use all
the major amounts of web infrastructure that already exists and already
solves most of the problems that currently plague virtual worlds based
on SL tech.
The down side of separated is that changes might be slower propagating
to the web server, and there might be two copies of any given set of
assets in memory at once.
A third option is to be separated, but any given web server could have a
mod_love type module written for it. This could share memory with the
love server process. So tighter integration is an option, but they can
work apart. Changes happen in this shared memory, driven by the command
pump in the love server. Lspace just needs read access, and just
serves the current state of the world. Love server persists to disk
when it's ready to, though the shared memory can just be memory mapped
files. This is the best of both worlds, excuse the pun.
Thoughts about directory structure.
========================================
A major goal is to have the disk structure of a sim (and inventory) be
decently human readable. The assets should be stored as normal files of
the appropriate type, so that they can be edited with normal editing
software like blender, gimp, a text editor, etc. Other goals include
not duplicating assets, and making it easy to move assets around.
Names.
------
A major LL created problem is that in world objects can have the same
name, though stuff in an objects inventory is forced to have unique
names by automatically adding numbers to the names. In inventory you
can have stuff with the same name to. The same named objects don't have
to be the same object, they can be completely different. A simple
object name to file name matching, with directories for contents, just
wont work. Need to munge the names anyway.
All name munging should produce names that are compatible with various
OS file systems, compatible with URLs, add "_123" numbers at the end for
duplicate names in the same directory, and auto add a file extension if
one is missing. Probably should check the file type if there IS a file
extension.
Links and URLs.
---------------
Any asset file could be a stuffs.lnk file, which holds a relative path
name or full URL pointing to the real asset. An external lspace server
would return the .omg file when the stuffs URL is requested, or an
actual asset file when those are requested.
Would have to do copy on write for editing and other state changes, not
including script state changes.
Probably need to store other info in the .lnk file if it's a URL, SHA-1
of the original file, other web cache info. Which starts to encroach on
web proxy / cache territory, which we may not want to do, since we want
to use real ones instead of crappy LL cache.
Actually, file names / URLs in .omg files would mostly be relative to
the file name / URL of the sim, and all the way down, so relative to the
directory things are in. It's up to the client to keep track of where
they are and build appropriate full URL / full path file names.
UUIDS.
------
Original LL UUIDs are the usual 36 byte string representing 32 lower
case hex characters and some dashes, encoding a 128 bit number. I was
inspired by git using SHA-1 hashes for content addressable assets.
SHA-1 hashes are 40 character hex codes representing 160 bit numbers
that are calculated based on the content. So the same content will give
the same SHA-1 hash. Git has proved that you only need the first digits
of the SHA-1 hash to ensure uniqueness, so it's feasible to use only the
first 128 bits of SHA-1 hashes to squeeze it into a UUID for the
purposes of uniquely identifying assets. Precisely what git does. This
means it could be backwards compatible with LL's use of UUIDs.
Since the SHA-1 code of identical files is the same, we could use this
to reduce duplicated large assets that never change, like textures and
sounds. This will be a big win.
I think we can get away with not storing SHA-1 hashes permanently, just
use them for in memory references, but cache them to disk separately.
The caches can be recreated at any time, since the SHA-1 hashes can be
calculated based on the data in the assets. So no UUIDs stored in .omg
files, just relative file / URL friendly names. The UUID / SHA-1 hashes
are mostly for keeping in memory as keys to stuff, coz they can shrink
down to a long long 128 bit integer.
Each asset file, whether texture, script, mesh, text file, etc, comes
with a matching .sha1 file that holds the SHA-1 hash of that file. .lnk
files get hashed to, so that each copy of a linked stuffs gets it's own
SHA-1 hash, but in this case the "content" is the relative path name.
The .sha1 files of the real asset .lnk files point to can be found in
the same place the real asset file is. Hmm, this means that reference
counting will be needed, otherwise the one real copy of an asset can get
deleted while links still point to it.
There will be a .sha1 directory full of files with the SHA-1 hashes as
part of the name, and the rest being similar to a .lnk file, a path to
the asset or .lnk file. Would save love server needing to keep that all
in memory all the time.
If the file system date stamp for the asset file is later than the one
for the .sha1 file, then someone edited the file, recreate the .sha1
files.
All the SHA-1 hashes can be recreated at any time, using file system
date stamps to tell if one is stale. They are only used internally to a
running system, to pass small identifiers around, and to fake LL UUIDs
for LSL scripts. When a SHA-1 hash is calculated for a new asset, it
gets stored in the .sha1, but if it already exists in .sha1, then the
asset is replaced by that sha1.lnk file, thus automatically
deduplicating assets.
Reference counting.
-------------------
Dunno yet, just realised the need for this, will come up with something
soon. Will solve this problem when we implement links, wont need it
until then anyway.
Obviously the count has to be kept with the real asset file, there's a
few ways to go about that. I've been thinking that the .sha1 file might
be a good place to keep other meta data, like perhaps owner and group
info. So one way is to include the reference count there to. Another
option is a separate .ref file with the count inside. A third option,
just tack the count onto the end of a file name. This is likely a bit
quicker than updating a file.
On disk structure.
------------------
"some sim name" -> some%20sim%20name/index.omg
list of stuffs rezzed in the sim
stuffs position, size, and orientation
relative file / URL name pointing to the stuffs
no need for the in world name, those interested in that will likely grab the stuffs.omg file anyway
"a stuffs" -> a%20stuffs.omg
in world name, description
list of stuffs similar to the sim index.omg, only this is for the various meshes that make up this stuffs.
stuffs position, size, and orientation, relative to this stuffs
relative file / URL name pointing to the mesh and textures
extra info for each material
a%20stuffs/ directory
files that are the contents of this stuffs
could be .lnk files
.sha1 files
a%20stuffs/index.omg
used to be a list of content file names, type, and UUID
file names are right there in the directory
UUID ala SHA-1 can now be calculated based on those files
and stored in an asset.sha1 file
type can use the magic/file/MIME system to identify file types
can get rid of this file, though maybe have it in a .types directory,
coz we would want to cache the file type
or just use a poor mans magic/file/MIME thingy based on file extension,
since we only have a small number of file types
note cards should have a .txt, scripts a .lsl or .lua
People could even be free to use their own organising directory
structure. A directory for ground level, and one for each sky box for
instance. Relative paths inside .omg files sorts that all out.
A sims index.omg file might be constantly updated for busy sims. Could
generate it on the fly by the Lspace server, based on the actual
contents of the sim directory. Alternative Lspace servers could just
use a CMS system for all of this anyway. They would still use the same
structure for URLs and .omg files.
Avatars.
--------
Storing avatars in this way isn't such a good idea? Avatars could have
their own avatar.omg dealing with shape, skin, clothes, attachments,
etc. But instead of a client asking for a list, avatar arrivals and
departures are driven by love. Though try to keep avatars as "just
ordinary object, but with a person controlling it". Still, they move
around a lot.
Avatar.omg would live on the users hard drive, but sent to the love
server on login, and after any change.
Misc.
-----
Right now I'm using Lua style .omg files, but eet would be a better
choice I think. Saves having to write a Lua table to C structure
system, which eet already has, sorta. Lua tables are at least more
readable while I consider the design, but likely use eet instead when I
have to write code to read the suckers. .omg files are managed by the
love server, so fiddling with them is an expert thing anyway.
Should have a tool to validate a sims files and recreate the caches.
Remaining issues.
-----------------
Owner / group UUID might be better dealt with elsewhere? Coz links.
Also, we wont replicate the LL user / group stuff exactly, but morph
into more standardised variations. Jabber users, jabber group rosters,
OS users, LDAP users and groups, web site users, etc. So just provide
an abstraction, and an example or two.
might be better to move compiled scripts and generated Lua source to the LuaSL server's own private store?
LuaSL needs to assign UUIDs to compiled script binaries, so it knows which running script is which
coz there might be lots of copies of scripts
on the other hand, each copy is uniquely named inside some objects contents,
even if it's a link,
so the UUID of the stuffs plus the UUID within the stuffs contents, for this copy / link of the script should suffice?
|