Understanding the Structure of a RISC OS !Application Directory (part 1)
First programming article for beginners for the series “BitBook”, and it’s about how RISC OS applications are structured and organised.
| If you’re beginning to code for RISC OS, one of the first concepts you need to grasp is the structure and purpose of a !Application directory. RISC OS was the first operating system to introduce self-contained applications, and in order to achieve that, Acorn developers decided to use a special type of file system directory called an Application Directory.
On RISC OS, an application is typically encapsulated in a special kind of directory that begins with an exclamation mark (!). |
![]() |
Traditionally, the exclamation mark is called “pling”. This naming convention is what makes the directory launchable directly from the desktop (WIMP) environment.

Below is a breakdown of the standard components of a !Application directory and the role each file or subdirectory plays in the application lifecycle.
1. !Boot (optional, but common)
The !Boot file is a small Obey file that runs automatically when the application is first seen by the Filer. It typically sets up filetype definitions, system variables, and icons. This file is crucial for making the application appear integrated with the desktop because it loads the Application’s main Icon.
It is recommended to write !Boot in Obey scripting, because it will work on every version of RISC OS, including machines that do not have a UniBoot boot system installed.
Please note: It is not strictly required to write the !Boot and the !Run files in Obey scripting. Obey scripting is a popular choice because it’s always available in RISC OS and is well-suited to the typical tasks associated with these files (e.g., configuring paths, loading WIMP icon files, and checking whether required modules are loaded). However, it is entirely possible to use other programming languages like BBC BASIC, Python, or Lua, as long as the RISC OS Filer has seen where these interpreters are located. It will then be able to run both the !Boot and !Run files written in those languages.
Obey: The traditional Acorn shell scripting language. If you are familiar with modern operating systems like Linux, Obey is similar to Bash scripts. However, Obey scripting is much simpler and less powerful than Bash.
UniBoot: The original Acorn boot process, fully contained in an !Application directory called !Boot, and generally installed on an HDD or SD card.
Typical responsibilities:
- Registering custom filetypes
- Setting system variables (e.g., <App$Dir>)
- Loading required modules or resources
Please note: the App in <App$Dir> should be replaced with the unique name of your application.
There have been discussions over the years on whether !Boot should set the application directory. The reason is that when a new !Application directory is seen by the RISC OS Filer, it will always execute the !Boot file in it. If the !Boot file sets the application directory for an already seen !Application somewhere else in the system, this may lead the system to inadvertently change the path and potentially load an older or undesired version of the application in certain situations.
To avoid this problem, it’s probably best to set the application directory in the !Run file, which is executed by the express wish of the user when they double-click the !Application directory. Or, if we really need to set the application directory in !Boot (for example, because we want to notify RISC OS to use our application every time the user tries to launch a file of a given type), then we could check if our application directory has already been set, and if not, then we set it in !Boot. In contrast, in !Run we always set it, given the user has expressed the desire to launch that specific copy of our application.
2. !Run (obligatory)
Executed when the user double-clicks the application. This file usually sets up the application’s environment and then runs the main executable.
Typical contents:
- Set <App$Dir> to the application’s full path (even if it has been set already in !Boot)
- Load required modules
- Run the main executable or script (e.g., RunImage)
3. !Sprites / Sprites21 / !Sprites22 / !Sprites11
These are sprite files used to store the application’s icons for different screen modes. They provide a visual identity in the desktop environment.
- !Sprites: Default
- !Sprites21: 256-colour icons (8 bits per pixel), often used by RISC OS 4 and 5
- !Sprites22: For 22 bpp modes (RISC OS 3.5+)
- !Sprites11: For 1 bpp (monochrome) icons
Please note: The number after the “Sprites” portion of the name is a reference to the video mode that traditionally allowed the use of such graphics characteristics
4. !Help (optional)
Contains help text shown when the user clicks Menu on the application icon and chooses “Help”.
Please Note: To ensure an help file is written keeping in mind internationalisation (check #10 for more details), instead of using a text file here, we can use an Obey file that then loads the appropriate !Help in text format from the correct resource directory (more details on this on part 2).
5. !RunImage (optional, but common)
This is usually the main binary or program executed by !Run. The file can be a compiled ARM binary, a BASIC file or any other language supported on RISC OS like Python or Lua etc.
6. !Choices (optional)
A place where the application stores user preferences. Not all applications need this, but it’s a good convention to follow.
7. Sprites Directory (optional, resource)
Some applications store additional sprite files in a Sprites subdirectory (without the exclamation mark). These are known as Application’s Sprites and might be loaded at runtime depending on the application logic.
There have been discussions over the years or wheter or not application sprites should be localized aka designed depending on the language resources (check point 10 for more details). Given that different cultures may identify icons differently. However, it’s rare to find applications that use localized sprites given that this may impose mroe work on the application design and maintenance.
8. Additional Data/Resource Files and Subdirectories
Applications can include directories for messages (Messages), templates (Templates), or additional libraries and modules. These follow no strict naming conventions but should be internally consistent.
9. System Variable Usage
A well-behaved application will use the <App$Dir> system variable to locate its files, avoiding hard-coded paths. This ensures the application works regardless of its location on the filesystem.
10. Internationalisation (Style Guide Recommendations)
The RISC OS Style Guide strongly encourages developers to support internationalisation in their applications. Normally all the internationalisation in an application is stored in a subdirectory called Resources and organized using sub-directories named using country codes. All internationalized resource files are then stored in the specific country sub-directory.
The recommended approach includes:
- Using Messages files to store all user-visible text. Avoid hardcoding strings directly into code or templates.
- Pairing Templates and Messages: Use a Templates file to define UI layout, and refer to Messages keys for the labels and text displayed. This allows translation without altering the layout.
- Language-specific directories: To support multiple languages, you can include subdirectories like Resources.Fr, Resources.De, etc., containing translated Messages and other resource files.
- Fallback behaviour: If no translation is available, the application should default to the base Messages file.
This structure makes it easy to adapt your application for international users and maintain consistency with the RISC OS desktop.
A Quick Checklist for Your First RISC OS Application Directory
- [x] Create a directory and name it with a leading !
- [x] Include !Boot and !Run files
- [x] Use <App$Dir> consistently
- [x] Provide icon sprites in !Sprites
- [x] Optionally include help, user choices, and message files
There is more to know, but by structuring your application as described in this article, it will behave consistently with other RISC OS software and integrate cleanly with the desktop environment. This is the first step towards creating powerful and well-behaved RISC OS applications!
(Paolo Fabio Zaino)

