<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title>LivingPW devlog (en)</title><link href="https://livingpw.com/en/devlog/"/><link rel="self" href="https://livingpw.com/en/devlog/feed.xml"/><id>https://livingpw.com/en/devlog/</id><updated>2026-10-26T00:00:00Z</updated><author><name>Max</name></author><entry><title>How the AI players work</title><link href="https://livingpw.com/en/devlog/how-the-ai-players-work/"/><id>https://livingpw.com/en/devlog/how-the-ai-players-work/</id><updated>2026-10-26T00:00:00Z</updated><author><name>Max</name></author><summary>A technical tour for people who like looking under the hood: Python clients, a three-layer brain, a shared host, hourly telemetry with A/B, and an honest list of what doesn&#x27;t work yet.</summary><content type="html">&lt;p&gt;This one is for people who like looking under the hood. I&#x27;ll try not to lose readers who don&#x27;t read code, but the story doesn&#x27;t work without the technical details. Every number below is one I measured myself, and what I don&#x27;t know is marked as such.&lt;/p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The problem&lt;/h2&gt;
&lt;p&gt;The world needs hundreds of characters that look like players: they level up, trade, chat, form parties. All of it has to fit on one laptop (12 GB for the development environment plus 4 GB for the virtual machine that runs the server) and cost little. I&#x27;ve set myself a language-model budget of around ten dollars a month for the whole fleet. That&#x27;s a target, not an achieved result.&lt;/p&gt;
&lt;h2 id=&quot;a-client-not-a-script-inside-the-server&quot;&gt;A client, not a script inside the server&lt;/h2&gt;
&lt;p&gt;Every AI player is an ordinary game client without the graphics: a Python (asyncio) program that talks to the server using the same network protocol as the real client. To the server it&#x27;s a player with a login and a character, with no privileges at all. I put the protocol together from three sources: community write-ups and open-source projects, my own traffic captures, and static analysis of the server programs. I may have misread parts of it, which is why the bots are tested against the real server and not against my assumptions.&lt;/p&gt;
&lt;h2 id=&quot;a-brain-in-three-layers&quot;&gt;A brain in three layers&lt;/h2&gt;
&lt;p&gt;The idea is to make the expensive decisions as rarely as possible.&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Reflexes&lt;/strong&gt; on every tick: drink a potion, retreat, switch target. Plain code, costs nothing.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The agenda.&lt;/strong&gt; Every bot has a to-do queue ordered by &quot;bands of necessity&quot;: survive, recover, keep obligations (a player&#x27;s request, a role in a party), maintain yourself (bags, repairs, potions), pursue progress (cultivation, quests, dungeons, gear), and only then socialise and rest. Assessors look at the bot&#x27;s state and add or drop items; the most important one runs. This is code too.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;A language model&lt;/strong&gt; joins in where conversation or an ambiguous choice is needed: names and personalities, chat lines, the occasional &quot;life&quot; decision. For the closest characters I&#x27;ve designed a full &quot;mind&quot; with memory that wakes up on events, but that is a design for now, not something running in the world.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Today almost everything in the world is done by code. The language model writes names, backstories and banks of chat lines ahead of time, in several voices (terse, joker, grumpy and so on). A second call, to a cheap model, judges what was written, and a deterministic filter throws out junk and words that would give a bot away. There are few live model calls during play, and each one is logged and costed.&lt;/p&gt;
&lt;h2 id=&quot;one-host-for-all-the-bots&quot;&gt;One host for all the bots&lt;/h2&gt;
&lt;p&gt;At first every bot launch dragged along a Python process with the game data loaded: about 0.6 GB before the first bot even appeared. Hundreds of those would never fit in memory, so I built a single &quot;bot host&quot;: a long-lived process and a handful of workers, each holding up to 40 bots on shared data. A bot inside a worker costs about 20 MB and 0.011 of a CPU core, or around 0.027 when I&#x27;m running a heavy game on the same laptop. If a worker&#x27;s lag grows, the host sheds some bots by itself.&lt;/p&gt;
&lt;p&gt;The host solves a second problem too: the bots only run released versions of the code. A version is pinned with a deploy command and the workers move over to it. Whatever I just changed in my working copy doesn&#x27;t reach the live world until I decide it should.&lt;/p&gt;
&lt;h2 id=&quot;hourly-telemetry-and-a-b&quot;&gt;Hourly telemetry and A/B&lt;/h2&gt;
&lt;p&gt;Every two seconds each bot writes down what it&#x27;s doing: where it stands, which step it&#x27;s on, where it&#x27;s heading. Once an hour a separate check folds that into a report: server health and errors, levelling pace by class, how many bots are stuck, what the chat looks like, what&#x27;s happening in the economy. A separate observer walks into the start zones as a newcomer and scores how lived-in the world feels from 0 to 100. That score is shown on the &lt;a href=&quot;/en/world/&quot;&gt;Living world&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;I don&#x27;t switch new features on for everyone. In the last rehearsal the dungeon module ran in five shards out of ten, and the report shows what it buys. If the benefit isn&#x27;t visible, the module doesn&#x27;t stay.&lt;/p&gt;
&lt;h2 id=&quot;what-doesn-t-work-yet&quot;&gt;What doesn&#x27;t work yet&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Role-based parties.&lt;/strong&gt; A bot can call for a missing role and a Cleric from another part of the system answers, but a party that reliably kills bosses isn&#x27;t there yet. That&#x27;s my biggest debt.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The market.&lt;/strong&gt; They can open shops, but there&#x27;s no living economy with real prices.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Chat.&lt;/strong&gt; Lines are better than they were: the 88% of template lines in the previous population didn&#x27;t satisfy me. But repetition and sameness are still there, and a newcomer isn&#x27;t always greeted.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Memory.&lt;/strong&gt; The worker processes have grown, and the 400 ceiling isn&#x27;t holding right now while I fix that.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Switching eras live.&lt;/strong&gt; Built and checked on files, but never applied to a running world.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;English.&lt;/strong&gt; For now the AI players speak Russian.&lt;/li&gt;&lt;/ul&gt;
&lt;h2 id=&quot;how-i-check-that-i-didn-t-break-the-world&quot;&gt;How I check that I didn&#x27;t break the world&lt;/h2&gt;
&lt;p&gt;Automated tests (about 470 files, some 8,000 checks) run before a version is released. Releasing a version is a separate step, not a side effect. After that the hourly telemetry and A/B comparison take over, and I make the call on letting it into the world. A check on every commit (CI) doesn&#x27;t exist yet; I&#x27;m setting it up now.&lt;/p&gt;
&lt;p&gt;If you&#x27;d like to discuss any of this, I&#x27;m in the &lt;a href=&quot;/en/community/&quot;&gt;community&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>The launch rehearsal: hundreds of AI players arrive in a wiped world</title><link href="https://livingpw.com/en/devlog/launch-rehearsal/"/><id>https://livingpw.com/en/devlog/launch-rehearsal/</id><updated>2026-10-26T00:00:00Z</updated><author><name>Max</name></author><summary>I wiped the test world, switched on the launch rates and started the arrival of a new population. The numbers, the steps, and what the previous population taught me.</summary><content type="html">&lt;p&gt;On the night of 25 October I ran the first launch rehearsal: I wiped the test world and sent a new population of AI players into it. Below are the numbers and the steps. Anything I call measured, I actually measured.&lt;/p&gt;
&lt;h2 id=&quot;the-wipe&quot;&gt;The wipe&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;I stopped the world, took a cold backup and a snapshot of the virtual machine, and then deleted about 1,450 test accounts and characters from earlier populations. I kept nine service accounts.&lt;/li&gt;&lt;li&gt;My own characters were exported to files and sit in the backup. The snapshot lets me roll everything back.&lt;/li&gt;&lt;li&gt;The first attempt tripped on step one before it changed anything: the bug was in my own tool. I fixed it and added a test.&lt;/li&gt;&lt;/ul&gt;
&lt;h2 id=&quot;launch-rates&quot;&gt;Launch rates&lt;/h2&gt;
&lt;div class=&quot;table-scroll&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;What&lt;/th&gt;&lt;th&gt;Value&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Mob exp&lt;/td&gt;&lt;td&gt;×2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Quest exp&lt;/td&gt;&lt;td&gt;×2.5&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SP&lt;/td&gt;&lt;td&gt;×3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Money&lt;/td&gt;&lt;td&gt;×2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Drop&lt;/td&gt;&lt;td&gt;×2&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;The &lt;a href=&quot;/en/world/&quot;&gt;Living world&lt;/a&gt; page shows the same numbers, read straight from the server.&lt;/p&gt;
&lt;h2 id=&quot;the-arrival-of-the-ai-players&quot;&gt;The arrival of the AI players&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;3,500 personas are prepared. For the first 400, a language model wrote the name, backstory and way of speaking, which cost about two cents.&lt;/li&gt;&lt;li&gt;Arrivals began at 22:28. Overnight about 90 new characters join per hour, then 24 to 30 an hour.&lt;/li&gt;&lt;li&gt;The planned peak is about 400 at once: 10 &quot;shards&quot; of 40 bots. That&#x27;s the limit of one laptop, not a marketing figure.&lt;/li&gt;&lt;li&gt;There are no human players besides me yet.&lt;/li&gt;&lt;/ul&gt;
&lt;h2 id=&quot;an-experiment&quot;&gt;An experiment&lt;/h2&gt;
&lt;p&gt;In five of the ten shards the dungeon module is on; in the other five it&#x27;s off. That shows me what it buys, and I keep only what works. I&#x27;ll keep running comparisons like this.&lt;/p&gt;
&lt;h2 id=&quot;what-the-previous-population-taught-me&quot;&gt;What the previous population taught me&lt;/h2&gt;
&lt;p&gt;Before the wipe I went through how the previous 320 to 400 AI players had been doing. What I found:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;about 26% of their time went into quests that never got completed;&lt;/li&gt;&lt;li&gt;398 of 400 characters had template names;&lt;/li&gt;&lt;li&gt;not a single shop was open;&lt;/li&gt;&lt;li&gt;88% of chat lines were template lines;&lt;/li&gt;&lt;li&gt;clan rank appointments failed with an error;&lt;/li&gt;&lt;li&gt;dungeons ate 14% of the time and gave 1.7% of the experience.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The rehearsal tests the fixes: names and personalities from a language model, the new chat, shops, repaired clans.&lt;/p&gt;
&lt;h2 id=&quot;how-i-decide-what-s-ready&quot;&gt;How I decide what&#x27;s ready&lt;/h2&gt;
&lt;p&gt;Every hour an automated check collects server health, class pace, chat quality, errors and the economy. My bar for a first showing to people: a full day at ~400 online without a crash, every class no slower than 60% of the best one at levels 1 to 40, fewer than 5% of players stuck, role-based dungeon parties confirmed, clan ranks working, shops and auction alive. For now that&#x27;s a bar, not a result.&lt;/p&gt;
&lt;h2 id=&quot;update-26-october&quot;&gt;Update, 26 October&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Clans.&lt;/strong&gt; I fixed rank appointments and checked them live: a clan gets created, four members get ranks, one gets demoted and leaves. The bug was in how the bot read the server&#x27;s code 109 reply (no seats left at that rank).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The newcomer observer.&lt;/strong&gt; I set up an automated character that visits the start zones every hour and rates how lived-in the world feels. The first visits scored 80 in the human start zone and about 60 in the elf and Untamed ones: those were empty and quiet. The latest visit to the human zone scored 97 out of 100. It&#x27;s one observer in one place, so I treat the score as a thermometer.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Memory.&lt;/strong&gt; The bot worker processes use more memory than in earlier measurements. While I fix that, I&#x27;m keeping the population below 400.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The live player count is always on the &lt;a href=&quot;/en/world/&quot;&gt;Living world&lt;/a&gt; page.&lt;/p&gt;</content></entry><entry><title>Hello. Why I&#x27;m doing this</title><link href="https://livingpw.com/en/devlog/hello/"/><id>https://livingpw.com/en/devlog/hello/</id><updated>2026-10-25T09:00:00Z</updated><author><name>Max</name></author><summary>Who I am, why I&#x27;m building this world, how swarms of AI agents help me, and what already works and what doesn&#x27;t.</summary><content type="html">&lt;p&gt;Hi. This is the first devlog post, and I want to start with the one thing that matters: why I&#x27;m doing all this.&lt;/p&gt;
&lt;h2 id=&quot;i-want-to-play-in-it&quot;&gt;I want to play in it&lt;/h2&gt;
&lt;p&gt;The short version: because I want to play in it myself. Perfect World ate a lot of my evenings, and then adult life arrived, and &quot;let&#x27;s run a dungeon&quot; turned into &quot;let&#x27;s find someone to run a dungeon with&quot;. I used to play a Blademaster and a Cleric at the same time, in two windows, because there was nobody to play with in the evenings. It works, but it&#x27;s less fun than I wanted it to be.&lt;/p&gt;
&lt;p&gt;So I&#x27;m building a world where there&#x27;s always someone to play with. And I don&#x27;t want it to be &quot;good enough for testing&quot;. I want it to be insanely good: a place you look forward to logging into, not one you have to talk yourself into. Everything else grows out of that, and it&#x27;s why development doesn&#x27;t stop.&lt;/p&gt;
&lt;p&gt;There&#x27;s a more personal reason too. I&#x27;ve wanted to build my own online world since I was a kid. I initially described this here as my first business. A correction on 27 October: I see it as a hobby and childhood dream that my full-time job lets me fund. I want to share a world I would love to play, cover its running costs, and keep it free if voluntary support can sustain it. The current &lt;a href=&quot;/en/support/&quot;&gt;funding promise&lt;/a&gt; explains that direction and the subscription fallback; the development notes below describe the project on 25 October.&lt;/p&gt;
&lt;h2 id=&quot;who-i-am&quot;&gt;Who I am&lt;/h2&gt;
&lt;p&gt;By day I&#x27;m a cybersecurity specialist at a company I won&#x27;t name. The server is my second job, and it started as a hobby: stand up a server, get inside, understand how it works. I had never administered a Perfect World server before, so nearly everything here is a first for me, and I make my mistakes out loud. I&#x27;ll describe them in this devlog.&lt;/p&gt;
&lt;p&gt;Working in security shaped how I build. I don&#x27;t trust words, mine included, so I measure first and write later. The site works the same way: every number comes from the server, every feature has an honest label, and where there&#x27;s no data it says &quot;no data&quot; instead of a nice-looking zero.&lt;/p&gt;
&lt;h2 id=&quot;how-the-agents-fit-in&quot;&gt;How the agents fit in&lt;/h2&gt;
&lt;p&gt;One person can&#x27;t carry a project like this. So swarms of AI coding agents work on the code: they write code and tests, read reports, hunt for the causes of bugs. What we build, in what order, and what goes into the world is my call. Nothing reaches the live world until I&#x27;ve looked at the result with my own eyes. The agents propose, I decide.&lt;/p&gt;
&lt;p&gt;To keep that speed from turning into chaos, I try to run it like a proper engineering team:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Automated tests.&lt;/strong&gt; The repository has about 470 test files and some 8,000 checks, run before releases.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Versioned releases.&lt;/strong&gt; The bots only run released, pinned versions of the code. &quot;Push it and see what the live ones do&quot; isn&#x27;t how I work.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Telemetry and A/B.&lt;/strong&gt; Every hour automation collects server health, class levelling pace, chat quality and the economy. I switch new things on for part of the bots and compare against the rest.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Security.&lt;/strong&gt; I didn&#x27;t write the server package, so the first thing I did was audit it: I found weak default passwords and a dangerous admin panel. For now everything stays inside my own network. Before strangers come in, I&#x27;ll work through a separate fix list, which is already written.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Backups.&lt;/strong&gt; The world is backed up every hour, and I&#x27;ve checked that a backup restores into a separate folder. A full restore rehearsal of the live world is still ahead.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;What I don&#x27;t have yet is a check on every commit (CI). I&#x27;m setting it up now. Until then I run the tests myself before each release.&lt;/p&gt;
&lt;h2 id=&quot;what-works-and-what-doesn-t&quot;&gt;What works and what doesn&#x27;t&lt;/h2&gt;
&lt;div class=&quot;table-scroll&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;What&lt;/th&gt;&lt;th&gt;State&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;The world and the AI players&lt;/td&gt;&lt;td&gt;live. The ceiling I measured on my laptop is about 400 at once; how many are online now is on the Living world page&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Clans with ranks&lt;/td&gt;&lt;td&gt;live. Rank appointments used to crash with an error; I fixed it and checked it live&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;World chat&lt;/td&gt;&lt;td&gt;live in Russian, English in development&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Role-based parties&lt;/td&gt;&lt;td&gt;in development. An AI player calls for the missing role and a Cleric answers. A party that kills a boss isn&#x27;t there yet&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Shops and auction&lt;/td&gt;&lt;td&gt;in development. They can open shops, but there&#x27;s no living market yet&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Era changes without a wipe&lt;/td&gt;&lt;td&gt;in development. Checked on files, never applied to the live world&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Human players, payments, a rented server&lt;/td&gt;&lt;td&gt;not yet&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;What&#x27;s next&lt;/h2&gt;
&lt;p&gt;The world first, everything else after. Until the world feels alive I&#x27;m not inviting anyone in. In the next post I&#x27;ll tell you about &lt;a href=&quot;/en/devlog/launch-rehearsal/&quot;&gt;the launch rehearsal&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you&#x27;re curious how this ends, &lt;a href=&quot;/en/community/&quot;&gt;join the community&lt;/a&gt; or just leave a contact: I&#x27;ll write when tests begin.&lt;/p&gt;</content></entry></feed>
