Home Work Sketchbook Backlog About
--:-- CET

Laura Sirvent 2026

Email Instagram Behance

Overthinker (V): Routine, tiny scenes, and building a house

21.04.2026

Once the temporal model was in place, the next problem was making daily life readable instead of abstract.

I tightened the activity catalog a lot. It is now a compact set with explicit constraints: sleep continuity, commute in and out of work, and hangover only after drunk. This sounds small, but it removes a lot of nonsense transitions and makes the day feel less random.

I also standardized the visible scene pack in firmware to a fixed 8-sprite set and cleaned the mapping so office moments read as office moments, and running is actually running.

That is the current tradeoff I keep making in this project: simple visuals, more internal structure.

Overthinker activities catalog

I am still defining how to treat user inputs. I am limited to two buttons and one rotary encoder with a press button, so I am testing interaction ideas and the behavior is not fully locked yet.

Right now I am experimenting with the rotary as a kind of physical reinforcement input, almost like a soft stroke versus a slight hit, producing a positive or negative reaction in him. I am still not fully convinced this feature should stay.

Overthinker activities catalog

I also spent a lot of time fighting with the enclosure so it would stop being a naked device on my desk. At some point I pivoted the concept toward a desktop companion you keep nearby while working, and the design was heavily constrained by the components I had already soldered, the 3D print format, and my near-zero experience with practical product design.

After several versions, a lot of caliper measuring, and many mistakes, my sister Patri and I finally got something decent.

Overthinker (IV): More layers, more continuity

15.04.2026

Compared to the previous version, this stage adds real complexity to how Overthinker behaves.

Until now, the interaction worked, but it was still easy to feel the same loop repeating. I wanted him to react with more nuance and carry more continuity between turns.

Overthinker logical loop and structure

The emotional model now has two layers:

  1. immediate mood: the state of the current moment, which can change quickly.
  2. slow traits: the deeper personality baseline, which shifts slowly over many interactions.

Memory is also split into two horizons:

  1. daily memory: emotionally relevant things from the current day.
  2. mid term memory: events that stay longer because they had stronger impact.

This gives me a better balance: some things should fade quickly, others should leave a mark.

I also introduced activity-based structure. Instead of only existing when you press a button, he now moves through small everyday states like sleeping, commuting, working, or scrolling.

Then there are sub-events: little internal incidents that can happen inside those activities before you interact with him. That means he can arrive already affected by something, like getting overloaded at work.

So the core now is: emotional layers, memory horizons, activities, and sub-events. Still compact, but much closer to the feeling that he has an ongoing day, not just isolated dialogue turns.

On the hardware side, I also moved from breadboard prototyping to a smaller soldered board that feels more final. The plan is to build a 3D-printed enclosure, but I am already happy that it now has a much more manageable format.

Soldered device

Overthinker (III): Trying to stop it from getting repetitive

06.04.2026

Now that the system basically works, I can already see the next problem: the loop might be too simple.

Right now the structure is this: you check in on the pet, he tells you something about his life, you react to it with a positive, negative, or ignore response, and then he reacts back. That reaction changes his emotional state.

That already works, but if I leave it there it will probably get repetitive very fast. So a big part of the work now is making sure the same structure can still feel different depending on mood. If he is low, maybe he does not really want to tell you much. If he is upset, he can be colder. If he is spiralling, he asks more, pushes more, and needs more reassurance.

Overthinker showing a low mood on screen

Prompting the LLM with all of this in mind is delicate. Finding a free model that is actually useful for this is also part of the problem. More and more I feel that the model itself is not the interesting part. What matters is the framing: what memory it gets, what biography the pet has, what parts of his life he can bring back, and how his voice shifts depending on state.

The backend already has persistent memory. It is a pretty ugly JSON, but it does the job:

{
  "attachment": 6,
  "fragility": 4,
  "resentment": 0,
  "soothed": 31,
  "energy": 96,
  "mood": "calm",
  "pending_initiative": false,
  "utterance_counter": 202
}

And then lower down there are actual dialogue fragments and topic references, for example:

{
  "text": "Overthinker[utt_200]: Pues a mi me paso que el otro dia estuve charlando con un cliente en la tienda y luego me dio la sensación de que me quedé hablando demasiado y lo incomode sin darme cuenta.",
  "source_topic": "futuro_duda"
}

The other thing I am trying to add is initiative. I do not want him to only exist when you poke him. Every now and then he should decide on his own to go “hey” and try to tell you something.

That helps for two reasons. First, it adds surprise. Second, it gives you a small decision: do I listen or do I brush him off? And obviously that should affect him.

Overthinker showing rejection on screen

I am also starting to let bits of the outside world into the device: weather, day, season, and later maybe other information or even news. The tricky part is making sure that does not turn it into an assistant, a weather app, or anything too useful.

One of the prompt rules says this:

Si usas este contexto, hazlo de forma escasa y totalmente filtrada por tu sesgo.
Si el contexto es weather, puedes mencionar temperatura, lluvia o cielo,
pero integrado en tu tono, no como un boletin.
Convierte ese tiempo en sensacion, bajon, pereza, encierro, mal cuerpo o una rayada tuya.

That is probably the balance I am chasing now. I want it to stay somewhere between a narrative device and a tech experiment. I want there to be enough surprise in it that you still feel like giving it what it wants, which is attention and reassurance.

Overthinker (II): Giving it a brain

04.04.2026

This was the point where the project started feeling real.

The firmware runs on the board and I am building that side with PlatformIO. Then there is a backend where the state, logic, memory, and decisions live. And then the LLM sits on top of that, not as the whole brain of the thing, but as a text layer shaped by mood, memory, context, and intent.

I wanted that split from the start because I did not want the pet to just feel like a screen hooked up to a chatbot.

I also started writing the personality down properly so it would stop living only in my head. Right now I have a character canon with things like identity, daily life, social world, psychology, voice, and mood rules. A small part of it looks like this:

"identity": {
    "name": "Overthinker",
    "age_range": "treinta y tantos",
    "life_stage": "adulto funcional pero estancado",
    "core_need": "sentirse validado y percibido como interesante",
    "core_fear": "haber quedado como pesado, raro o fuera de lugar",
    "main_contradiction": "quiere gustar y conectar, pero fuerza la interaccion y genera rechazo",
}

The moods are not just names either. Each one has actual speaking rules:

"spiraling": {
    "speech_pattern": "analiza detalles concretos",
    "interpretation": "sobredimensiona micro senales",
    "focus": "tono, pausas, palabras exactas",
}

I am also building the project in Spanish on purpose. Partly because I think hearing him speak in my own language will make me react to him more instinctively, and partly because it makes me want to keep going with the project.

Visually, he started as more of a blob, very close to the classic tamagotchi look. But pretty quickly I realised that making him human worked much better. It made him easier to read, easier to empathise with, and honestly a bit more awkward in the right way.

At the same time, the hardware limits were shaping the interaction. There are only three buttons: positive, negative, and ignore. That is it. Depending on how you answer, his emotional variables shift.

Version 2 of Overthinker

The OLED has also pushed me into monochrome 1-bit pixel art more than I expected. I am used to having way more tools when I want expression (3D), so working with something this limited is weirdly fun. A pixel is either on or off. That is the whole deal.

I am using u8g2 library for text and sprites rendering, and this is the current talk loop sprite sheet.

Talk loop sprites for Overthinker

Overthinker (I): A virtual pet

02.04.2026

I’ve been in Elda for a few days, staying at my parents’ place, with a bit of unexpected free time. So I gave myself a small challenge: build something using the electronics stuff I already had lying around from a different project that never really worked out.

Vista general de Overthinker montado

The basic idea came from mixing two things I already liked. One was the old tamagotchi logic: a small creature that keeps pulling your attention. The other was a more human thing, which is how often people get stuck talking about themselves, spiralling around their own problems, and using other people for reassurance.

That is where Overthinker came from. Not really a cute pet, and definitely not an assistant. More like a needy little character who keeps making everything about himself.

On the hardware side, I had an ESP32 (a microcontroller board for small electronics and programming projects), a 64x128 OLED screen, a couple of tiny breadboards (those little boards you use to prototype circuits without soldering), wires, and a few push buttons. So the shape of the project was already kind of there: one screen, three buttons, and not much else. The limitations were doing a lot of the design work for me from the start.

ESP32 and protoboard for Overthinker

Later I realised the pet needed sound too, mostly because it had to be able to demand attention in a way that felt a bit more annoying and alive. That is when the piezo speaker (a tiny electronic part that makes sound when you drive it with certain frequencies) entered the story, thanks to a very funny side mission involving my dad and his retired friends trying to find one the day before Easter, with the only electronics shop in town closed.

In the end they found a cheap door alarm from a bazaar and I pulled the piezo out of that.

Door alarm used to get the piezo speaker

I also wanted to use this project to be a bit stricter about process. LLMs make it very easy to build fast and get messy, so I decided to lean into spec-driven development and force myself to define things properly instead of just improvising forever.