celeste: dream oriented computing

please note that the system documented on this page is not implemented, and an implementation is not a primary goal for me right now, because i am enjoying thinking about all the different aspects of it more than actually writing any code.

a mockup screenshot of celeste.

celeste is a future-retro personal computing stack. key design principles are introspection and user simplicity. currently it is vapourware. at the moment i am much more interested in writing and dreaming than programming and implementing. it is defined as three parts:

psyche is a virtual machine and hardware specification. physical celeste machines are a non-goal, but so is taking advantage of the flexibility that software offers. psyche defines input and output devices as well as the cpu architecture.

dialect is a programming language.

aesthetic is a graphics library, interface framework, and set of opinions on how computer interfaces should be.




Celeste is a graphic-oriented system. There is no way to access only a command line.


1. Inspirations

Almost nothing written here is original. I've taken things that i like from all over the place and kept going with it, creating something that brings me real joy.

Classic Mac OS (System 6 and earlier)—i don't think that this will surprise anyone, because graphically there are many clear similarities. I like the playful nature of the early Macintosh, and how personal it is, with the names of the programmers written in the programs.

Canon Cat—there are things i like and don't like about the Cat see www.canoncat.net. and the rest of Jef Raskin's work. Though i recommend his book The Humane Interface to everyone. Two things i particularly like about the Cat is the lack of context switches, and the way that disks work. I have tried to remove the idea of different programs that work in different ways from Celeste, though i've approached that in a different way to Jef. Celeste is similarly image-based, with a disk holding the state of the RAM.

Smalltalk—a family of languages with the isolation and exploration i like.

Plan 9—primarily the executable text.

Emacs—while i couldn't give an explicit example of a feature i copied right now, Emacs is a piece of software that i use frequently, so i'm sure that some things must have crept in.

Kinopio—a delightfully designed interface and self-contained world. see kinopio.club. This isn't supposed to be a general-purpose environment like some of the things on this list, but the best way of solving its particular problem space has been very thoughtfully considered, and it shows.

2. The Principles of Aesthetic

The part of a system that a user knows is the part that they use. As the name suggests. Therefore, this user interface must act in such a way that the user can feel familiar with it. These are my guidelines on how to create interfaces that will let the user do what they want to do with the minimum of friction. My intention is for these guidelines to be based on fact, not opinion. If you think anything veers into opinion, let me know and i will do my best to make alterations. If you follow them, it is my hope that anyone using your application could not tell me exactly how they went about using it, because it was so easy for them to do so that no pain points stuck out in their mind.

Do note that i am writing this with the Celeste system in mind, which may work differently to other common systems. Because of that, some of the principles given may not be directly transferable to other systems. I encourage you to consider carefully the underlying point of any advice given, and from that draw the right conclusion on how your application should work.

Principle of Physicality: people understand the physical world because we live in a physical world. It follows that where possible we should bring these affordances into the digital interfaces that we design. I see the main physical affordances as being reactivity, immediacy, and spatiality.

Every action causes a reaction. If i push something, it moves. If i press something, it clicks. Similarly, things don't click without being pressed, and things don't move without being pushed. Of course there are exceptions to this rule because the world is so big. The advantage of a computer system is that we can work at a manageable size where things really do only react to actions.

Whenever i perform an action, the reaction happens immediately. If i push something, the movement happens with the push, not a few seconds later. Within a computer system, anything that feels like it should happen at once should act like it has happened at once. See www.nngroup.com/articles/response-times-3-important-limits/. Behind the scenes, things may take longer, but this is an implementation detail. See craigmod.com/essays/fast_software/.

Every element on the screen has a presence. They cannot teleport or blink in and out of existence. Within computer systems, we can make use of animation to show hierarchy and position. See bibliography.selflanguage.org/animation.html. Windows can zoom out from their parents, and zoom back in when they are closed. Jumping to a section of a document can cause the window to scroll until it reaches it. Note that animations should not be blocking. Take as long as you like to transition between two windows, as long as they user can start typing into the new window immediately after enacting the transition. Humans are usually better at locating things based on where they are and what they look like than by name.

Principle of Forgiveness: in the physical world, often making a mistake means starting over. Here is somewhere that computers have a significant advantage, because undo is a powerful concept we can take advantage of. I have written previously about the best way to implement undo, because it is common to provide a sub-par experience. There is no reason to limit the amount of undo history until the limits of the computer hardware are reached.

In many existing computer interfaces, modal popups are used before an action is taken rather than enabling undo afterwards. This is especially common with destructive actions such as deleting files and irreversible actions such as sending emails. The problem with this approach is that it causes the user to form the habit of clicking through any alert without reading it, which can have significant consequences. See delftdesignlabs.org/wp-content/uploads/2017/07/124-nlugtenburg.pdf. Instead, put off irreversible actions for as long as possible. For deleting a file, this may mean setting a flag on the file that isn't processed until the system is shut down. For sending an email, i suggest an airgap of about a minute. See alistapart.com/article/neveruseawarning/. Make sure to use your common sense here; if an instant messenger were to hold messages for thirty seconds it would become frustrating, because it would no longer be instant. The informality of the medium means that spelling mistakes and forgotten attachments are unlikely to cause the same embarrassment as they would with an email. Before the action is actually undertaken, the user should be able to reverse it.

The key takeaway from this principle is to ensure that the user feels in control and does not need to panic. Panic leads to more mistakes, resentment, and misery. See www.asktog.com/columns/066Panic!.html.

Principle of Consistency: consistency is golden. The look of your application should not be unique. See lawsofux.com/jakobs-law/ and gist.github.com/BriSeven/a0899f49602823c6c9424f938358115b. Make the function stand out because of its function, not its form. Buttons and keypresses should always do the same thing.

Things that behave differently should also look different. people don't mistakenly brush their hair with scissors, because the function is clear from the design. Don't just change the colour of an element, change its shape too, because not everyone can distinguish between colours.

Things that are not related should be separate. Humans like to find patterns in everything, and they are good at it, even if there isn't a pattern, even if a pattern is accidental. See psychclassics.yorku.ca/Wertheimer/Forms/forms.htm. Do your best to avoid accidental patterns, and to cultivate intentional patterns.

If you update your application to add a new feature, you face a dilemma: where do you add the new feature into the interface? You are inevitably going to have to move some interface elements around, which will frustrate your existing users, who are used to particular positions. You should try to find the best middle path here: don't resist change too much, but avoid change for the sake of change. On the other hand, obsessive backwards compatibility is the bane of well-designed software. The people already using your application should be more valuable to you than people not using it. on the other hand, if someone is not using it and you think perhaps they should be, ensure that the reason they are not is because of any accessibility issues or other integral design decisions that you overlooked.

Principle of Modelessness: avoid modal systems, which add the unnecessary mental burden of remembering which mode is active. Modes are systems of operation where the same input will result in a different output. A notorious example is the caps lock key.

If you think that a mode is necessary, see if it can be replaced with a quasimode. A quasimode is a mode which is enabled by a constant action from the user. The shift key is the quasimode parallel to the caps lock key. Control, alt, and the other keyboard modifier keys are also examples of quasimodes. Quasimodes have the accessibility advantage of being easily translated to modes, while the reverse is not always true. Microsoft's stickykeys are an example of converting quasimodes into modes, to make the functionality more accessible to people with physical disabilities.

If not, try and design it out of your interface. Otherwise, ensure that it is very clear at the user's focus which mode is enabled. The vi family of editors fails at this, with the only indication of mode being a label at the bottom of the screen. If the user is looking at the cursor, this is entirely redundant. Some graphical versions change the cursor from a block to a line to distinguish the two most common modes, which is a good start. Apple's Mac OS has a help feature which changes the cursor into a question mark until anything an interface is clicked. This is a good example of a mode, because the user's focus is on the cursor. Modeless operation tends to be tied to a noun/verb interaction order. That is, i select something and then act upon it. Modal software tends to encourage a verb-noun order, which can be useful for batch operations, but has two main problems: first, it breaks the principle of immediacy; second, it causes more error for the user, because upon making the noun selection the verb is immediately executed, with no room for making adjustments to that selection. Letting the user make the noun selection first means they can be totally satisfied that on executing the verb, they will immediately see the desired result of the intended action.

Principle of Choice: if you offer a choice to the user, ensure that the options are distinct. If all things are considered and a modal popup really is the right solution, do not provide more than two choices. See www.interaction-design.org/literature/topics/hick-s-law. Highlight the option that is most likely to be the one that the user wants. Previously here i said highlight the least destructive option. If you follow the other principles listed here, any destruction should be reversible, so it is better to convenience the user if they obviously want to commit a destructive action. Do not use scary or patronising language in the dialogue, but make it clear what will happen. If the modal is a warning about an action the user has requested one of the actions should confirm the action, and the other option should cancel the action. There is also a high chance you are ignoring the principle of forgiveness. Please try and design the modal out of your interface. The window's close button should also cancel the action. See modalzmodalzmodalz.com.

If you are following the principle of reactivity, there should never be any popups that weren't the result of the user's actions. But to make it explicit here: no popup should ever replace the cancel button with a remind me later button. The user should always be able to say no, and then the computer should back off.

Principle of Competency: do not patronise the user. Assume every user is a competent human, even if they don't know how to use your software. Software isn't natural and isn't intuitive; we can try our best to make it so, but there will always be something that someone doesn't understand, and they shouldn't think that this is their fault. Something something the only intuitive interface is the nipple Disability isn't incompetence. If a user can't distinguish between colours or cannot use an input device, we should be making adjustments for that. Speaking a language that doesn't use latin characters isn't incompetence, and your software should support international scripts.

Don't force tutorials or startup wizards on the user. Make use of the universal help features in the system. Have an extensive manual that is not necessary to consult, but is easy to consult when necessary, by considering every single thing someone might want to do with your software, and what they might call that. For example, modifying the margin sizes might be described as making the margins bigger, shrinking the margins, or something else.

The computer should be a tool to make things easier for the user, not replace their cognitive ability. Consider the computer to be a bicycle for the mind. Know what humans are good at, and what computers are better at. For example, computers are better at repeated tasks, tasks involving numbers, and remembering things. Provide interfaces that let the user offload their weaknesses onto the computer.

Principle of Humility: humans make mistakes, so we the designers will make mistakes. we have a responsibility to carefully consider everything that could go wrong with our software, and come up with ways to inform the user about these issues, on their level. Only use jargon related to the domain of the application. Don't tell the user there was a stack overflow if they're using a word processor. Only use relevant jargon, but don't oversimplify. Remember the principle of competency.

when something goes wrong, don't just tell the user things are broken. also tell the user what they can do next. tell them how to report the error to us. tell them how to restore their file, which should be in good shape.

Intuitive complex systems are made up of simple intuitive parts. A mechanical watch can be understood as a mechanical hierarchy which is ultimately just cogs turning cogs. Start out with the simplest possible design, and work from there. this is gall's law. See personalmba.com/galls-law. Note that simplest possible design refers to simplest possible for the user, not the programmer. it is the programmer and the system's job to take on the burden of complexity for the user. Any solution will have a minimum amount of complexity, and it is your duty to take as much responsibility for that as possible. See humanist.co/blog/law-of-conservation-of-complexity/.