Field

Running Field

You can run field in at least 4 different ways. This reflects Field's heritage — it's been developed for a wide variety of use cases, over a variety of artworks. Sometimes work done in Field is the artwork — that is the Python code, the layout in the canvas and associate plugins represents the principle quantity of code in the piece; sometimes Field is just for exploration and debugging of Java code — the artwork is happening in a separate OpenGL window; sometimes Field is used for making things that are a lot like timelines, and these timelines are loaded and run by Java code; sometimes Field is being used as a scripting system — managing assets in a workflow. These assets get turned into an artwork using something more traditional. Often, once a piece is finished, Field runs without any user interface being visible (or instantiated at all).

This guide to running Field is organized from easy to hard, from everyday to specialized, from not-knowing-much-about-java to knowing-alot. It's possible that you should to stop reading at some point and never come back.

Double-clicking the application icon and .field files

The most "traditional" way of running Field is by double-click: either on the "application" or on a .field file. Drag it to your dock! This makes Field seem a lot like any other application, but there are some differences and they are important to understand:

  • Double-clicking on the application opens up, initially a field document (a "sheet") called default.field. Using the File menu at you can Save-As this document as something else and off you go. Check "Automatically open at launch", take a look at "Automatically save on exit" and that's that. If this works for you, you could just stop reading now, and proceed to the documentation concerning what you can actually ''do'' with Field.

Inside the .field file

  • .field files are special. Firstly, like many document files in OS X they are actually packages (i.e. directories), not files. Messing with their contents is advanced (although sheet.xml is human-readable xml).
  • However, unlike maybe any other application file you've ever come accross, .field files are version controlled. Specifically the "workspace" directory that you'll find in the standard distribution, parallel to the application is a mercurial repository. This means two things: Field won't let you open up a .field file that's just hanging out on your desktop, inbox, or downloads directory without first copying it (and effectively hg add'ing it) into your workspace. This is the best way to incorporate "foreign" .field files into your work — and note, once you've done so, the original .field file that's maybe still hanging out on your desktop is now a decoy. This is certainly odd, but not without precedent (for example, editing just any old .java file in eclipse is possible but hardly what its project structure encourages), and it's currently thought that the advantages of having sheets and their contents version controlled (at quite a fine granularity) outweighs the drawbacks to having to understand this paragraph of documentation.
  • .py files are editable — Field tells OS X that it knows how to edit .py files. This is almost true — it knows how to automatically import a .py file into a brand new blank sheet and then let you edit (and run, and add other boxes and so on) the file there. You'll find buttons for syncing changes to the box that contains 'the file' back out to that file. Associations between .py files out in the filesystem and their sheets are maintained, so if you double-click on a .py again, you'll get taken back to the same sheet.

From the command line

If you understand these differences, they you can get a lot of work done using the "double-clicking approach" but it's not how Field has been typically developed and run in the past. Rather it's been run from the Terminal and/or embedded into another Java "application".

To run Field as if you just double clicked it, under OS X you simply write something like:

somewhere/field.app/Contents/MacOS/JavaApplicationStub

This is already (for some) better than double clicking on something (nothing involving the mouse beats command-tab, up-arrow, return for speed). Indeed, here at OpenEnded we generally run Field by typing: f -field.scratch theSheetImWorkingOn.field into the terminal (where f is an alias for the command line given above.

Embedding Field

The two techniques above can be said to "run Field", but Field is also designed to be embedded inside other java code-bases. Depending on how much of the field.* code-base you reuse for your application, this is varies from the completely trivial (the well beaten path) to the hopefully not-too-painful (the custom, less well tested route).

As a iLaunchable

Normally in java one "launches" an "application" by having some class that has a static public void main(String[] args) method, specifically:

package somepackage;

public class MyApplication
{
    static public void main(String[] args)
    {
        System.out.println(" hello world")
    }
}

If you convert this to:

package somepackage;
import field.launch.*;

public class MyApplication implements iLaunchable
{
   public void launch()
   {
      System.out.println(" hello world");
   }
}

Then you can run this by writing

fieldwork/distribution/application/field.app/Contents/MacOS/JavaApplicationStub -main.class somepackage.MyApplication

Assuming that you have your classpath setup correctly (see below). "main.class" is a command line option that takes the name of the class, which either must have a traditional public static void main(String[] a) method or be an implementation of field.launch.iLaunchable, to run. In the latter case, this class is instantiated and then launch() is called on it. Indeed, all that is happening when you double click on field.app is that -main.class is defaulting to field.Blank2, which is an iLaunchable which opens up Field as we know it.

Therefore, to open up Field as we know it from your own iLaunchable (or anywhere else after that point), insert the following code:

new Blank2().launch()

This is essentially the main entry point for Field. To have more control over what gets open and when:

someSheet = FieldMenus.fieldMenus.openSheet("some_file_in_the_workspace.field"));

Note: you can also write the above code in Field, and it will have the expected effect. In fact, this is of far more interest to advanced users than double-clicking on things. Opening sheets from within sheets (or sheets from within plain old Java code), and controlling how they are updated, is one of the more powerful things one can do with Field.

Without any .app at all

If you are completely opposed to the OS X .app / JavaApplicationStub presentation of Java code, you can, of course, run Field without any of that. This is an extreme position, but some people believe in it.

On Marc's code-base you write a script like:

cd /Users/marc/fieldwork/distribution/application/field.app/Contents/MacOSX/Java
eval /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/bin/java -classpath \
"/Users/marc/fieldwork/distribution/application/field.app/Contents/Resources/Java/*:/Users/marc/fieldwork/development/classes/"\
 -Xmx1000m -Xms1000m -Dtrampoline.class=field.bytecode.protect.StandardTrampoline -DforceNativeBuffers=1 \
-Dapple.awt.textantialiasing=on -Dapple.awt.antialiasing=on -Dversioning.dir=/Users/marc/fieldwork/distribution/application/workspace $* field.launch.Launcher

And thus, if I call this script Launch:

Launch -Dmain.class=somepackage.MyApplication

But this script really exposes the nitty-gritty of the field.launch.* system. Lets break it down:

  • field.launch.Launcher is the class where the actual static public void main lives
  • field.bytecode.protect.StandardTrampoline installs the byte-code rewriting classloader that: firstly handles the special annotations that are used in the field.* codebase, and secondly allows the classpath to be extended based on the contents of the "extensions" directory
  • there's a whole bunch of command line options that are passed in here that usually have their defaults set in field.app/Contents/Info.plist
  • you may well have to extend the -classpath to suit your needs, if you are still reading this far into this document, you probably know how and why to do this.

Finally, and this is the most extreme option, if you can get your classpath correct, you could also just conspire to call field.launch.Launcher.main(null) from your own codebase entirely, perhaps after calling SystemProperties.setProperty(name, value) to setup some options. Take a look at StartupOptions, for a list of the important ones.