https://www.sirikata.com/wiki/api.php?action=feedcontributions&user=Ewencp&feedformat=atomSirikata Wiki - User contributions [en]2024-03-28T22:05:08ZUser contributionsMediaWiki 1.35.7https://www.sirikata.com/wiki/index.php?title=Creating_a_Release&diff=1308Creating a Release2012-06-07T23:08:03Z<p>Ewencp: Fix minor typos</p>
<hr />
<div>This guide describes all the steps for creating a new release. The process is mostly automated, so this mostly serves as a checklist.<br />
<br />
== Before Building Packages ==<br />
<br />
* Test! Make sure that things are working well on all the platforms. In order to do this you need a fully functional build on all platforms. You'll need this setup to build the packages as well.<br />
* Update the version number.<br />
** In build/cmake/CMakeLists.txt, search for the SIRIKATA_VERSION_* variables and update them.<br />
** See [[Debian Packaging]] for how to update the Debian packaging information.<br />
* Commit '''but do not tag''' the release.<br />
** Ideally bumping the version number is the last commit.<br />
** These commits need to be in a public repository that you can clone them when building packages. One way to accomplish this is to build<br />
** We don't tag the release until we've got all the packages built and tested so that tags don't become public until they are finalized. If you aren't using the central repository to get the source for building packages, you can safely tag now since the tag can be deleted and changed if necessary.<br />
<br />
== Building Packages ==<br />
<br />
This step is entirely automated on each platform. <br />
<br />
=== Windows ===<br />
From a fully functional checkout (i.e. you've built from within the directory and have the latest dependencies) run<br />
<br />
./tools/release/build-win32-release.bat x.y.z<br />
<br />
This depends on a bunch of tools being available in their default locations: CMake and Visual Studio for the build, Python (to run a script that extracts Breakpad symbols), 7zip (for generating the archive).<br />
<br />
The version number here is only used for naming the archive, you don't necessarily need a tag or branch with the name vx.y.z. '''However, this means that you do need to already have the correct revision checked out in your working copy.'''<br />
<br />
This should result in two files, sirikata-x.y.z-win32.zip and sirikata-x.y.z-win32.dbg.zip, sitting in the top directory.<br />
<br />
=== Mac ===<br />
From a fully functional checkout (i.e. you've built from within the directory and have the latest dependencies) run<br />
<br />
./tools/release/build-mac-release.sh [--debug] x.y.z<br />
<br />
The version number here is only used for naming the archive, you don't necessarily need a tag or branch with the name vx.y.z. '''However, this means that you do need to already have the correct revision checked out in your working copy.'''<br />
<br />
This should result in one file, sirikata-x.y.z-mac.tar.gz, sitting in the top directory.<br />
<br />
=== Linux ===<br />
See [[Debian Packaging]] for details. As long as you've tested on Linux this package can be generated after the rest.<br />
<br />
=== Source ===<br />
From an existing checkout, run<br />
<br />
./tools/release/build-source-release.sh x.y.z<br />
<br />
where x.y.z is the version number you're building. One of the steps in this script is<br />
<br />
git checkout vx.y.z<br />
<br />
so you need a branch or tag with that name that points at the latest commit for this release, i.e. the version number bumping commit.<br />
<br />
This should result in one file, sirikata-x.y.z-src.zip, sitting in the top directory.<br />
<br />
== Building Installers ==<br />
<br />
We also provide simple installers for Windows and Mac. We use BitRock's InstallBuilder. Ask Ewen for license info. Once you have it, you need to checkout the [http://github.com/sirikata/sirikata-installer sirikata-installer] repository. Then, just do<br />
<br />
./create-release.sh x y z<br />
<br />
from the top-level of that repository, where x, y, and z correspond to the version number.<br />
<br />
You need to have the <tt>builder</tt> binary from InstallBuilder on your path.<br />
<br />
The output should be:<br />
<br />
* sirikata-x.y.z-win32-installer.exe<br />
* sirikata-x.y.z-mac-installer.dmg<br />
* sirikata-x.y.z-mac-installer.tgz (which contains the same thing as the dmg, but in a format the autoupdater can use)<br />
* update.xml (which allows the autoupdaters to figure out what the most recent version is and where to download it)<br />
<br />
You'll need to upload these along with the simple packages.<br />
<br />
{{note}} '''Always''' upload the update.xml file last, and only after testing that everything else is available for download.<br />
<br />
== After Building Packages ==<br />
<br />
* Test! Make sure the packages built on each platform are sane -- at a minimum extract them and run a space and object host.<br />
* Upload to sirikata.com/releases/.<br />
** Just scp the archives into the appropriate win32/, mac/, and src/ directories on the web server. This includes the installer packages.<br />
** scp update.xml into sirikata.com/releases/<br />
** Grab the Ubuntu data from [http://ppa.launchpad.net/sirikata/sirikata/ubuntu/pool/main/s/sirikata/ launchpad's package archive] after it's built and put it under ubuntu/{DISTRO}/<br />
** Ask Ewen for the account details.<br />
* Upload the crash reporter symbols to crashes.sirikata.com.<br />
** Take the package sirikata-x.y.z-win32.dbg.zip generated in the build process and extract it. The directory sirikata_win32_syms/ contains Breakpad symbols that the crash collector uses to generate stacktraces. You just need to scp these to the crash server.<br />
** Ask Ewen for account details.<br />
* Update the version number on the release page.<br />
** This is handled through a WordPress page called 'Downloads'. Edit the source of that page, just search for 'version' and update the number.<br />
** Again, ask Ewen for account details.<br />
* Test the download page links. Make sure they work on each platform.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Debian_Packaging&diff=1307Debian Packaging2012-06-07T21:20:39Z<p>Ewencp: /* Creating Release */ Update distribution specification for new version note to precise.</p>
<hr />
<div>==Prerequisites==<br />
* Create a PGP key (required) and import into Launchpad (optional): https://help.launchpad.net/YourAccount/ImportingYourPGPKey<br />
* Install debian packaging tools: <code>sudo apt-get install pbuilder debootstrap devscripts</code><br />
* Set your /etc/pbuilderrc to something like this:<br />
MIRRORSITE=http://us.archive.ubuntu.com/ubuntu/<br />
<br />
BUILDUSERID=12345<br />
BUILDUSERNAME=fakeuser<br />
<br />
DISTRIBUTION=oneiric<br />
COMPONENTS="main restricted universe multiverse"<br />
<br />
EXTRAPACKAGES="nano ssh"<br />
<br />
TIMEOUT_TIME=24h<br />
* After setting up /etc/pbuilderrc, run:<br />
sudo pbuilder --create<br />
<br />
==Creating Release==<br />
Create a directory to be used for packaging. The rest of the commands assume you are in that directory.<br />
mkdir packaging<br />
cd packaging<br />
<br />
Next, decide what release you are making. The release version should be the upstream release version. The minor version is if the upstream release has a minor release. The debian version is for making new packaged versions for the same upstream release. The debian version for each upstream release should always start with 1. The minor version should be 0 if the upstream release has no minor number.<br />
export SIRIKATA_RELEASE="0.0.20"<br />
export SIRIKATA_MINOR="0"<br />
export SIRIKATA_DEBIAN="1"<br />
<br />
Clone the repository, switch to the release tag, and check out submodules:<br />
git clone git://github.com/sirikata/sirikata.git sirikata-${SIRIKATA_RELEASE}<br />
cd sirikata-${SIRIKATA_RELEASE}<br />
git checkout v${SIRIKATA_RELEASE}<br />
git submodule update --init --recursive<br />
make update-dependencies<br />
cd dependencies<br />
./install --download-only sdl bullet opencollada v8 ogre chromium ffmpeg<br />
cd ..<br />
<br />
Now edit the changelog file to add a new section (you might do this step *before* the tag so it can be part of the "original" tgz). Make sure that the email address in the signature is identical to your Launchpad address:<br />
dch --newversion ${SIRIKATA_RELEASE}-${SIRIKATA_MINOR}ubuntu${SIRIKATA_DEBIAN}<br />
<br />
If you are on an older version of Ubuntu, you might need to specify the distribution:<br />
dch --newversion ${SIRIKATA_RELEASE}-${SIRIKATA_MINOR}ubuntu${SIRIKATA_DEBIAN} --distribution precise<br />
<br />
Now go back up a directory and create the "orig" tar file that debian requires (note _ instead of -, it matters):<br />
cd ..<br />
tar --exclude-vcs -cvzf sirikata_${SIRIKATA_RELEASE}.orig.tar.gz sirikata-${SIRIKATA_RELEASE}<br />
<br />
Go back into the directory and create the build:<br />
cd sirikata-${SIRIKATA_RELEASE}<br />
debuild -S<br />
<br />
Go back up and run pbuilder to test if the build works:<br />
cd ..<br />
sudo pbuilder --build sirikata_${SIRIKATA_RELEASE}-${SIRIKATA_MINOR}ubuntu${SIRIKATA_DEBIAN}.dsc<br />
<br />
To upload to launchpad:<br />
dput ppa:sirikata/sirikata sirikata_${SIRIKATA_RELEASE}-${SIRIKATA_MINOR}ubuntu${SIRIKATA_DEBIAN}_source.changes<br />
<br />
==Installing==<br />
=== The Easy Way ===<br />
<br />
sudo add-apt-repository ppa:sirikata/sirikata<br />
sudo apt-get update<br />
sudo apt-get install sirikata<br />
<br />
=== The Manual Way ===<br />
Put this:<br />
deb http://ppa.launchpad.net/sirikata/sirikata/ubuntu oneiric main<br />
in this file:<br />
/etc/apt/sources.list.d/sirikata.list<br />
Then run:<br />
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E3BB648B583006F3<br />
sudo apt-get update<br />
sudo apt-get install sirikata</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Roadmap&diff=1306Roadmap2012-06-02T22:47:35Z<p>Ewencp: Filter out a bunch of tasks we've finished since this list was last updated</p>
<hr />
<div>''This is the roadmap and brainstorm for development''<br />
<br />
==Assigned Tasks==<br />
* B scripter GUI (improvements to interface)<br />
* B/E V8 closures (fix storage of functions in v8 to save closure as well as function text)<br />
* E/J CDN support for music (serve music files as well as meshes)<br />
<br />
==Ideas==<br />
<br />
===Deployment===<br />
* Backups of OH data<br />
<br />
===Demo World===<br />
* Repository for world-specific scripts (avatar script, anything we expect to be in there by default).<br />
* Build a nice demo scene, large enough to require some exploration to see it all.<br />
* Scripts for building into package (i.e. all the data required to support [[Sirikata URIs]]<br />
* Get a few good, tested avatars on the CDN and get the default demo avatar to use these simple animations well<br />
<br />
===System Features===<br />
* Space<br />
** Physics improvements -- get avatars on terrain working well<br />
** Generate collision event messages for objects, maybe based on subscription request<br />
<br />
* CDN<br />
** Expose progressive meshes<br />
<br />
* OH<br />
** Progressive mesh loading<br />
** Improve Emerson storage -- make it much easier to interface and get a persistent object<br />
** Improve object manipulation interface (could be in deployment specific code, i.e. under Demo World)<br />
** Object migration between OHs<br />
** Fix closures/provide full snapshotting (timers/register handlers/etc)<br />
** libmesh filters should not strip animations (eg. check if joints before collapsing two vertices).<br />
** Playing multiple animations at once (blend/interpolation)<br />
** Exposing physics collisions to Emerson.<br />
** Fix Gui isolation<br />
** Better OH connection failure handling<br />
** Reduce Emerson memory usage<br />
<br />
===Documentation===<br />
* Storage tutorial<br />
* Sandbox tutorial<br />
* Getting started with demo, maybe just update getting started for users since a lot of steps can be avoided when someone provides the configuration for you.<br />
* Simple demo videos showing how to join and interact with the world/other users.<br />
<br />
==Long-term Goals & Research==<br />
* Add audio support (purely OH-based to support, e.g. simple sound effects and local voice chat, then consider adding mixing support to the space server).<br />
* Load balancing objects across object hosts<br />
* Distributed physics -- extend physics to work with objects including boundaries<br />
* Mesh/object aggregation<br />
* Multicast<br />
* New transport abstractions targeted at VWs (e.g. last reliable)</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Installation&diff=1305Installation2012-06-01T00:41:31Z<p>Ewencp: Add note that installers are preferred</p>
<hr />
<div>== Downloading and Installing Sirikata ==<br />
<br />
Start by downloading the binary packages from the [http://sirikata.com/blog/download/ download page]. The installers are preferred and should just work. If you're having trouble with the installers or prefer installing manually, then follow the instructions below for your platform.<br />
<br />
=== Windows ===<br />
To run Sirikata, including the graphical client, you'll need to install two additional packages:<br />
*[http://www.microsoft.com/downloads/details.aspx?familyid=2DA43D38-DB71-4C1B-BC6A-9B6652CD92A3 DirectX End-User Runtime Web Installer]<br />
*[http://www.microsoft.com/downloads/details.aspx?FamilyID=a5c84275-3b97-4ab7-a40d-3802b2af5fc2 Microsoft Visual C++ 2008 SP1 Redistributable Package (x86)]<br />
<br />
With these installed, simply download the [http://sirikata.com/blog/download/ latest package]. Unzip it anywhere on your computer. You should then have directories that look like this:<br />
<br />
* sirikata_win32/<br />
* bin/<br />
* include/<br />
* lib/<br />
* share/<br />
<br />
Go into sirikata_win32/bin/ and run space.exe, then cppoh.exe. space.exe starts a space locally. It is private and will only use the objects you start. cppoh.exe is the client. By default, it loads up a few objects as well as your avatar. If everything worked, you should see a window pop up and start displaying the world.<br />
<br />
=== Mac OS X ===<br />
<br />
Download the [http://sirikata.com/blog/download/ latest package]. Unzip it anywhere on your computer. You should then have directories that look like this:<br />
<br />
* sirikata_mac/<br />
* Frameworks/<br />
* bin/<br />
* include/<br />
* lib/<br />
* share/<br />
<br />
Go into sirikata_mac/bin/ and run space, then cppoh.app. To run these, you likely need to set DYLD_LIBRARY_PATH, e.g.:<br />
<br />
cd sirikata_mac/bin<br />
./space<br />
<br />
space starts a space (world) locally. It is private and will only use the objects you start. cppoh.app is the client. By default, it loads up a few objects as well as your avatar. If everything worked, you should see a window pop up and start displaying the world.<br />
<br />
To run cppoh.app from the command line and add parameters, run it as<br />
<br />
./cppoh.app/Contents/MacOS/cppoh [--option=value]<br />
<br />
=== Linux ===<br />
<br />
==== Ubuntu ====<br />
<br />
Follow the link on the [http://sirikata.com/blog/download/ download page] and follow the instructions to install the packages from the PPA. The binaries (e.g. space, cppoh) will be installed in your PATH.<br />
<br />
==== Other Distributions ====<br />
<br />
Linux users on other distributions should [[GetTheCode|check out]] and [[BuildTheCode|build]] the code themselves. This process is scripted, so it should be simple even though it takes awhile.<br />
<br />
==== Configuration ====<br />
<br />
See the [[Keybindings]] page for information about how to control your object.<br />
<br />
When you first start the client, a window will pop up with the Ogre logo asking for some settings. Usually you only need to change two settings: from the top drop down, select 'OpenGL Renderer' and in the resulting option list chnage 'Fullscreen' to off. OpenGL is the more reliable default, but you may also try the Direct3D renderer (see 'Troubleshooting' below for more details).<br />
<br />
=== Troubleshooting ===<br />
<br />
* I'm getting the message 'This application has failed to start because d3dx9_42.dll was not found. Re-installing the application may fix this problem.'<br />
** You need to install the DirectX End-User Runtime. Make sure you've followed the instructions above.<br />
* Nothing is showing up.<br />
** Give it a minute or two on the first run. The default scene isn't small and the meshes need to be downloaded. On future runs, the content will be loaded from your local disk if possible, making it start up much more quickly. If, after a few minutes, still nothing shows up, get in touch with the developers as described below.<br />
* I'm getting a message that I don't have permissions to access a file when I try to run the space server.<br />
** Chances are you unzipped the sirikata package using Cygwin, which doesn't handle file permissions properly. Try unzipping using Windows' standard utilities.<br />
* The settings I chose for Ogre don't work and it doesn't pop up the configuration screen anymore.<br />
** You need to clear out your ogre.cfg file. On Windows you can find this under, e.g., C:\Users\Username\AppData\Local\Sirikata. Under Linux and Mac it should be under ~/.sirikata. Delete the file ogre. and the next time you run the configuration will pop up again.<br />
* I'm having another problem not covered here.<br />
** Get in touch with the developers on the [http://groups.google.com/group/platformtalk developer mailing list] or via IRC (#sirikata on irc.freenode.net).<br />
<br />
<br />
== Scripting Objects ==<br />
<br />
Once you've connected, you might want to try scripting some objects. Check out the [[Guides/Scripting Guide|Scripting Guide]] for more details.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Creating_a_Release&diff=1304Creating a Release2012-06-01T00:29:05Z<p>Ewencp: Add notes about creating installers</p>
<hr />
<div>This guide describes all the steps for creating a new release. The process is mostly automated, so this mostly serves as a checklist.<br />
<br />
== Before Building Packages ==<br />
<br />
* Test! Make sure that things are working well on all the platforms. In order to do this you need a fully functional build on all platforms. You'll need this setup to build the packages as well.<br />
* Update the version number.<br />
** In build/cmake/CMakeLists.txt, search for the SIRIKATA_VERSION_* variables and update them.<br />
** See [[Debian Packaging]] for how to update the Debian packaging information.<br />
* Commit '''but do not tag''' the release.<br />
** Ideally bumping the version number is the last commit.<br />
** These commits need to be in a public repository that you can clone them when building packages. One way to accomplish this is to build<br />
** We don't tag the release until we've got all the packages built and tested so that tags don't become public until they are finalized. If you aren't using the central repository to get the source for building packages, you can safely tag now since the tag can be deleted and changed if necessary.<br />
<br />
== Building Packages ==<br />
<br />
This step is entirely automated on each platform. <br />
<br />
=== Windows ===<br />
From a fully functional checkout (i.e. you've built from within the directory and have the latest dependencies) run<br />
<br />
./tools/release/build-win32-release.bat x.y.z<br />
<br />
This depends on a bunch of tools being available in their default locations: CMake and Visual Studio for the build, Python (to run a script that extracts Breakpad symbols), 7zip (for generating the archive).<br />
<br />
The version number here is only used for naming the archive, you don't necessarily need a tag or branch with the name vx.y.z. '''However, this means that you do need to already have the correct revision checked out in your working copy.'''<br />
<br />
This should result in two files, sirikata-x.y.z-win32.zip and sirikata-x.y.z-win32.dbg.zip, sitting in the top directory.<br />
<br />
=== Mac ===<br />
From a fully functional checkout (i.e. you've built from within the directory and have the latest dependencies) run<br />
<br />
./tools/release/build-mac-release.sh [--debug] x.y.z<br />
<br />
The version number here is only used for naming the archive, you don't necessarily need a tag or branch with the name vx.y.z. '''However, this means that you do need to already have the correct revision checked out in your working copy.'''<br />
<br />
This should result in one file, sirikata-x.y.z-mac.tar.gz, sitting in the top directory.<br />
<br />
=== Linux ===<br />
See [[Debian Packaging]] for details. As long as you've tested on Linux this package can be generated after the rest.<br />
<br />
=== Source ===<br />
From an existing checkout, run<br />
<br />
./tools/release/build-source-release.sh x.y.z<br />
<br />
where x.y.z is the version number you're building. One of the steps in this script is<br />
<br />
git checkout vx.y.z<br />
<br />
so you need a branch or tag with that name that points at the latest commit for this release, i.e. the version number bumping commit.<br />
<br />
This should result in one file, sirikata-x.y.z-src.zip, sitting in the top directory.<br />
<br />
== Building Installers ==<br />
<br />
We also provide simple installers for Windows and Mac. We use BitRock's InstallBuilder. Ask Ewen for license info. Once you have it, you need to checkout the [http://github.com/sirikata/sirikata-installer sirikata-installer] repository. Then, just do<br />
<br />
./create-release.sh x y z<br />
<br />
from the top-level of that repository, where x, y, and z correspond to the version number.<br />
<br />
You need to have the <tt>builder</tt> binary from InstallBuilder on your path.<br />
<br />
The output should be:<br />
<br />
* sirikata-x.y.z-win32-installer.exe<br />
* sirikata-x.y.z-win32-installer.dmg<br />
* sirikata-x.y.z-win32-installer.tgz (which contains the same thing as the dmg, but in a format the autoupdater can use)<br />
* update.xml (which allows the autoupdaters to figure out what the most recent version is and where to download it)<br />
<br />
You'll need to upload these along with the simple packages.<br />
<br />
{{note}} '''Always''' upload the update.xml file last, and only after testing that everything else is available for download.<br />
<br />
== After Building Packages ==<br />
<br />
* Test! Make sure the packages built on each platform are sane -- at a minimum extract them and run a space and object host.<br />
* Upload to sirikata.com/releases/.<br />
** Just scp the archives into the appropriate win32/, mac/, and src/ directories on the web server. This includes the installer packages.<br />
** scp update.xml into sirikata.com/releases/<br />
** Grab the Ubuntu data from [http://ppa.launchpad.net/sirikata/sirikata/ubuntu/pool/main/s/sirikata/ launchpad's package archive] after it's built and put it under ubuntu/{DISTRO}/<br />
** Ask Ewen for the account details.<br />
* Upload the crash crash reporter symbols to crashes.sirikata.com.<br />
** Take the package sirikata-x.y.z-win32.dbg.zip generated in the build process and extract it. The directory sirikata_win32_syms/ contains Breakpad symbols that the crash collector uses to generate stacktraces. You just need to scp these to the crash server.<br />
** Ask Ewen for account details.<br />
* Update the version number on the release page.<br />
** This is handled through a WordPress page called 'Downloads'. Edit the source of that page, just search for 'version' and update the number.<br />
** Again, ask Ewen for account details.<br />
* Test the download page links. Make sure they work on each platform.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=List_of_Worlds&diff=1303List of Worlds2012-05-31T01:45:51Z<p>Ewencp: Clarify how slauncher links works.</p>
<hr />
<div>This is a list of worlds that are publicly available. You can use [[Sirikata_URIs|slauncher]], included with Sirikata, to connect to these worlds by just clicking the link in the '''slauncher''' column. If you used an installer, this should already be setup.<br />
<br />
{| class="wikitable"<br />
|-<br />
! World Name & Homepage<br />
! slauncher<br />
! Description<br />
<br />
|-<br />
| [[Basic Demo World]]<br />
| [sirikata:http://sirikata.com/demos/basic/melville.json Launch]<br />
| A very simple world where you can chat and experiment with Sirikata's scripting language, Emerson.<br />
<br />
|-<br />
| [[Large City World]]<br />
| [sirikata:http://sirikata.com/demos/merustadt/merustadt.json Launch]<br />
| A city scene, demonstrating aggregation & simplification for large scenes.<br />
<br />
|}</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Platform_Development/Tutorials/Writing_a_Plugin&diff=1302Guides/Platform Development/Tutorials/Writing a Plugin2012-05-28T18:07:58Z<p>Ewencp: Formatting cleanup</p>
<hr />
<div>= Writing a Sirikata Plugin =<br />
<br />
The primary way to extend Sirikata is to provide a new implementation of an interface in one of the libraries. These implementations generally live in plugins and only the plugins required to run the desired world are loaded. For example, the interface <tt>ObjectSegmentation</tt> defines the interface for the component that stores the mapping from objects to the servers managing them. However, we could implement it in different ways. Sirikata already has one implementation called <tt>LocalObjectSegmentation</tt> for spaces which will only ever run on a single server. This implementation is trivial. It also has another, <tt>CraqObjectSegmentation</tt>, which works in the distributed case by using a separate key-value store based on CRAQ.<br />
<br />
Most components in the system can have different implementations. To make these options pluggable and not require all dependencies to build the system, we utilize a plugin-based architecture. This tutorial will explain how to create a new plugin to extend the system. Obviously this approach works for any interface, but this tutorial will focus on a new <tt>ObjectSegmentation</tt> implementation called <tt>TutorialObjectSegmentation</tt>.<br />
<br />
== Skeleton Code ==<br />
<br />
The best way to start a new plugin is to base it on the skeleton plugin for <tt>libcore</tt>, found in <tt>libcore/plugins/skeleton</tt>. The rest of this tutorial will be based on this code, so you can start by copying it into place for your new plugin. It contains only a single file, <tt>PluginInterface.cpp</tt>, since it has no real interface implementation. You will add new files for the implementation later in this tutorial.<br />
<br />
== Adding the Plugin to the Build System ==<br />
<br />
As with the skeleton code, there are some commands for adding the skeleton plugin to the build system. This is a good starting point, especially since the build system is complex. Translating the skeleton commands, we might end up adding something like this to <tt>build/cmake/CMakeLists.txt</tt>.<br />
<br />
<pre class="sourceCode cmake">SET(LIBSPACE_PLUGIN_TUTORIAL_DIR ${LIBSPACE_PLUGIN_DIR}/tutorial)<br />
SET(LIBSPACE_PLUGIN_TUTORIAL_SOURCES ${LIBSPACE_PLUGIN_TUTORIAL_DIR}/PluginInterface.cpp)<br />
<br />
ADD_PLUGIN_TARGET(space-tutorial<br />
SOURCES ${LIBSPACE_PLUGIN_TUTORIAL_SOURCES}<br />
TARGET_LDFLAGS ${sirikata_LDFLAGS}<br />
LIBRARIES ${SIRIKATA_CORE_LIB} ${SIRIKATA_SPACE_LIB}<br />
TARGET_LIBRARIES ${SIRIKATA_CORE_LIB} ${SIRIKATA_SPACE_LIB})<br />
SET(PLUGIN_INSTALL_LIST ${PLUGIN_INSTALL_LIST} space-tutorial)</pre><br />
First, note that we've labelled it appropriately as a space plugin by prefixing everything with <tt>LIBSPACE</tt> . Second, we've made sure all our variables have our plugin name in them, <tt>TUTORIAL</tt> . The utility macro <tt>ADD_PLUGIN_TARGET</tt> takes care of most of the complicated work of setting up a plugin to be built. You specify source files, any linker flags and target libraries, and the macro takes care of the rest. The final line adds the plugin for installation.<br />
<br />
If this plugin has a non-standard dependency, then we should only add the plugin if that dependency is found. This would look like this for a dependency called <tt>tutdep</tt><br />
<br />
<pre class="sourceCode cmake">FIND_PACKAGE(tutdep)<br />
IF(TUTDEP_FOUND)<br />
ADD_PLUGIN_TARGET(space-tutorial<br />
...<br />
)<br />
ENDIF(TUTDEP_FOUND)</pre><br />
If necessary, add the <tt>tutdep</tt> library to the <tt>LIBRARIES</tt> argument of <tt>ADD_PLUGIN_TARGET</tt>.<br />
<br />
== Implementing the Interface ==<br />
<br />
How the interface is implemented obviously depends on the plugin you are writing. Here, we'll present the skeleton for `TutorialObjectSegmentation` , which is enough to explain the basic concepts.<br />
<br />
Following the interface for <tt>ObjectSegmentation</tt> we create a file <tt>TutorialObjectSegmentation.hpp</tt> with the following contents<br />
<br />
<pre>#ifndef _SIRIKATA_TUTORIAL_OBJECT_SEGMENTATION_HPP_<br />
#define _SIRIKATA_TUTORIAL_OBJECT_SEGMENTATION_HPP_<br />
<br />
#include &lt;sirikata/space/ObjectSegmentation.hpp&gt;<br />
<br />
namespace Sirikata {<br />
<br />
class TutorialObjectSegmentation : public ObjectSegmentation {<br />
public:<br />
...<br />
};<br />
<br />
} // namespace Sirikata<br />
<br />
#endif //_SIRIKATA_TUTORIAL_OBJECT_SEGMENTATION_HPP_</pre><br />
and a <tt>TutorialObjectSegmentation.cpp</tt> with the following contents<br />
<br />
<pre>#include &quot;TutorialObjectSegmentation.hpp&quot;<br />
<br />
namespace Sirikata {<br />
<br />
TutorialObjectSegmentation::TutorialObjectSegmentation() {<br />
}<br />
<br />
...<br />
<br />
} // namespace Sirikata</pre><br />
Recall that we had to specify our source files in the build system. Having added the implementation file, we need to add it to the build, changing our source file list:<br />
<br />
<pre class="sourceCode cmake">SET(LIBSPACE_PLUGIN_TUTORIAL_SOURCES<br />
${LIBSPACE_PLUGIN_TUTORIAL_DIR}/PluginInterface.cpp<br />
${LIBSPACE_PLUGIN_TUTORIAL_DIR}/TutorialObjectSegmentation.cpp<br />
)</pre><br />
== Exposing the Implemented Interface from the Plugin ==<br />
<br />
The previous steps got the implementation into the dynamic library, but it isn't exposed to the rest of the system. Sirikata enables you to expose it as an option via a <tt>Factory</tt>. Usually, any interface which could be instantiated from a plugin has a <tt>Factory</tt> associated with it. The factory allows implementations to register a constructor function which can be invoked to create a new instance, and names that constructor with a string. In this way, the library, and its users, only needs to know about the generic interface, the factory, and what strings can be used to identify implementations.<br />
<br />
Back in the <tt>PluginInterface.cpp</tt> we add (or replace) the following code:<br />
<br />
<pre>namespace Sirikata {<br />
<br />
static ObjectSegmentation* createTutorialOSeg(<br />
SpaceContext* ctx, Network::IOStrand* oseg_strand,<br />
CoordinateSegmentation* cseg, OSegCache* cache,<br />
const String&amp; args)<br />
{<br />
return new TutorialObjectSegmentation(ctx, oseg_strand, cseg, cache);<br />
}<br />
<br />
} // namespace Sirikata<br />
<br />
SIRIKATA_PLUGIN_EXPORT_C void init() {<br />
using namespace Sirikata;<br />
if (space_tutorial_plugin_refcount==0) {<br />
using std::tr1::placeholders::_1;<br />
using std::tr1::placeholders::_2;<br />
using std::tr1::placeholders::_3;<br />
using std::tr1::placeholders::_4;<br />
OSegFactory::getSingleton()<br />
.registerConstructor(&quot;tutorial&quot;,<br />
std::tr1::bind(&amp;createTutorialOSeg, _1, _2, _3, _4));<br />
}<br />
space_tutorial_plugin_refcount++;<br />
}<br />
<br />
SIRIKATA_PLUGIN_EXPORT_C void destroy() {<br />
using namespace Sirikata;<br />
if (space_tutorial_plugin_refcount==0) {<br />
OSegFactory::getSingleton().unregisterConstructor(&quot;tutorial&quot;);<br />
}<br />
}</pre><br />
This registers our constructor (indirectly via a wrapper function) to the factory when the plugin is initialized, and unregisters it when the plugin is destroyed. In this case, you can ignore the parameters to the constructor --they are just the parameters all <tt>ObjectSegmentation</tt> implementations must take. While the <tt>createTutorialOSeg</tt> function must match this signature, the constructor could take additional parameters. In fact, a common pattern is to parse arguments from the last parameter and pass them directly into the <tt>TutorialObjectSegmentation</tt> constructor so the parsing of options is isolated from the implementation.<br />
<br />
If you aren't familiar with it, you probably want to learn about boost::bind. It is a generalization of function pointers which is type-safe and allows you to curry arguments. In this case, it is used to turn <tt>createTutorialOSeg</tt> into a type-safe &quot;constructor&quot; which returns an <tt>ObjectSegmentation*</tt>.<br />
<br />
That's all that's required -- no modifications to the core code and no need to export symbols from the plugin.<br />
<br />
== Conclusion ==<br />
<br />
This tutorial should have enabled you to create a new plugin for Sirikata which adds and exposes a new interface implementation to Sirikata. Frequently, after a basic implementation works one of the first needs is to control its behavior with options. See [[Guides/Platform_Development/Tutorials/Adding_Options|the options tutorial]] for details on using options.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Platform_Development/Tutorials/Application_Structure&diff=1301Guides/Platform Development/Tutorials/Application Structure2012-05-28T18:00:57Z<p>Ewencp: Cleanup formatting</p>
<hr />
<div>= Structure of a Sirikata Application: Contexts, Services and Plugins =<br />
<br />
In order to add new components to the system, and in some cases when creating a plugin implementing an existing interface, you'll need to understand how a Sirikata application (like <tt>space</tt> or <tt>cppoh</tt>) is structured. This document walks you through the process of setting up a new application. Although this will be unusual -- you would only follow this process directly to add a new binary for a completely new service -- it is useful to provide context for how components you write will fit into an application.<br />
<br />
Sirikata provides a basic framework for constructing applications which provides common infrastructure, for example managing the event loop, managing the lifetime of the application, some simple timing functions, and managing the services running in the application.<br />
<br />
== Definitions ==<br />
<br />
To begin, we start with some definitions. These should give a sense of what each one does, but the rest of the tutorial will fill in the details.<br />
<br />
== A Barebones Application ==<br />
<br />
A barebones application is simple to setup: simply create a Context to run the application and start it. When the application finishes running, it will return and we just need to clean up.<br />
<br />
First, start by including the necessary headers:<br />
<br />
<pre>#include &lt;sirikata/core/service/Context.hpp&gt;<br />
#include &lt;sirikata/core/network/IOServiceFactory.hpp&gt;<br />
#include &lt;sirikata/core/network/IOService.hpp&gt;<br />
#include &lt;sirikata/core/trace/Trace.hpp&gt;</pre><br />
Then create the <tt>main</tt> method and create the <tt>Context</tt> , filling in a few parameters<br />
<br />
<pre>int main(int argc, char** argv) {<br />
<br />
Network::IOService* ios = Network::IOServiceFactory::makeIOService();<br />
Network::IOStrand* mainStrand = ios-&gt;createStrand();<br />
<br />
Trace::Trace* trace = new Trace::Trace(trace_file);<br />
Time epoch = Timer::now();<br />
<br />
Context* ctx = new Context(&quot;OurApplication&quot;, ios, strand, trace, epoch);</pre><br />
The first two lines setup the basic event handling system and these objects are stored in <tt>Context</tt> to make them available throughout the system. The <tt>Trace</tt> and <tt>epoch</tt> values are for collecting statistics and controlling timed applications.<br />
<br />
At this point, the context has almost enough information to run. The <tt>Context</tt> is itself a <tt>Service</tt> that will be added to itself to get notified of the run starting and ending. Then we'll start the application by calling <tt>run</tt>.<br />
<br />
<pre>ctx-&gt;add(ctx);<br />
ctx-&gt;run(1);</pre><br />
The parameter to the run method is how many threads to run with. Sirikata supports running with many threads to exploit as many cores as are available on the system. Events will be dispatched and handled on multiple threads. To ensure serialization of certain event handlers, see <tt>IOStrand</tt> or use locks directly.<br />
<br />
Finally, when everything has stopped running and we just need to clean up and close the main method.<br />
<br />
<pre>ctx-&gt;cleanup();<br />
trace-&gt;prepareShutdown();<br />
<br />
delete ctx;<br />
<br />
trace-&gt;shutdown();<br />
delete trace;<br />
<br />
delete mainStrand;<br />
Network::IOServiceFactory::destroyIOService(ios);<br />
<br />
return 0;<br />
<br />
}</pre><br />
<br />
And that's it. This should be sufficient to get a running application -- but it won't do anything except wait for shutdown to be requested (which you can do via a signal, hit Ctrl-C).<br />
<br />
== Loading Plugins ==<br />
<br />
In order to use implementations of interfaces that are not included in the libraries, you must load a plugin. For example, there is not an implementation of the <tt>ObjectSegmentation</tt> interface provided directly in the <tt>libspace</tt> library. One implementation, <tt>LocalObjectSegmentation</tt> is implemented in the <tt>space-local</tt> plugin and is used to run a single space server system where only a local table is required for the ObjectSegmentation.<br />
<br />
In our hypothetical application, let's assume we need an <tt>ObjectSegmentation</tt> instance and we know ahead of time that we want the <tt>LocalObjectSegmentation</tt> . First, we'll need to add the header that brings in the interface and its factory, <tt>OSegFactory</tt> . Because we'll need to load the appropriate plugin, we'll also need to use the <tt>PluginManager</tt> class.<br />
<br />
<pre>#include &lt;sirikata/space/ObjectSegmentation.hpp&gt;<br />
#include &lt;sirikata/core/util/PluginManager.hpp&gt;</pre><br />
Then, after the creation of our <tt>Context</tt> , we need to first load the plugin to make the implementation available to the <tt>OSegFactory</tt> , and then instantiate a copy through the factory.<br />
<br />
<pre>PluginManager plugins;<br />
assert( ! OSegFactory::getSingleton().hasConstructor(&quot;local&quot;) );<br />
plugins.load(&quot;space-local&quot;);<br />
<br />
assert( OSegFactory::getSingleton().hasConstructor(&quot;local&quot;) );<br />
ObjectSegmentation* oseg = OSegFactory::getSingleton().getConstructor(&quot;local&quot;)(ctx, ctx-&gt;mainStrand);</pre><br />
On the last line, the parameters are not important; the key point is that we retrieved the constructor for the <tt>&quot;local&quot;</tt> implementation of <tt>ObjectSegmentation</tt> . That's it -- we dynamically loaded the plugin, making this local implementation available, and instantiated it. The <tt>assert</tt> statements show what the call to <tt>PluginManager::load()</tt> changed: the <tt>&quot;local&quot;</tt> constructor became available.<br />
<br />
Of course we'll need to clean this up along with the other objects.<br />
<br />
<pre>delete oseg;</pre><br />
== Adding a Service ==<br />
<br />
Of course, the <tt>ObjectSegmentation</tt> we created isn't connected to anything and won't be notified of the start and end of the application. Knowing how to connect the component depends on the particular component, but adding the component to the application's context is easy<br />
<br />
<pre>ctx-&gt;add(oseg);</pre><br />
<tt>ObjectSegmentation</tt> implements the <tt>Service</tt> interface, so it will now be notified with <tt>start()</tt> and <tt>stop()</tt> method invokations.<br />
<br />
== Conclusion ==<br />
<br />
Now that you know the basics of a Sirikata application, you should take a look at the <tt>Context</tt>, <tt>Service</tt>, and <tt>Plugin</tt> classes in the API documentation to see what else they can do. And of course the <tt>main.cpp</tt> files for each Sirikata binary is a good place to start: they are long but readable, will teach you some of the common patterns, and show how these tools are integrated with others such as the options system.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Platform_Development/Tutorials&diff=1300Guides/Platform Development/Tutorials2012-05-28T17:58:02Z<p>Ewencp: /* Platform Development Tutorials */ Make link names more attractive</p>
<hr />
<div>= Platform Development Tutorials =<br />
<br />
The sheer size of complexity of the Sirikata code can be a real barrier to contributing. The other parts of the guide try to help a new developer isolate themselves to a smaller portion of the code, allowing them to quickly understand the components they need to modify or extend. Here, we try to address a number of common tasks that span the entire project, either because they deal with utility code used throughout the project or because they deal with the architecture of the entire system.<br />
<br />
* [[Guides/Platform_Development/Tutorials/Application Structure|Application Structure]]<br />
* [[Guides/Platform_Development/Tutorials/Writing a Plugin|Writing a Plugin]]<br />
* [[Guides/Platform_Development/Tutorials/Adding Options|Adding Options]]</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Platform_Development&diff=1299Guides/Platform Development2012-05-28T17:57:01Z<p>Ewencp: /* Getting Started */ Fix link to the tutorials</p>
<hr />
<div>= Introduction for Platform Developers =<br />
<br />
This guide helps you get started working on the code that runs Sirikata -- fixing bugs or adding new functionality to the system, rather than scripting objects in a running system. It provides:<br />
<br />
* A high-level map of the components of the system and the code base to help you find our way around the code and figure out what you want to be modifying.<br />
* A breakdown a detailed description of each service so you can find where in a service you need to work.<br />
* A small set of general tutorials. These are specific to the Sirikata code base, but not specific to any component. Look here to understand the code infrastructure and idioms, such as plugin architecture, the options system, and the event system.<br />
<br />
It's oriented towards the primary C++ code base; for other projects (e.g., KataJS), you'll need to look at their documentation.<br />
<br />
== Getting Started ==<br />
<br />
As mentioned above, you probably want to start with one of the three main sections:<br />
<br />
* [[Guides/Platform_Development/Tour of the Code|Tour of the Code]] - A technical tour of the system and the code repositories.<br />
* [[Guides/Platform_Development/Components|Components]] - A breakdown of the services and components of the system, with details of their operation.<br />
* [[Guides/Platform_Development/Tutorials|Tutorials]] - A series of tutorials describing certain aspects of the system which aren't specific to any component but which any developer will encounter when working with the system.<br />
<br />
== Resources ==<br />
<br />
Besides documentation and tutorials included in this guide, there's a lot of infrastructure around Sirikata and its development, e.g. the code repository, bug tracking, IRC, mailing lists, debugging tools and libraries, and more.<br />
{{:Getting_Started_for_Platform_Developers}}</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Platform_Development/Components/Space&diff=1298Guides/Platform Development/Components/Space2012-05-26T02:25:56Z<p>Ewencp: Minor clarifcation of terms and cleanup</p>
<hr />
<div>= Space =<br />
<br />
The space provides the actual world: it enforces the physical laws that objects obey. Objects connect to it and it provides the coordinate system, simulates global effects like physics, and enables interaction between objects.<br />
<br />
From the perspective of objects connected to the space (or their object hosts) a space provides these logical service:<br />
<br />
* Presence (also known as space membership, session management, authentication)<br />
* Coordinate System<br />
* Physical Simulation<br />
* Object Discovery<br />
* Interobject Communication<br />
<br />
This image shows the software components of the space at a high level.<br />
<br />
[[Image:space_server_architecture.png]]<br />
<br />
We'll cover each logical service and map it to the software components in the image. This mapping should guide you to the right classes and interfaces to look at when addressing a particular aspect of the system.<br />
<br />
In the image, the <tt>Server</tt> is shown as encompassing all other components but has a dashed border. This shows that the <tt>Server</tt> has references to all these objects but doesn't create or own them all -- it ties them together and helps coordinate them. The <tt>Server</tt> can be thought of as the core service of the space server.<br />
<br />
== Presence ==<br />
<br />
When an object wants to enter the world, the space acts as the guardian. The policy for entrance is pluggable, but most of the machinery is the same regardless of the authentication method -- customization is provided simply by implementing different identify verification methods. In the code, authentication and presence management is driven by the <tt>Server</tt> class, supported by the <tt>ObjectHostConnectionManager</tt> and <tt>ObjectConnection</tt> classes. The <tt>Authenticator</tt> interface abstracts authentication methods.<br />
<br />
In many existing systems, especially games, authentication is only required for clients: a distinction is made between objects in the world and avatars. In Sirikata, all objects require authentication. This may sound costly, but the cost can easily be mitigated by using intelligent <tt>Authenticator</tt> implementations.<br />
<br />
Part of acquiring a presence in a world is providing the space with all the basic information necessary to represent the object in the world. In this respect, the code for presence management interacts with all other components since it provides initial values for them. This explains why it is managed in the central <tt>Server</tt> class, which ties together all the components of the space server.<br />
<br />
== Coordinate System ==<br />
<br />
The unique aspect of virtual worlds is that objects inherit a shared, 3D space. The space provides the coordinate system, controls the extents of the world, and determines whether object's request positions can be set. &quot;Location&quot; in Sirikata refers to a collection of geometric properties in addition to position: velocity, orientation, rotational velocity, bounds, and mesh URL.<br />
<br />
=== Coordinate Segmentation ===<br />
<br />
The <tt>CoordinateSegmentation</tt> is an internal service for spaces which divides the world into regions and maps each region to a space server for simulation. It can map from a position to the space server managing it as well as from a space server to the region managed by it. This is used by many other parts of the system since it lets them discover other servers they might need to communicate with.<br />
<br />
=== LocationService ===<br />
<br />
The <tt>LocationService</tt> is the externally visible service which maintains object locations. A <tt>LocationService</tt> implementation is essentially a large table storing information for each object. As necessary, this information is replicated to the <tt>LocationService</tt> on other space servers.<br />
<br />
<tt>LocationService</tt> also provides a subscription service: objects can be subscribed for updates about other objects positions (currently performed only by <tt>Proximity</tt>). Instead of always sending all updates to all listeners, <tt>LocationUpdatePolicy</tt> determines when updates should be sent to objects. For instance, the update policy might reduce the rate of updates when the messaging system is overloaded or send updates more frequently to nearby objects since changes will be more significant to them.<br />
<br />
== Physical Simulation ==<br />
<br />
Physical simulation is just a set of constraints on the values stored in <tt>LocationService</tt>: requests to change position must be checked for validity and a continuous simulation must be run to update those values according to the laws of physics for the world. This is shown in the figure as the Physics component intercepting requests from objects before they reach the location service.<br />
<br />
== Object Discovery ==<br />
<br />
Once objects are inhabiting the world, they need to be able to interact. Aside from the physical simulation, this occurs through interobject messaging. But to message an object, you must first know how to address it. The process of learning object identifiers is called &quot;object discovery.&quot;<br />
<br />
Sirikata restricts object discovery to simple geometric queries. This enables efficient implementation and objects can filter results further when they receive the results. In Sirikata the query has a single parameter: a solid angle. All with solid angle larger than this value from the perspective of the querying object will be returned.<br />
<br />
Because this interface is fixed and the default implementation is efficient, unlike most other components, object discovery isn't abstracted into an interface and an implementation via plugin. Instead, the class <tt>Proximity</tt> implements query handlers, including hanlding interaction with other servers to return objects connected to other servers.<br />
<br />
<tt>Proximity</tt> interacts heavily with <tt>LocationService</tt>, which provides all the state required to evaluate queries. It also uses <tt>CoordinateSegmentation</tt> to determine which other servers to communicate with. This process is handled by the <tt>PintoServerQuerier</tt> class.<br />
<br />
== Interobject Communication ==<br />
<br />
Once an object has identifiers for other objects, it needs to interact with them. It does so by sending Object Datagram Protocol (ODP) messages. These are formatted and have semantics a lot like UDP or IP packets: they have source and destination addresses and ports and a payload. The system knows nothing more about the format of the packets (unless they are destined for a space service such as <tt>LocationService</tt> or <tt>Proximity</tt>). Packets are best-effort: they may be dropped if the space servers are overwhelmed with traffic.<br />
<br />
The two components responsible for getting messages to their destination are the <tt>ObjectSegmentation</tt> and the <tt>Forwarder</tt>.<br />
<br />
=== ObjectSegmentation ===<br />
<br />
In order to deliver a packet, the space server needs to know ''where'' to deliver it. The first step is to lookup which space server the destination object resides on. The <tt>ObjectSegmentation</tt> class performs this lookup, and externally looks like an asynchronous key-value store. In order to avoid unnecessary lookups (<tt>ObjectSegmentation</tt> storage may be on another node, requiring a network hop), <tt>OSegCache</tt> caches previously retrieved entries. To avoid a backlog, <tt>OSegLookupQueue</tt> manages the total number of outstanding queries, and also allows coalescing of requests for the same destination object's data.<br />
<br />
=== Forwarder ===<br />
<br />
With the destination server in hand, forwarding begins. This is handled by the <tt>Forwarder</tt> class. A supporting class <tt>LocalForwarder</tt> handles checking for and forwarding to local objects. Otherwise, at its simplest, the <tt>Forwarer</tt> just ships the packet to the appropriate server, using the <tt>ServerIDMap</tt> to convert from a server's unique identifier to an IP address.<br />
<br />
In practice, the <tt>Forwarder</tt> is much more complicated: it has to ensure competing flows between objects don't deny service to other flows, also manages communication between space servers and balances it with interobject communication, and make sure messages destined for space server components make it to their appropriate destination. Additional supporting classes include <tt>ODPFlowScheduler</tt> and <tt>ForwarderServiceQueue</tt>.<br />
<br />
=== Transport Protocols ===<br />
<br />
For users, it can be very inconvenient to work with best-effort datagrams. Much of the time, they'd prefer a reliable protocol, possibly stream oriented. The core system provides one such protocol based on Structured Streams (SST). The templated <tt>Stream</tt> class (and templated <tt>Connection</tt> class for support) implement this abstraction. This protocol is used between the space server and object host for services that need reliability or ordering. For instance, because <tt>Proximity</tt> results contain deltas, ordering is important. These updates are sent over SST.<br />
<br />
== Extensions ==<br />
<br />
These are the core set of services provided, but one could extend the space to provide additional services. One example where this might make sense is audio mixing: the space server can more efficiently mix audio for each client as well as collaborate with nearby space servers to generate a more complete mix than a client might be able to.<br />
<br />
If you'd like to add extensions like this, you should structure them as a generic interface which fits into the architecture. A dummy implementation (plugin) should allow spaces to run without the service and your implementation would provide the actual service. Note that usually adding an extension requires modifying both the space and the object host.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Platform_Development/Components/Object_Host&diff=1297Guides/Platform Development/Components/Object Host2012-05-26T02:19:31Z<p>Ewencp: Remove bogus reference to other page giving more detail.</p>
<hr />
<div>= Object Host =<br />
<br />
The object host handles simulation of objects and provides utilities or them to interact with the space, other objects, and the CDN. It is where object scripts (or behaviors) are loaded and run.<br />
<br />
The object host has 3 main duties:<br />
<br />
* Object simulation, including running object scripts, performing any local physical simulation that may be necessary<br />
* Session management for objects, including communication for basic services such as location management, proximity queries, and message routing.<br />
* Expose utilities to objects. Examples might include persistent storage, higher level communication abstractions, timers, an inventory service, animation utilities, and so on.<br />
<br />
In some sense, the choice of scripting language is just an extension of the first and third duties. Because we define a network protocol which the components use to communicate, the choice of scripting language is not fixed -- as long as the language can encode our messages (or connect to our library which can encode the core set of messages), it can work with the rest of the system. Scripts written in a convenient scripting language such as Python, Lua, or Ruby are just one way to extend objects. The object host may also provide other extensions (implemented as plugins) which provide other fixed functionality for objects via the same extension interface. Examples of these might be timers, an interface for web requests, or an inventory service.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Platform_Development/Components/Content_Distribution_Network&diff=1296Guides/Platform Development/Components/Content Distribution Network2012-05-26T02:19:16Z<p>Ewencp: Remove bogus reference to other page giving more detail.</p>
<hr />
<div>= Content Distribution Network =<br />
<br />
The content distribution network is used to store and distribute large, static, long-lived content. Some examples include meshes, textures, and object scripts. Although we can take advantage of its use in a virtual world to optimize it, the content distribution network looks very similar to existing solutions for other applications. We take advantage of this by leveraging existing solutions.<br />
<br />
The CDN supports two levels: names and content. The inputs to the CDN are always URIs. All URIs can respond with data directly. However, the preferred organization is to use a hash URI for direct data storage. This allows efficient storage, replication, and flexibility in the source of the data (e.g. direct from the provider, via a torrent, etc). Then, when referring to the content, for example when specifying a mesh, a human readable URI is used. This attaches some semantic meaning the URL and allows changes to be made in hierarchical resources without requiring large adjustments (for instance, changing a texture only requires pointing the name URI at a different hash URI; since the mesh refers to the named resource its hash doesn't change and so the content for the mesh remains the same but now points to the new texture).<br />
<br />
The CDN should support additional features that are especially useful in this context -- attaching certain types of standard metadata, range requests, and hashes on partial data to allow for safe use of partial data for lower levels of detail.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Sirikata&diff=1295Sirikata2012-05-26T02:13:49Z<p>Ewencp: /* Try it out */ Links to newer versions of pages: installation page and scripting guide</p>
<hr />
<div>== What is [http://sirikata.com Sirikata]? ==<br />
[http://sirikata.com Sirikata] is a BSD-licensed platform for virtual worlds. Instead of a single world, Sirikata lets anyone create a custom virtual world. All the common, core components of virtual worlds are built-in -- servers that simulate the world and distribute content, a graphical client, and scripting language support — allowing you to focus on creating the objects and behaviors unique to your world.<br />
<br />
== Try it out ==<br />
<br />
You can try Sirikata out by [http://sirikata.com/blog/download/ downloading the current version] and then [[List_of_Worlds|visiting a Sirikata world]]. See the [[Installation|installation]] instructions for full details and then follow the [[Guides/Scripting_Guide|scripting guide]] to learn how to script objects and build applications once you're in-world.<br />
<br />
==Contact==<br />
<br />
We love feedback. You can get in touch [[Communication|in a bunch of ways]] -- via email, IRC, or filing a bug. Any feedback, good or bad, is appreciated!<br />
<br />
== Developers ==<br />
<br />
If you want to extend Sirikata's functionality (add a new scripting language, a different physics simulation, or better rendering), head to the [[Guides/Platform Development|platform development guide]].<br />
<br />
<br />
<br />
<br />
Looking for something in particular? Use the search in the top right or look through the list of [[Special:AllPages|all pages]].</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Getting_Started_for_Users&diff=1294Getting Started for Users2012-05-26T02:11:03Z<p>Ewencp: Redirect to installation as that's all this page was</p>
<hr />
<div>#REDIRECT [[Installation]]</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Installation&diff=1293Installation2012-05-26T02:10:23Z<p>Ewencp: Copy over from original Getting Started For Users</p>
<hr />
<div>== Downloading and Installing Sirikata ==<br />
<br />
Start by downloading the binary packages from the [http://sirikata.com/blog/download/ download page]. Then follow the instructions for your platform.<br />
<br />
=== Windows ===<br />
To run Sirikata, including the graphical client, you'll need to install two additional packages:<br />
*[http://www.microsoft.com/downloads/details.aspx?familyid=2DA43D38-DB71-4C1B-BC6A-9B6652CD92A3 DirectX End-User Runtime Web Installer]<br />
*[http://www.microsoft.com/downloads/details.aspx?FamilyID=a5c84275-3b97-4ab7-a40d-3802b2af5fc2 Microsoft Visual C++ 2008 SP1 Redistributable Package (x86)]<br />
<br />
With these installed, simply download the [http://sirikata.com/blog/download/ latest package]. Unzip it anywhere on your computer. You should then have directories that look like this:<br />
<br />
* sirikata_win32/<br />
* bin/<br />
* include/<br />
* lib/<br />
* share/<br />
<br />
Go into sirikata_win32/bin/ and run space.exe, then cppoh.exe. space.exe starts a space locally. It is private and will only use the objects you start. cppoh.exe is the client. By default, it loads up a few objects as well as your avatar. If everything worked, you should see a window pop up and start displaying the world.<br />
<br />
=== Mac OS X ===<br />
<br />
Download the [http://sirikata.com/blog/download/ latest package]. Unzip it anywhere on your computer. You should then have directories that look like this:<br />
<br />
* sirikata_mac/<br />
* Frameworks/<br />
* bin/<br />
* include/<br />
* lib/<br />
* share/<br />
<br />
Go into sirikata_mac/bin/ and run space, then cppoh.app. To run these, you likely need to set DYLD_LIBRARY_PATH, e.g.:<br />
<br />
cd sirikata_mac/bin<br />
./space<br />
<br />
space starts a space (world) locally. It is private and will only use the objects you start. cppoh.app is the client. By default, it loads up a few objects as well as your avatar. If everything worked, you should see a window pop up and start displaying the world.<br />
<br />
To run cppoh.app from the command line and add parameters, run it as<br />
<br />
./cppoh.app/Contents/MacOS/cppoh [--option=value]<br />
<br />
=== Linux ===<br />
<br />
==== Ubuntu ====<br />
<br />
Follow the link on the [http://sirikata.com/blog/download/ download page] and follow the instructions to install the packages from the PPA. The binaries (e.g. space, cppoh) will be installed in your PATH.<br />
<br />
==== Other Distributions ====<br />
<br />
Linux users on other distributions should [[GetTheCode|check out]] and [[BuildTheCode|build]] the code themselves. This process is scripted, so it should be simple even though it takes awhile.<br />
<br />
==== Configuration ====<br />
<br />
See the [[Keybindings]] page for information about how to control your object.<br />
<br />
When you first start the client, a window will pop up with the Ogre logo asking for some settings. Usually you only need to change two settings: from the top drop down, select 'OpenGL Renderer' and in the resulting option list chnage 'Fullscreen' to off. OpenGL is the more reliable default, but you may also try the Direct3D renderer (see 'Troubleshooting' below for more details).<br />
<br />
=== Troubleshooting ===<br />
<br />
* I'm getting the message 'This application has failed to start because d3dx9_42.dll was not found. Re-installing the application may fix this problem.'<br />
** You need to install the DirectX End-User Runtime. Make sure you've followed the instructions above.<br />
* Nothing is showing up.<br />
** Give it a minute or two on the first run. The default scene isn't small and the meshes need to be downloaded. On future runs, the content will be loaded from your local disk if possible, making it start up much more quickly. If, after a few minutes, still nothing shows up, get in touch with the developers as described below.<br />
* I'm getting a message that I don't have permissions to access a file when I try to run the space server.<br />
** Chances are you unzipped the sirikata package using Cygwin, which doesn't handle file permissions properly. Try unzipping using Windows' standard utilities.<br />
* The settings I chose for Ogre don't work and it doesn't pop up the configuration screen anymore.<br />
** You need to clear out your ogre.cfg file. On Windows you can find this under, e.g., C:\Users\Username\AppData\Local\Sirikata. Under Linux and Mac it should be under ~/.sirikata. Delete the file ogre. and the next time you run the configuration will pop up again.<br />
* I'm having another problem not covered here.<br />
** Get in touch with the developers on the [http://groups.google.com/group/platformtalk developer mailing list] or via IRC (#sirikata on irc.freenode.net).<br />
<br />
<br />
== Scripting Objects ==<br />
<br />
Once you've connected, you might want to try scripting some objects. Check out the [[Guides/Scripting Guide|Scripting Guide]] for more details.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Sirikata&diff=1292Sirikata2012-05-26T02:04:20Z<p>Ewencp: Point to the platform development guide, which includes the old platform developers landing page.</p>
<hr />
<div>== What is [http://sirikata.com Sirikata]? ==<br />
[http://sirikata.com Sirikata] is a BSD-licensed platform for virtual worlds. Instead of a single world, Sirikata lets anyone create a custom virtual world. All the common, core components of virtual worlds are built-in -- servers that simulate the world and distribute content, a graphical client, and scripting language support — allowing you to focus on creating the objects and behaviors unique to your world.<br />
<br />
== Try it out ==<br />
<br />
You can try Sirikata out by [http://sirikata.com/blog/download/ downloading the current version] and then [[List_of_Worlds|visiting a Sirikata world]]. The [[Getting_Started_for_Users|user starting page]] has complete instructions, and once you're connected, you'll also find information about getting started with scripting objects and building applications in-world.<br />
<br />
==Contact==<br />
<br />
We love feedback. You can get in touch [[Communication|in a bunch of ways]] -- via email, IRC, or filing a bug. Any feedback, good or bad, is appreciated!<br />
<br />
== Developers ==<br />
<br />
If you want to extend Sirikata's functionality (add a new scripting language, a different physics simulation, or better rendering), head to the [[Guides/Platform Development|platform development guide]].<br />
<br />
<br />
<br />
<br />
Looking for something in particular? Use the search in the top right or look through the list of [[Special:AllPages|all pages]].</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Sirikata&diff=1291Sirikata2012-05-26T02:00:08Z<p>Ewencp: Simple rearrangement</p>
<hr />
<div>== What is [http://sirikata.com Sirikata]? ==<br />
[http://sirikata.com Sirikata] is a BSD-licensed platform for virtual worlds. Instead of a single world, Sirikata lets anyone create a custom virtual world. All the common, core components of virtual worlds are built-in -- servers that simulate the world and distribute content, a graphical client, and scripting language support — allowing you to focus on creating the objects and behaviors unique to your world.<br />
<br />
== Try it out ==<br />
<br />
You can try Sirikata out by [http://sirikata.com/blog/download/ downloading the current version] and then [[List_of_Worlds|visiting a Sirikata world]]. The [[Getting_Started_for_Users|user starting page]] has complete instructions, and once you're connected, you'll also find information about getting started with scripting objects and building applications in-world.<br />
<br />
==Contact==<br />
<br />
We love feedback. You can get in touch [[Communication|in a bunch of ways]] -- via email, IRC, or filing a bug. Any feedback, good or bad, is appreciated!<br />
<br />
== Developers ==<br />
<br />
If you want to extend Sirikata's functionality (add a new scripting language, a different physics simulation, or better rendering), head to the [[Getting_Started_for_Platform_Developers|platform developer's starting page.]]<br />
<br />
<br />
<br />
<br />
Looking for something in particular? Use the search in the top right or look through the list of [[Special:AllPages|all pages]].</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Platform_Development/Components&diff=1290Guides/Platform Development/Components2012-05-26T01:46:04Z<p>Ewencp: Drastically simplify. We already have an explanation of the functionality and composition of the components elsewhere. We only need to introduce the level of detail we're giving here</p>
<hr />
<div>= Sirikata Components =<br />
<br />
The [[Guides/Architecture|architecture]] describes the components and their basic jobs. But to start working with the system you'll need more details about their components and how they work:<br />
<br />
* [[Guides/Platform Development/Components/Space|Space and the Space Server]]<br />
* [[Guides/Platform Development/Components/Object Host|Object Hosts]]<br />
* [[Guides/Platform Development/Components/Content Distribution Network|Content Distribution Network (CDN)]]</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Platform_Development&diff=1289Guides/Platform Development2012-05-26T01:40:34Z<p>Ewencp: clarify locations</p>
<hr />
<div>= Introduction for Platform Developers =<br />
<br />
This guide helps you get started working on the code that runs Sirikata -- fixing bugs or adding new functionality to the system, rather than scripting objects in a running system. It provides:<br />
<br />
* A high-level map of the components of the system and the code base to help you find our way around the code and figure out what you want to be modifying.<br />
* A breakdown a detailed description of each service so you can find where in a service you need to work.<br />
* A small set of general tutorials. These are specific to the Sirikata code base, but not specific to any component. Look here to understand the code infrastructure and idioms, such as plugin architecture, the options system, and the event system.<br />
<br />
It's oriented towards the primary C++ code base; for other projects (e.g., KataJS), you'll need to look at their documentation.<br />
<br />
== Getting Started ==<br />
<br />
As mentioned above, you probably want to start with one of the three main sections:<br />
<br />
* [[Guides/Platform_Development/Tour of the Code|Tour of the Code]] - A technical tour of the system and the code repositories.<br />
* [[Guides/Platform_Development/Components|Components]] - A breakdown of the services and components of the system, with details of their operation.<br />
* [[Guides/Platform_Development/Tour of the Code|Tutorials]] - A series of tutorials describing certain aspects of the system which aren't specific to any component but which any developer will encounter when working with the system.<br />
<br />
== Resources ==<br />
<br />
Besides documentation and tutorials included in this guide, there's a lot of infrastructure around Sirikata and its development, e.g. the code repository, bug tracking, IRC, mailing lists, debugging tools and libraries, and more.<br />
{{:Getting_Started_for_Platform_Developers}}</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Platform_Development/Tour_of_the_Code&diff=1288Guides/Platform Development/Tour of the Code2012-05-26T01:36:10Z<p>Ewencp: Clean up, tighten, wiki formatting, and fix missing refs</p>
<hr />
<div>= A Tour of the Sirikata Code =<br />
<br />
In order to extend or modify the Sirikata code, you'll need a basic understanding of the components involved and where to find them in the code base. Make sure you've already familiarized yourself with the [[Guides/Architecture|system architecture]] before moving on.<br />
<br />
== Implementation Approach ==<br />
<br />
The Sirikata implementation is broken down into libraries, binaries, and plugins.<br />
<br />
;Libraries<br />
:hold the bulk of the common functionality and all the exported interfaces in the system. They are organized logically based on high level tasks. By keeping most of the code in libraries it is reusable: they contain all the components or interfaces but don't full connect them.<br />
<br />
;Binaries<br />
:put the pieces together, making sure all the necessary components for a service are available, instantiate them, connect them, and manage the service. They are minimal because they only tie existing components together. Adding new binaries should be unusual -- new functionality is usually added to libraries or plugins.<br />
<br />
;Plugins<br />
:contain the specialized functionality of the system. They usually contain an implementation of an interface from one of the libraries and add it to a factory so a binary can instantiate it. This is probably the most common location for code modifications -- the basic functionality is already defined in libraries and plugins provide different implementations with different features (e.g. different scripting engines).<br />
<br />
== Code Layout Conventions ==<br />
<br />
Navigating the code base is made simpler by following a few conventions.<br />
<br />
# Each library or binary is organized into its own directory. Library directories are prefixed with <tt>lib</tt>, e.g. <tt>libmesh</tt>, and binaries aren't, e.g. <tt>space</tt>.<br />
# Source within each code directory should be broken into a standard set of directories: <tt>include</tt> for public header files, <tt>src</tt> for internal headers and source files, and <tt>plugins</tt> for all code associated with plugins for interfaces in that library.<br />
# Plugins are always associated with a library, not a binary. Plugins implement generic interfaces and these generic interfaces should always be in libraries (binaries should not export any additional symbols).<br />
<br />
Of course there are some additional directories that don't follow these conventions, but they are easily identified. Examples include the <tt>scripts</tt> and <tt>build</tt> directories.<br />
<br />
As an example, here are is the directory layout for a few items in the repository:<br />
<br />
<pre>libcore/<br />
include/<br />
sirikata/core/*.hpp<br />
src/<br />
plugins/<br />
local/<br />
test/<br />
space/<br />
src/</pre><br />
The library has longer include directories to make the directory structure work for both in-tree builds and when the libraries have been installed into system directories. Since only libraries should have headers installed, only libraries require this structure.<br />
<br />
In this example, libcore has a plugin <tt>local</tt> in addition to its <tt>include</tt> and <tt>src</tt> directories. It also has some unit tests associated with it, stored in a separate <tt>test</tt> directory. The space binary only has a source directory.<br />
<br />
== A Tour of the Libraries and Binaries ==<br />
<br />
At a high level, the system is broken down into two binaries which clearly map to the space and object host components:<br />
<br />
* <tt>space</tt> is the space server binary. It can be run in isolation or on many servers to simulate a larger world.<br />
* <tt>cppoh</tt> is the object host binary. It ties together the components for simulating objects -- storage, scripting, display, etc.<br />
<br />
As mentioned earlier, these binaries should be minimal. They should instantiate implementations (in plugins) of interfaces (in libraries). Therefore, they depend on a number of libraries:<br />
<br />
* <tt>libcore</tt> provides '''a lot''' of core utilities across a range of functionality. As you're adding code, this library will be a powerful resource for common functionality -- options, network utilities, CDN access, geometric data types, threads and locking, platform abstractions for dealing with OS interaction like signals, factory and listener patterns, etc.<br />
* <tt>libmesh</tt> provides basic data structures for dealing with meshes and generic interfaces for mesh processing. Plugins for libmesh implement loading and saving for different file formats and &quot;filters&quot; for meshes, e.g. for simplification, computing statistics, or any type of content conditioning.<br />
* <tt>libproxyobject</tt> provides functionality organized around &quot;proxies&quot; or replicated objects. Proxies are objects which you have learned about and may have knowledge of their location, appearance, and messaging identifier, but they are not local. For most developers this library is most relevant when dealing with display since display is focused around these basic properties and a display plugin lives under this library.<br />
* <tt>libspace</tt> contains all the interfaces and generic services for space servers. This include the generic parts of session management, message forwarding, location management, and querying, as well as interfaces for OSeg (routing table), CSeg (region to space server mapping), and PIntO (object queries).<br />
* <tt>liboh</tt> contains all the interfaces and generic services for object hosts. This includes the code for managing connections to space servers and interacting with them, managing collections of objects, and the interface for object scripts.<br />
<br />
This figure shows how the binaries depend on these libraries (and the libraries depend on each other).<br />
<br />
[[Image:code_libraries_and_binaries.png]]<br />
<br />
Since plugins are stored within the directories of the library they are associated with, most code specific to a space is under <tt>libspace</tt> and most code specific to object hosts is under <tt>liboh</tt>. However, code useful to both appears in the other libraries, upon which <tt>libspace</tt> and <tt>liboh</tt> depend. The separation of these core libraries is simply to logically partition the code to make it more manageable. Note that there are direct dependencies that are only implicit transitively in the image. For instance, both <tt>liboh</tt> and <tt>libspace</tt> depend directly on <tt>libcore</tt>, but this is only implied by their dependence on <tt>libmesh</tt> and <tt>libproxyobject</tt>.<br />
<br />
You may also notice that the content distribution network is missing from this description. Currently, the CDN uses stock web servers, so its implementation is separated and not referenced in the remainder of this guide. It can be found in the <tt>cdn</tt> directory. Access to the CDN is provided in the <tt>transfer</tt> directories in <tt>libcore</tt> since it is used throughout the system.<br />
<br />
=== Additional Libraries and Binaries ===<br />
<br />
You'll notice that there are some additional directories for libraries and binaries:<br />
<br />
* <tt>libsqlite</tt> provides access to SQLite databases. It is a library since SQLite is used by plugins associated with multiple libraries.<br />
* <tt>analysis</tt> performs analysis of trace data from measurement experiments of the system. This reports data which helps evaluate the performance and correctness of the system.<br />
* <tt>bench</tt> performs a few low-level benchmarks.<br />
* <tt>cseg</tt> is a service which the CoordinateSegmentation in the space server communicates with. It organizes and coordinates space servers.<br />
* <tt>pinto</tt> is a service which the Proximity service in the space server communicates with. It aids in the query handling process for large deployments with many servers.<br />
* <tt>simoh</tt> is a stripped down simulated object host used for automatic evaluation of the system. It lacks true scripting support, opting for simplicity and minimalism to accurately benchmark the system.<br />
<br />
These won't be discussed further in this guide as they are more would require more detail than this guide aims to give.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Getting_Started_for_Platform_Developers&diff=1287Getting Started for Platform Developers2012-05-26T01:26:20Z<p>Ewencp: Move the documentation page up front as the comprehensive map for platform development resources</p>
<hr />
<div><noinclude><br />
Platform developers work on the code which runs the core of Sirikata worlds. Both the core system and plugins implementing. Examples of code developed by platform developers are the core message forwarding code, physics simulation plugins, the renderer for clients, and scripting plugins.<br />
</noinclude><br />
=== Map for Platform Development ===<br />
* [[Documentation|Documentation]] is very much a work in progress but is a comprehensive overview of what we currently have. Covers just about all the technical aspects of the system, tools and infrastructure around it, and how to work with it. If you're looking for a particular topic, start here.<br />
<br />
=== Getting into the Code ===<br />
* You'll need to [[GetTheCode|Check out]] and [[BuildTheCode|build]] the code before you can contribute any changes.<br />
** The [[Source Code]] page helps you understand more about how we manage source code.<br />
** Learn about the available [[Git Branches|branches in the git repository]], how to work with them, and how to develop new features.<br />
** We're not too picky, but we suggest following the [[Coding Standards]] so we have a consistent, readable codebase.<br />
* The [[Guides/Platform_Development|Platform Development Guide]] explains how to work with the code.<br />
<br />
=== Getting in Touch with Other Developers ===<br />
<br />
* Need to talk to other platform developers to bounce implementation ideas off them or ask questions about the code? [[Platform Developer Communication]] describes how to get in touch with other platform developers, both synchronously and asynchronously.<br />
<br />
=== How and Where to Contribute ===<br />
<br />
* The [[Roadmap|roadmap]] gives a 10,000 foot view of developers current plans<br />
* Looking for something to work on? Learn [[Contributing|how you can contribute]] and check out some [[CodingProjects|coding project]] ideas.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Sirikata&diff=1286Sirikata2012-05-26T01:21:51Z<p>Ewencp: Linkify the first instances of sirikata back to the homepage</p>
<hr />
<div>== What is [http://sirikata.com Sirikata]? ==<br />
[http://sirikata.com Sirikata] is a BSD-licensed platform for virtual worlds. Instead of a single world, Sirikata lets anyone create a custom virtual world. All the common, core components of virtual worlds are built-in -- servers that simulate the world and distribute content, a graphical client, and scripting language support — allowing you to focus on creating the objects and behaviors unique to your world.<br />
<br />
You can try Sirikata out by [http://sirikata.com/blog/download/ downloading the current version] and then [[List_of_Worlds|visiting a Sirikata world]]. The [[Getting_Started_for_Users|user starting page]] has complete instructions, and once you're connected, you'll also find information about getting started with scripting objects and building applications in-world.<br />
<br />
If you want to extend Sirikata's functionality (add a new scripting language, a different physics simulation, or better rendering), head to the [[Getting_Started_for_Platform_Developers|platform developer's starting page.]]<br />
<br />
==Contact==<br />
<br />
We love feedback. You can get in touch [[Communication|in a bunch of ways]] -- via email, IRC, or filing a bug. Any feedback, good or bad, is appreciated!<br />
<br />
<br />
Looking for something in particular? Use the search in the top right or look through the list of [[Special:AllPages|all pages]].</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Platform_Development&diff=1285Guides/Platform Development2012-05-26T01:19:29Z<p>Ewencp: Include the getting started page for platform developers to give more pointers into</p>
<hr />
<div>= Introduction for Platform Developers =<br />
<br />
This guide helps you get started working on the code that runs Sirikata -- fixing bugs or adding new functionality to the system, rather than scripting objects in a running system. It provides:<br />
<br />
* A high-level map of the components of the system and the code base to help you find our way around the code and figure out what you want to be modifying.<br />
* A breakdown a detailed description of each service so you can find where in a service you need to work.<br />
* A small set of general tutorials. These are specific to the Sirikata code base, but not specific to any component. Look here to understand the code infrastructure and idioms, such as plugin architecture, the options system, and the event system.<br />
<br />
It's oriented towards the primary C++ code base; for other projects (e.g., KataJS), you'll need to look at their documentation.<br />
<br />
== Getting Started ==<br />
<br />
As mentioned above, you probably want to start with one of the three main sections:<br />
<br />
* [[Guides/Platform_Development/Tour of the Code|Tour of the Code]] - A technical tour of the system and the code repositories.<br />
* [[Guides/Platform_Development/Components|Components]] - A breakdown of the services and components of the system, with details of their operation.<br />
* [[Guides/Platform_Development/Tour of the Code|Tutorials]] - A series of tutorials describing certain aspects of the system which aren't specific to any component but which any developer will encounter when working with the system.<br />
<br />
== Resources ==<br />
<br />
Besides documentation and tutorials, there's a lot of infrastructure around Sirikata and its development, e.g. the code repository, bug tracking, IRC, mailing lists, debugging tools and libraries, and more.<br />
{{:Getting_Started_for_Platform_Developers}}</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Getting_Started_for_Platform_Developers&diff=1284Getting Started for Platform Developers2012-05-26T01:18:16Z<p>Ewencp: Move to new guide link and remove links into it, clarify documentation page's purpose</p>
<hr />
<div><noinclude><br />
Platform developers work on the code which runs the core of Sirikata worlds. Both the core system and plugins implementing. Examples of code developed by platform developers are the core message forwarding code, physics simulation plugins, the renderer for clients, and scripting plugins.<br />
</noinclude><br />
=== Getting into the Code ===<br />
* You'll need to [[GetTheCode|Check out]] and [[BuildTheCode|build]] the code before you can contribute any changes.<br />
** The [[Source Code]] page helps you understand more about how we manage source code.<br />
** Learn about the available [[Git Branches|branches in the git repository]], how to work with them, and how to develop new features.<br />
** We're not too picky, but we suggest following the [[Coding Standards]] so we have a consistent, readable codebase.<br />
* The [[Guides/Platform_Development|Platform Development Guide]] explains how to work with the code.<br />
* [[Documentation|Documentation]] is very much a work in progress but is a comprehensive overview of what we currently have<br />
<br />
=== Getting in Touch with Other Developers ===<br />
<br />
* Need to talk to other platform developers to bounce implementation ideas off them or ask questions about the code? [[Platform Developer Communication]] describes how to get in touch with other platform developers, both synchronously and asynchronously.<br />
<br />
=== How and Where to Contribute ===<br />
<br />
* The [[Roadmap|roadmap]] gives a 10,000 foot view of developers current plans<br />
* Looking for something to work on? Learn [[Contributing|how you can contribute]] and check out some [[CodingProjects|coding project]] ideas.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Getting_Started_for_Platform_Developers&diff=1283Getting Started for Platform Developers2012-05-26T01:12:57Z<p>Ewencp: Don't include intro section when including page into other pages</p>
<hr />
<div><noinclude><br />
Platform developers work on the code which runs the core of Sirikata worlds. Both the core system and plugins implementing. Examples of code developed by platform developers are the core message forwarding code, physics simulation plugins, the renderer for clients, and scripting plugins.<br />
</noinclude><br />
=== Getting into the Code ===<br />
* You'll need to [[GetTheCode|Check out]] and [[BuildTheCode|build]] the code before you can contribute any changes.<br />
** The [[Source Code]] page helps you understand more about how we manage source code.<br />
** Learn about the available [[Git Branches|branches in the git repository]], how to work with them, and how to develop new features.<br />
** We're not too picky, but we suggest following the [[Coding Standards]] so we have a consistent, readable codebase.<br />
* The [http://www.sirikata.com/docs/guides/platformguide/ Platform Developer's Guide] is the best reference for platform development. It provides:<br />
** A high-level breakdown of the [http://www.sirikata.com/docs/guides/platformguide/components/ components of Sirikata's architecture], followed by more detail on each component.<br />
** A [http://www.sirikata.com/docs/guides/platformguide/tour/ tour of the source code] should help you get into the code and figure out where you want to start working.<br />
** [http://www.sirikata.com/docs/guides/platformguide/tutorials/ Tutorials] covering a few common tasks in the Sirikata code and describing how to use some utilities already available within the code base.<br />
<br />
* [[Documentation|Documentation]] is very much a work in progress but this is an overview what we currently have<br />
<br />
=== Getting in Touch with Other Developers ===<br />
<br />
* Need to talk to other platform developers to bounce implementation ideas off them or ask questions about the code? [[Platform Developer Communication]] describes how to get in touch with other platform developers, both synchronously and asynchronously.<br />
<br />
=== How and Where to Contribute ===<br />
<br />
* The [[Roadmap|roadmap]] gives a 10,000 foot view of developers current plans<br />
* Looking for something to work on? Learn [[Contributing|how you can contribute]] and check out some [[CodingProjects|coding project]] ideas.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Documentation&diff=1282Documentation2012-05-26T01:09:52Z<p>Ewencp: Extra space</p>
<hr />
<div>== Guides ==<br />
The primary source for documentation should be the [[Guides]] written on this wiki (covering users, scripting, the system architecture, and platform development). Please add to these if you find something missing.<br />
<br />
== Learning the System ==<br />
* [[System Architecture|Architecture]] gives a high level overview of Sirikata's architecture. Only the highest level components are described, making this the best place to start.<br />
* [[Protocol|Protocol]] describes our current wire protocol. This is subject to change.<br />
* [[TypeSystems|Type Systems]] describes the types we want our serialization format to natively support to minimize the amount of tedious work platform developers and end-user scripters need to do to exchange data.<br />
<br />
== Source Code ==<br />
* [[Source Code|Source Code]] describes the infrastructure related to our source code. This describes both how to get and build the code, as well as how developers can work with our infrastructure to add new source code.<br />
* [[Subsystems|Subsystems]] describes how the [[System Architecture|Architecture]] is broken down to smaller components and how they map to our source code repository.<br />
* [[Coding Standards]] is a description of how to keep our source code consistent and readable.<br />
* [http://www.sirikata.com/docs/head/api/ Doxygen Documentation] generated nightly from the Git repository gives low level documentation about the components that make up Sirikata.<br />
* [[Dependencies|Dependencies]] are libraries Sirikata builds on. The libraries and their uses are described, followed by suggestions on how to get the necessary dependencies running on a new platform when porting Sirikata.<br />
* [[CDN Transfer Layer]] describes the new interface for accessing files from the CDN<br />
* [[Debugging Minidumps on Windows]] talks about how to take crash reports and debug them in Visual Studio.<br />
* [[Sirikata URIs]] talks about how to build a Sirikata URI (and associated data) to allow users to click a link to open a client.<br />
<br />
== Developer Tools ==<br />
* [[Buildbot]] describes how to test builds across all platforms using Sirikata's buildbot<br />
* [[Debugging Memory Issues]] talks about how to look for leaks and do heap profiling.<br />
* [[Debugging Performance Issues]] talks about using external tools (e.g. OProfile, gprof) and Sirikata's internal tools to track down performance problems<br />
* [[Crash Reports]] describes how to use the crash reporting system to automatically collect crash stacktraces<br />
* [[Debugging Minidumps on Windows]] describes how to use files delivered with crash reports to debug Windows crashes using Visual Studio<br />
* [[Creating a Release]] describes the steps for tagging and building a release for all platforms<br />
== Getting Involved ==<br />
* [[CodingProjects|Coding Projects]] describes some ideas for projects a new developer might be interested in working on and that core developers believe would be feasible within the current system. These are just ideas and new developers should not, of course, limit themselves to these options.<br />
<br />
== Plugins ==<br />
* [[Berkelium|Berkelium]] is our standalone library to embed a [http://www.chromium.org/ Chromium] browser in a 3d space<br />
* [[Physics|Physics]] gives notes on our physics plugin implementation, which is based on [http://www.bulletphysics.com Bullet Physics].<br />
<br />
== Working with Sirikata ==<br />
* [[Video Capture]] describes current best practices for collecting video captures from Sirikata.<br />
<br />
== Other ==<br />
* [[Dev preview|Developer Preview]] is our system prototype from December 2008. This system is now completely out of date and likely only useful for reference and historical purposes.<br />
* [[CDN Cassandra Schema]]<br />
* [[CDN Progressive Format]]<br />
* [[CDN API Documentation]]<br />
* [[Debian Packaging]]</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Documentation&diff=1281Documentation2012-05-26T01:09:31Z<p>Ewencp: Link to wiki Guides instead of guide repository.</p>
<hr />
<div>== Guides ==<br />
The primary source for documentation should be the [[Guides]] written on this wiki (covering users, scripting, the system architecture, and platform development). Please add to these if you find something missing.<br />
<br />
<br />
== Learning the System ==<br />
* [[System Architecture|Architecture]] gives a high level overview of Sirikata's architecture. Only the highest level components are described, making this the best place to start.<br />
* [[Protocol|Protocol]] describes our current wire protocol. This is subject to change.<br />
* [[TypeSystems|Type Systems]] describes the types we want our serialization format to natively support to minimize the amount of tedious work platform developers and end-user scripters need to do to exchange data.<br />
<br />
== Source Code ==<br />
* [[Source Code|Source Code]] describes the infrastructure related to our source code. This describes both how to get and build the code, as well as how developers can work with our infrastructure to add new source code.<br />
* [[Subsystems|Subsystems]] describes how the [[System Architecture|Architecture]] is broken down to smaller components and how they map to our source code repository.<br />
* [[Coding Standards]] is a description of how to keep our source code consistent and readable.<br />
* [http://www.sirikata.com/docs/head/api/ Doxygen Documentation] generated nightly from the Git repository gives low level documentation about the components that make up Sirikata.<br />
* [[Dependencies|Dependencies]] are libraries Sirikata builds on. The libraries and their uses are described, followed by suggestions on how to get the necessary dependencies running on a new platform when porting Sirikata.<br />
* [[CDN Transfer Layer]] describes the new interface for accessing files from the CDN<br />
* [[Debugging Minidumps on Windows]] talks about how to take crash reports and debug them in Visual Studio.<br />
* [[Sirikata URIs]] talks about how to build a Sirikata URI (and associated data) to allow users to click a link to open a client.<br />
<br />
== Developer Tools ==<br />
* [[Buildbot]] describes how to test builds across all platforms using Sirikata's buildbot<br />
* [[Debugging Memory Issues]] talks about how to look for leaks and do heap profiling.<br />
* [[Debugging Performance Issues]] talks about using external tools (e.g. OProfile, gprof) and Sirikata's internal tools to track down performance problems<br />
* [[Crash Reports]] describes how to use the crash reporting system to automatically collect crash stacktraces<br />
* [[Debugging Minidumps on Windows]] describes how to use files delivered with crash reports to debug Windows crashes using Visual Studio<br />
* [[Creating a Release]] describes the steps for tagging and building a release for all platforms<br />
== Getting Involved ==<br />
* [[CodingProjects|Coding Projects]] describes some ideas for projects a new developer might be interested in working on and that core developers believe would be feasible within the current system. These are just ideas and new developers should not, of course, limit themselves to these options.<br />
<br />
== Plugins ==<br />
* [[Berkelium|Berkelium]] is our standalone library to embed a [http://www.chromium.org/ Chromium] browser in a 3d space<br />
* [[Physics|Physics]] gives notes on our physics plugin implementation, which is based on [http://www.bulletphysics.com Bullet Physics].<br />
<br />
== Working with Sirikata ==<br />
* [[Video Capture]] describes current best practices for collecting video captures from Sirikata.<br />
<br />
== Other ==<br />
* [[Dev preview|Developer Preview]] is our system prototype from December 2008. This system is now completely out of date and likely only useful for reference and historical purposes.<br />
* [[CDN Cassandra Schema]]<br />
* [[CDN Progressive Format]]<br />
* [[CDN API Documentation]]<br />
* [[Debian Packaging]]</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Architecture&diff=1280Guides/Architecture2012-05-25T23:44:34Z<p>Ewencp: Clean up, update, and fix up references</p>
<hr />
<div>= Sirikata Architecture =<br />
<br />
== Introduction ==<br />
<br />
This document describes the basic components of a Sirikata world at the highest (and hopefully non-technical) level. Whether you're developing an application in a Sirikata world or creating and deploying your own world, you'll need to understand these basic components. World developers need to understand these components because they will configure and run them to pull together a virtual world. Application developers need to understand them because they interact with each component.<br />
<br />
At the highest level, Sirikata is composed of three parts, the space, the object hosts, and the content distribution network:<br />
<br />
;Object Host<br />
:Simulates object behavior in the world by running scripts. User clients are object hosts that also know how to run a display.<br />
<br />
;Space<br />
:A collection of one or more servers that simulate the world. Mediates interaction between objects, such as physics and communication.<br />
<br />
;Content Distribution Network<br />
:Stores semi-permanent to permanent data and delivers it to the other components. For instance, meshes that are used to display objects are stored on a CDN and client object hosts can download them to view the world.<br />
<br />
All of these components are required for a functioning world. Without object hosts, there wouldn't be any scripted behavior and no objects would connect to the world. Without the space, object hosts wouldn't know how to interact and other centralized global services like physics wouldn't be available. Without the content distribution network, there wouldn't be a place to store and retrieve data lets us display the world.<br />
<br />
These components can be put together in different ways to create different types of worlds:<br />
<br />
[[File:Deployment_open.png|200px]]<br />
[[File:Deployment_game.png|200px]]<br />
<br />
These images show two ways to deploy Sirikata. In the first, one company runs the infrastructure for the world (space), but leaves other services up to users and third parties. In the second, to ensure game rules are enforced and a good user experience, the game company runs all servers except for object hosts acting as clients.<br />
<br />
The rest of this document gives a little more detail on these components, but tries to remain non-technical. For more technical detail, look at the [[Guides/Platform Development|Platform Development Guide]].<br />
<br />
== Space ==<br />
<br />
The space is what you might think of as the laws of the world: it isn't the objects but the set of rules they must follow and how they interact with each other. In Sirikata this boils down to only a small set of services: the space manages objects locations, physics simulation, lets objects learn about other nearby objects, and enables those objects to communicate with each other. All the rest of the functionality of the world can be built on this very small base.<br />
<br />
Spaces may also provide additional services. For example, a world could function perfectly well with sounds handled entirely by exchanges between objects. However, it might be more cost effective to have the space manage sound to efficiently generate sound for each object that wants to listen.<br />
<br />
Spaces can be simulated using a single server, but are commonly simulated across a number of ''space servers'', enabling them to handle larger regions, more objects, and more clients.<br />
<br />
== Object Host ==<br />
<br />
An object host simulates objects, allowing them to specify their behavior in scripts and providing them access to spaces and CDNs. At their core, object hosts are simple: they embed a scripting language for objects and expose ways for the objects to connect to spaces and CDNs and usually provide some easier methods for interacting with other objects.<br />
<br />
The earlier examples of deployment suggest how object hosts might be used. In an open world, anybody running an object host can connect to the space. The owner adds their scripted objects, which connect to that space and start interacting with other objects. They might add code while they are in the world to extend the behavior of objects, perhaps teaching it how to interact with a new type of object or provide a new service to other avatars.<br />
<br />
In the second example, a company is developing a game. Because they want complete control over how objects behave in the world, they run all the object hosts containing objects in the world (from mountains, to swords, to goblins), except for those with the players.<br />
<br />
In both cases, clients are just a special type of object host that knows how to display the world and respond to user input. The object that manages this is the avatar. This means that clients and objects in the world aren't differentiated, both can be and are scripted using the same tools.<br />
<br />
A graphical display isn't the only extension an object host can have. Object host can support a variety of plugins: display of the 3D world, input from the user, sound input and output, different scripting languages, access to permanent storage (e.g. disk), and interoperation with other systems (e.g. HTTP access) are just a few examples.<br />
<br />
== Content Distribution Network ==<br />
<br />
The content distribution network stores and serves long-lived content the world requires to run. The most obvious example is mesh data, which often can't be distributed up-front (for instance, because users add objects with their own meshes to the world).<br />
<br />
A &quot;content distribution network&quot; can be as simple as a web server, and in fact that is a common solution. The CDN really only needs to be able to serve requests for files. However, the CDN might be much more complicated, handling a very large number of users, intelligently serving data from servers near the source of requests, doing advanced processing of content (like simplification, conversion to progressive formats for streaming), and caching files to reduce the cost of running the CDN.<br />
<br />
= The Sirikata Ecosystem =<br />
<br />
Sirikata isn't a monolithic piece of software. At its most basic, Sirikata is an architecture and set of protocols that allow the components of that architecture to interact. Implementations of these components allow a world developer to collect and tie together all the pieces necessary to run a world.<br />
<br />
The above described the high level components of Sirikata and below we list the available implementations. To run a world, you'd select at least one implementation for each component and tie them together. Within implementations there may be a lot of configuration flexibility as well. For example, the C++ implementation has a wide variety of plugins and feature toggles.<br />
<br />
== Protocol ==<br />
<br />
There is one source for the protocols that allow Sirikata components to interact. The repository is at [http://github.com/sirikata/sirikata-protocol http://github.com/sirikata/sirikata-protocol] and is referenced by all implementations listed here. Note that some components which support distributed deployment (e.g. the C++ space server) have additional, internal protocols. These internal protocols are always maintained within the repository for the specific project. Other implementations are not required or expected to support these internal protocols. Only protocols in the protocol repository should be used or relied on.<br />
<br />
== Space Server ==<br />
<br />
* C++ Space Server -- [http://github.com/sirikata/sirikata http://github.com/sirikata/sirikata] -- Currently the only implementation. Easy setup for running a single server, but also supports large, distributed deployment.<br />
<br />
== Object Host ==<br />
<br />
* C++ Object Host -- [http://github.com/sirikata/sirikata http://github.com/sirikata/sirikata] -- Plugin based scripting.<br />
** JavaScript - embeds Google's V8 and exposes core C++ object host API to JavaScript.<br />
** Emerson - A custom, domain specific language for virtual world scripting. Built as an extension on the Javascript plugin.<br />
** .NET Languages (Mono) - embeds the Mono .NET runtime and exposes core C++ object host API to .NET. Depends only on the runtime and is therefore language agnostic.<br />
<br />
* KataJS -- [http://github.com/sirikata/katajs http://github.com/sirikata/katajs] -- Runs in modern web browsers.<br />
** WebSockets for communicating with space servers.<br />
** WebGL for 3D graphics.<br />
** WebWorkers support for parallelism, script isolation.<br />
** HTML5 for UI and interaction.<br />
<br />
== Content Distribution ==<br />
<br />
So far, content distribution has been focused around HTTP based solutions.<br />
<br />
* Web Server (e.g. Apache)<br />
** Trivial implementation that just serves up static files.<br />
** Good for centrally controlled content, e.g. not incorporating user generated content.<br />
** Currently only CDN for KataJS since access from the browser requires using stock HTTP requests.<br />
<br />
* Progressive HTTP CDN -- [http://github.com/sirikata/sirikata http://github.com/sirikata/sirikata]<br />
** Allows content to be intelligently chunked and progressively loaded.<br />
** Scripts on top of web server, based on HTTP using additional headers.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides&diff=1279Guides2012-05-25T23:24:54Z<p>Ewencp: Rewrite to simplify for new layout, make more concise, and link to correct pages.</p>
<hr />
<div>= Welcome =<br />
<br />
== What is Sirikata? ==<br />
<br />
Sirikata is a BSD-licensed platform for virtual world applications. Virtual worlds are shared, online, 3D, interactive spaces. They have a lot of applications -- from games and entertainment, to education, to social applications. Sirikata makes creating virtual worlds easy.<br />
<br />
If you're not sure if Sirikata is, start by learning more on the [http://sirikata.com home page] or just try it out by following the instructions below to login.<br />
<br />
== How to get started ==<br />
<br />
Sirikata provides all the tools for creating a virtual world, but it isn't a single world that you can log into. Instead, you use Sirikata to run your own world or to log into someone else's world to interact with others and write scripts.<br />
<br />
If you want to join a world, start out with the [[Guides/Scripting Guide|Scripting Guide]]. It'll help you get connected to a world and write some simple scripts to make objects in the world do some simple things. Almost everyone should start here.<br />
<br />
If you're an advanced scripter, check out the [[Guides/Architecture|Architecture Guide]] to better understand Sirikata's architecture, it's features, and it's limitations.<br />
<br />
And if you're interested helping build Sirikata itself, look at the [[Guides/Platform Development|Platform Development Guide]] to help you take your first steps into the Sirikata source code.<br />
<br />
== List of Guides ==<br />
{{:Guides/TOC}}</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides&diff=1278Guides2012-05-25T23:15:17Z<p>Ewencp: Add list of guides/table of contents</p>
<hr />
<div>= Welcome =<br />
<br />
== What is Sirikata? ==<br />
<br />
Sirikata is a BSD-licensed platform for virtual world applications. Virtual worlds are shared, online, 3D, interactive spaces. They have a lot of applications -- from games and entertainment, to education, to social applications. Sirikata makes creating virtual worlds easy.<br />
<br />
== How do I use Sirikata? ==<br />
<br />
Sirikata provides all the tools for creating a virtual world, but it isn't a single world that you can log into. Instead, you use Sirikata to create your own world or an ''application'' in a Sirikata-based world.<br />
<br />
There are two types of users of Sirikata:<br />
<br />
<br />
Application Developers<br />
A user that participates in a Sirikata-based world created by a world developer and adds content to it, for instance adding objects, their associated appearance, and adding behavior to them to bring the world to life.<br />
<br />
World Developers<br />
A user that takes components of Sirikata, configures them, and ties them together to create their own, unique world. <br />
<br />
While application developers might be end-users, generally this guide is not for end-users. The world developer is responsible for providing documentation for them since Sirikata is highly customizable -- clients for different worlds may look different, respond differently to interaction, and permit different actions in the world.<br />
<br />
Both types of users should start out by understanding the :ref:`general-architecture`: you need to understand the components of the system at a high level and how they work together to create the world before you can understand how to setup a world or build within a world.<br />
<br />
Application developers should proceed to the :ref:`app-guide`, and will likely want to begin with the :ref:`emerson-tutorials`. World developers should then read about the :ref:`ecosystem` to understand their options when constructing a world and then proceed to the :ref:`world-guide`.<br />
<br />
For a complete list of available documentation, see the :doc:`contents`. Or :ref:`search` for a particular topic.<br />
<br />
== How do I help develop the Sirikata platform? ==<br />
<br />
Found a bug and want to try fixing it? Need functionality that isn't built into Sirikata? If you want to dig into the Sirikata platform code (rather than building on it), check out the :ref:`platform-guide`.<br />
<br />
== List of Guides ==<br />
{{:Guides/TOC}}</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/TOC&diff=1277Guides/TOC2012-05-25T23:14:26Z<p>Ewencp: Add basic TOC</p>
<hr />
<div>* [[Guides/Scripting Guide|Scripting Guide]]<br />
* [[Guides/Architecture|Sirikata's Architecture]]<br />
* [[Guides/Platform Development|Platform Development]]</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Scripting_Guide/Tutorials/TOC&diff=1276Guides/Scripting Guide/Tutorials/TOC2012-05-25T23:13:11Z<p>Ewencp: Clean up names</p>
<hr />
<div>* [[Guides/Scripting_Guide/Tutorials/Connecting|Tutorial: Connecting]]<br />
* [[Guides/Scripting_Guide/Tutorials/Hello World|Tutorial: Hello World]]<br />
* [[Guides/Scripting_Guide/Tutorials/Reset|Tutorial: Reset]]<br />
* [[Guides/Scripting_Guide/Tutorials/Move Presence|Tutorial: Move Presence]]<br />
* [[Guides/Scripting_Guide/Tutorials/Create Presence|Tutorial: Create Presence]]<br />
* [[Guides/Scripting_Guide/Tutorials/Create Entity|Tutorial: Create Entity]]<br />
* [[Guides/Scripting_Guide/Tutorials/Send Message|Tutorial: Send Message]]<br />
* [[Guides/Scripting_Guide/Tutorials/GUI|Tutorial: GUI]]</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Scripting_Guide/TOC&diff=1275Guides/Scripting Guide/TOC2012-05-25T23:09:17Z<p>Ewencp: Add TOC for scripting guide</p>
<hr />
<div>* [[Guides/Scripting Guide/Terminology|Terminology]] <br />
* [[Guides/Scripting Guide/Tutorials|Tutorials]]<br />
{{:Guides/Scripting Guide/Tutorials/TOC}}</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Scripting_Guide/Tutorials/Send_Message&diff=1274Guides/Scripting Guide/Tutorials/Send Message2012-05-25T22:52:13Z<p>Ewencp: Initial import from sirikata-docs</p>
<hr />
<div>= Communicating with Other Entities =<br />
<br />
The primary way that a presence associated with one entity interacts with a presence associated with another entity is for the presences to send messages between each other. This tutorial will show you how to send and receive messages between presences.<br />
<br />
In the real world, if you were going to email your friend, you would first need your friend's email address. Similarly, before Presence A can send a message to Presence B in the virtual world, Presence A must be have Presence A's &quot;address&quot;. This tutorial will first describe how to get a presence's address, then it will explain how to send messages, and, finally, it will describe how to receive messages. It will use the example of one presence's sending another presence a request to move, and the other presence's responding to that message by moving.<br />
<br />
== Register proximity queries/discover presences ==<br />
<br />
=== Theory ===<br />
<br />
By default an entity only knows about its own presences. For an entity to discover other presences in the virtual world, it registers a query through one of its presences with the Meru system. Here's an example of such a query:<br />
<br />
system.self.onProxAdded( userAddedCallback );<br />
system.self.setQueryAngle(.4);<br />
<br />
These queries take a little thinking about. Roughly translated, the first line of the above code reads: &quot;When a presence gets near to be important to me, execute the function <tt>userAddedCallback</tt>, which the scripter has defined somewhere earlier in the program.&quot; (We will show an example of <tt>userAddedCallback</tt> that sends messages in the next section.)<br />
<br />
The second line of the above code actually defines what it means to be &quot;important&quot;. Meru uses the amount of Presence A's field of view taken up by Presence B as a measure of B's importance to A. Maybe a more concrete way to think about the above is through pixels. If Presence B takes a large number of pixels on a computer monitor showing Presence A's view of the world, it is more important than if it takes only a small number of pixels to render B. In this way, presences that are nearer to A or larger are more important to A than those that are more distant and smaller. The below figures highlight relative importance. The lower figures are more &quot;important&quot; than the upper figures.<br />
<br />
[[Image:scripting_tutorial_messaging_leastimportant.png|512px]]<br />
<br />
The bug in the above picture is less &quot;important&quot; than the bug in the picture below.<br />
<br />
[[Image:scripting_tutorial_messaging_mediumimportant.png|512px]]<br />
<br />
The bug in the above picture is less &quot;important&quot; than the bug in the picture below.<br />
<br />
[[Image:scripting_tutorial_messaging_mostimportant.png|512px]]<br />
<br />
The bug in the above figure would be more &quot;important&quot; than the bugs in either of the previous two figures.<br />
<br />
However, because of discretization and other errors caused by pixels, we don't use pixels directly. Instead we use steradians. The second line of the above code therefore reads, &quot;A presence is important to me if it takes up at least .4 steradians of my field of view&quot;. (steradians are a measure of solid angle. You can read more about them here [http://en.wikipedia.org/wiki/Steradian. http://en.wikipedia.org/wiki/Steradian.] All we really want you to know is that a large steradian means that a presence would take up many pixels on your monitor; a small steradian would take up very few pixels on your monitor.)<br />
<br />
Before moving on to the next section, it should be noted that in addition to the <tt>onProxAdded</tt> function shown above, Emerson has a complementary <tt>onProxRemoved</tt> function for presences. It looks something like this in practice:<br />
<br />
system.self.onProxRemoved(userRemovedCallback);<br />
<br />
Essentially, when an external presence no longer satisfies a solid angle query, the system notifies you that that presence has left the result set by calling userRemoveCallback.<br />
<br />
=== Try it yourself ===<br />
<br />
Enter the virtual world as an avatar. You should have just one presence associated that is connected to the space. From here, script yourself. Enter the following code into your own scripting terminal (hit <tt>ctrl</tt> + <tt>s</tt> to bring up a scripting window for yourself):<br />
<br />
function userAddedCallback(nowImportantPresence) {<br />
system.print(&quot;nnPresence with address &quot; + nowImportantPresence.toString() + &quot; is now important!nn&quot;);<br />
}<br />
<br />
function userRemovedCallback(nowUnimportantPresence) {<br />
system.print(&quot;nnPresence with address &quot; + nowUnimportantPresence.toString() + &quot; is now unimportant!nn&quot;);<br />
}<br />
<br />
system.self.onProxAdded( userAddedCallback );<br />
system.self.setQueryAngle(.4);<br />
<br />
Now, move closer and farther from other presences in the virtual world. You should see the print message associated with <tt>userAddedCallback</tt> when you get very close to an presence, and you should see <tt>userRemovedCallback</tt> when you move away from that presence after being more distant.<br />
<br />
You can monkey around by changing <tt>userAddedCallback</tt> and <tt>userRemovedCallback</tt> to do more elaborate things, for instance, rotating your avatar in a circle on each message.<br />
<br />
== Send message ==<br />
The previous section should have explained to you how to discover presences in the virtual world. However, even if you know the address and existence of a presence how can you interact with it?<br />
<br />
The way that presences on distinct entities interact in Emerson is through ''messages''. This section explains how a scripter would create and send a message to another presence. To do so, let's start by re-using a little code from the previous section:<br />
<br />
function userAddedCallback(nowImportantPresence) {<br />
system.print(&quot;nnPresence with address &quot; + nowImportantPresence.toString() + &quot; is now important!nn&quot;);<br />
...<br />
We will be changing the contents of this function.<br />
...<br />
}<br />
<br />
function userRemovedCallback(nowUnimportantPresence) {<br />
system.print(&quot;nnPresence with address &quot; + nowUnimportantPresence.toString() + &quot; is now unimportant!nn&quot;);<br />
}<br />
<br />
system.self.onProxAdded( userAddedCallback );<br />
system.self.setQueryAngle(.4);<br />
<br />
As mentioned in the previous section, the Emerson runtime system will automatically execute <tt>userAddedCallback</tt> when a new presence consumes more than .4 steradians of <tt>presence[0]</tt>'s field of view. What we didn't mention before was what the runtime binds to <tt>nowImportantPresence</tt> (the argument of <tt>userAddedCallback</tt>) how it can be used. <tt>nowImportantPresence</tt> corresponds to an Emerson ''visible'' object.<br />
<br />
To simplify sending messages, Emerson provides &quot;angle-angle&quot; syntax below.<br />
<br />
function userAddedCallback(nowImportantPresence) {<br />
system.print(&quot;nnPresence with address &quot; + nowImportantPresence.toString() + &quot; is now important!nn&quot;);<br />
<br />
//create a new message<br />
var moveMsg = new Object();<br />
moveMsg.action = &quot;forward&quot;;<br />
<br />
moveMsg &gt;&gt; nowImportantPresence &gt;&gt; [];<br />
<br />
}<br />
<br />
The line <tt>moveMsg &gt;&gt; nowImportantPresence &gt;&gt; []</tt>, handles message-sending, where <tt>moveMsg</tt> is an Emerson object (that does not have data written into the reserved fields <tt>seqNo</tt>, <tt>streamID</tt>, and <tt>makeReply</tt>), <tt>nowImportantPresence</tt> is the intended recipient of the message, and <tt>[]</tt> will be described in section :ref:`msgResponse`. That's all there is to it. You can now send messages. The next section will describe how to react to messages that you receive.<br />
<br />
== Receive Message ==<br />
<br />
In general, a scripter may want to perform different actions depending on the type of message that his/her presence receives and who that message is from.<br />
<br />
Emerson provides custom &quot;angle-angle&quot; syntax to make this process easier.<br />
<br />
For instance, examine the following code snippet:<br />
<br />
function actionMsgCallback(msg,sender) {<br />
system.print(&quot;I got a message with action: &quot; + msg.action);<br />
}<br />
<br />
actionMsgCallback &lt;&lt; [{'action'::}];<br />
<br />
In English, the last line of the above code states, &quot;If any presence connected to this entity receives a message that has a field entitled action in it, then call the function actionMsgCallback.&quot;<br />
<br />
One can also create more elaborate patterns for matching. For instance,<br />
<br />
actionMsgCallback &lt;&lt; [{'action'::}] &lt;&lt; someSender;<br />
<br />
the above line of code transalates to &quot;Call actionMsgCallback if any of my presences receive a message from someSender that has an action field.&quot;<br />
<br />
actionMsgCallback &lt;&lt; [{'action':'forward':}] &lt;&lt; someSender;<br />
<br />
And the above line of code transalates to &quot;Call actionMsgCallback if any of my presences receive a message from someSender that has an action field that has the value 'forward'.&quot;<br />
<br />
actionMsgCallback &lt;&lt; [{'action':'forward':}, {'seqno':3:}] &lt;&lt; someSender;<br />
<br />
And the above line of code translates to &quot;Call actionMsgCallback if any of my presences receive a message from someSender that has an action field that has the value 'forward' ''and'' has a field named 'seqno' with value 3.&quot;<br />
<br />
To match any message, with any fields, scripters currently, must enter:<br />
<br />
actionMsgCallback &lt;&lt; [new util.Pattern()] &lt;&lt; someSender;<br />
<br />
This is because of a compiler bug, which will be fixed in the next released version of the code.<br />
<br />
== Message Responses ==<br />
<br />
In section :ref:`secSendMsg`, you may have noticed the funny <tt>[]</tt> at the end of message send statements. This section describes how you can use this final statement in the angle-angle pipeline to to support message-response pattern of communication (A sends a message to B, B responds to that message, A responds to B's response, etc.).<br />
<br />
The array at the end of the message sending statement can have zero to three fields. The first field is a function that describes what to do if a message sender receives a response to his/her message. For instance, if you simply want to print &quot;I got a response&quot;, whenever you receive a response to one of your messages, you would do the following:<br />
<br />
<pre>function printOnRespFunc(msgResp,msgRespSender)<br />
{<br />
system.print('\n\nI got a response\n');<br />
}<br />
<br />
msgToSend &gt;&gt; receiver &gt;&gt; [printOnRespFunc];</pre><br />
By default, the system executes the <tt>printOnRespFunc</tt> when a receiver replies to your message. The receiver's reply is placed in the argument <tt>msgResp</tt> and the receiver (as a visible object) is placed in the argument <tt>msgRespSender</tt>.<br />
<br />
The system automatically stops waiting for a response after 5 seconds pass. Any response that you receive after this time will not trigger <tt>printOnRespFunc</tt> to execute. If you want to listen for a response for a longer or shorter time, you can provide a second argument to the sending array. For instance, if you instead want to listen for a response to your message for a full 10 seconds after your message has been sent, you would change the last statement to:<br />
<br />
msgToSend &gt;&gt; receiver &gt;&gt; [printOnRespFunc,10];<br />
<br />
Finally, if you want to print &quot;No response&quot; if you do not receive a response within 10 seconds, the send array takes a third parameter:<br />
<br />
function printOnRespFunc(msgResp,msgRespSender) {<br />
system.print('nnI got a responsen');<br />
}<br />
<br />
function printOnNoRespFunc() { system.print('nNo responsen'); }<br />
<br />
msgToSend &gt;&gt; receiver &gt;&gt; [printOnRespFunc,10,printOnNoRespFunc];<br />
<br />
The above code describes how one would catch a response, but does not explain how one would actually generate a response. Consider a new example where instead of printing &quot;I got a response&quot;, you want to instead echo back any responses that you receive to your first message. This is simply done through the <tt>makeReply</tt> function that the system appends to each message: <br />
<br />
function echoOnRespFunc(msgResp,msgRespSender) {<br />
msgResp.makeReply(msgResp) &gt;&gt; [echoOnRespFunc, 10, printOnNoRespFunc];<br />
}<br />
<br />
function printOnNoRespFunc() { system.print('nNo responsen'); }<br />
<br />
msgToSend &gt;&gt; receiver &gt;&gt; [printOnRespFunc,10,printOnNoRespFunc];<br />
<br />
<tt>makeReply</tt> takes a single argument, an object that you want to send to whoever sent you a message in response to the message that that presence sent you. If for instance, you wanted to send an empty object in response to any message that you received, you would change the body of <tt>echoOnRespFunc</tt> to state: <tt>msgResp.makeReply({}) &gt;&gt; [echoOnRespFunc, 10, printOnNoRespFunc];</tt>.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=File:Scripting_tutorial_messaging_mediumimportant.png&diff=1273File:Scripting tutorial messaging mediumimportant.png2012-05-25T22:41:52Z<p>Ewencp: </p>
<hr />
<div></div>Ewencphttps://www.sirikata.com/wiki/index.php?title=File:Scripting_tutorial_messaging_mostimportant.png&diff=1272File:Scripting tutorial messaging mostimportant.png2012-05-25T22:41:42Z<p>Ewencp: </p>
<hr />
<div></div>Ewencphttps://www.sirikata.com/wiki/index.php?title=File:Scripting_tutorial_messaging_leastimportant.png&diff=1271File:Scripting tutorial messaging leastimportant.png2012-05-25T22:41:30Z<p>Ewencp: </p>
<hr />
<div></div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Scripting_Guide/Tutorials/GUI&diff=1270Guides/Scripting Guide/Tutorials/GUI2012-05-25T22:38:57Z<p>Ewencp: Initial import from sirikata-docs</p>
<hr />
<div>= Adding Graphical User Interfaces =<br />
<br />
Sometimes 2D user interface widgets are a better way to interact with a user than 3D interactions. For example, you might use a 2D widget to request that a user execute a script locally in a sandbox or provide a simpler interface to some interaction, like completing a purchase in a store.<br />
<br />
In Sirikata, 2D UIs are presented via small Javascript and HTML based widgets. You can find examples in the UI you get with the default client: both the scripting window and chat use these simple widgets to allow the user to take action in the world through a 2D interface.<br />
<br />
== Components ==<br />
<br />
There are 3 components involved in making a UI that can perform actions in the world.<br />
<br />
* The graphics object -- manages the UI widget and is required to allocate a widget.<br />
* The UI widget code -- Javascript and embedded HTML, just like the code in a web page.<br />
* Emerson driver code -- requests allocation of the UI widget and mediates interaction between the UI and the world, sending and receiving events in both directions.<br />
<br />
Generally you will be adding the UI to an avatar which already has the graphics object allocated. Your driver code is loaded somehow (as part of the user's default avatar script, or dynamically by sending a request to the user), asks the graphics object to allocate the UI widget, and then interacts with it, possibly sending events to the UI and receiving events back.<br />
<br />
In this tutorial, we'll construct a simple UI with a single button that sets your mesh to a predefined value when clicked. This is a simple but complete example of constructing a 2D UI.<br />
<br />
== Graphics Object ==<br />
<br />
In order to load a UI, you need a graphics object to allocate it within. The graphics object manages everything that occurs within the window that displays the world.<br />
<br />
In the current default avatar script (<tt>js/scripts/std/defaultAvatar.em</tt>) you can find it in the global variable <tt>simulator</tt> and it is an instance of the <tt>std.graphics.DefaultGraphics</tt> class. Because you need the graphics and GUI systems to be completely initialized before executing your code, we'll place our code inside the callback it provides:<br />
<br />
<pre>simulator = new std.graphics.DefaultGraphics(<br />
system.self, 'ogregraphics',<br />
function() {<br />
// Invoked when DefaultGraphics is done initializing,<br />
// we'll put our new code in here<br />
}<br />
);</pre><br />
== Emerson Driver Code and Allocating a UI Widget ==<br />
<br />
On disk, a UI widget is just a Javascript file that lives somewhere under <tt>ogre/data/</tt>). We'll get to the exact code later, but let's assume we have the code in the files <tt>setmesh.js</tt>. To load the GUI module, we call the <tt>addGUIModule</tt> method on the graphics object to load the UI:<br />
<br />
<pre>simulator.addGUIModule(<br />
&quot;SetMesh&quot;, &quot;setmesh.js&quot;,<br />
function(gui) {<br />
// gui is the new GUI object<br />
}<br />
);</pre><br />
The third parameter is a callback function. UI loading is asynchronous because it might involve downloading resources. To avoid blocking for a long time, a callback is invoked and provides you with the newly created GUI object only after it is safe to start interacting with it. A common pattern is to store the resulting GUI object in a field of the object that created it:<br />
<br />
<pre>simulator.addGUIModule(<br />
&quot;SetMesh&quot;, &quot;setmesh.js&quot;,<br />
std.core.bind(<br />
function(gui) {<br />
this._gui = gui;<br />
},<br />
this<br />
)<br />
);</pre><br />
In this approach, we use <tt>std.core.bind</tt> to make the <tt>this</tt> object the same in the callback as it is for the constructor. Any additional initialization for the GUI, such as calling an initialization function in the GUI with parameters from your Emerson script, should also occur in this callback function.<br />
<br />
Next, we know that our UI is going to generate some events we need to handle. In particular, it is going to send a request to change mesh. Events from the UI are specified by a string and a series of Javascript arguments (basic types such as strings and numbers only). To handle this event, we'll ''bind'' a handler for the event <tt>&quot;setmesh&quot;</tt>. Extending our previous code, we get:<br />
<br />
<pre>simulator.addGUIModule(<br />
&quot;SetMesh&quot;, &quot;setmesh.js&quot;,<br />
std.core.bind(<br />
function(gui) {<br />
this._gui = gui;<br />
<br />
var setmesh_pres = system.self;<br />
handleSetMesh = function(meshurl) {<br />
setmesh_pres.mesh = meshurl;<br />
};<br />
this._gui.bind(&quot;setmesh&quot;, handleSetMesh);<br />
},<br />
this<br />
)<br />
);</pre><br />
And that's it. When the UI sends a setmesh event, handleSetMesh will be invoked. It uses the reference <tt>setmesh_pres</tt>, the presence active when the GUI was loaded, to set the mesh. Because we know the arguments (and types!) that will be provided, we put a named argument for <tt>meshurl</tt>. However, if we don't know the exact form or number of arguments, we can use the <tt>arguments</tt> keyword to extract them dynamically.<br />
<br />
Finally, we have all the code we need to setup the GUI from the Emerson script. You can replace a line like<br />
<br />
<pre>simulator = new std.graphics.DefaultGraphics(system.self, 'ogregraphics');</pre><br />
in <tt>std/defaultAvatar.em</tt> with our updated code<br />
<br />
<pre>simulator = new std.graphics.DefaultGraphics(<br />
system.self, 'ogregraphics',<br />
function() {<br />
<br />
simulator.addGUIModule(<br />
&quot;SetMesh&quot;, &quot;setmesh.js&quot;,<br />
std.core.bind(<br />
function(gui) {<br />
this._gui = gui;<br />
<br />
var setmesh_pres = system.self;<br />
handleSetMesh = function(meshurl) {<br />
setmesh_pres.mesh = meshurl;<br />
};<br />
this._gui.bind(&quot;setmesh&quot;, handleSetMesh);<br />
},<br />
this<br />
)<br />
);<br />
}<br />
);</pre><br />
== UI Widget Code ==<br />
<br />
As discussed earlier, the UI code lives in a single Javascript file. The UI code is similar to Emerson code: it will be fully executed as soon as it is loaded. To continue taking actions, it sets up HTML elements that trigger events or uses timers to periodically take actions.<br />
<br />
Here's our entire script, <tt>setmesh.js</tt>:<br />
<br />
<pre>sirikata.ui(<br />
'SetMesh',<br />
function() {<br />
$('&lt;div id=&quot;set-mesh-ui&quot; title=&quot;SetMesh&quot;&gt;' + // (1)<br />
' &lt;button id=&quot;set-mesh-button&quot;&gt;Set Mesh!&lt;/button&gt;' +<br />
'&lt;/div&gt;').appendTo('body');<br />
<br />
var window = new sirikata.ui.window( // (2)<br />
&quot;#set-mesh-ui&quot;,<br />
{<br />
width: 100,<br />
height: 'auto'<br />
}<br />
);<br />
window.show();<br />
<br />
sirikata.ui.button('#set-mesh-button').click(setMesh); // (3)<br />
<br />
function setMesh() { // (4)<br />
sirikata.event(&quot;setmesh&quot;, &quot;meerkat:///test/cube.dae/original/0/cube.dae&quot;);<br />
}<br />
}<br />
);</pre><br />
Our entire UI script is wrapped in a <tt>sirikata.ui</tt> call, which also takes a name for our UI. This allows Sirikata to set up some helpers and try to isolate us from other UIs. It also automatically wraps your script that gets rid of some quirks with the way web pages load. You should always wrap your UI code in <tt>sirikata.ui</tt>.<br />
<br />
The first statement (1) injects our UI into the page by creating a <tt>div</tt> containing all our UI elements and appending it to <tt>body</tt>. This example was very simple, but complete examples may require a few lines to get all the components put together. Our UI just consists of a single button. Note that we've labeled each element with an ID.<br />
<br />
The second line (2) uses the ID we assigned to the <tt>div</tt>, <tt>set-mesh-ui</tt> to create a window out of it using <tt>sirikata.ui.window</tt>. The second parameter is a dictionary of parameters. In this case, we just set the size of the window.<br />
<br />
The third line (3) sets up the action that should be taken when the <tt>set-mesh-button</tt> is clicked. We simply tell it to execute a callback <tt>setMesh</tt>. Many other types of actions can be bound as callbacks --mouse over, mouse move, click, keypresses, etc.<br />
<br />
Of course, to invoke <tt>setMesh</tt> it must be defined. The fourth statement (4) does just that. However, the callback can't set the mesh itself -- it doesn't have a presence to act upon. Instead, it relays this information back to the Emerson script. Recall that we decided to use the string <tt>&quot;setmesh&quot;</tt> to filter events from the UI (other elements may also be sending events, e.g., &quot;chat&quot; or &quot;scripting&quot;). The special <tt>sirikata.event</tt> method allows you to send events out of the browser and back into the underlying system, getting them back to your Emerson script. The first parameter is our filter string. The remaining arguments are passed as the arguments to the callback registered for this event. In this case, we specify the URL for the mesh we want to use.<br />
<br />
And that's it, with the UI loaded and the callback setup, clicking on the button will trigger a message back to Emerson code, which will be handled by the Emerson <tt>handleSetMesh</tt> method. This, in turn, results in a request to the space to set the presence's mesh.<br />
<br />
== Manipulating Widgets from Emerson ==<br />
<br />
This simple example only required the UI to be setup and then listen for events, but didn't require any further manipulation of the UI from Emerson. To further interact or update the UI from Emerson, you use the <tt>std.graphics.GUI</tt> object returned by <tt>addGUIModule</tt>. This object has a few simple methods like <tt>show</tt>, <tt>hide</tt>, and <tt>bind</tt> (as used earlier). It also includes <tt>GUI.eval</tt>, which is the generic way of interacting with the code in the UI widget. <tt>GUI.eval</tt> takes a single string argument containing Javascript to execute in the page. In our example, if we instead used the function:<br />
<br />
<pre>var setMeshURL = &quot;meerkat:///test/cube.dae/original/0/cube.dae&quot;<br />
function setMesh() {<br />
sirikata.event(&quot;setmesh&quot;, setMeshURL);<br />
}</pre><br />
we could change the URL we'd request by executing the following:<br />
<br />
<pre>this._gui.eval(&quot;setMeshURL = 'meerkat:///test/multimtl.dae/original/0/multimtl.dae'&quot;);</pre><br />
which overwrites the value of <tt>setMeshURL</tt>. The next time the button is pressed and setMesh is invoked, the new value is passed back to the script. This approach is convoluted, but it demonstrates how additional actions can be taken by Emerson code on the GUI well after the GUI is created.<br />
<br />
GUI objects also provide a few methods to make the most common interactions with GUIs simpler: <tt>GUI.call</tt>, <tt>GUI.set</tt>, <tt>GUI.variable</tt>. <tt>GUI.call</tt> invokes a method in the context of the GUI, making sure all variables passed through are substituted for their values and properly escaped if necessary. For example:<br />
<br />
<pre>var x = 7;<br />
var st = 'hello &quot;Bob&quot;';<br />
this._gui.call('myfunc', x, st);</pre><br />
is equivalent to<br />
<br />
<pre>this._gui.eval( &quot;myfunc(7, 'hello \&quot;Bob\&quot;');&quot; );</pre><br />
and is much simpler and more readable than the normal approach:<br />
<br />
<pre>this._gui.eval( 'myfunc(' + x + ',' + escape(st) + ');' );</pre><br />
It looks more natural, is closer to a normal function call, and is less error-prone since escaping is performed automatically.<br />
<br />
<tt>GUI.set</tt> sets the value of a variable in the script's context. The above example of setting the mesh URL could be written as:<br />
<br />
<pre>this._gui.set('setMeshURL', 'meerkat:///test/multimtl.dae/original/0/multimtl.dae');</pre><br />
Of course this isn't much shorter, but the <tt>GUI.eval</tt> string is generated automatically, escaping of strings is automatic, and you can easily substitute variables:<br />
<br />
<pre>this._gui.set('setMeshURL', new_mesh_url);</pre><br />
Sometimes you want to be able to specify variable names in the GUI's context in other expressions, but any strings you pass in are converted to literals. <tt>GUI.variable</tt> solves this by producing a special object which will be interpreted as a variable name. For example, to use an existing JavaScript variable <tt>name</tt> when evaluating a function we would say<br />
<br />
<pre>this._gui.call('printname', this._gui.variable('name'));</pre><br />
Note that because <tt>GUI.set</tt> has a fixed format for parameters, you don't need to use <tt>GUI.variable</tt> on its first argument.<br />
<br />
== Debugging GUI Code ==<br />
<br />
The <tt>sirikata</tt> object provides utilities besides the ability to notify the owning script of events. In particular, <tt>sirikata.log</tt> allows you to log information to the console:<br />
<br />
<pre>sirikata.log('info', 'Value: ', myvalue);</pre><br />
This will log the message and value of <tt>myvalue</tt> to the console. The first parameter should always be a string and indicates the ''log level''. These levels let you control the amount of information that is reported ('fatal', 'error', 'warn' or 'warning', 'info', 'debug', 'detailed', 'insane'). You might put a lot of logging at the 'debug' level, which is off by default, and more important messages at 'warn', 'info', or 'fatal'.<br />
<br />
To control the level of messages reported, start the client with a different level for the `ui` module:<br />
<br />
<pre>cppoh --moduleloglevel=ui=debug</pre><br />
If you need messages provided by other components that may use the standard logging mechanisms in browsers, you can also enable these with the <tt>webview</tt> module:<br />
<br />
<pre>cppoh --moduleloglevel=ui=debug,webview=debug</pre><br />
Note that this also turns on other logging from this module besides that generated by <tt>console.log</tt> calls from scripts, so using <tt>sirikata.log</tt> is the preferred method for logging.<br />
<br />
Another approach to debugging UI code is to develop much of it in a normal browser and use the debugging tools there. You can't test any code which interacts with the rest of Sirikata (e.g. the <tt>sirikata.event()</tt> calls), but this can be helpful for the initial development of the UI and workflow.<br />
<br />
To do this, there are just 2 steps. First, you need to force the system to load your GUI as a builtin. In <tt>ogre/data/chrome/ui.html</tt>, find the section where a bunch of modules are loaded by <tt>$LAB</tt>. Add a line for your own file ''after'' all the other <tt>.js</tt> files. For example, given the placement described earlier, <tt>setmesh.js</tt> would be loaded as:<br />
<br />
<pre>.script(&quot;../setmesh.js&quot;).wait()</pre><br />
Next, you'll just load up <tt>ui.html</tt> directly in a browser. You should see at least the menu system and be able to click and select them. If your UI doesn't pop up by default, you'll need to force it to since the Emerson code cannot initialize it for you. In this mode, certain functions (like sirikata.log and sirikata.event) cannot function normally. They should just end up getting logged to the JavaScript console in the browser and ignored.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Scripting_Guide/Tutorials/Create_Entity&diff=1269Guides/Scripting Guide/Tutorials/Create Entity2012-05-25T22:37:25Z<p>Ewencp: Initial import from sirikata-docs</p>
<hr />
<div>= Creating entities =<br />
<br />
By now, you should know how to add presences to an entity. This tutorial describes how you would go about creating a '''new''' entity. We'll use an example in which we create a new entity, and then have that entity's presence move through the world.<br />
<br />
==The create entity call ==<br />
All a scripter does to create a new entity is to execute the <tt>create_entity</tt> call. The call:<br />
<br />
* creates a new entity on the same entity host that processed the <tt>create_entity</tt> call and<br />
* automatically connects a presence for that entity to the world.<br />
<br />
The second task requires some additional information, and requires that the <tt>create_entity</tt> call takes several parameters. In order, these parameters are:<br />
<br />
* The position the entity's presence should occupy in the world (Vec3).<br />
* The type of script to import. (For emerson scripts, include &quot;js&quot;.).<br />
* The filename of the script to import.<br />
* A URI to the mesh the entity's automatically-connected presence should take.<br />
* A scaling factor for that mesh.<br />
* A steradian value for the solid angle query the entity's automatically-connected presence should issue.<br />
<br />
== Example ==<br />
<br />
Now that you know the structure of a <tt>create_entity</tt> call, consider the following code:<br />
<br />
//new entity's presence has the mesh of a sphere<br />
var meshToChangeTo = &quot;meerkat:///test/sphere.dae/original/0/sphere.dae&quot;;<br />
<br />
//new entity's presence will be located two units away from creating<br />
//presence's position<br />
var newPos = system.self.getPosition(); newPos.x = newPos.x + 2;<br />
<br />
//First thing that the new entity will do after its presence connects<br />
//to space is import the following file.<br />
var scriptToImport = &quot;test/testMove.em&quot;;<br />
<br />
system.create_entity(newPos,<br />
&quot;js&quot;, //this arg will almost always be 'js'<br />
scriptToImport, meshToChangeTo,<br />
1.0, //how do you want to scale the mesh of<br />
//the entity's new presence<br />
3 //what is the solid angle query that<br />
//the entity's initial presence <br />
//queries with.<br />
);<br />
<br />
This code would be executed on an already-existing entity to create a new entity. The new entity's automatically-connected presence would have a mesh of <tt>meshToChangeTo</tt> (a sphere), be positioned a the x,y,z coordinates contained in <tt>newPos</tt> (2 meters away from the previous entity's first presence), import a script from <tt>scriptToImport</tt> (in filename 'test/testMove.em'), and set a solid angle query of 3 steradians.<br />
<br />
The actual structure in the script 'test/testMove.em' may be a little different than scripters are used to. Most of the scripts that we have discussed to this point operated on entities that already had presences connected to the world: scripters were able to assume <tt>system.self</tt> existed, and was connected to the world. In contrast, the imported script executes '''before''' its first presence is automatically connected. This means that 'test/testMove.em' must actually catch the first presence's connection before operating on it.<br />
<br />
This is easy, and is accomplished through the <tt>onPresenceConnected</tt> system call. Below is the 'test/testMove.em' script, which uses the <tt>onPresenceConnected</tt> call.<br />
<br />
//whenever a presence in the system connects to the world,<br />
//execute the argument of onPresenceConnected<br />
system.onPresenceConnected(moveFunc);<br />
<br />
function moveFunc(newPres) {<br />
//set a unit velocity for the first presence in the x direction.<br />
system.self.setVelocity(&lt;1,0,0&gt;);<br />
}</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Scripting_Guide/Tutorials/Create_Presence&diff=1268Guides/Scripting Guide/Tutorials/Create Presence2012-05-25T22:32:02Z<p>Ewencp: Initial import from sirikata-docs</p>
<hr />
<div>= Creating presences =<br />
<br />
The previous tutorials explained how to move an entity's presence. This tutorial describes how to create new presences for an entity.<br />
<br />
== The create presence call ==<br />
All a scripter does to create a new entity is to execute the <tt>createPresence</tt> call.<br />
<br />
<tt>createPresence</tt> requires two arguments: a uri for the mesh to load for the newly created presence (as a string) and a callback function to execute once the presence connects.<br />
<br />
The <tt>createPresence</tt> call is ''non-blocking''. What this means is that a presence is not created as soon as the call returns. Instead, a presence is connected to the world and appears some time (usually less than one second) after the call has been made. When the presence does get connected, the system automatically executes the callback, passing in the newly-created presence as an argument to this callback.<br />
<br />
Let's combine this information with the previous example on moving presences to create a new presence, and then have it move forever in one direction:<br />
<br />
function presCreatedCallback(presCreated) {<br />
//the new presence's velocity is set to<br />
//1 m/s in the x direction.<br />
presCreated.setVelocity(&lt;1,0,0&gt;);<br />
}<br />
<br />
//the new presence will have the mesh of a kiosk.<br />
var newPresMesh = 'meerkat:///kittyvision/kiosk/flyers.dae/optimized/0/flyers.dae';<br />
system.createPresence(newPresMesh,presCreatedCallback);<br />
<br />
== Managing presences: <tt>system.presences</tt> and <tt>system.self</tt> ==<br />
As you can imagine, an entity with very many presences can become difficult to manage. To address this, Emerson automatically manages two global variables: <tt>system.presences</tt> and <tt>system.self</tt>. Any time a new presence is created, it gets loaded into <tt>system.presences</tt>, an array that contains all the presences connected to an entity. If, for instance, a scripter wanted to set the velocity for all of his/her presences, he/she could enter the following code:<br />
<br />
for (var s in system.presences) {<br />
system.presences[s].setVelocity(&lt;1,0,0&gt;);<br />
}<br />
<br />
While, <tt>system.presences</tt> allows a scripter to track ''all'' the presences he/she has connected, <tt>system.self</tt> is intended to automatically track the most &quot;relevant&quot; presence for an event.<br />
<br />
Emerson is event-based, and the majority of events in the virtual world are associated with a single presence. <tt>system.self</tt> gets set to the presence associated with that event. This may seem a little confusing, and may make more sense through a series of examples:<br />
<br />
* If an entity's presence receives a message, <tt>system.self</tt> is automatically set to the presence that received the message.<br />
* If an entity receives a timeout event, <tt>system.self</tt> is automatically set to the presence that originally set the timeout.<br />
* If an entity receives a presence connected event, <tt>system.self</tt> is automatically set to the presence that was connected.<br />
<br />
To provide an example of <tt>system.self</tt> in action, recall our earlier task of creating a new presence and setting its velocity to be 1 m/s. We can re-write <tt>presCreatedCallback</tt> to use <tt>system.self</tt> instead of <tt>presCreated</tt>:<br />
<br />
function presCreatedCallback(presCreated) {<br />
//the new presence's velocity is set to<br />
//1 m/s in the x direction.<br />
system.self.setVelocity(&lt;1,0,0&gt;);<br />
//now using system.self<br />
}</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Scripting_Guide/Tutorials/Move_Presence&diff=1267Guides/Scripting Guide/Tutorials/Move Presence2012-05-25T22:27:24Z<p>Ewencp: Initial import from sirikata-docs</p>
<hr />
<div>= Moving in the World =<br />
<br />
It would be a pretty boring world if all presences just stayed in one place. This tutorial explains how a scripter can move presences throughout the world.<br />
<br />
There are two basic types of movement in the system: translational and rotational. In translational movement, every point of the presence's mesh moves the same distance; in rotational movement, a presence's mesh spins around a fixed axis. A useful way of understanding the difference between translational and rotational movement is to think about a wheeled office chair. A person wanting to translate his/her office chair would roll it from one point in a room to another. A person wanting to rotate his/her office chair would spin in place on the office chair.<br />
<br />
Translational and rotational movement can be combined (ie, one can use Emerson to translate and rotate a presence simultaneously). For the simplicity of this tutorial, we instead focus on each separately.<br />
<br />
Before we begin, a quick note on code in the following examples: the Emerson run-time keeps track of all of an entity's connected presences in an array available to the scripter as <tt>system.presences</tt>. For the example code used in this tutorial, we'll assume that the presence being moved is named by <tt>system.self</tt>.<br />
<br />
== Translational motion ==<br />
Emerson allows a scripter to either instantly teleport a presence to a new position or to assign a velocity to the presence. A presence with an assigned velocity automatically moves through the world in the assigned direction and rate. For both position and velocity, Emerson uses standard Cartesian coordinates, and represents each using 3-dimensional vectors. We'll talk about position and velocity separately below, but it may be useful for the reader to refer to the Vec3 type described here&lt;lkjs&gt; before beginning.<br />
<br />
=== Teleport/SetPosition ===<br />
Assume that you have a presence that you want to instantly translate from its current position to a position 100m away in the x direction.<br />
<br />
We'll break such a script into 3 pieces:<br />
<br />
<blockquote>* Getting the presence's current x, y, and z coordinates in the space.<br />
* Specifying a new 3-dimensional position based on the presence's current x, y, and z coordinates in the space.<br />
* Requesting the system to move your object to this new position.<br />
</blockquote><br />
Here's the entire script to perform the above.<br />
<br />
var pos = system.self.getPosition();<br />
pos.x = pos.x + 100;<br />
system.self.setPosition(pos);<br />
<br />
The above is explained more methodically below.<br />
<br />
==== Getting the presence's current coordinates in the space ====<br />
<br />
To get a 3-dimensional vector representing the current position of a presence in space, simply use the <tt>getPosition()</tt> function. As an example, open a scripting window and enter:<br />
<br />
var pos = system.self.getPosition(); system.print(pos);<br />
<br />
You should see the position of a presence printed in the following form: &lt;x,y,z&gt;. You can access the individual x, y, and z fields of this position with the accessors `.x`, `.y`, and `.z`, respectively. That is, if you wanted to just print the x position of a presence, you would replace the second line of the above function as shown below:<br />
<br />
var pos = system.self.getPosition(); system.print(pos.x);<br />
<br />
====Specifying a new 3-dimensional position based on <tt>pos</tt>====<br />
After the previous section, the variable <tt>pos</tt> stores the current position associated with <tt>system.self</tt>. We need to specify a new target position. Doing so is simple:<br />
<br />
pos.x = pos.x + 100;<br />
<br />
It is important to note, the above line does ''not'' move the presence by itself. It instead changes the value stored in <tt>pos</tt>. <tt>pos</tt> now describes the position that we want to move our presence to.<br />
<br />
====Requesting the system to move your object to <tt>pos</tt>====<br />
To actually set the position of <tt>system.self</tt> to <tt>pos</tt>, one simply uses the <tt>setPosition</tt> function:<br />
<br />
system.self.setPosition(pos);<br />
<br />
The <tt>setPosition</tt> function takes in a single argument, a 3-dimensional vector, and instantly moves the associated presence to that point in the space.<br />
<br />
=== SetVelocity ===<br />
<br />
The above example instantly moved a presence from one point to another. While such an operation is possible in a virtual world, it certainly does not agree with (most of) the real world: one wouldn't see a train teleport from one station to another -- instead, the train acquires a velocity and moves from point to point non-instantaneously.<br />
<br />
Emerson provides similar capabilities for presences by allowing a scripter to set a presence's velocity (both magnitude and direction). (Note: in Emerson, a scripter ''cannot'' set higher order movement properties for presences such as acceleration or jerk.)<br />
<br />
Consider the simple task of moving a stationary presence 30m in the y direction. To do so, a scripter would use the <tt>setVelocity</tt> command. Like the <tt>setPosition</tt> command described in the previous section, <tt>setVelocity</tt> takes in a single argument: a 3-dimensional vector. The x, y, and z components of this argument 3-dimensional vector specifies the velocity that the presence should move in meters per second (in the x, y, and z directions respectively). You can experiment with the <tt>setPosition</tt> function pretty easily. For instance, at a scripting prompty, enter the following code:<br />
<br />
var zeroVelocity = new util.Vec3(0,0,0);<br />
var posYVelocity = new util.Vec3(0,1,0);<br />
var negYVelocity = new util.Vec3(0,-1,0);<br />
<br />
Now, to get a presence to stop moving, just enter:<br />
<br />
system.self.setVelocity(zeroVelocity);<br />
<br />
To get a presence to start moving in the positive y direction, enter:<br />
<br />
system.self.setVelocity(posYVelocity);<br />
<br />
And, to get a presence to start moving in the negative y direction, enter:<br />
<br />
system.self.setVelocity(negYVelocity);<br />
<br />
To complete the simple task of moving a stationary presence 30m in the y direction, enter into the command prompt:<br />
<br />
system.self.setVelocity(posYVelocity);<br />
<br />
and then 30 seconds later:<br />
<br />
system.self.setVelocity(zeroVelocity);<br />
<br />
The first command should start the presence moving in the y direction at 1 m/s. The second command should stop the presence. Manually entering such commands obviously leaves something to be desired. For a more robust solution, read about <tt>timeout</tt>s in the tutorial.<br />
<br />
== Rotational motion ==<br />
Ugh. I hate quaternions.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Scripting_Guide/Tutorials/Reset&diff=1266Guides/Scripting Guide/Tutorials/Reset2012-05-25T22:21:59Z<p>Ewencp: Initial import from sirikata-docs</p>
<hr />
<div>= Resetting Scripts =<br />
<br />
Using the in-world scripting prompt may not be the best way for you to build your virtual world application. This tutorial talks about:<br />
<br />
<blockquote>* Writing a script file.<br />
* Loading that script on an entity.<br />
* Resetting an entity to an initial script.<br />
</blockquote><br />
<br />
== Writing a script file ==<br />
If you are running the entire system locally, look for the &quot;std&quot; and &quot;test&quot; scripts directories. (If you're on the windows build, go to the sirikata folder you unzipped, open the &quot;share&quot; folder, then, open the &quot;js&quot; folder; if you're on Mac or Linux, then go to &quot;liboh&quot;, then &quot;plugins&quot;, then &quot;js&quot;, then &quot;scripts&quot;.) Once in this folder, create a new file, and name it &quot;myScript.em&quot;.<br />
<br />
The script that we're going to write is going to print the text &quot;timer fired!&quot; every 3 seconds. Think about how you would do this in an in-world command prompt. You'd probably enter the following commands into the prompt: :: system.import('std/core/repeatingTimer.em');<br />
<br />
<blockquote>function testCallback() { system.print(&quot;ntimer fired!n&quot;); }<br />
<br />
var repTimer = new std.core.RepeatingTimer(3,testCallback);<br />
</blockquote><br />
Your script should look exactly the same. All that executing a script does is sequentially evaluate all the commands in a script file as if they had been individually entered at an in-world scripting terminal.<br />
<br />
== Loading a script ==<br />
By the end of the previous section, you should have your script in 'myScript.em'. How do you get an in-world entity to execute it? Approach a presence in the world, and open a scripting point associated with it. To execute the script you just wrote, all you need to do is call import: :: system.import('myScript.em');<br />
<br />
The first argument of the import call should be the name of your script. (If you had put your script in the &quot;test&quot; folder, then you would have entered 'test/myScript.em' as the first argument.)<br />
<br />
At this point, every 3 seconds, you should see, printed into your scripting console, 'timer fired!'. At this point, you should know how to write a script in an external file and get it<br />
<br />
== Resetting ==<br />
<br />
Let's say that you don't want to print 'timer fired!' every 3 seconds. Instead, you want to print 'timer REALLY fired!' every 5 seconds. You can certainly, by hand, call `repTimer.clear()`, and then create a new timer. In practice, this process may be a little cumbersome. A better approach would be to modify myScript.em, clear the entity's current script, and then import the now-modified myScript.em. Emerson makes this easy.<br />
<br />
Before showing you how to do this, it's worth a little explanation. Emerson has a special &quot;reset&quot; call that can only be executed from your root sandbox. When a scripter executes this call, almost everything that he/she scripted is wiped away. The two things that remain:<br />
<br />
<blockquote>* The root sandbox's presences (and their associated state)<br />
* A special `script` string associated with each entity.<br />
</blockquote><br />
You should know about the first of these by now, so let's focus on the second part. A user can set the `script` string by calling: :: system.set_script(someString);<br />
<br />
where `someString` is a string the scripter provides. When an Emerson entity is reset, the Emerson runtime explicitly executes whatever is contained in that string after wiping away all other data.<br />
<br />
A really useful thing to put into strings like this is a simple import call. Let's think about how that would work for our simple timer fired script. After making the changes to myScript.em so that the timer fires every 5 seconds (instead of 3) and displays a different message, enter: :: system.set_script(&quot;system.import('std/default.em'); system.import('std/shim.em'); system.import('myScript.em');&quot;);<br />
<br />
into your in-world scripting console, then wehenever you call `system.reset()`, the first thing that happens after reset is that your entity re-imports myScript.em. You can now change your script files, and automatically incorporate those changes. You may be a little confused by the two imports that precede importing from &quot;myScript.em&quot;. For entities that exist in the world before you bring them up, the system automatically imports these libraries (they do things like allowing entities in the world to respond to scripting messages, move events, etc.). Because you're resetting the entire entity state, you must include these explicitly.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Scripting_Guide/Tutorials/Connecting&diff=1265Guides/Scripting Guide/Tutorials/Connecting2012-05-25T22:19:46Z<p>Ewencp: Initial import from sirikata-docs</p>
<hr />
<div>= Connecting to a Sirikata World =<br />
<br />
Before you can start scripting, you need to be connected to a world. Currently, the connection procedure isn't very user friendly -- there isn't a UI for it -- but its also not too challenging to customize.<br />
<br />
First, you'll need to know what server you are connecting to. You'll need to know both the hostname (e.g `sample.sirikata.com`) and the port (e.g. `7777`). If you are running your own space server, these values will be `localhost` and `7777` by default.<br />
<br />
To run, find the object host binary, called `cppoh` (or `cppoh_d`). If you're using a prepackaged version then it should be under `sirikata/bin/`. If you've built from scratch, it is under `sirikata/build/cmake/`. Then, we just run the binary, specifying the hostname and port:<br />
<br />
<pre>./cppoh_d &quot;--servermap-options=--host=sample.sirikata.com --port=7777&quot;</pre><br />
Note the quotes around the one option string -- because we need to specify both the host and port as '''suboptions''' to `servermap-options`, we need to put quotes around the entire `servermap-options` string.<br />
<br />
If everything went right, a window should have popped up and started displaying the world.<br />
<br />
== Client Configuration ==<br />
<br />
The default scene should provide you with a configuration . If you want to use a customized client script (for instance, providing different features or key bindings) you need to specify.<br />
<br />
In Sirikata, the client is not special in anyway -- it is just a normal object that connects to and interacts with the world just as any other object and it just happens to also display the world in a window and handle user input. Because of this, the program being executed is just the normal `object host`. Generally, when running as the client, the configuration specifies only one object -- your avatar -- to be loaded. To control the set of objects that are loaded, you can specify a scene file instead of using the default of `scene.db`:<br />
<br />
<pre>./cppoh_d --object-factory-opts=--db=my.db</pre><br />
Within the database file, each object can specify a `script_type` and `script_options`. By setting these for your avatar object, you can alter the behavior of the client. The defaults for the client are `js`, which specifies the JavaScript/Emerson scripting plugin, and `--init-script=std/defaultAvatar.em`, which is a script that turns on graphics and sets up many useful default interactions such as using the mouse for manipulating objects and key bindings for bringing up a scripting window for objects.<br />
<br />
== Additional Configuration ==<br />
<br />
If you need to specify additional options, or you always want to connect to the same server, it can be more convenient to create a configuration file which specifies all your options. A configuration file has one option per line, formatted as:<br />
<br />
<pre>--option=optionvalue</pre><br />
From the example above, we might specify the following in our configuration [file: file:]<br />
<br />
<pre>--servermap-options=--host=sample.sirikata.com --port=7777</pre><br />
to avoid typing it every time we want to start the client. To run with the configuration file, you specify it as an option to the client:<br />
<br />
<pre>./cppoh_d --cfg=my.cfg</pre><br />
Now, if you have many options in `my.cfg`, they will all be included when you specify the configuration file.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=Guides/Scripting_Guide/Tutorials/Hello_World&diff=1264Guides/Scripting Guide/Tutorials/Hello World2012-05-25T22:19:16Z<p>Ewencp: Initial import from sirikata-docs</p>
<hr />
<div>= Hello World -- Your First Script =<br />
<br />
== Hello World! ==<br />
<br />
Let's put together a quick hello world script. One can do this in one of two ways: by printing from a running entity's presence or by creating a new entity, connecting that entity to the world, and then telling that entity to print your message.<br />
<br />
We'll talk about each separately below.<br />
<br />
=== Print from running object ===<br />
<br />
Presumably, you're connected to a world with already-existing entities connected through presences. Move close towards one (you can use the arrow keys to navigate in flat space and 'q' and 'z' to adjust your height). Click on it. A white cube should appear around the presence's mesh as seen in the following figures:<br />
<br />
; Before clicking on object:<br />
[[Image:scripting_tutorial_helloworld_0.png|512px]]<br />
; After clicking on object:<br />
[[Image:scripting_tutorial_helloworld_1.png|512px]]<br />
<br />
This white cube means that the presence is &quot;selected&quot;. Type <tt>alt</tt>+<tt>s</tt> to bring up a scripting window for the entity connected. Note that although the presence is highlighted, you will be scripting the '''entity''' associated with the presence, '''not''' the presence itself. The scripting window appears as the white rectangle in the following example image:<br />
<br />
[[Image:scripting_tutorial_helloworld_2.png|512px]]<br />
<br />
In the window, type <tt>system.print(&quot;\n\nHello, World!\n\n&quot;);</tt>. Hit <tt>ctrl</tt>+<tt>enter</tt> to execute this script (or, hit the button marked &quot;run&quot;). You should see &quot;Hello, World!&quot; appear in the scripting window. That should be it. You've created your first program! If you want, you can enter other commands into the scripting window to do basic math, :ref:`movepresence`, print more messages, etc.<br />
<br />
; Typing in command at prompt.<br />
[[Image:scripting_tutorial_helloworld_3.png|512px]]<br />
; Result of running hello, world command.<br />
[[Image:scripting_tutorial_helloworld_4.png|512px]]<br />
<br />
=== Bring up entity and print when first presence is connected ===<br />
<br />
There are a variety of ways to create new entities in the world. The simplest is to approach an object in the world, and ask it to create a new entity for you. The tutorial on :ref:`createent` explains how a scripter can create a new entity. This subsection focuses on writing a script that a newly created entity would use to print &quot;Hello, World!&quot; after it has connected to a new space.<br />
<br />
Conceptually, there are several ways to approach such a task. For instance, one could send a request to connect to the space and frequently check an indicator to see when that request has been accepted, performing some action on acceptance. Such an approach is called &quot;polling&quot;. As an alternate strategy, one could instead request a connection to the space and register a ''callback'' with the underlying run-time environment so that the script is notified when the connection request is successful. This is called an &quot;event-based approach&quot;. Emerson, for the most part, encourages event-based scripting, and therefore uses the second strategy.<br />
<br />
Consider the simple following script:<br />
<br />
function printHelloWorld(newPres) {<br />
system.print(&quot;nnHello, World!nn&quot;);<br />
}<br />
system.onPresenceConnected(printHelloWorld);<br />
<br />
Let's break it into pieces:<br />
<br />
function printHelloWorld(newPres) {<br />
system.print(&quot;nnHello, World!nn&quot;);<br />
}<br />
<br />
As one might guess from the print from running object section of this tutorial, when the above function is called, it simply prints &quot;Hello, World!&quot;. No surprises here. Let's look at the next bit:<br />
<br />
system.onPresenceConnected(printHelloWorld);<br />
<br />
The above <tt>system.onPresenceConnected</tt> function takes in a single argument: a function that specifies what to do when a presence is newly connected. When a new presence is connected, the Emerson run-time automatically executes this function for the scripter.<br />
<br />
In general, a scripter might write presence initialization code in such a function, but, for our purposes, printing &quot;Hello, World!&quot; suffices.</div>Ewencphttps://www.sirikata.com/wiki/index.php?title=File:Scripting_tutorial_helloworld_4.png&diff=1263File:Scripting tutorial helloworld 4.png2012-05-25T22:12:54Z<p>Ewencp: </p>
<hr />
<div></div>Ewencphttps://www.sirikata.com/wiki/index.php?title=File:Scripting_tutorial_helloworld_3.png&diff=1262File:Scripting tutorial helloworld 3.png2012-05-25T22:12:44Z<p>Ewencp: </p>
<hr />
<div></div>Ewencphttps://www.sirikata.com/wiki/index.php?title=File:Scripting_tutorial_helloworld_2.png&diff=1261File:Scripting tutorial helloworld 2.png2012-05-25T22:12:33Z<p>Ewencp: </p>
<hr />
<div></div>Ewencphttps://www.sirikata.com/wiki/index.php?title=File:Scripting_tutorial_helloworld_1.png&diff=1260File:Scripting tutorial helloworld 1.png2012-05-25T22:12:15Z<p>Ewencp: </p>
<hr />
<div></div>Ewencphttps://www.sirikata.com/wiki/index.php?title=File:Scripting_tutorial_helloworld_0.png&diff=1259File:Scripting tutorial helloworld 0.png2012-05-25T22:11:54Z<p>Ewencp: </p>
<hr />
<div></div>Ewencp