---
# System prepended metadata

title: Speed Hoonin w/ Quartus

---

# Speed Hoonin w/ Quartus
Quartus builds applications by coming up with names first and then making the hoon do something. Not every name results in a valid product, so we have to start a lot of projects to see what will work. As a result we've become relatively proficient at quickly producing userspace Gall applications on Urbit.

Over the course of this demonstration, we'll build a hoon agent live, as well as expose you to some patterns you might see in modern Gall agents. We'll also reveal some tips and tricks from our experience in rapid hoon prototyping.

## Goal:
### Build an MVP Remind Me In bot for New-Groups' Chat:
1. Watch Chat Store in New-Groups
2. Listen for `!remind-me <@dr> <reference>`
3. Interpret the `@dr`
4. Comment the instruction post after `@dr` has elapsed

### Examine Some Build Patterns Used By Quartus Team

## Phase 1 + 2:
Build a New Groups Fakezod.

### Sub-Ins:
1. zodbak has standard zod build
2. grozod has groups installed and new-desk

### How To:
1. First, clone both the repositories for [urbit/urbit](https://github.com/urbit/urbit) and [tloncorp/landscape-apps](https://github.com/tloncorp/landscape-apps)
2. Follow the instructions in the DEVELOPMENT.md file on `/landscape-apps` to get a gro-zod set up, back this up as well.
3. Get `new-desk` if you don't have it yet, coming soon in new arvo (copy and paste the last (most recent) commit file from [here](https://github.com/urbit/urbit/pull/5360/commits) to `/gen/hood/new-desk.hoon` in the `base` desk)

### Affordances:
* Fail Fast - with backups at different stages we can restore to where we knew things to be working and keep moving
* New Desk - makes it easier to start a desk
* Blank Agent - get started with a working pattern you can iterate off of (see [here](https://github.com/dalten-collective/agent-skeleton))
* Build desks that `just compile`. I don't care what anyone else says about copying in multiple desks or merging or any of that cruft. Build desks that compile and you'll save yourself a lot of headache in the future.

### Current Agent Capacities:
Print `:prod +dbug %state`

## Phase 3:
Start watching Chat, prepare to interpret responses

### Sub-Ins:
1. Install step-2-empty-app on GroZod
2. Finish with step-3-watching chat

### Anecdote:
I prewrote this in one evening, so yes, we're doing TV magic with some of the code but we're going to work through as much of it as we can. That being said, I did watch the wrong thing - I did a quick read through Chat, like we'll do here:
  1. Read `+on-watch`, see that we're directed to `watch` in the engine.
  2. Glance at the path names - only really `briefs` seemed appropriate (I realize now I should have watched `ui` to get more details and not have to use the pattern I did) - exercise to the viewer to fix this.
3. Look around for sections where `chat` passes on `briefs` - looks good enough let's try it - and again, I'm not faking this part because a more careful review would have had me watch on `ui`

### How To:
1. Write `+hear`
2. Change `+on-init`
3. Write `+dude`
4. Modify `on-agent`

### Affordances:
* Get started successfully, make things happen early, learn from experimentation
* Use known parts:
    * Sign:Agent:Gall is always going to have the same head components
    * Naming Conventions help me navigate my own programs
    * When in doubt, sig-rune it out.

### Current Agent Capacities:
Do something in chat, maybe see something in dojo, probably a mark

## Phase 4:
Unpack the Mark File

### Sub-Ins:
1. Start with `step-3-watch-chat`
2. End with `step-4-so-you-say`

### Pre-Work:
1. Read `/mar/chat/brief-update/hoon` - following all of its threads to build everything we can quickly surmise the following:
    * Include all of `/chat` from landscape's `/mar` file
    * Include the following `/sur` files from landscape
        * `chat-0.hoon`
        * `chat.hoon`
        * `cite.hoon`
        * `groups.hoon`
        * `meta.hoon`
    * Include `epic.hoon` and `chat-json.hoon` from `/lib`

### How To:
1. Write an import for `/-  c=chat`
2. Slightly modify `fact` receipt to print out what we're getting

### Affordances:
* We can just see what we're working with and start to form a theory
* We can create a scry, to newest writs, getting the last message, and check and see if it's of a valid type that we want
    * In this case it needs to have a head of flag, as we only want this in group chats not DMs or `club`s

### Current Agent Capacities:
When I get a new message from chat, I print it in the dojo.

## Phase 5:
Frame out an engine for checking whether we got a request for a reminder

### Sub-Ins:
1. Start with `step-4-so-you-say` but immediately proceed to `step-5-why-engine`

## How To:
1. ADD SUR FILE AND STATE
2. Use prebuilt `step-5` and talk through the elements and affordances of the engine
3. Note changes in dude for engine use
4. Write `arvo` and walk thru it

### Affordances:
* We're now tracking and replying to messages in chat.
* We need a sail page which I'll just cheat into existence