Citavon

Citavon Bot · player guide

Citavon Bot

Citavon Bot accepts all NEAT bot and OTTObot goals and scripts, and it is written specifically for Citavon players. It is faster than NEAT bot. Please report any issues in the Citavon support rooms.

This guide takes you from the download to a running fleet, then explains every part of the bot: the Director (all your lords on one page), each lord's console, every goal the bot plays by and every script command it runs. Use the search box on the left (or press /) to jump straight to a goal or command.

New to Citavon itself? The game guide explains the game: buildings, troops, valleys, NPCs, medals and more.

1Downloads

Version 2026.10.18-d31b01b. One file, nothing else to install.

Windows

Windows 10 / 11, 64-bit · 88.9 MB
Download CitavonBot.exe
SHA-256
6ac058d9b00481a372e6e962bc5e4367cd65446583fee62290a5802f3b06cf5f

Linux

x64 server or PC · 118.5 MB
Download citavon-bot
SHA-256
19b2b5bf7904946729dcb3559714d19270e4cb34a41ca6ffc266b718e627e071

Check your download (optional, recommended)

The checksum proves the file is exactly the one published here. Both are listed in SHA256SUMS.txt.

Windows: open the folder you downloaded to, click the address bar, type cmd and press Enter. Then:

certutil -hashfile CitavonBot.exe SHA256

Linux: in the folder with the file:

sha256sum citavon-bot

The long number it prints must match the one on the card above. If it doesn't, don't run the file. Download it again.

"Windows protected your PC"

The program isn't code-signed, so the first time you start it Windows shows a blue Windows protected your PC box. Click More info, then Run anyway. Your browser may also say the file "isn't commonly downloaded": choose Keep.

2Install and start

There's no installer. The program is the whole bot.

Windows

  1. Put CitavonBot.exe somewhere you'll find it again (your Desktop or Documents is fine) and double-click it.
  2. A black window opens. That's the Director's log, so leave it open.
  3. A moment later the Director opens in a window of its own (an Edge or Chrome window with no tabs). If you have neither, it opens in your normal browser at http://127.0.0.1:8720.
Closing the black window

stops the Director. Your lords' consoles keep running and keep playing, and the next start picks them up again.

Starting it again while it runs

does no harm. It just opens the Director's window.

To stop your lords too

untick On for them in the Director (or click stop) before you close it.

Your files

(lords, goals, scripts, logs) live in %APPDATA%\CitavonBot. Updates don't touch them.

Tip: to open your files folder, press Win+R, type %APPDATA%\CitavonBot and press Enter.

Linux PC or server

  1. Download citavon-bot with the button above, or straight onto a server:
    curl -LO https://citavon.com/downloads/citavon-bot
  2. Make it runnable and start it:
    chmod +x citavon-bot
    ./citavon-bot --no-window
  3. Open http://127.0.0.1:8720 in a browser on that machine. On a desktop PC you can leave off --no-window and it opens a browser window for you. On a server with no screen, see first time on a server below.

Your files live in ~/.local/share/citavon-bot. To keep them somewhere else, set GERMBOT_HOME, for example GERMBOT_HOME=/srv/citavon ./citavon-bot --no-window.

Run it as a service on a server (systemd)

This keeps the bot running after you log out and starts it again when the server reboots. Run these in the folder where you downloaded citavon-bot.

  1. Make a user for the bot, and put the program in place:
    sudo useradd --system --user-group --home-dir /var/lib/citavon-bot --shell /usr/sbin/nologin citavon
    sudo install -m 755 citavon-bot /usr/local/bin/citavon-bot
    sudo install -d -o citavon -g citavon -m 750 /var/lib/citavon-bot
  2. Write the service file:
    sudo tee /etc/systemd/system/citavon-bot.service > /dev/null <<'EOF'
    [Unit]
    Description=Citavon Bot
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    User=citavon
    Group=citavon
    Environment=GERMBOT_HOME=/var/lib/citavon-bot
    ExecStart=/usr/local/bin/citavon-bot --no-window
    Restart=on-failure
    RestartSec=10
    KillMode=process
    
    [Install]
    WantedBy=multi-user.target
    EOF

    Why KillMode=process: each lord's console is its own process. With this line, restarting the service restarts only the Director and does not log every lord out. (systemd may warn about it. That's expected.)

  3. Start it, now and at every boot:
    sudo systemctl daemon-reload
    sudo systemctl enable --now citavon-bot
  4. Watch its log (Ctrl+C to stop watching; the bot keeps running):
    journalctl -u citavon-bot -f

First time on a server with no screen

The Director only answers on the server itself at first. Reach it from your PC through an SSH tunnel:

  1. On your PC (Windows Terminal, PowerShell, macOS or Linux terminal), with your own login and server name:
    ssh -L 8720:127.0.0.1:8720 you@your-server
    Keep that window open.
  2. On your PC, open http://127.0.0.1:8720. Through the tunnel you count as the server itself, so everything works, including the Setup tab.
  3. In Setup, switch on Tailscale and choose a Director password (see Phone or another PC). Then restart the service:
    sudo systemctl restart citavon-bot
  4. From now on open the Director over Tailscale, from any of your devices, with no tunnel.

The tunnel only carries the Director's port. A lord's name in the Fleet links to that lord's own port, which the tunnel doesn't carry. Use the tunnel for the first setup, and Tailscale for everyday use (there, every console opens through the Director).

Updating

  • Windows: close the black window, download the new CitavonBot.exe, start it. Your lords, goals and scripts are kept.
  • Linux service:
    sudo install -m 755 citavon-bot /usr/local/bin/citavon-bot
    sudo systemctl restart citavon-bot
  • Lords that were already running keep their console from the old version until you click restart on them in the Fleet (that logs the lord in again).

Ports

The Director uses port 8720. Each lord's console gets its own port from 8721 up. All of them answer on the computer itself only, unless you switch on Tailscale.

3Log in: add your lords

On Citavon, one email and password owns all your lords, and each lord logs in by its lord name.

There are two passwords. Don't mix them up.

Your Citavon password

The one you log in to citavon.com with.

Used in Add account and Import fleet to log your lords into the game.

The Director password

One you choose for the bot itself.

Protects the Director's page when you open it from your phone or another PC. It never goes to the game.

Add one lord: Add account

  1. In the Director, click Add account.
  2. Lord name: your lord's name exactly as in the game, for example YourLord.
  3. Password: your Citavon password.
  4. Label, Notes and Start-up parameters are optional. Click Save.
  5. The Director starts a console for the lord and it logs in. Its status in the Fleet turns online.

Account email: leave it empty for your own lords. It's only for a lord a friend shared with you (Accounts tab, column Account email (shared lords)). Import fleet fills it in for you.

Add all your lords at once: Import fleet

  1. Click Import fleet.
  2. Enter your account email and your Citavon password, then Import.
  3. Every lord on the account is added. Lords already in the Director are skipped.
Your own lords come in switched ON and start logging in right away

They start one after another. If you're playing one of them by hand at that moment, you get logged out. Lords friends shared with you come in switched OFF, in the group Shared with me, and only run once you switch one on.

One login at a time

Never log the same lord in from two places

Citavon allows one login per lord. Two bots, or the bot and you in your browser, keep kicking each other out. Before you play a lord by hand, untick On for it in the Director. If you forget, the bot is kicked, waits 30 minutes (you can change this in Settings) so it doesn't kick you straight back, then logs in again.

Security code

If your lord has a security code, put it in the Accounts tab, column Security code. It's stored with the lord and only sent when the game asks for it. The bot never shows it or writes it to a log.

A typo in the lord name?

The console stops with "no lord of that name" (or "wrong password"). Click ✎ on the lord's row, fix it, and Save. It logs in again with the new details.

4The Director

Your whole fleet on one page. It starts, watches and restarts a console for every lord that's switched on.

Along the top

  • Add account and Import fleet: see Log in: add your lords.
  • The filter box narrows every tab to the lords you type.
  • ⋯ → Settings: the Citavon server, how often the engine runs, how long to wait after being kicked, and the Director password. Also Names sheet (Citavon's names next to the old server's, plus the goal codes) and the dark theme.

The Fleet tab, row by row

  • On: tick to run the lord, untick to switch it off (its console stops). Untick it before you play that lord by hand.
  • Keep on: the Director starts the console again whenever it goes down.
  • The lord's name: click it to open that lord's console in its own tab.
  • Console: start, stop or restart. A start or restart logs the lord in.
  • ✎: edit the lord (name, password, label, start-up parameters) or remove it.
  • Views above the table: All, Under attack, On holiday, High resources, Big armies, Errors, Switched off. Groups… and Columns… sort the fleet your way.

The tabs

Fleet

Every lord: status, cities, prestige, troops, resources. Switch lords on and off, open consoles.

Uptime

Each lord online / out / down / switched off, over 6 hours up to 30 days.

Log

What the Director itself did.

Alerts

Discord alerts: attacks, scouts coming, a city lost, a bot down for over an hour. Also Friendly fire: your own attacks heading for a city one of your lords holds, with Recall.

Resources

Every city's resources and troops.

Items

What every lord holds.

Accounts

Every field of every lord in one grid (password, security code, account email…), and the start-up parameters for the whole fleet.

Monitor

One lord reads the server's rankings every 30 minutes: every lord and alliance, a map of cities, who has stopped growing.

Scouting

All your scout reports in one place: what each place held, failed scouts, who scouted you.

Heroes

The server's hero ranking, and your own heroes.

Setup

Reach the bot from your other devices (Tailscale), and connect an AI assistant.

5The console

One lord's own page. Open it by clicking the lord's name in the Fleet.

Top bar

❚❚ pause / resume the goals, ⟳ read everything from the game again, ⚙ this lord's settings, 🌐 connect now. Packages, Reports, Mail and Quests counters (click Reports or Mail to read them).

City tabs

One per city. Pick a city first: goals, scripts, the gate and the monitors all follow the open city.

Editor

Three icons: 🎯 Goals, ✎ Script, and Engine view (what the bot decided for this city on its last pass).

Gate and War Town

Gate Control opens or closes the gate now. War Town Mode: nothing marches out of the city while it's on.

Monitors (right)

Resources, Inn, heroes, buildings, research, armies, incoming, troops, barracks, walls, valleys, reinforcements, map.

Logs and chat (bottom)

Log, City log, Engine, script Output, Reports, Items, Alliance, Statistics, Friends, Market. Alliance, World and Private chat.

Kicked because someone logged in elsewhere? A bar says so, with Take it back now to log straight back in.

In the chat box, a line starting with a backslash runs an in-line command instead of chatting. For example \who YourFriend. Nothing starting with \ is sent as chat.

6Reach it from your phone or another PC

Use Tailscale. It's free for personal use and encrypted, and nothing is opened to the internet. Your devices join a private network only you can reach.

  1. Install Tailscale on the computer running the bot and sign in: tailscale.com/download. On a Linux server:
    curl -fsSL https://tailscale.com/install.sh | sh
    sudo tailscale up
    then open the link it prints to sign in.
  2. Install Tailscale on your phone or other PC and sign in with the same account.
  3. In the Director, open the Setup tab. It finds Tailscale by itself and offers Use Tailscale.
  4. Choose a Director password (at least 8 characters) and click Use Tailscale. Windows may ask whether the program may use the network: allow it.
  5. Restart the Director. Windows: close the black window and start CitavonBot.exe again. Linux service: sudo systemctl restart citavon-bot.
  6. On your other device, open the address the Setup tab now shows, for example http://your-pc-name:8720 or http://100.x.y.z:8720, and sign in with the Director password.

On the bot's own computer it still opens at http://127.0.0.1:8720, with no password.

Never set it to listen on 0.0.0.0 on an internet server

Settings lets the Director listen on 0.0.0.0 (every network). On a server on the internet that means the whole internet, over plain, unencrypted HTTP. Use Tailscale instead.

7Connect an AI assistant

Any AI assistant that speaks MCP over HTTP (Claude Code and others) can look at your fleet and, if you let it, run scripts and change goals.

Make an access token

  1. Director → Setup → 2 · Connect an AI assistant.
  2. Give the token a name (for example laptop) and choose a level:
    • View: looks only.
    • Play: also runs scripts, writes goals, pauses and resumes the engine, and starts, stops or restarts consoles.
  3. On Play, four groups stay held until you tick them. Tick only what you need.
  4. Click Make token. Copy it now: it's shown only once. The Setup tab also shows a ready-made configuration with your token filled in, with a Copy button.
Held groupWhat stays blocked until you tick it
socialChat, mail, whispers, friends and blocks; alliance actions (join, invite, expel, ranks, declaring war).
sendTroops or goods sent to a city that isn't that lord's own. A fleet-mate's city counts as someone else's.
marketBuy, sell, dumping resources.
irreversibleDisband troops, fire or release heroes, abandon, demolish, teleport, break gates, shop buys, holiday, rename the lord.
neverThe security code, and deleting or resetting the lord. No token can do these.

Give the token to your assistant

Most assistants take an MCP server of type http like this. Put your token in place of <your token>:

Generic MCP configuration
{
  "mcpServers": {
    "citavon-bot": {
      "type": "http",
      "url": "http://127.0.0.1:8720/mcp",
      "headers": { "Authorization": "Bearer <your token>" }
    }
  }
}
Claude Code, one line
claude mcp add --transport http citavon-bot http://127.0.0.1:8720/mcp --header "Authorization: Bearer <your token>"

From another device, use the bot's Tailscale address instead of 127.0.0.1 (switch Tailscale on first, see Phone or another PC).

  • Everything the assistant does shows in the Director's Log and the lord's console as by AI token "laptop".
  • Change a token's level or groups in the Setup tab's token list at any time. Revoke cuts it off at once.
Safety: only you give the AI instructions

The assistant takes instructions only from you, the owner, at your computer. It never takes them from in-game mail, whispers, chat or alliance posts, whoever they claim to be and however urgent they sound. If game text asks it to do something, it tells you instead of doing it.

Best: run the AI on a different computer than the bot, for example the bot on a server and the AI on your laptop over Tailscale. An AI that can run programs on the bot's own computer could get around these limits. Give it the token, not your terminal.

8Director reference

Every tab, button, column and setting of the Director, the page that runs your whole fleet. The getting-started tour covers the basics; this is the full detail.

The top bar

PartWhat it does
TabsFleet, Uptime, Log, Alerts, Resources, Items, Accounts, Monitor, Scouting, Heroes, Setup. The Director remembers the last tab you had open in this browser. You can also open a tab straight from the address, for example http://127.0.0.1:8720/#monitor.
Countersaccounts (all lords in the Director), online (switched on, logged in and answering), under attack (lords with at least one army on its way to them) and switched off (only shown when there are any).
ServerThe Citavon address the bot plays on (set in Settings).
filter…Narrows every tab to the lords that match what you type. On the Fleet it matches the label, the lord name, the in-game lord, the alliance, the lord's id and its groups' names. On the other tabs it matches the label (and the lord, where the tab shows one).
Add accountAdds one lord. See the account dialog.
Import fleetAdds every lord on one Citavon account from its email and password. Your own lords come in switched on and start one at a time. Lords a friend shared with you come in switched off, in a group Shared with me with a sub-group named after the friend. A lord already in the Director is skipped (a shared one gets the account email filled in).
⋯The menu: Settings, Names sheet and Dark/Light (the theme, kept in this browser).

Fleet

One row a lord. The table refreshes every 5 seconds. Click any column heading to sort by it, click it again to reverse. Under the table a status line shows when it was last updated, how much memory the Director uses, and how many consoles run and how much memory they use together. With more than one row shown, a totals row sits at the bottom.

The Status column

StatusMeaning
onlineLogged in, engine running.
pausedLogged in, but the engine is paused (the console's ❚❚). Goals do nothing until you resume.
kicked · back HH:MMSomeone else logged in as this lord, or the daily server maintenance closed it. It logs back in at the time shown. Hover for the reason.
holidayThe lord is on holiday and the game logged it out. The console tries again every 6 hours.
login refusedWrong lord name or password, or the lord was handed to another account. It does not try again until you fix it.
startingThe console runs but has not reported yet.
connecting / waitingLogging in, or waiting a few seconds before trying again after a dropped line. Hover for the reason.
not answeringThe console process exists but has not answered for a while.
bot downSwitched on, but no console runs for it.
offSwitched off. No console runs it.

Every Fleet column

Three columns are always shown: the tick box, On and Account. The rest you choose with Columns…. A dash with a tooltip "not reported yet" means that lord's console started before the column existed: restart the console.

ColumnShown at firstWhat it shows
TickalwaysTicks the row for the group buttons. The box in the heading ticks every row shown.
OnalwaysTick to run the lord (its console starts and logs in). Untick to switch it off (its console logs out and stops).
Edit (✎)yesOpens the account dialog.
OrderyesThe lord's place in the list. The table sorts by it until you click another heading. Change it in the Accounts tab.
Keep onyesTicked (the default): if the console of a switched-on lord goes down, the Director starts it again within about 30 seconds, one lord at a time. Unticked: a console that stops stays down until you click start.
AccountalwaysThe lord's label. Click it to open its console in a browser tab of its own (clicking again brings that tab forward). Greyed out when no console runs.
StatusyesSee the table above.
GroupsnoThe groups the lord is in.
MemoryyesHow much memory its console uses.
LordyesThe lord's name in the game.
AllianceyesIts alliance.
Title, RanknoIts title and its prestige ranking.
CitiesyesHow many cities it has.
Prestige, HonoryesAs the game shows them.
IncomingyesHow many enemy attacks are on their way to its cities, in red. Only what the cities' Beacon Towers see is counted.
TroopsyesEvery troop it owns, at home and marching.
Worker … CatapultnoOne column a troop type (home and marching), in the Troops section of the Columns dialog.
HeroesyesIts own heroes (prisoners not counted).
PrisonersyesOther lords' heroes it holds. They take room in the hall. Hover for who and where.
Empty / full citiesyes"N empty": cities with no hero at all. "N full": cities whose hall has no room for another hero (for example the training hero). Hover for the city names.
Idle popyesIdle population across its cities. "· N high" (amber) counts cities whose population is full and more than 5% of it idle, which usually means the barracks are not training. Hover for the detail.
PopulationyesPopulation across its cities (hover for the maximum).
MarchingyesTroops out on marches.
ResourcesnoFood, wood, stone and iron added up (gold not counted).
Food, Wood, Stone, Iron, GoldyesEach resource across its cities, run on at the cities' hourly rates since the last reading.
Wayfarer's Map, Surveyor's Map, Siege Map, Seeking StoneyesHow many it holds.
Recruiter's Sigil, Grand Strategy, Warlord's Standard, Swift BootsnoHow many it holds.
CoinsyesIts coins.
ScriptsyesHow many scripts are running in its cities right now.
ProtectednoWhen its beginner protection ends (empty once it has).
Start-upnoThe lord's own start-up parameters.
NotesnoYour notes for the lord.
UpyesHow long its console has been running.
ConsoleyesFor a switched-on lord: restart and stop when a console runs, start when none does. A start or restart logs the lord in afresh.
Stop is not "switch off"

stop ends the console, but if Keep on is ticked the Director starts it again within about 30 seconds. To keep a lord out of the game (for example while you play it by hand), untick On.

Views

The row of views above the table picks which lords are listed. The filter box works on top of the view.

ViewLists the lords that…
Allevery lord.
Under attackhave at least one army on its way to them.
On holidayare on holiday.
High resourceshold 100m or more of food, wood, stone and iron together.
Big armiesown 100k or more troops (home and marching).
Errorsare switched on but have no console, are not answering, or are kicked, refused or waiting to log in.
Switched offare switched off.

Groups

A group is only a label on the Fleet page. Nothing about groups touches a lord or its console. A lord can be in as many groups as you like, and groups can sit inside other groups to any depth. Groups are kept by the Director, so every browser sees the same ones.

grouped (ticked by default): the table is shown in sections, one a group, each with a coloured heading: its tick box, its name, how many bots, how many online and how many under attack. Click a heading to fold it away (remembered in this browser). Lords in no group come last, under Unlabelled. When a view or the filter empties a group, its heading is hidden too.

Groups… opens the groups window:

  • Each group has a colour box, its name (press Enter or leave the box to save), where it sits (top level or inside another group), how many lords are in it and its sub-groups, ↑ ↓ to move it among its neighbours, and ✕ to delete it.
  • Deleting a group never deletes a lord. Its sub-groups move up one level.
  • At the bottom, type a name, pick where it sits and click Add group. Two groups side by side can't share a name. Names are up to 60 characters.

To put lords in groups, tick their rows. A bar appears: "N ticked", a group list, and

ButtonDoes
Add toPuts them in that group too. They stay in their other groups.
Move toPuts them in that group and takes them out of every other group.
Remove fromTakes them out of that group only.
UngroupTakes them out of every group.
ClearUnticks them.

In grouped mode you can also drag rows onto a group heading. Dragging moves them out of the group they came from into the new one. Hold Ctrl while dropping to keep them in the old group as well. Dropping on Unlabelled takes them out of the group they came from. If the row you drag is ticked, every ticked row goes with it.

Columns…

Tick the columns you want. Drag a row in the list (or a heading in the table itself) to move that column. The Resources, Troops and Items columns sit in folding sections, each with a box that ticks or unticks the whole section and a count of how many are shown. All shows every column. Defaults goes back to the columns and order you started with. Your choice is kept in this browser only.

The account dialog (Add account and ✎)

FieldWhat to put
Lord nameThe lord's name exactly as in the game. This is its login.
PasswordYour Citavon password. When editing, leave it empty to keep the one stored.
LabelHow the fleet lists it. Empty: the lord name.
NotesAnything you like. Shown in the Notes column.
Start-up parametersThis lord's own, on top of the fleet's. See Start-up parameters & files. A mistake is refused with the reason.

When editing, Remove takes the lord out of the Director: its console stops, and its goals, script loadouts and last snapshot are deleted from the bot. The lord in the game is not touched. The security code and the account email are not in this dialog: set them in the Accounts grid.

A changed password, lord name or account email on a switched-on lord makes its console log in again straight away.

Uptime

One band a lord, coloured by what it was doing over the range you pick: 6 h, 24 h (the default), 3 days, 7 days or 30 days. Hover a stretch of the band for its state, the reason, and when it started and ended.

ColourState
onlineLogged in.
outThe console runs but is not logged in: kicked, on holiday, maintenance, or waiting to try again.
downSwitched on, but no console runs, or it does not answer.
offSwitched off.
stripedThe Director itself was not running, so nobody was watching. Recorded when the Director was down for over 2 minutes.

The percentage beside each name is the share of the time the lord was switched on that it was logged in (switched-off and unwatched stretches don't count). Hover it to see how many times it dropped. History is kept for 31 days.

Log

What the Director itself did, newest first: consoles started, stopped and restarted, lords added, switched on or off, settings saved, alerts saved, sign-ins from other devices (and refused ones), Monitor scans, friendly-fire recalls, AI token changes. It shows the last 300 lines. The Log tab is kept in memory only: it starts empty each time the Director starts. The same lines go to the Director's own window (on a Linux service, its journal).

Alerts

The Director can post news about your fleet to Discord, through one or more Discord webhooks ("channels"). Each channel picks the kinds of news it wants, and can ping someone when the news is urgent.

Setting up a Discord channel, step by step

  1. In Discord, on a server where you can manage the channel, open the channel's settings (the gear beside its name) → Integrations → Webhooks → New Webhook. Name it if you like, then Copy Webhook URL.
  2. In the Director, open Alerts and click Add channel. A new card appears, switched on, with attacks, city lost, bot down / back and scouts coming ticked.
  3. Give the channel a name, and paste the webhook URL into the long box. It must look like https://discord.com/api/webhooks/<numbers>/<letters>. Anything else is refused when you save.
  4. Optional: in ping (urgent), put who to ping on urgent news: @here, @everyone, a role as <@&role id> or a person as <@user id>. To get an id, switch on Discord's Developer Mode (User Settings → Advanced), then right-click the role or person → Copy ID.
  5. Tick the kinds of news this channel wants (see the table below).
  6. Click Save. Nothing on this tab is kept until you do.
  7. Click Test on the card. A test message should appear in Discord within seconds. Under the cards the tab says "test sent", or what Discord answered.

After saving, the URL box shows only the last few characters ("discord webhook …abc123"): the URL is a secret and is never shown again. Leave the box empty to keep it, or paste a new one to replace it. Untick on to silence a channel without losing it. Remove drops the card; it is gone once you Save.

You can make several channels, for example one for urgent news with a ping and one for everything else.

The settings above the channels

SettingDefaultWhat it does
bot down alert after … min60 (at least 5)How long a switched-on lord must be not logged in before bot down is sent.
ignore our own armiesonAn attack or scout by one of your own lords on another of your lords (a test hit, one lord feeding another) is not news. Only works when the target city's Beacon Tower shows the attacker's name.
never alert aboutemptyLabels or ids (from the Accounts grid's Id column), separated by commas. These lords never cause an attack, wave landed, city lost, scouts coming, bot down or back alert. The other kinds still come.

Every alert kind

Urgent kinds put the ping in front of the message. Messages wait in a queue and go out every few seconds, several lines to one Discord message. If Discord is busy or does not answer, they are tried again. If Discord refuses for good (a deleted webhook), they are dropped. When the Director starts it first learns what is already going on and sends nothing about it: only what changes after that is news.

Tick boxUrgentWhen it is sent
attacksyesAn enemy attack sets off for one of your cities, once an army. It says which city, who (when the city's Beacon Tower shows the lord, level 4 and up), how many troops (when the tower shows them; "up to" when it only shows words), when it lands, and the city's loyalty. A city with no Beacon Tower is told nothing, so no alert comes. Checked every 10 seconds; the consoles report every 30 seconds, so it can come up to about half a minute after the attack sets off.
a wave landednoAn attack you were told about has landed, with the city's loyalty after it. An attack that turned back is not news.
city lostyesA city is gone from a lord that is logged in. If another of your lords now holds it, it is not sent. A city you gave up yourself is reported as lost too.
scouts comingnoMeant for enemy scouts on their way. Citavon does not tell a city about scouts on their way, so this alert has nothing to send. See the Scouting tab's We were scouted for scouts after they arrive.
bot down / backyes (down)A switched-on lord has not been logged in for the minutes set above (kicked, refused, console down, on holiday…), with the reason. back follows when it logs in again, with how long it was gone. When more than 10 go down (or come back) at once, one line names a few and gives the count.
our scouts failednoOne of your scout reports came back with nothing, and why (for example their scouts stopped yours at an open gate). Found by the Scouting sweep, every 5 minutes.
friendly fireyesOne of your attacks is on its way to a city one of your own lords holds. See Friendly fire.
revolt (no gold for heroes)noA city has no gold for its heroes' salaries (their loyalty falls), or heroes ran off because of it. Sent again when another hero runs.
riotnoA city rioted and what it lost, or a blessing spared it from rioting.
troops deserted (no food)noTroops left a city for want of food, and how many.
transport ambushednoBarbarians took part of a transport going to a far bigger lord, and what they took.
war: we were attacked / scoutednoA new line in your alliance's War Reports where a member was attacked or scouted, with both sides and the result.
war: our attacks and scoutsnoA new line in your alliance's War Reports where a member attacked or scouted someone.

Revolt, riot, deserted and ambushed come from your lords' reports, and the war kinds from the alliance War Reports. Both are read every 5 minutes. The first read after the Director starts only notes where the lists are up to, so old reports never all alert at once. Reading them does not mark them read in the game.

Sent at the bottom of the tab lists the last 60 messages, newest first. A failed one starts with ✗ and says what Discord answered. The line at the top says how many channels are live and how many messages are waiting.

Friendly fire

When one of your lords captures a city, other lords of yours may still have attacks in the air at it. The game stops a lord attacking its own city, but not another of your lords' cities. Every 30 seconds the Director checks every attack of yours on its way against every city your fleet holds.

PartWhat it does
The tableEach such attack: the lord sending it, the city it left from, the target, whose city it is, troops, hero and how long until it lands.
RecallRecalls that one attack.
Recall allRecalls every attack on the list (after you confirm).
on purposeKeeps that target out of the alerts and the automatic recall for 24 hours (you meant it, for example to drop the city's loyalty so another lord can take it). watch again undoes it.
recall them by themselvesOff by default. On: each new friendly attack is recalled as soon as it is found.

Each new friendly attack is sent once to the channels with friendly fire ticked.

Resources

One row a lord: its number of cities, food, wood, stone, iron, gold and troops, and how long ago its console reported. Figures are what each console last saw, run on at the cities' hourly rates. A lord whose console is down still shows its last report.

  • every city: adds a line for each city under its lord, with its coordinates and loyalty.
  • troops by type: adds a column for each troop type.
  • Click a heading to sort. A totals row sits at the bottom.

Items

A grid of what every lord holds: one row a lord, one column an item (Citavon's names; hover a heading for the item's code). A dot means none. Totals at the bottom.

  • The kind list narrows it to one kind of item (chests, speed-ups, medals…).
  • The name box finds items by name or code.
  • items nobody holds adds a column for every item in the game, held or not.
  • Click a heading to sort the lords by how many of that item they hold.

Accounts

Two parts. At the top, Start-up parameters for every account: a box for the fleet's start-up parameters and a Save button. They reach each console at its next start. The line beside Save says whether they were kept, and notes anything unusual. A refused parameter is not kept. See Start-up parameters & files.

Below, every field of every lord in one grid, sorted by Order. Each field saves as soon as you leave it: a green outline means saved, a red one means refused (hover it for why).

ColumnWhat it holds
IdThe bot's own id for the lord (g1, g2…). It names the lord's log file, and the Alerts tab accepts it. Can't be changed.
LabelHow the fleet lists it. Empty: the lord name.
Lord name (login)The lord's name in the game.
PasswordNever shown. Type a new one to change it; empty keeps the old one.
Security codeThe lord's security code, if it has one. Sent only when the game asks for it, never shown, never logged. The box says "stored — unchanged" or "none".
Account email (shared lords)Leave empty for your own lords. For a lord a friend shared with you, the email of the account that has access: the lord then logs in through that account. Import fleet fills it in.
On, Keep onAs on the Fleet.
OrderA number: the Fleet lists lords from low to high.
NotesYour notes.
Start-up parametersThis lord's own, over the fleet's.
GroupsIts groups (change them on the Fleet).

A new password, lord name or account email makes a running console log in again.

An empty box keeps the old value

Leaving the Password or Security code box empty never clears what is stored. To remove a security code you no longer have, type a single space and leave the box.

Monitor

One of your lords reads the server's rankings on a timer: every lord, the alliances, the hero ranking and every city. Each scan is kept for 31 days, so the Monitor can show who has grown and who has stopped moving.

ControlDefaultWhat it does
scan the serveronUntick to stop the timed scans.
every … min30 (at least 10)How long between scans.
reading withany account that is onlineWhich lord's console reads the rankings. If the one you pick is not online, the first online lord is used.
Scan nowScans at once.

The cards: Lords (and how many are yours), Alliances (and the top one), Cities on the map, Not moved 24 h+ (lords whose prestige has not changed for a day) and Scans kept.

Lords table: Lord (yours tagged ours), Alliance, Title, Prestige, Change (prestige gained or lost over the range you pick: 6 h, 24 h, 3 days or 7 days), Honor, Cities (with the change in brackets), People and Not moved for (how long since its prestige last changed; a + means it has not changed in any scan kept). Find a lord or alliance with the box, and set not moved for at least … h to list only the still ones. Up to 1,000 rows are shown. Click headings to sort.

Map: every city as a dot, coloured by the nine biggest alliances (grey for the rest), yours ringed in blue. Hover it for the cities under the pointer. Alliances: members, prestige and honor.

Scouting

Every 5 minutes the Director reads the latest 100 reports of each online lord and keeps the scouting ones for 31 days. It opens them with a peek, so they stay unread in the game. Read reports now does it at once. Pick the last day, 7 days or 30 days, and search by lord, city or x,y.

  • What our scouts saw: the newest report of each place your scouts reached: the place, the lord and city (or the valley or NPC and its level, and who holds it), when, which of your lords scouted it, troops (and other lords' troops stationed there), fortifications, resources and loyalty. A words tag means your Informatics was below their Beacon Tower (or the NPC's level), so the report gives words like Few or Lots instead of numbers.
  • Failed scouts: when, which lord, where, and why.
  • We were scouted: when, which of your lords and city, who scouted (lord and alliance), from where, and whether your scouts stopped them or they got through.

Heroes

  • The server's heroes: the game's hero ranking, read by the Monitor's scan (so it needs the Monitor on): place, hero, lord, level, attack, politics, intelligence. Yours are tagged ours; tick ours only to list just those.
  • Ours: every hero of every lord, from the consoles' reports: lord, city, hero, level, attack, politics, intelligence and status.

Search by hero or lord. Click headings to sort.

Setup

Two boxes: 1 · Reach it from your other devices (Tailscale) and 2 · Connect an AI assistant (access tokens). Both are explained step by step in Reach it from your phone or another PC and Connect an AI assistant.

The first box also tells you what the Director listens on right now. "Saved: it listens on … once the Director starts again" means a change is waiting for a restart. A red line warns you when it listens on every network.

The Settings dialog

⋯ → Settings.

FieldDefaultWhat it does
Citavon serverhttps://citavon.comThe game's address. Each console uses a new address the next time it connects: restart them in the Fleet. Import fleet uses it at once.
Engine pass every (seconds)15 (at least 5)How often each console's engine goes over every city's goals. Used by the consoles straight away, with no restart.
After being kicked, wait (minutes)30 (at least 1)When another login kicks a lord out (you playing it by hand, for example), its console waits this long before logging back in, so it does not kick you straight back. A lord's own setting in its console's ⚙ wins over this one.
Listen on127.0.0.1Which address the Director answers on. 127.0.0.1: this computer only. A Tailscale address: your Tailscale devices too (the Setup tab fills it in for you). 0.0.0.0: every network. It always answers on 127.0.0.1 as well. Takes effect when the Director starts again.
Director passwordnoneThe password other devices must sign in with. The box shows "set" or "none set"; leave it empty to keep the one you have. Setting a new one signs out every other device.

From another device every page asks for the Director password. A sign-in lasts 30 days, but only until the Director restarts: after a restart, sign in again. Consoles open through the Director there, since they only answer on the bot's own computer.

0.0.0.0 on an internet server

On a server with a public address, 0.0.0.0 opens the Director to the whole internet over plain, unencrypted HTTP, behind nothing but the Director password. Use Tailscale instead.

The Names sheet

⋯ → Names sheet opens a page of its own with five lists: Items, Buildings, Troops, Fortifications and Research. Each row gives Citavon's name, the game's internal key, the short code you can use in goal and script lines (for buildings, troops, fortifications and research), and what the thing was called on the old server, or "the same". The search box finds any name or code. The bot shows Citavon's names everywhere else; this sheet is the one place to look up an old name or a goal code.

9Console reference

Every part of a lord's console page: the top bar, city tabs, the editor, the gate and war town controls, the fourteen monitors, the bottom tabs, the chat and the lord's own settings.

The top bar

PartWhat it does
❚❚ PausePauses the engine: goals stop acting until you press it again. Scripts are not affected. The pause is remembered across console restarts. The badge beside the connection light says LIVE or PAUSED.
⟳ RefreshReads everything from the game again. (The console also does this by itself every 5 minutes.)
⚙ SettingsThis lord's own settings. See below.
🌐 ConnectLogs in again now. It also ends any wait: after a kick, after a script's logout, or after "logged out for good". It reads the lord's password again first, so use it after fixing the password in the Director.
Connection lightGreen and "connected" when logged in; otherwise the state and its reason (connecting, waiting, kicked…).
Server, LordThe game address and the lord's name.
PackagesToday's free gift (if not taken yet) plus every chest, pack, charm, token, hoard, lockbox, hero box and muster the lord holds but has not opened. Hover for the list. Click: if today's gift is waiting it offers to claim it, then it opens the Items tab.
Reports, MailUnread counts. Click to open the reports and mail window.
QuestsQuests ready to claim.
Coins, Prestige, Honor, RankAs in the game.
Server TimeThe game's clock (UTC), ticking.
🌙Dark or light console, kept in this browser.

The kicked bar

A bar under the top bar appears while the lord is not logged in for a reason that needs a wait or a fix:

  • Another login took this account — the bot logs back in at HH:MM. Someone logged in as this lord (or the daily maintenance closed it, which shows the same words). The console waits the kick time, then logs back in.
  • The account is on holiday: the game logged it out. It tries again every 6 hours.
  • Login refused: … Fix the password in the Director. A wrong name or password, or a lord handed to another account or no longer shared with you. It does not try again by itself.

Take it back now logs straight back in, which kicks whoever is in. Same as 🌐.

City tabs

One tab a city: the first three letters of its name and its coordinates, as Cap(120,340). Pick a city first: the editor, the gate, War Town Mode, the monitors, the City log and the script Output all follow the open city.

  • Red: armies are on their way to it.
  • Amber: its food runs out within a day.
  • A * after the name: War Town Mode is set by hand for it.
  • Hover a tab for its name, armies coming, when food runs out, the gate, the builder, and whether a script is running.

If the editor has unsaved changes, switching city asks first.

The editor

Three icons above the editor pick what it shows.

IconWhat you editButtons
🎯 GoalsThe selector under the editor picks the text: This city; Prepend (every city, run first); Append (every city, run last); New-city template (the goals a city you gain gets, if it has none of its own); New-city script (a script run in a city you gain, a few seconds after you get it); Goal set 1–9 (what loadgoals loads).Save keeps the text and the engine picks it up on its next pass. Apply saves and runs the goals pass now (if the engine is paused, it runs when you resume).
✎ ScriptThe city's ten script loadouts, Load 1–Load 10.Save, Run (in the open city), Stop (while one runs), Quick…, the line box, dry run.
🐞 Engine viewRead only: what the engine made of this city on its last pass, the time of that pass, its notes, any goal errors, and goals a script added or loaded for the city.none

Ctrl+S saves. Saving with mistakes still saves, and the line under the editor lists them.

The colours: blue lines act, red lines are mistakes or lines the bot doesn't act on, grey lines are comments. Put the cursor on a line and the line under the editor says why it is red (or what a blue line does). With the cursor on a blank or comment line it shows "N working · M red".

The Script tab's run bar

ControlWhat it does
RunRuns the editor's text (saved or not) in the open city. A city runs one script at a time. The Output tab opens.
line boxStart from this line number or label instead of the top. Empty: the top.
dry runNothing is sent to the game: each line says what it would have done.
StopEnds the city's running script.
Quick…One-click scripts from quick-scripts.txt in your scripts folder, and Restart autorun. Hidden when the list is empty. See quick-scripts.txt.
Running a script by hand ends autorun

A city runs one script at a time, so a script you run by hand ends that city's autorun. Quick… → Restart autorun (offered whenever a loadout holds label autorun) starts it again in every city with no script running, without restarting the console.

Gate Control and War Town Mode

Gate Control: Open and Closed open or close the open city's gate in the game at once. Beside them the console shows the gate's state now.

War Town Mode sets one city's war town mode by hand, over the goals' config wartown line:

ChoiceEffect
AutoThe city follows its goals (the default).
OffNo war town, whatever the goals say.
On — hero may moveNothing marches out of the city: no NPC run, no resource transfer leaves it, and its marching armies are recalled once, on the engine's next pass. It still receives. The training hero may still come and go.
On — hero staysThe same, and the training hero stays where it is.

Turning it on asks you to confirm. The choice is kept by the bot for that city until you change it. A city set by hand shows a * on its tab.

The monitors (right)

Fourteen icons above the right-hand panel pick a monitor. They all show the open city (some also every city). The caption names the monitor and the city. Hover a row in most tables for a card with the full detail. The Incoming icon turns red while armies are on their way to any of your cities.

MonitorWhat it shows
GeneralThe city at a glance: name and place; status (incoming armies, beginner protection, truce, holiday); gate; whether alliance troops may stay; population and idle; loyalty and grievance; tax rate; gold an hour after hero salaries; troop upkeep in food; heroes against hall room; what is being built and researched, with countdowns; wall space used; garrisons against room; and the lord's alliance, title, prestige, honor, ranking and beginner protection.
ResourcesEach resource: amount; Incoming (market deliveries, transports and marches coming home with loot; hover for each); Needed (what the current troop and fortification goal stages still cost); net an hour; production (the field's labour %, or the tax rate for gold); storage; and when it runs out or fills up (red when under a day). A population line, then the Town Hall's labour table: each field's labour % and output an hour. Hovering a resource also shows the market's best prices and what your stock is worth.
InnHeroes for hire in the city's Inn: level, politics, attack, intelligence and fee, each with a hire button; Refresh the Inn above.
HeroesThe city's heroes: status (mayor in bold), type (by best stat), level, politics, attack, intelligence (a buffed stat in bold with its %), loyalty, experience to the next level. An idle hero has a mayor button; unspent points show as a chip.
BuildingsWhat the builder is doing now (with Finish free when 5 minutes or less are left), what waits in line, what the engine plans next (or why it waits), free plots inside and outside, then each kind of building: how many and their levels.
ResearchWhat is being studied (with Finish free when it can be), then every study: what it does, where it is being studied, and its level out of the top. Yellow: being studied. Green: at the top.
ArmiesThe Rally Spot's march slots in use and the most troops a march may take, then the city's marches and every city's marches: mission, direction, troops and cargo, hero, target, distance, when it lands or comes home (on your PC's clock), a countdown with a progress bar, and Recall or Home. Red: attacks and scouts going out. Green: reinforcements and transports. Blue: coming home. Amber: waiting at home or stationed.
IncomingEvery enemy attack on its way to any of your cities, first to land on top: lord, mission, which city, when it lands, countdown, what is seen, and the Beacon Tower level that saw it. A bold city is the one you have open. How much you see depends on the target city's Beacon Tower: from level 2 the mission, 3 the landing time, 4 the lord and alliance, 5 where it left from, 6 the troop types, 7 their numbers in words, 8 exact numbers, 9 the hero's level.
TroopsEach troop type: total (home, training and out), in the city, in the queue, the troop goal, how many short, % short, inward (coming home or your reinforcements arriving), outward (out on marches or stationed with allies), wounded. Red rows are short of the goal, green ones met. A note says which troop goal stage the city is on. Hover a row for the troop's stats and what the city's own add up to.
Barracks queuesOne row a barracks: its level, queue slots used, then each batch in order (troop code and count, the first with its countdown) with a ✖ that cancels it (half its cost comes back). Idle barracks are yellow. The script command canceltroopqueues clears them all.
FortificationsEach fortification: on the walls, in the queue, the goal and how many short; the free and total wall space; then the queue with countdowns. It warns when there are no Walls yet or the walls are full.
Valleys and flatsThe valleys and flats this city holds, then every city's: tile, kind, level, city, held since, and abandon (asks first).
ReinforcementsWhether allied troops may stay in the city (and how many the Embassy takes), with a button to let them in or keep them out; troops stationed here (lord, troops, hero, send home); your own troops stationed elsewhere (home).
MapThe world around the city. See the map.

The map

  • x, y, radius (1 to 40, default 12) and Show go to a place and read it again. Reset goes back to the open city. The arrows move half a radius. Full screen enlarges it (Esc to leave).
  • Drag the map to move it, or click it and use the arrow keys (Shift: 10 tiles).
  • The filter chips (all, city, npc, flat, lake, forest, hill, swamp, grassland, desert) and min lvl dim everything else. The list beside the map then shows the matches, nearest first; without a filter it lists the cities in view.
  • Colours: yellow your cities, green your alliance, light blue allied alliances, red enemy alliances, gold neutral alliances, brown no alliance, white valleys, pink flats, greys the NPCs. The legend under the map names each.
  • The find box (press Enter) searches lords, cities and alliances, but only in the parts of the map read so far. Click coordinates to go there.
  • The world wraps at its edges (a dashed line). Solid blue lines are state borders, and the states in view are named under the map.
  • The map is read in blocks, nearest the centre first, and kept for 3 minutes before it is read again.

The bottom tabs

A search box on the right filters the lines of the log tabs, and the count beside it says how many there are.

TabWhat it shows
LogWhat the bot did, in every city: logins, kicks, goals acting, scripts starting and ending, autorun, settings saved.
City logThe same, plus the engine's notes, for the open city only.
EngineThe engine's thinking: one line a city each time its plan changes.
OutputThe open city's script output, from the last run (up to 1,000 lines).
ReportsThe 50 newest reports. Unread ones are highlighted. Click one to read it in the reports window.
DebugEverything, including the connection's own messages.
ItemsFour views: Items (what the lord holds, with an Apply button), Medals, Buffs (what is running, where, time left) and Shop (price, how many you hold, Buy). See below.
AllianceThe alliance window. See below.
StatisticsThe rankings: by prestige, honor, title, population, cities, heroes, or cities by size. Says your place. Page with < >; type a lord in "find a lord" and press Enter to jump to its page. Page 1 also lists the alliances.
FriendsYour friends and your blocked lords (with online, alliance, title, prestige and remove). Type a name to Add friend or Block.
MarketThe market from the open city. See below.

The console keeps the last 3,000 log lines while it runs. They are gone when it restarts. The lord's log file keeps the Log and Debug lines (not the Engine lines).

Items, Medals, Buffs, Shop

  • Apply asks for what the item needs (which hero, which plot, a flag text, a new name, a lord, a place x,y, an hour, a state), asks you to confirm, and uses it in the open city. Then it says what it gave.
  • Some items have a greyed Apply. Click it to see how that item is used instead (keys open chests when you apply the chest; a Warlord's Standard goes with a march; speed-ups go on a job; and so on).
  • A season token asks whether to trade for its season's chest or key, while the season runs.
  • Buy in the Shop asks how many, shows the coin total and asks you to confirm.

Alliance

Without an alliance: found one (needs an Embassy), accept or decline invitations, and apply to any alliance in the list. In an alliance: its name, founder, your rank, members out of the limit, the notice and note; Invite (host, vice host and officers); Leave the alliance; applications to accept or decline; the members (officers can expel); diplomacy; the War Reports (10 a page, each with a report button that shows who won, each side's troops and the loot); and the list of alliances.

Market

An order form (buy or sell, resource, amount such as 10k or 1.5m, price, Place, asks to confirm), placed from the open city. The fee is 0.5% in gold and is not given back on cancel. Below: the four books (offers above, bids below, the reference price and the day's average), your open orders with cancel, and what you bought that is on its way.

The reports and mail window

Opened from the Reports or Mail counter. Tabs: Inbox, Sent, System, Reports. Tick items (or all) to Mark read or Delete; reports also have All read and Delete all; mail has pages. Click an item to read it. A report shows its body as tables, anything found in the battle at the top, and the raw data under raw. A mail has Reply and Delete. Write mail opens a form: To, Subject, text (up to 2,000 characters), Clear, Send.

The chat

  • Three tabs: Alliance Chat, World Chat, Private Chat. The last 200 lines, refreshed every few seconds.
  • Whisper from any tab with /name your words, or /'name with spaces' your words. Click a name in the chat to whisper to it. A plain line in Private goes to the last lord you whispered with.
  • A line starting with a backslash runs an in-line command in the open city, for example \who YourFriend (see \who). Its output appears under the chat. Nothing starting with \ is ever sent as chat.

The lord's own settings (⚙)

FieldWhat it does
After being kicked, wait (minutes)This lord's own kick wait. Empty: the Director's setting (shown in the box). At least 1. Used from the next kick.
Start-up parametersThis lord's own, over the fleet's. The dialog shows the fleet's and the ones this console is running now (the ones it started with). Changes apply from the console's next start: restart it in the Director.

Layout and sounds

Drag the bars between the panels to resize them; the sizes, the monitor you picked and the open city are kept in this browser. A script's play command plays its sound in every open console page of that lord.

10Start-up parameters & files

Start-up parameters change how a lord's console starts. Environment variables change where and how the whole program runs. And here is where everything is kept, and how to back it up or move it.

Where start-up parameters go

  • Every lord: Director → Accounts → Start-up parameters for every account, then Save.
  • One lord: the Accounts grid's Start-up parameters column, the ✎ dialog, or the console's ⚙.

A lord's own parameters win over the fleet's, name by name. A console reads them once, when it starts: after saving, restart the lord's console in the Fleet. A parameter that is refused is not saved, and the reason is shown.

How to write them

  • Each starts with - or /, then the value after a space, = or :. These are all the same: -autoscripts 1, -autoscripts=1, /autoscripts:1.
  • Several may share a line. A value with spaces goes in "quotes".
  • A line starting with # or // is a comment.
  • Names don't care about case. Switches take 1, yes, on, true for on and 0, no, off, false for off.
  • At most 4,000 characters.
A fleet's start-up parameters
# every lord runs its autorun scripts after logging in
-autoscripts 1 -runscript "morning chores.txt"
-maxtrade 5000000

-autoscriptsConfig

Usage
-autoscripts <1|0>
Example
-autoscripts 1
Values
1 (or yes, on, true): autorun on. 0 (or no, off, false): off. Anything else is refused.
Default
Off.
See also
-runscript, AutoRunScript.txt

Switches on autorun: scripts that start by themselves. After the console's first login (never after a reconnect), every city runs, one after the other:

  1. the start-up file: the -runscript file if you set one, otherwise AutoRunScript.txt from your scripts folder if it is there;
  2. then each of the city's loadouts that holds the line label autorun, Load 1 first, each from that label down.

The cities run side by side. When one script ends, that city's next one starts. If you stop one, the rest of that city's autorun does not start. A city where a script is already running is skipped.

To stop a crash loop from sending the same orders again and again, autorun starts at most once every 10 minutes for a lord. A console that restarts sooner logs "not started — it already started N minute(s) ago" and skips it.

With autorun off, the Log says so once after logging in. With it on but nothing to run, the Log says that too.

-runscriptConfig

Usage
-runscript <file>
Example
-runscript "morning chores.txt"
Values
A file name inside your scripts folder. A name that points outside the folder is refused.
Default
AutoRunScript.txt
See also
-autoscripts

The file every city runs first when autorun starts. It only matters with -autoscripts 1. If the file you name is not there, the Log says so and the cities go on to their label autorun loadouts. If you don't set it and there is no AutoRunScript.txt, nothing is said: only the loadouts run.

-autorunConfig

Usage
-autorun <0|1>
Example
-autorun 0
Values
0 (or no, off, false): the engine starts paused. 1 (or yes, on, true): no effect. Anything else is refused.
Default
Not set: the engine starts the way you left it.

Controls the goals, not the scripts. With -autorun 0 the console starts with its engine paused, so no goal acts until you press ❚❚ in the console to resume. Scripts and autorun still run.

Without it (or with 1), the engine starts as it was: a lord you paused stays paused after a restart, a running one runs. -autorun 1 does not resume a paused lord.

-maxtradeConfig

Usage
-maxtrade <amount>
Example
-maxtrade 5000000
Values
A whole number, at least 1, written out in full (no k or m).
Default
Not set: the bot puts no cap on an order.
See also
buy, sell

The most one market order placed by a script's buy or sell (or the same typed as an in-line command) may be for. A bigger order is not sent: the script's Output says "not sent — more than one order may be for (-maxtrade …)" and the script carries on. A guard against a typo selling your whole stock. Orders from the trade goals and the console's Market tab are not checked.

-teleportConfig

Usage
-teleport <state | random>
Example
-teleport random
Values
One of the map's states by name (in quotes if it has a space), or random.
Default
Not set.
See also
autoteleport

The state autoteleport moves cities to when the script line names none. Scripts can also read it as Config.teleport. A name that is not a state is only noticed when autoteleport runs, which then refuses with the list of states.

-autologinConfig

Usage
-autologin <value>
Default
Not set.

Accepted and kept, but does nothing: a console always logs in. To keep a lord out of the game, switch it off in the Director (untick On).

-titleConfig

Usage
-title <text>
Default
Not set.

Accepted and kept, but does nothing: a console's browser tab is always named after the lord's label. Change the label in the Accounts grid instead.

-usernameConfig

Usage
-username <name>, also -u

Refused. The lord logs in with its own Lord name from the Director. Change that in the Accounts grid or the ✎ dialog.

-passwordConfig

Usage
-password <password>

Refused. The lord's stored password is used. A password in a start-up parameter would be visible to anyone on the computer who looks at running programs.

-serverConfig

Usage
-server <address>, also -s

Refused. The game's address is set once for the whole fleet in the Director's Settings.

-proxyConfig

Usage
-proxy <address>

Refused. Citavon Bot always connects straight to the game.

-prependgoalsConfig

Usage
-prependgoals <file>

Refused. Write the goals into the lord's Prepend text in its console (Goals → the selector → Prepend): they run before every city's own goals.

-appendgoalsConfig

Usage
-appendgoals <file>

Refused. Use the lord's Append text in its console: it runs after every city's own goals.

Any other name

Any other -name value is kept, with a note that it is not one of the bot's own. Scripts read it as Config.name (in lower case), so you can give each lord its own values for a shared script:

Start-up parameters of one lord
-home "120,340" -role farmer
In a script
echo "I am a " + Config.role + ", home is " + Config.home

Config.server always holds the game's address.

Program options

Options for the program itself (CitavonBot.exe or citavon-bot), typed after its name in a terminal.

OptionWhat it does
--no-windowStarts the Director without opening its window. For servers, or if you prefer your own browser: open http://127.0.0.1:8720.
--versionPrints the version and stops.
--consoleUsed by the Director to start each lord's console. Don't use it yourself.

Starting the program while a Director already runs only opens the window (or, with --no-window, does nothing) and says "Citavon Bot is already running".

Environment variables

Set these before the program starts. On Windows, in a Command Prompt in the program's folder: set NAME=value, then CitavonBot.exe in the same window. On Linux: NAME=value ./citavon-bot --no-window, or an Environment=NAME=value line in the service file. The consoles inherit the Director's environment when the Director starts them; a console already running keeps what it started with until it is restarted.

VariableDefaultWhat it does
GERMBOT_HOMEWindows %APPDATA%\CitavonBot; Linux ~/.local/share/citavon-botYour files folder: data, logs, scripts. Use it to keep the bot's files somewhere else, or to run two separate bots on one computer (each with its own folder and port).
GERMBOT_DATAdata in your files folderMoves only the data folder (the database). The logs folder then sits next to it.
GERMBOT_DBgermbot.db in the data folderUses a different database file.
GERMBOT_PORT8720The Director's port. Use it when something else holds 8720. Open the Director at the new port.
GERMBOT_HOSTthe Settings' Listen on (127.0.0.1)The address the Director listens on, over the Settings. Handy to get back in when the setting points at an address this computer no longer has.
GERMBOT_CONSOLE_BASE8721The first port handed to a console. Each console takes the first free port from here.
GERMBOT_CONSOLE_SPAN400How many console ports to hand out, so the most lords that can run at once. Each console uses about 40 MB of memory, so mind the computer's memory before raising it.
GERMBOT_ALLOW_ABANDON_TOWNoffSet to exactly 1 to allow the abandontown script command, which gives a city up for good. Without it the command refuses. Set it before starting the Director, then restart the consoles that need it.
GERM_URLnot setMakes every console play on this game address instead of the Settings' one. Meant for testing; leave it unset.

Where your files live

SystemFolder
Windows%APPDATA%\CitavonBot (usually C:\Users\<you>\AppData\Roaming\CitavonBot). Press Win+R, type %APPDATA%\CitavonBot and press Enter.
Linux~/.local/share/citavon-bot, or $XDG_DATA_HOME/citavon-bot if that is set.
Linux service (as set up in this guide)/var/lib/citavon-bot
AnywhereWherever GERMBOT_HOME points.

The Director prints the folder in its window when it starts ("Your files: …"). Updating the program never touches it.

In the folderWhat it is
data\germbot.dbEverything the bot knows, in one database: your lords (lord names, passwords, security codes, account emails, labels, notes, on and keep-on), every lord's goals (each city's, Prepend, Append, the new-city template and script, goal sets 1–9) and script loadouts (ten a city), the Settings and Director password, start-up parameters, groups, alert channels and their webhooks, friendly-fire choices, War Town Modes set by hand, kick waits, which lords are paused, AI tokens, and the history behind the Uptime, Monitor and Scouting tabs and the last snapshot of each lord.
data\germbot.db-wal, data\germbot.db-shmWorking files of the same database while the bot runs. They belong with it: always copy all three together.
logs\console-g1.log…One log a lord, named by its Id (the Accounts grid's first column): its Log and Debug lines. When one passes 20 MB it is renamed to .log.1 (replacing the older one) and a new one starts. Look here when a console stops at once.
scripts\Your script files: what call runs by name, the Quick… list, autorun's start-up file.
scripts\quick-scripts.txtThe Quick… list. Put there with commented examples the first time the program starts; never overwritten after that.
scripts\AutoRunScript.txtNot there until you make it. With -autoscripts 1, every city runs it first at autorun.
window\The Director window's own browser profile (Windows and desktop Linux). Nothing of yours; safe to leave out of a backup.

Goals and loadouts are not separate files: they live in the database and you edit them in the console. Script files in scripts\ are plain text you can edit with any editor.

The Director's own log is not kept in a file: it shows in its window (on a Linux service, journalctl -u citavon-bot) and in the Log tab.

quick-scripts.txt

One entry a line, read again each time you open the Script tab, so an edit needs no restart:

scripts\quick-scripts.txt
# Label | script | all
Clean the reports (every city) | clean-reports.txt | all
Beg (this city) | Load 3
Daily chores | Daily
  • Label: what the list shows.
  • script: a .txt file in the scripts folder, or one of the open city's loadouts: Load 3, or the name on the loadout's first line (a comment line counts, without its //).
  • all (optional): run it in every city with no script running. Without it: the open city only.
  • Lines starting with # are comments. A line naming a .txt file that is not there is left out of the list.
  • Restart autorun is added at the top by itself whenever any loadout holds label autorun.

AutoRunScript.txt

A plain script file in the scripts folder. With -autoscripts 1, every city runs it after the console's first login, before its own label autorun loadouts. It runs in each city, so write it for "the city it runs in". Use -runscript to use a file with another name.

Backing up

Copy the whole files folder. For a clean copy, stop the bot first, consoles included (closing the Director leaves the consoles running).

  1. Windows: close the Director's black window. Open Task Manager → Details, and end every CitavonBot.exe left. Copy %APPDATA%\CitavonBot somewhere safe. Start CitavonBot.exe again: lords that were switched on log in again one at a time.
  2. Linux service:
    sudo systemctl stop citavon-bot
    sudo pkill -u citavon -f citavon-bot     # the consoles
    sudo tar czf ~/citavon-backup.tgz -C /var/lib citavon-bot
    sudo systemctl start citavon-bot
A backup holds your passwords

The database keeps every lord's password and security code so the bot can log in. Anyone with the file can read them. Keep backups somewhere private, and never send the folder or germbot.db to anyone (to get help, send lines from the log files instead).

To restore: stop the bot the same way, put the copied folder back in place of the files folder, and start it.

Moving to another computer

  1. On the old computer, stop the bot completely (see Backing up) and copy the files folder.
  2. On the new computer, download the program. Don't start it yet. (If you already did, stop it.)
  3. Put the copied folder where the new computer looks: %APPDATA%\CitavonBot on Windows, ~/.local/share/citavon-bot on Linux, or the folder GERMBOT_HOME names (for the service, /var/lib/citavon-bot, owned by the citavon user: sudo chown -R citavon:citavon /var/lib/citavon-bot). Moving between Windows and Linux works too.
  4. Start the program. Every lord, goal, loadout, group, alert channel, setting, Director password and AI token comes along, and switched-on lords log in one at a time.
  5. Don't start the old computer's bot again with the same lords: Citavon allows one login per lord, so the two would keep kicking each other out.
If the Director listened on Tailscale

If Settings had Listen on set to the old computer's Tailscale address, the Director can't open that address on the new one and stops with "could not open port". Start it once with GERMBOT_HOST=127.0.0.1 (Windows: set GERMBOT_HOST=127.0.0.1 first), open the Setup tab, and click Use Tailscale again so it picks up the new computer's address. Then restart it normally.

If a lord shows a console that never answers after the move, click restart on its row.

11Intro to goals

What goals are, how the engine works through them, where you write them in the console, and the short codes every goal line uses. It ends with a full goal file for a new city.

What a goal is

A goal is a standing order for a city: "keep 8 Cottages at level 5", "train until there are 2,000 Archers", "keep the tax between 10% and 30%". You write what you want, not the steps to get there. The bot looks at the city again and again and does the next thing that brings it closer. A goal that is already met does nothing until something changes (a building is lost, troops die), and then it works again.

Goals are not a script. A script runs once, top to bottom, and stops. Goals never finish; they are read afresh on every pass. Where a goal file says "in order", it means the order in which targets are worked on (build lines, research lines, troop stages), not a list of commands.

Every line starts with a goal word. There are three kinds of line:

config

Switches and settings, key:value, several on one line with commas: config comfort:1,hero:1.

Targets

What the city should have: build, research, plan, troop, fortification. Several lines stack, in order.

Policies

How the city behaves: taxpolicy, comfortpolicy, schedulepolicy, rallypolicy and the rest. Most take one line per city.

How often the engine runs, and what one pass does

The engine makes a pass every 15 seconds by default. You can change that in the Director under ⋯ → Settings → Engine pass every (seconds) (5 seconds at the least). A pass only runs while the account is logged in and the engine is not paused. Nothing is done while the lord is on holiday.

In each pass the engine takes the account's cities one after another. For each city it reads the goals, then works through them in this fixed order:

  1. Free speed-ups, then finishing a building with speed-up items (freespeedup, itemspeedup).
  2. Defence: War Town Mode, hiding, the gate, defensepolicy, warrules, the Embassy and healing (see wartown, hiding, gatepolicy, defensepolicy).
  3. The schedulepolicy check. Outside its hours the city stops here.
  4. Upkeep: comfort, tax, production, the Warehouse split.
  5. Heroes: the mayor, hero levels and points, prisoners, hiring, hero items.
  6. The training hero moves on if its work in this city is done.
  7. The builder: buildings research needs first, the Walls a fortification goal needs, then the build lines.
  8. Research.
  9. Troop stages, then fortification stages.
  10. Transfers, trade, NPC farming, valleys, buildnpc, report clean-up.

Once per account per pass, after all the cities, quests and the daily gift are claimed (completequests).

Each city may do at most 6 actions per pass (an action is one thing sent to the game: start a building, queue a batch, send a march, change the tax…). When the 6 are used up, the rest of that city's goals wait for the next pass. This keeps a pass short and means early steps (speed-ups, defence, upkeep) always get their turn first.

Where goals are written: the editor's selector

Open a city in the console and pick the Goals editor (the target icon above the editor). Under the editor a drop-down chooses which text you are editing:

SelectorWhat it is
This cityThe open city's own goals. Each city has its own.
Prepend (every city, first)One text for the whole account. Every city runs it before its own goals.
Append (every city, last)One text for the whole account. Every city runs it after its own goals.
New-city templateGoals copied into a city the account gains, if that city has none of its own yet.
New-city scriptA script (not goals) that runs in a city the account gains, a few seconds after it arrives.
Goal set 1 … Goal set 9Nine spare goal texts. They do nothing by themselves; a script switches a city onto one with loadgoals.

What a city actually runs is the three texts joined together: Prepend, then the city's own, then Append. That order matters:

  • config settings are merged, and the last one written wins. So a config in Append beats the same key in a city's own goals, which beats Prepend. Put account-wide defaults in Prepend and anything that must always hold in Append.
  • Goals a city can have only once (taxpolicy, comfortpolicy, production, warehousepolicy, schedulepolicy, rallypolicy, reportstokeep, defensepolicy) also go to the last one written.
  • Lines that stack (build, research, plan, troop, fortification, processingpolicy) are worked in the joined order: Prepend's build lines come before the city's own.
Good uses of Prepend

Lines every city should share: config completequests:3, a traininghero line (every city must see it, see traininghero), reportstokeep, a schedulepolicy. Then each city's own text holds only what is special about it.

The editor checks one text at a time

The colours only judge the text in front of you. A taxpolicy in Prepend and another in a city's own goals both look fine in their own editors, but only one of them runs. The Engine view (below) lists the clash for the joined text, with line numbers counted through Prepend, the city's text and Append together.

The new-city template and the new-city script

When the account gains a city it did not have before (founded, captured, taken over), the console:

  1. copies the New-city template into that city's own goals, unless the city already has goals of its own. It is a copy: changing the template later does not change cities that already got it;
  2. then, about 5 seconds later, runs the New-city script in that city, if there is one.

The log says what was done ("new city: goals set from the new-city template (12 line(s))"). The first time a console sees an account it only learns the cities it has; none of them count as new.

Goal sets 1-9

Goal sets are spare texts kept for the whole account. A city runs one only when a script tells it to: loadgoals 3 makes the city run goal set 3 instead of its own goals (Prepend and Append still wrap it). loadgoals 0 or resetgoals puts the city back on its own goals. loadgoals with a city's name runs that city's goals instead. A switch made by a script lasts until it is undone or the console restarts. See loadgoals, resetgoals and goal (which adds single lines on top of the saved goals).

A typical use: a "war" set with no NPC farming and the gate rules you want, loaded by a script when an attack comes and reset afterwards.

Line colours, comments, Save and Apply

While you type, every line is checked and coloured:

ColourMeaning
BlueThe line reads correctly and the engine acts on it.
RedSomething is wrong: an unknown goal, a bad value, a goal written twice where only one counts (the earlier one turns red), or a line the bot reads but does not act on.
GreyA comment.

Comments are whole lines that start with // or # (spaces before them are fine). A comment cannot follow a goal on the same line: build t:9 // town hall is read as a build line with two unknown buildings, "//" and "town", and turns red. Blank lines are ignored.

Two buttons save your work:

  • Save stores the text. The engine picks it up on its next pass (at most one pass interval later). The line under the editor lists any errors.
  • Apply stores the text and starts a pass at once. If the text has errors, Apply still stores it but does not start the pass; it lists the errors instead. The saved text is used at the next normal pass anyway, so fix red lines rather than relying on Apply to stop them. If the engine is paused, Apply says the goals are saved and will run when you resume.

Leaving the editor (another city, another text, the Script tab) with unsaved changes asks you first.

Reading why a line is red

Put the cursor on a red line: the line under the editor says why, starting with the line number. Some messages you will meet:

MessageWhat to do
unknown goal "troops"The first word is not a goal. Here it should be troop.
BUILD: unknown building "x"Check the building codes below. The rest of the line still works.
CONFIG: "a: 1" has a spaceWrite config pairs with no spaces: key:value.
CONFIG: unknown config key "x"A typo, or a key from another bot. The other keys on the line still work.
troopslot is minutes … as a plain numberTimes and shares take plain numbers: 30, .5, never 30m.
taxpolicy appears more than once — the later one winsDelete one of the two lines.
a ?condition? goes right before or right after its targetsNo space between a ?condition? and its targets. The whole line is left out until fixed.

A red line is not always dead. A line keeps whatever parts of it read correctly: in troop a:1k,zz:5 the Archers still count; only zz is dropped. The exceptions are said in the message ("the whole line is left out", "is left out"). Some blue lines also carry a note under the editor, for example a line that was read differently from how it was written (see pasting, below).

The Engine view

The third icon above the editor (the bug) opens the Engine view for the open city. It shows what the engine made of the city on its last pass:

  • the time of the last pass ("no pass yet (is the engine paused?)" if there has not been one);
  • one note per step that had something to say, for example build: waits for Barracks 3 (short 2.1k wood), research line 2/3 waits: Mining 1: needs Ironmine 1, troops: stage 1/2, short Archer 500; Archer: needs Barracks 4, tax: 20% (policy 10-30);
  • "goal errors" for the joined text (Prepend + city + Append), with line numbers counted through all three;
  • what a script has set for the city (loadgoals, goal lines added by a script).

When a goal is blue but nothing happens, the Engine view is where to look: it says what each goal is waiting for. The engine log tab keeps the same notes over time, one line each time a city's notes change.

Pausing the engine

The pause button (❚❚) in the console's header stops the goal engine for this account; the badge beside it reads PAUSED instead of LIVE. Press it again to resume. While paused no goal acts, but scripts you run still run. The paused state is remembered when the console restarts. The start-up parameter -autorun 0 starts the console with the engine paused.

Pasting NEAT and OTTObot goal files

Citavon Bot reads NEAT's goal language, so a goal file written for NEAT (or for another bot that uses the same language) can be pasted into the editor as it is. What reads correctly runs; every line that does not says why, in red. Things to know:

  • A config key written as a line of its own, such as wartown 1 or itemspeedup 0, is read as config wartown:1. The line stays blue and the note under the editor says how it was read.
  • NEAT's obsolete goals (ballsused, npc10troops, npc10list, capturedfirelimit…) are read as the goals that replaced them, with a note saying so.
  • Comments at the end of a goal line are not allowed here (see above); move them onto their own lines.
  • Building, research, troop and fortification codes are NEAT's, and the full names work too.
  • Item names in Citavon differ from the original game's. The goal words do not change (for example /usewarhorn uses Citavon's Battle Horn).

Short codes

Goal lines name buildings, research, troops, fortifications and resources by short codes. Case does not matter, and the full name always works too (spaces may be left out: ironmine:10:5, iron mine:10:5).

Buildings

CodeBuildingCodeBuilding
t (or th)Town HallinnInn
wWallsfhFeasting Hall
cCottage *eEmbassy
bBarracks *rRally Spot
whWarehouse *beBeacon Tower
aAcademyfoForge
mMarketplacestStable
wsWorkshoprsRelief Station
fFarm * (field)sSawmill * (field)
qQuarry * (field)iIronmine * (field)

* a city may have many of these; every other building stands once per city. "barrack", "market" and "wall" also work.

Research

CodeResearchCodeResearch
agAgricultureloLogistics
luLumberingcomCompass
masMasonryhoHorseback Riding
miMiningarArchery
metMetal Castingsp (st)Stockpile
inInformaticsmedMedicine
msMilitary ScienceconConstruction
mtMilitary TraditionenEngineering
irIron WorkingmacMachinery
prPrivateering
st: Stable or Stockpile?

On a research line st is Stockpile. Inside a ?condition? and on a plan line st is the Stable, so write Stockpile as sp there. sp means Stockpile everywhere. A research line also takes agri, info, metal, horse and eng; inside a condition use the codes in the table or the full name.

Troops

CodeTroopAlso
woWorkerworker
wWarriorwarr, warrior
sScoutscout
pPikemanpike, pikeman, pikemen
swSwordsmansword, swordsman
aArcherarch, archer
tTransportertrans, transport, transporter
cCavalrycav, cavalry
cataCataphractphract, cataphract
bBallistaball, ballista
rBattering Rambr, ram
cpCatapultcat, pult, catapult

Plurals of the longer words work too (archers, ballistas). Note that cata is the Cataphract, not the Catapult.

Fortifications

CodeFortificationAlso
traTraptr, trap
abAbatisabatis
atArcher Towertower, arrowtower, archertower
rRolling Logrl, log, logs, rollinglog
treDefensive Trebuchettreb, trebuchet, dt, rf, rock, rockfall

r is a Rolling Log on a fortification line and a Battering Ram on a troop line.

Resources

CodeResourceAlso
fFoodfood
wWoodl, lumber, wood
sStonestone
iIroniron
gGoldgold

Numbers

Amounts of troops, fortifications and resources may use a suffix: k thousand, m million, b billion, with decimals: 2k = 2,000, 1.5m = 1,500,000. Settings measured in hours, minutes or shares take plain numbers only (30, .5, 0.25): troopslot:30m is an error, not 30 minutes.

A full example: a starter city

A goal file for a new city that takes it to Town Hall 5 with a first army. Every line here is blue. Note how the build lines put each requirement before what needs it: the builder raises what a line asks, but it does not go looking for a building that another building needs (see What is built first).

This city (or the New-city template)
// ===== Starter city: from a new Town Hall to Town Hall 5 =====
// Comments sit on lines of their own. Nothing after a goal on the same line.

// --- Upkeep ---
// keep loyalty up, level heroes, tax between 10% and 30%, every field worked
config comfort:1,hero:1
taxpolicy 10 30
production 100 100 100 100

// --- The builder: one line at a time, top to bottom ---
// 1. homes and fields for Town Hall 2
build t:2,c:2:4,f:2:4,s:2:3,q:2:2,i:2:2
// 2. the chain Town Hall 3 needs: Ironmine 3, Forge 2, Workshop 1, Walls 1
build r:1,i:3:1,fo:2,ws:1,w:1
// 3. Town Hall 4 (needs Walls 2), Academy, Inn, Feasting Hall, two Barracks
build w:2,t:4,a:3,c:3:6,inn:1,fh:1,b:2:2,f:4:6
// 4. Town Hall 5 (needs Walls 3) and the rest of a young city
build w:3,t:5,c:5:8,b:4:2,m:1,wh:1:2,be:1,e:1
// 5. once the Walls reach 5, a Rally Spot 3 (a condition on its group)
build ?w:5?r:3

// --- Research: one line at a time ---
research ag:3,lu:3
research mas:2,mi:2,ms:2,mt:1
// whatever these need (Military Science 4, Academy 4 ...) is done first
research ar:1,lo:2,in:1,met:1

// --- Troops: stage 1, then stage 2 (each number is the total wanted) ---
troop wo:500,w:500
troop w:2k,s:200,p:1k,a:1k
// training may use a quarter of the day of troop food that is kept
config troopsusereserved:0.25

// --- Walls: traps first, then abatis ---
fortification tra:500
fortification tra:1k,ab:300

What happens: the builder works on line 1 until it is met, then line 2, and so on. Line 5 waits for Walls 5, which no line asks for, so it simply waits and lets nothing else stall. Research runs beside the builder; when Archery needs Academy 4 and Military Science 4, the bot researches Military Science and hands Academy 4 to the builder ahead of the build lines. Troops train in stage 1 until there are 500 Workers and 500 Warriors (home, training and out on marches all count), then stage 2. Scouts, Pikemen and Archers wait until their Barracks level and research exist; the Engine view says which. The Walls come early (a fortification line has them built ahead of the build lines), so traps start as soon as there is wall space and resources; Abatis wait for Walls 2 and Metal Casting 1.

12General goals

The config line and its general switches, city upkeep (comfort, tax, production, the Warehouse), when goals may act (schedule, processing, the Rally Spot), quests, hero levels and the mayor, and report clean-up.

Goals covered elsewhere: NPC farming (npc, farmingpolicy), valleys (valley), buildnpc and the hero goals such as hero, nomayor, keepheroes, heropoints, spamheroes, homeheroes and fasthero; transfers (requestresources, sendresources), the market (trade, tradepolicy) and war (hiding, gatepolicy, wartown, defensepolicy).

The config line

configGoal

Usage
config <key>:<value>[,<key>:<value>…]
Example
config comfort:1,hero:1,troopsusereserved:0.25
See also
config (script), Prepend and Append

Sets one or more switches for the city. Pairs are separated by commas and written with no spaces: key:value. A pair with a space in it is an error and is skipped; the other pairs on the line still count.

A city may have as many config lines as you like. They are merged, and when the same key is set twice the last one wins, also across Prepend, the city's own text and Append (Append wins). A key with a bad value is an error; for the troop and wall settings the key then keeps its default rather than a value that could mean something else. An unknown key turns the line red and does nothing.

A key written as a line of its own (comfort 0, itemspeedup 0) is read as config comfort:0, and the note under the editor says so. In a script, config key:value adds the setting to the city's running goals until the goals are reset.

On/off switches

Each of these turns one part of the engine off for a city. All are on by default except hero and nomayor.

config buildingConfig

Usage
config building:<0|1>
Example
config building:0
Values
0 the builder is paused; 1 it works.
Default
1 (any build line is enough)
See also
build, plan

With building:0 the city starts no building job of any kind: not the build lines, not the plan lines' buildings, not the buildings research needs, not the Walls a fortification goal needs. A job already under way finishes. The Engine view says "paused by config building:0". Any other value than 0 or 1 is an error.

config researchConfig

Usage
config research:<0|1>
Example
config research:0
Values
0 research paused; 1 on.
Default
1
See also
research

With research:0 the city starts no research, and the builder no longer raises the buildings that research lines need. A research already under way finishes.

config planConfig

Usage
config plan:<0|1>
Example
config plan:0
Values
0 plan lines are ignored; 1 on.
Default
1
See also
plan

With plan:0 every plan line is left out, as if it were not there. Ordinary build and research lines still run.

config troopConfig

Usage
config troop:<0|1>
Example
config troop:0
Values
0 no troop training; anything else, on.
Default
on
See also
troop

With troop:0 the city queues no troops for its troop lines ("troops: off (config troop:0)"). Batches already queued carry on. The training hero still judges the city's troop stages when it chooses where to go next.

config fortificationConfig

Usage
config fortification:<0|1>
Example
config fortification:0
Values
0 no fortifications are built; 1 on.
Default
1
See also
fortification

With fortification:0 no fortification batches are queued, and a city with no Walls no longer has the Walls built for its fortification lines.

Speed-ups

config freespeedupConfig

Usage
config freespeedup:<0|1>
Example
config freespeedup:0
Values
0 off; anything else on.
Default
on
See also
itemspeedup, Speed-ups and the builder

Citavon finishes a building or research job for free when the job is short enough (5 minutes or less; the game decides which jobs qualify). The bot uses this the moment such a job starts: it is the first thing in every pass, once per job, for the building job and the research job of each city. It costs nothing. Troop and wall batches never qualify (Citavon only speeds those up with items).

Turn it off only if you want short jobs to run their course, for instance to watch a city by hand.

config itemspeedupConfig

Usage
config itemspeedup:<0|1>
Example
config itemspeedup:0
Values
0 off; 1 on. Anything else is an error.
Default
1 (on)
See also
freespeedup

Finishes a building upgrade with speed-up items the account already holds, when the free speed-up does not cover it. The bot picks the cheapest set of items, by their shop price, whose time covers what is left of the job; among equal prices, the fewest items, then the least time wasted. The items it may use are the fixed-time ones: Speed-up 15 min, Speed-up 1 hour, Speed-up 2.5 hours, Speed-up 8 hours, and Speed-up 10-30 hours (counted as 10 hours).

What it never does:

  • buy anything: only items you hold are used;
  • use the items that cut a share of the time (Builder's Ledger, Stonecutter's Masterwork) or the troop and wall ones (Drillmaster's Diary, Engineer's Notes);
  • speed up research, troops, walls or a building being taken down;
  • act on a job with 5 minutes or less to go, or one longer than 4 days;
  • use part of a set: if the items you hold cannot finish the whole job, it waits (and tries again if you get more items while the job runs).

Each job is tried once. Using the items takes one action each, out of the pass's 6; if there are not enough actions left the job waits for the next pass.

Not working yet

At present the bot does not recognise Citavon's speed-up items for this setting, so it finds nothing to use and finishes no job with items. The free speed-up is not affected.

Comfort, tax, production and the Warehouse

config comfortConfig

Usage
config comfort:<0|1>
Example
config comfort:0
Values
0 off; 1 on. Anything else is an error.
Default
1 (on)
See also
comfortpolicy, taxpolicy

Keeps the city's loyalty up and public grievance down with the Town Hall's comfort actions, and runs the tax (taxpolicy). With comfort:0 the bot leaves comfort, levies and the tax rate alone.

At most one comfort action a pass, and the bot tries each kind (relief, prayer, each levy) at most once every 15 minutes, as Citavon allows. What it does, in order:

  1. Riot risk first. The bot treats a city as at risk when its loyalty is under 30, its public grievance is 50 or more, or its loyalty is drifting toward a value under 30 (loyalty heads for 100 minus the tax rate minus the grievance). Then: it gives disaster relief when grievance is 50 or more (or there is any grievance and loyalty is under 30) and the city holds at least its population limit in food; it prays once loyalty is within 10 of the line (under 40) if the city holds at least its population limit in gold; and the tax drops to the lowest your taxpolicy allows. If it cannot afford prayer, the Engine view says "RIOT RISK" and how much gold it needs.
  2. Ordinary comfort. Disaster relief whenever there is any grievance and the city has over 1,000,000 food; prayer whenever loyalty is under 95 and the city has over 100,000 gold.
  3. Your comfortpolicy, if there is one (see below).

comfortpolicyGoal

Usage
comfortpolicy <min_minutes> <max_minutes> <option>[,<option>…]
Example
comfortpolicy 30 60 popraise,bless
comfortpolicy 15 15 gold
Values
OptionShortWhat it does
popraisepoRaise population. Skipped when the city is at its population limit.
blessblBlessing (on Citavon it spares the city its next riot).
prayprPrayer.
reliefdrDisaster relief.
gold, food, wood, stone, irongo fo wo (lu) st irA levy of that resource. Skipped while loyalty is under 80 (a levy costs loyalty).
See also
comfort

Every min to max minutes (a random time in between), the bot does the first option in your list that can be done now, then waits again. If none can be done, it tries again on the next pass. Options may be separated by commas or spaces.

It needs config comfort on, and it comes after the riot-risk and ordinary comfort steps: in a pass where those acted, the policy waits. Each kind still has its own 15-minute timer. One line per city; a second line replaces the first.

taxpolicyGoal

Usage
taxpolicy <min_rate> <max_rate> [<war_rate>]
Example
taxpolicy 10 30
taxpolicy 5 40 60
Values
Whole percentages from 0 to 100; min may not be above max. war_rate: the rate while an attack is on its way to this city.
Default
without a line: 0 to 100, no war rate

The bot keeps the tax as low as it can within the range: the lowest rate whose gold income covers the city's hero salaries, but never under min or over max. When the city holds gold for a week of salaries (and at least 1,000,000), it goes to min. A city at riot risk (see comfort) also goes to min.

With a war_rate, while an attack is on its way to the city the tax is set to it, whatever else is true. It goes back once the attack has landed or turned away.

Needs config comfort on. One line per city.

productionGoal

Usage
production <food> <wood> <stone> <iron>
Example
production 100 100 100 100
production 100 50 50 100
Values
Four whole percentages, 0 to 100: the share of each resource's fields that is worked.

Holds the city's field work at these shares. When one differs, the bot sets it, one resource per pass. Fewer workers in the fields leaves more idle population for training. It does not depend on config comfort. One line per city.

troopsusepopmax lowers these shares for a moment to free workers for a troop batch and puts them back straight after.

warehousepolicyGoal

Usage
warehousepolicy <food%> <lumber%> <stone%> <iron%>
Example
warehousepolicy 40 20 20 20
Values
Four whole percentages; together at most 100.

Holds the city's Warehouse split: the share of the warehouses' protected space given to each resource (the part an attacker cannot carry off). When the city's split differs, the bot sets it. Gold is never protected by warehouses. One line per city.

When goals may act

schedulepolicyGoal

Usage
schedulepolicy <start> <end> [<start> <end> …]
Example
schedulepolicy 06:00 12:00 18:00 23:30
schedulepolicy 22:00 06:00
Values
Times as hh:mm, 24-hour (24:00 allowed as an end), in start/end pairs. A window may run past midnight.
Default
no line: always

The city's goals act only inside these windows. Outside them only the city's defence runs (War Town Mode, hiding, the gate, defensepolicy, warrules, the Embassy and healing), plus the free speed-ups and item finishes, which come first in a pass. Nothing that keeps a city safe waits for the schedule. Quests are still claimed.

The times are the clock of the computer the bot runs on, not the game's clock. The Engine view says "outside 06:00-12:00, 18:00-23:30 — only the defence runs". One line per city.

processingpolicyGoal

Usage
processingpolicy [/start:<hh:mm>] [/end:<hh:mm>] <task>[:<priority>] …
Example
processingpolicy n:10 !b *:5
processingpolicy /start:22:00 /end:06:00 !n
Values
TaskMarches it covers
nNPC farming
bbuildnpc (founding cities on flats)
vvalley farming
ssafe valley farming (its scouting)
avalley and flat taking
mmedal hunting
ttroop sends (sendtroops, requesttroops) and the training hero's moves
rresource sends (sendresources, requestresources)
qrescue: accepted, nothing uses it
Turn a task off with !x, x:0 or x:off. !* turns off every task the line does not name; *:N gives the rest priority N. = may stand for :. A task named without a number gets 10. /start and /end (hh:mm or hhmm) make the line hold only between those times; the window may run past midnight.
Default
every task on
See also
rallypolicy

Before a goal sends a march, the bot asks whether its task is allowed. A march whose task is off is not sent, and the goal's note in the Engine view ends "held: processingpolicy: npc farming is off". Marches you send yourself, or a script sends, are never held.

You may write several lines. Lines without times are read first, then the timed lines whose window is open now; for each task the last line that mentions it wins (a line with *:N or !* mentions every task). So the example above turns NPC farming off at night only.

Priorities are read and shown but do not change the order in which goals run: the engine always works through its steps in the same order, and a pass sends few marches. Only "off" changes anything. A transfer from another city answers to the sending city's policy.

rallypolicyGoal

Usage
rallypolicy <kind>:<slots> [n:<level>:<slots>] … [max:<slots>]
Example
rallypolicy n:8 n:10:1 r:2 t:1 max:8
Values
Kinds as in processingpolicy: n b v s a m t r (also npc, buildnpc, valley, safe, acquire, medal, troop, resource, transport…), plus: n:<level>:<slots> a limit for NPC runs to one camp level (n:*:8 is the same as n:8); max:<slots> goals start nothing once that many marches of the city are out, whoever sent them. The older form /npc:3 also works.
Default
no limits beyond a full Rally Spot

Limits how many of the city's Rally Spot slots each kind of goal march may hold at once. A march holds its slot while it goes, camps and comes back. Marches staying in another city as reinforcements do not count toward these limits. A march a goal sent counts by the kind it was sent for; one you or a script sent counts by its mission: attack as n, transport as r, reinforce as t, build as b, scout as s.

It only ever lowers what goals may send. It keeps nothing free for you: for that, set max below the Rally Spot's slots. With or without the policy, no goal march goes when the Rally Spot is full. One line per city.

Quests and reports

config completequestsConfig

Usage
config completequests:<0-3>
Example
config completequests:1
Values
ValueWhat is claimed
0Nothing.
1Every finished quest and the daily gift; no promotions.
2All of 1, and promotions (rank, then title) as they come.
3All of 1, and promotions, a title before a rank (a title raises how many cities you may hold).
Default
3

Quests belong to the account, so this runs once per account: from the first city that has any goals at all, using that city's settings. Put it in Prepend so every city agrees. It looks every 10 minutes, and again after 1 minute when it claimed something. Up to 10 quests a look.

No goals, no quests

If no city of the account has a single goal line, nothing is claimed, not even with the default. One line in Prepend is enough.

reportstokeepGoal

Usage
reportstokeep <treasure> <valley> <npc5> <npc10_low> <npc10_high>
Example
reportstokeep 1 a:500 b:1 a:3800 a:6000
Values
PositionValueKeeps a report when…
treasure0 or 11: the battle found something (a medal, an item, a season token).
valleytroop:amount or 0we lost at least that many of that troop attacking a valley.
npc5troop:amount or 0we lost at least that many attacking a level-5 NPC.
npc10_lowtroop:amount or 0level-10 NPC: we lost fewer than this many…
npc10_hightroop:amount or 0…or more than this many.
A 0 (or an amount of 0) keeps every report of that kind. All five numbers are needed.

Deletes battle reports of your own farming attacks that are not worth keeping. Only reports of attacks you won are ever deleted. Always kept: a battle you lost, one where a hero of yours was taken, attacks on flats, and anything kept by the rules above. Won attacks on lords' cities are judged by the valley rule as well, so a valley rule may delete them; write 0 for the valley number to keep them all. Attacks on NPCs of levels other than 5 and 10 have no rule to keep them, so they go (unless they found treasure and treasure is 1).

Reports belong to the account: the goal runs from the first city whose goals hold a correct reportstokeep line. It opens at most 5 new reports a run without marking them read, deletes the ones to go together, and looks again after 1 minute while it finds work, or after 10 minutes when there is nothing new. One line per city.

Hero levels and the mayor

Each pass, after upkeep, the engine picks the city's mayor (the training hero while it is there, otherwise the hero with the most politics) and, with config hero:1, levels heroes up and places their points. Those settings are described with the hero goals: hero, nomayor, heropoints, keepheroes and fasthero.

13Building and research goals

The build, research and plan lines: every form they take, the ?condition? syntax, the order the builder works in, what it raises first, taking buildings down, and speed-ups.

buildGoal

Usage
build [?<condition>?]<type>:<level>[:<qty>][,…][?<condition>?] [more groups…]
Example
build t:9,w:9,c:9:23,b:9
build c:0:20 f:9:0
build ?w:10?q:0:0,ws:0:0 w:10
Values
FormMeaning
type:levelAt least one of that building at that level or higher.
type:level:qtyAt least qty of them at that level or higher. c:9:23: 23 Cottages at level 9 or more.
type:0:qtyAt most qty of that building. The weakest extra ones are taken down. q:0:0: no Quarry at all.
type:level:0None at that level or higher: each one above is taken down to level−1. f:9:0: no Farm above level 8.
?condition?The group it is attached to counts only while the condition holds (see below).
Levels go from 0 to 10. A building a city has only one of (everything except Cottage, Barracks, Warehouse, Farm, Sawmill, Quarry, Ironmine) is read as quantity 1, with a warning if you wrote more. type:0 on its own reads as "at most 1".
See also
plan, config building, How the builder works

A build line lists targets separated by commas. Spaces split a line into groups, and each group can carry its own condition. A city can have many build lines; they are worked one line at a time, top to bottom (including those from Prepend and Append, in the joined order).

A target counts what stands now and what is under way or waiting in the building queue, so a Cottage being raised to 5 already counts as a level 5 Cottage for planning.

The Town Hall and the Walls are never taken down: t:0:0 or w:5:0 is an error. A target that would undo an earlier line is cut back to fit it: after build c:5:10, a later build c:0:6 still keeps 10 Cottages.

The two "down" forms demolish

type:0:qty and type:level:0 take buildings down, one level at a time, until the line holds. On Citavon taking a level down gives back only 30% of its cost. Check a line with a 0 in it twice before you save, and never paste one into Prepend or Append unless every city should obey it.

How the builder works

The bot starts one building job at a time per city. Each pass, it makes a list of jobs in this order of priority:

  1. buildings the city's open research needs (the Academy at a level, a Forge for Military Science…);
  2. the Walls, if the city has a fortification line and no Walls;
  3. the jobs of the first build line that is not yet met.

Within that line, for each building type in the order it first appears on the line: extra buildings come down first, then the strongest buildings of that type are raised to the levels asked (the highest level asked goes to the strongest one), then new ones go on free plots. The builder starts the first job on the list it can do now:

  • A job whose next level needs something the city lacks (another building at a level, a research level, a Master Builder's Script for level 10) is passed over; the Engine view says what it needs ("Barracks 3: needs Rally Spot 1").
  • A job the city cannot pay for stops the builder: it waits for that job, and keeps its cost aside so troops, walls and research do not spend it meanwhile. It does not jump to a cheaper job.
  • While a job is under way the builder starts nothing else, and keeps the next job's cost aside.

A line that is met is passed over and the next line is taken up at once. A line whose groups all fail their conditions is passed over, and so is a line that only waits for a free plot ("no free field plot for Farm"). A line that has work it cannot start for another reason holds the builder: the lines after it wait. So put what a building needs on the same line or an earlier one.

Plots. Farms, Sawmills, Quarries and Ironmines go on the field plots outside the city, the rest on the plots inside. Field plots open with the Town Hall (13 at Town Hall 1, 3 more each level, all 40 at level 10). When a line wants a new field building and no field plot is free, the builder raises the Town Hall to open more.

?Conditions?

A condition limits a group of targets to the time it holds. Write it between question marks, right against its targets, before or after them with no space:

build ?w:10?q:0:0            // once the Walls are level 10, take every Quarry down
build q:0:0?w:10?            // the same, condition written after
build ?met:10,w:10?ws:0:0    // both must hold
build ?i:4:0?i:3:10          // while no Ironmine is level 4 or higher: ten at level 3
build ?w:5?be:5 c:9:20       // two groups: only the Beacon Tower waits for Walls 5
research ?a:10?pr:10         // conditions work on research lines too
  • A condition is one or more parts separated by commas. Every part must hold.
  • A building part reads like a build target and holds when that target is met by the buildings standing now (jobs under way do not count yet): w:10 the Walls are level 10; c:9:20 twenty Cottages at 9 or more; i:4:0 no Ironmine at 4 or higher; q:0:0 no Quarry.
  • A research part, code:level, holds when that research is at that level or higher: met:10.
  • Inside a condition st is the Stable; write Stockpile as sp.
  • A group may have a condition both before and after; both must hold.
  • Spaces inside the question marks are ignored. A space between the condition and its targets (?w:10? q:0:0) is an error, and the whole line is left out, because the bot cannot tell which targets the condition was meant for.
  • A condition with an unknown part leaves its group out (the rest of the line still works).
  • plan lines take no conditions.

What is built or researched first

  • Research looks after itself: when a research level needs another research, that one is researched first (up to four steps back), and when it needs a building at a level, that building is handed to the builder, ahead of every build line.
  • Fortification lines get the Walls built if the city has none (level 1 only; higher Walls are up to your build lines).
  • Buildings do not: when a building's next level needs another building, the job waits and the Engine view says what it needs. Write the requirement on the same line or an earlier one, as in the example (Town Hall 3 needs Walls 1, which needs a Workshop and Quarry 2; the Workshop needs a Forge 2, the Forge an Ironmine 3).
  • Troops do not either: a troop whose Barracks level or research is missing waits (see troop).

Taking buildings down

Only the forms type:0:qty (at most) and type:level:0 (none at or above) take buildings down. For "at most", the weakest buildings go first (the lowest level, then the lowest plot). Each step takes one level off one building, one job at a time, just like an upgrade. On Citavon a level comes down in half the time it took to build and gives back 30% of its cost. The Town Hall and the Walls are never taken down. Since the builder works the first unmet line, a "down" target only acts when its line's turn comes.

Speed-ups and the builder

Every pass begins with speed-ups, before the builder looks at its lines. First the free speed-up finishes any building or research job short enough to qualify. Then, if the building job is still running, itemspeedup finishes it with held items when they cover all the time left. Both mean the builder is often free again in the same pass and can start the next job at once. Neither ever touches troops or walls, and items are never used on research.

researchGoal

Usage
research [?<condition>?]<code>:<level>[,…][?<condition>?] [more groups…]
Example
research lo:5,ho:5,com:4
research ?a:10?pr:10
Values
Research codes from the table (on this line st is Stockpile), or full names; levels 1 to 10. A type:level:qty part is an error: it belongs on a build line.
See also
config research, plan, conditions

Research lines are worked one line at a time: the next line starts once every target of the one before it is reached (or the only targets left wait on conditions). Within a line the bot tries each open target in the order written and starts the first one it can.

What the bot does for a target:

  • If the next level needs other research first, that research is started instead (up to four steps back). The log shows it: "research Military Science 3 (for Archery 1)".
  • If it needs a building (the Academy at a level, a Forge, a Stable, a Warehouse…), the builder raises that building first, ahead of your build lines.
  • If the city cannot pay, it tries the next target on the line.
  • A research another city of yours is busy with is skipped here (research is shared by the account).

One research at a time per city, and only in a city with an Academy. Research never spends what the builder is keeping for its next job. A research under way finishes free when it qualifies (freespeedup).

planGoal

Usage
plan <target>[,<target>…]
Example
plan c:4:9,i:4:40,b:4:14,mi:4
plan ar:8,mt:7,ho:5
Values
Build targets (type:level[:qty]) and research targets (code:level) mixed on one line, separated by commas or spaces. A building code is read first, so st is the Stable and Stockpile is sp. No conditions.
See also
config plan, build, research

A plan line is a build line and a research line in one, with a stricter order: the next plan line waits until every target of this one is finished, buildings and research together. In the examples, Archery 8 is not started until the 9 Cottages, 40 Ironmines, 14 Barracks and Mining 4 are all done.

The plan line in work, and every finished plan line above it, are placed ahead of the city's own build and research lines, so the same builder and research work on them first. A finished line keeps standing: if a building it asked for is lost, that line is back in work and the lines after it wait again. "Finished" means the buildings stand as asked now (jobs under way do not count) and each research is at its level.

The Engine view shows "plan: line 2 of 4 in work (…) — the next waits for it".

14Troop and wall goals

The troop and fortification stages, every switch and setting that shapes a batch, and the training hero that tours your cities.

troopGoal

Usage
troop <code>:<amount>[,…] [/increment:<n>] [/queuetime:<hours>] [/slot:<minutes>] [/idlequeuetime:<minutes>] [/usereserved:<share>] [/usepopmax:<share>] [/traineronly:<0|1>]
Example
troop a:2m,c:1m,t:250k
troop w:5k,p:2k /queuetime:.5 /usereserved:0.5
Values
SwitchMeaning (for this line only)Same as
/increment:nBatch size: a share of the target below 1, or a whole number of troops.troopincrement
/queuetime:hHours of work per barracks a batch.troopqueuetime
/slot:mThe same in minutes.troopslot
/idlequeuetime:mMinutes a batch may take while the training hero is away.troopidlequeuetime
/usereserved:sShare of the kept day of troop food training may spend.troopsusereserved
/usepopmax:sShare of field workers to free for a batch when the city is out of idle people.troopsusepopmax
/traineronly:0|1Wait for the training hero for slow troops.trooptraineronly
Amounts take k/m suffixes. An unknown switch, or one with a value that cannot be read, is an error and is left out. Writing both /queuetime and /slot is an error: /queuetime is used.
See also
config troop, traininghero, How a batch is sized

Each troop line is a stage. The city works on the first stage not yet met, and only on the types of that stage that are still short; when every type has reached its number, the next stage begins. A stage's numbers are totals, counting troops at home, in training, and out on marches from the city. They are not added to the stage before: write stage 2's numbers to include what stage 1 asked for. If troops die and a stage is no longer met, the city goes back to it.

In each pass the bot queues one batch for each short type, starting with a different type each pass so all of them move. It stops when the city has one action left for the goals that follow.

A type whose Barracks level or research is missing waits, and the Engine view says so ("Archer: needs Barracks 4"). The troop goal does not build or research what is missing: put it in your build and research lines. Each switch on a line overrides the matching config key for that line's stage only.

How a batch is sized

For each short type, the bot first works out a batch, then cuts it down to what the city can do:

  1. The size wanted. With troopincrement a share below 1: that share of the stage's target (rounded up). With a whole number of 2 or more: that many. Otherwise (0, 1 or none): enough to keep each barracks with room busy for the batch time (troopqueuetime / troopslot, 30 minutes by default), at the training speed of the current mayor. A troop that trains in under a second (instant training, see traininghero) is queued for its whole shortfall.
  2. The limits. Never more than the stage is short; never more than the idle population allows (a troop takes 1 to 10 people: Archer 2, Cavalry 3, Transporter 4, Ballista 5, Cataphract 6, Catapult 8, Battering Ram 10, the rest 1); never more than the resources allow. Training spends neither what the builder is keeping for its next job nor a full day of the city's troop food (see troopsusereserved).
  3. Where it goes. Into the barracks of the level that troop needs that still have room in their queue (a barracks of level L holds L batches), spread over all of them. With reservedbarrack, the best barracks is left out and the batch goes into one barracks.

Citavon fixes a batch's training time when it is queued, using the mayor of that moment (its attack, with Military Science). That is why the training hero matters, and why troopdelbadque exists.

fortificationGoal

Usage
fortification <code>:<amount>[,…]
Example
fortification tra:1k,ab:500
fortification tra:5k,ab:5k,at:3k,r:1k,tre:500
Values
CodeFortificationWall space eachNeeds
traTrap1Walls 1
abAbatis2Walls 2, Metal Casting 1
atArcher Tower3Walls 3, Archery 3
rRolling Log4Walls 5, Metal Casting 5
treDefensive Trebuchet5Walls 7, Metal Casting 6
Amounts take k/m suffixes. Other spellings are in the code table.
See also
config fortification, wallqueuetime, fortsusereserved

Stages, like troop lines: the first stage not met is worked on, and its numbers are totals (built plus queued). If the city has no Walls, the builder builds them first (level 1). Higher Walls are up to your build lines.

One batch a pass, for the first short type of the stage, in the order written. Its size: about wallqueuetime of work (15 minutes by default) at the speed of the current mayor (its politics, with Construction), or the whole shortfall when one piece takes under a second; never more than the wall space left (built and queued pieces both take space), and never more than the resources allow, keeping a day of troop food unless fortsusereserved says otherwise.

The Walls work through at most 5 batches at a time; with 5 queued the goal waits. If the first short type's requirement is missing, the whole stage waits ("fortifications: stage 2/2: Abatis needs Walls 2"); it does not skip to the next type. So write the types you can already build first, as in the example.

trainingheroGoal

Usage
traininghero <hero name> [<min_seconds>] [<max_seconds>]
Example
traininghero Arthur
traininghero Arthur 600 3600
Values
hero name: one word, any case. min_seconds: the least time it stays in a city that still needs troops. max_seconds: the most. A fourth number is accepted and does nothing.
Default
min 600 seconds (10 minutes); no max
See also
trooptraineronly, troopdelbadque, nomayor, feastinghallspace

A hero with high attack trains troops fast when it is mayor (on Citavon each attack point cuts training time by 0.5%, and with enough attack and Military Science a troop trains in under a second: instant). The training hero goes round your cities that still have troop stages to finish, and is mayor in each while it is there.

How it moves:

  1. In the city where it is, it becomes mayor (unless config nomayor:1) and troops are queued at its speed.
  2. It stays at least min_seconds, unless every troop stage there is met. It leaves when the stages are met or after max_seconds.
  3. It goes to the next city, in the account's city order, whose troop stage is not met (judged by that city's own goals). If no other city needs troops, it stays.
  4. It travels as a reinforcement with one troop beside it (the cheapest the city has of Worker, Warrior, Scout, Pikeman, Swordsman, Archer), after standing down as mayor. The move needs a free Rally Spot slot and counts as task t for processingpolicy and rallypolicy.

While War Town Mode 2 is on for its city, it stays where it is.

Put it in Prepend

A city only knows about the training hero if its goals hold the traininghero line. Write it once in Prepend so every city sees it: the city the hero is in moves it on, and the cities waiting for it hold their slow troops for it.

Cities without the hero wait

With a training hero, a city it is not in queues only troops that train instantly with its own mayor; slow troops wait for the hero (trooptraineronly, on by default). Turn that off, or give troopidlequeuetime a value, if those cities should keep training meanwhile.

Troop settings

Each of these is a config key for the whole city; most also have a switch on the troop line that overrides it for that line. Order of precedence: the line's switch, then the config key, then the default.

config troopincrementConfig

Usage
config troopincrement:<n> · line switch /increment:<n>
Example
config troopincrement:0.01
config troopincrement:5k
Values
0 off (batches by time); a share below 1, e.g. 0.01 = batches of 1% of the target; a whole number of 2 or more = that many troops a batch (k/m allowed); 1 accepted (NEAT's ratio mode) but here it sizes batches by time, the same as 0, and gives troopidlequeuetime a default of 1 minute. Fractions above 1 are an error.
Default
0 (batches by time)

Sets the size of each troop batch instead of the time-based size. With a share, the batch is that share of the stage's number for the type (rounded up), so troop a:100k with 0.01 queues 1,000 Archers at a time. The batch is still cut to what is short, the idle population, the resources and the barracks' room.

config troopqueuetimeConfig

Usage
config troopqueuetime:<hours> · line switch /queuetime:<hours>
Example
config troopqueuetime:2
config troopqueuetime:.5
Values
Hours, a plain number; fractions allowed. At least one minute is used.
Default
30 minutes (when neither this nor troopslot is set)
See also
troopslot

How much work each barracks gets in one batch when batches are sized by time: the batch holds enough troops to keep every barracks with room busy for this long, at the current mayor's speed. Longer batches mean fewer actions; shorter ones let a training hero arriving later make more of the work fast. Ignored when troopincrement sets the size. It beats troopslot when both are set.

config troopslotConfig

Usage
config troopslot:<minutes> · line switch /slot:<minutes>
Example
config troopslot:20
Values
Minutes, a plain number (30m is an error).
Default
30
See also
troopqueuetime

The batch time of troopqueuetime, in minutes. If both are set, troopqueuetime is used (on one line, setting both is an error). On a troop line, /queuetime beats /slot, and either beats both config keys.

config troopidlequeuetimeConfig

Usage
config troopidlequeuetime:<minutes> · line switch /idlequeuetime:<minutes>
Example
config trooptraineronly:0,troopidlequeuetime:10
Values
Minutes, a plain number. 0 = nothing slow is queued while the hero is away.
Default
0 (1 when troopincrement is 1)
See also
trooptraineronly, traininghero

Only matters in a city with a traininghero line while the hero is elsewhere, and only with trooptraineronly:0. Then troops that would not train instantly are queued in short batches of this many minutes of work, and only into barracks with nothing queued at all, so the barracks are nearly empty when the hero arrives. With 0 they wait for the hero.

config trooptraineronlyConfig

Usage
config trooptraineronly:<0|1> · line switch /traineronly:<0|1>
Example
config trooptraineronly:0
Values
1 while the training hero is away, queue only troops that train instantly; 0 allow short batches (troopidlequeuetime).
Default
1
See also
traininghero

In a city with a traininghero line, while the hero is in another city: with 1 (the default) only troops that train instantly under the city's own mayor are queued; the rest wait for the hero, and the Engine view says "waits for the training hero Arthur". This keeps the barracks free so the hero's fast batches go in when it arrives. Cities without a traininghero line are not affected.

config troopsusereservedConfig

Usage
config troopsusereserved:<share> · line switch /usereserved:<share>
Example
config troopsusereserved:0.5
Values
A share from 0 to 1 (0.5 = 50%).
Default
0 (the whole day of food is kept)
See also
fortsusereserved

Training always keeps a day's worth of the city's troop food upkeep in store, so that troops do not starve because of new troops. This setting says what share of that day's food training may still spend: 0 keeps it all, 1 lets training spend it all.

config troopsusepopmaxConfig

Usage
config troopsusepopmax:<share> · line switch /usepopmax:<share>
Example
config troopsusepopmax:0.2
Values
A share from 0 to 1. 0 = off.
Default
0
See also
production

Troops are made from idle population. When the city's idle people fall under 5% of its population, this frees workers from the fields for a moment: each resource's worked share is lowered by this share (0.2 = a fifth fewer workers), the batches are queued, and the shares are put back straight after, in the same pass. It lets a city that is full of workers keep training.

config reservedbarrackConfig

Usage
config reservedbarrack:<0|1>
Example
config reservedbarrack:1
Values
1 keep one barracks free; 0 off.
Default
0

Keeps the city's best barracks (the highest level; among equals, the last plot) free of goal batches, so you or a script can always train something there at once. Goal batches then go into one of the other barracks each, not spread over all. While the city is under attack (an attack on its way, or a battle there a short time ago) the reserved barracks is used too.

config troopdelbadqueConfig

Usage
config troopdelbadque:<0|1>
Example
config troopdelbadque:1
Values
1 on; 0 off.
Default
0
See also
traininghero

A batch keeps the training time it was queued with. When the training hero becomes mayor, batches queued earlier under a weaker mayor are slow by comparison. With troopdelbadque:1, while the training hero is mayor, the bot cancels a waiting batch (not the one training now) that is more than half as slow again as the hero would make it, plus 5 minutes: the one that wastes the most time first. One cancel per pass, and a troop type at most once an hour. The troop goal then queues the troops again at the hero's speed.

Citavon gives back most of a cancelled batch's cost (95%), not all of it. Without a training hero, or while it is not mayor, this setting waits ("troopdelbadque: waits for the training hero as mayor").

config feastinghallspaceConfig

Usage
config feastinghallspace:<n>
Example
config feastinghallspace:1
Values
A number of hero slots, 0 or more.
Default
0
See also
fasthero, traininghero

Keeps n slots of the Feasting Hall free from hiring by fasthero, plus one more while the training hero is away from this city (once the key is set at all, even to 0), so it always has a place to come back to. While slots are kept free, fasthero never fires a hero to make room. It only affects fasthero: without that setting it does nothing, and it never stops you or a script from hiring.

Wall settings

config wallqueuetimeConfig

Usage
config wallqueuetime:<hours>
Example
config wallqueuetime:1
Values
Hours, a plain number; fractions allowed (.25 = 15 minutes).
Default
15 minutes
See also
fortification

How much work one fortification batch holds, at the speed of the current mayor (its politics, with Construction). A fortification that builds in under a second is queued for its whole shortfall. There is no switch for it on the fortification line.

config fortsusereservedConfig

Usage
config fortsusereserved:<share>
Example
config fortsusereserved:1
Values
A share from 0 to 1.
Default
0 (the whole day of food is kept)
See also
troopsusereserved

As troopsusereserved, for fortifications: what share of the day of troop food kept in store fortification batches may spend. When food is what stops a batch, the Engine view says how much is being kept.

15Hero goals

Who becomes mayor, how heroes are levelled and where their points go, who is hired and fired, which prisoners are let go, and which heroes the other goals may send out. Most of these lines take a hero string, explained in full at the end of this section.

What runs, and when

Every pass the bot works each city's hero goals in this order, after comfort and tax and before building:

  1. The mayor is checked (always, unless config nomayor:1).
  2. Levelling and points (only with config hero:1).
  3. Prisoners are released (only with a keepcapturedheroes line).
  4. Hiring and firing (only with config fasthero or keepheroes /always).
  5. Hero items are kept running (only with keepherobuff lines).
  6. The training hero moves on if it is done.

A city does only a few things a pass, so a long list of heroes to level is worked over several passes. The Engine view shows what was done and why something waits.

The mayor

Unless the city has config nomayor:1, the bot keeps a mayor in office:

  • If the city's training hero is in the city (idle or already mayor), it is made mayor at once, so troops train at its speed.
  • Otherwise the hero with the highest politics, among the idle heroes and the mayor, gets the office.
  • To avoid swapping back and forth, a sitting mayor is only replaced when the better hero has more than 5 politics more than it.
  • Heroes out marching are not counted. The bot never removes a mayor without putting another in (except the training hero, which steps down when it leaves).

The stats compared are the heroes' own, without hero items.

config nomayorConfig

Usage
config nomayor:1
Example
config nomayor:1
Values
1 the bot leaves the mayor alone; anything else (or no line) the bot picks the mayor.
Default
Off: the bot picks the mayor.
See also
traininghero, trainpol

With nomayor:1 the bot never appoints, swaps or removes this city's mayor. Use it when you want a particular hero in office that is not the best politician, for example an attack hero for fast training without a traininghero line.

Levelling and points

With config hero:1 the bot goes through the city's heroes (not prisoners) each pass. A hero with enough experience for its next level is raised one level. A hero with unspent points gets them placed: by the first heropoints line that names it, otherwise all into its highest stat. Heroes a nolevelheroes line names are skipped completely: no level-up and no points.

One level a hero a pass, and the points on a later pass, so a hero with a lot of experience climbs steadily over a minute or two rather than all at once.

config heroConfig

Usage
config hero:<0|1>
Example
config hero:1
Values
1 (or more) level heroes and place their points; 0 off.
Default
Off.
See also
heropoints, nolevelheroes

Raises every hero in the city that has the experience for its next level, one level at a time, and places unspent points (heropoints says where; without a line, into the hero's highest stat). It stops early in a pass when the city's actions for that pass run low, and carries on next pass.

It never uses items for this (no experience or reset items).

nolevelheroesGoal

Usage
nolevelheroes <hero string>  or  nolevelheroes /reset
Example
nolevelheroes Merlin,Arthur
nolevelheroes any:base>=75
Values
/reset forgets the nolevelheroes lines above it (useful when the account's prepend goals set some and this city wants others).
Default
None: every hero is levelled.
See also
config hero, hero strings

The heroes it matches are left to you: config hero:1 neither levels them nor places their points. Use it for a hero you want to build by hand. Several lines add up (a hero matched by any of them is skipped).

heropointsGoal

Usage
heropoints <hero string> <stage> [<stage> …]  or  heropoints /reset
Example
heropoints any:politics>attack pol
heropoints Lancelot att:500 att:1000,int:300 att
heropoints any:base>=70 int:200 off
Values
PartMeaning
hero stringOne word (no spaces): which heroes this line is for. See hero strings.
stageOne word: one or more targets joined by commas, worked together. Stages are worked left to right.
stat:capRaise that stat until it reaches cap (the stat's total, not a number of points). Stat words: attack att atk power; politics pol management; intel int intelligence stratagem.
stat or stat:*No cap: every point left goes there.
stat:anyRead as a cap of 0, so that target takes nothing.
off / noneStop here: points beyond the stages before it stay unspent.
/resetForgets the heropoints lines above it.
Default
No line: every point into the hero's highest stat.
See also
config hero, nolevelheroes

Only works with config hero:1. For each hero the first heropoints line whose hero string matches it is used; a hero no line matches gets the default. Within a stage, the points are shared out in proportion to what each target still needs, so att:1000,int:300 moves both stats toward their caps together. A stage whose targets are all reached is skipped.

If the last stage has no open-ended target (and is not off), whatever is left after the last stage goes into the hero's highest stat. Worked example, for heropoints Lancelot att:50 att:100,int:850 att on a hero with attack 40, intelligence 800 and 200 points: stage 1 gives 10 to attack (to 50); stage 2 needs 50 attack and 50 intelligence and gets both; stage 3 puts the last 90 into attack. Result: attack 190, intelligence 850.

off with a big pile of points

When a line ends in off and the hero holds more points than the stages before off need, the bot places none of them that pass (and the next). It only places points while the hero holds no more than those stages still need. Levelling normally gives a few points at a time, so this shows mainly after a points reset. In that case place them by hand once, or use a line without off.

Hiring and firing

The bot only fires heroes in two cases: to make room for a better Inn hero (config fasthero), or because you asked it to clear out everyone not kept (keepheroes /always). In both cases it fires only idle heroes that no keepheroes rule keeps, never the training hero, and the weakest first (lowest base, then lowest level). The mayor and heroes out marching are never fired.

config fastheroConfig

Usage
config fasthero:<base>
Example
config fasthero:65
Values
The lowest hero base worth hiring (a number). 0 is off.
Default
Off.
See also
keepheroes, feastinghallspace, hero strings (base)

Each pass the bot looks at the city's Inn. If a hero there has a base (its best stat as it was born, before points) of at least this number, the best such hero is hired, as long as the city has the gold for the fee.

If the Feasting Hall is full, the bot first fires the weakest idle hero that no keepheroes rule keeps and whose base is lower than the Inn hero's; the hire follows on a later pass. If every hero is kept or better, the Inn hero waits. With feastinghallspace set, that many slots stay empty (one more while the training hero is away): hiring stops there and nobody is fired to make room.

keepheroesGoal

Usage
keepheroes <hero string> [/always]  or  keepheroes /reset
Example
keepheroes any:level>=60|any:base>=70
keepheroes Merlin,Arthur|any:politics>=300
keepheroes any:base>=68 /always
Values
/always fire, one a pass, every idle hero no rule keeps, even when no hire needs the slot. /reset forgets the keepheroes lines above it.
Default
any:level>=50|any:base>=69 (used while the city has no keepheroes line).
See also
fasthero, herofirelimit

Heroes that match are never fired by the bot. Several lines add up: a hero kept by any line is kept. Without /always this line only matters when config fasthero wants a slot.

/always fires for real

With /always the bot fires one idle hero a pass until every idle hero in the city matches a keep rule. A line of just keepheroes /always uses the default rule above, so every idle hero under level 50 with a base under 69 goes. Check your hero string before you add /always.

herofirelimitGoal

Usage
herofirelimit <level>
Example
herofirelimit 40 (the same as keepheroes any:level>=40)
See also
keepheroes

The older way to write a keep rule by level. It is read as keepheroes any:level>=<level> and adds to the city's other keepheroes lines. The level must be 1 or more. Write it once per city (a second line replaces the first).

keepcapturedheroesGoal

Usage
keepcapturedheroes <hero string>  or  keepcapturedheroes /reset
Example
keepcapturedheroes any:level>=100|any:base>=72
keepcapturedheroes none (release every prisoner)
Values
/reset forgets the lines above it; if nothing is left, the built-in rule any:level>=200|any:base>69 is used.
Default
No line: no prisoner is ever released by the bot.
See also
hero strings

This is about enemy heroes your city holds prisoner. Once the city has a keepcapturedheroes line, the prisoners it does not match are released, the lowest level first, one every 10 minutes per city. The kept ones stay in your prison. When a hero string uses best or worst here, it compares against the other prisoners.

The old line capturedfirelimit <level> is read as keepcapturedheroes any:level>=<level>.

spamheroesGoal

Usage
spamheroes <hero string>  or  spamheroes /reset
Example
spamheroes any:level<30,base<=60
spamheroes Spam*
Values
/reset forgets the lines above it.
Default
any:base<=69,level<50
See also
spamattack, loyaltyattack, capture

Says which heroes of the city the background attack commands may send with their waves: spamattack, loyaltyattack and capture. Only idle heroes are used. spamattack also wants the hero at 100 loyalty. The goal does nothing by itself; it only feeds those commands. Several lines add up.

homeheroesGoal

Usage
homeheroes <n>
Example
homeheroes 2
Default
0: every idle hero may go out.
See also
npcheroes, valleyheroes

The city's n best heroes never lead an NPC run or a valley run. "Best" is by the hero's highest stat (attack, politics or intelligence), counting every hero in the city that is not a prisoner, the mayor and heroes out marching included. So if your mayor is your best hero, it is one of the n.

keepherobuffGoal

Usage
keepherobuff <hero> <excalibur|wealth|artofwar> [/below:<n>]
Example
keepherobuff Lancelot excalibur
keepherobuff Merlin wealth /below:1500
Values
WordItemRaises
excalibur, bladeChampion's Bladeattack
wealth, wealthofnations, statecraftBook of Statecraftpolitics
artofwar, treatiseTreatise on Strategyintelligence
/below:<n>: only while the hero's own stat (without the item) is under n.
Default
No line: no item is used.

Keeps the 7-day item running on the hero: whenever nothing is raising that stat on it, one item is used from your stock. The city that holds the hero does it. The hero name is one word and must be the exact name (capitals do not matter). It never buys the item: with none in stock the Engine view says so and it waits. One line per hero and item; write several lines for several.

Rewarding heroes

No goal rewards heroes. Loyalty is yours to look after: use the script command rewardheroes (gold or a medal for every hero under 100 loyalty), by hand or in a script you run now and then. spamattack needs heroes at 100 loyalty, so reward your spam heroes before a run.

Hero strings

A hero string picks heroes by name, by numbers, or both. It is used by keepheroes, keepcapturedheroes, nolevelheroes, spamheroes, heropoints (its first word) and valleyheroes. (npcheroes uses a shorter form, described in its own entry.)

The shape

Grammar
string       = choice | choice | …          // any one choice may match
choice       = names : filters
names        = name , name , !name , any , none …
filters      = field op value , field op value …   // all must hold
  • Choices are joined by |. A hero matches the string when it matches any choice.
  • In a choice, the part before the first : is names; the part after it is filters. Names are separated by commas, and so are filters.
  • Names: the hero matches if it has any of the names listed. any means every hero. Capitals do not matter. * stands for any run of letters and ? for one letter (Ar* is every hero whose name starts with Ar).
  • !Name rules a hero out of that choice whatever else it matches. Wildcards work here too.
  • A choice with no names (only !Names or only filters after the colon) means any: !Bob is everyone except Bob, and :level>=50 is the same as any:level>=50.
  • none matches no hero at all.
  • Filters: every filter of the choice must hold.
  • Spaces are removed before reading. A hero name with a space in it (Sir Bob) can't be written as it is: use Sir?Bob or Sir*Bob.
  • Filters always go after a colon. level>=50 on its own is read as a name and matches nobody. Write any:level>=50.
  • A bare number (keepheroes 50) is an error. The editor suggests any:level>=50.

Fields

FieldShortWhat it is
attackattAttack, the hero's own (hero items not counted)
politicspolPolitics, the hero's own
intelintIntelligence, the hero's own. The full word intelligence is not a field here (it's an error)
levellvlHero level
loyaltyloyLoyalty, 0-100
experienceexpExperience held
pointsptsUnspent points
basebseThe best of the hero's three base stats (what it was born with, before points). The usual measure of a hero's quality: the number the Inn hero's worth is judged by

Operators and values

OperatorMeaning
>=at least
<=at most
>more than
<less than
=exactly
!= or <>not equal

The value on the right can be:

  • a number, with k, m or b for thousands, millions, billions (exp>=1.5m);
  • another field of the same hero (attack>politics, int>=base);
  • best or worst: the highest or lowest value of that field among the heroes being looked at. For most goals that is the city's heroes (prisoners left out). For keepcapturedheroes it is the prisoners. So any:attack=best is the city's top attacker.

Examples

Hero stringMatches
anyevery hero
noneno hero
Merlinthe hero named Merlin
Merlin,ArthurMerlin or Arthur
Ar*every hero whose name starts with Ar
Sir?Bob"Sir Bob" (the ? stands for the space)
!Merlineveryone except Merlin
any:level>=100heroes of level 100 or more
:level>=100the same
any:base>=69heroes with a base of 69 or more
any:base<=69,level<50base 69 or less and under level 50
any:level>=50|any:base>=69level 50 or more, or base 69 or more
!Merlin,any:base>=65base 65 or more, but never Merlin
Merlin,Arthur|any:attack>=600Merlin, Arthur, or any hero with attack 600 or more
Ar*:level>=20heroes named Ar… of level 20 or more
any:attack>politicsheroes whose attack is higher than their politics
any:politics>attack,politics>intpolitics heroes (politics is their top stat)
any:attack=bestthe hero with the highest attack
!Merlin,any:politics=bestthe best politician, unless that is Merlin (then nobody)
any:level=worstthe lowest-level hero(es)
any:loyalty<70heroes under 70 loyalty
any:points>0heroes with unspent points
any:exp>=2mheroes holding 2 million experience or more
any:level>=10,level<=40,base!=70level 10 to 40, base anything but 70
any:int>=baseheroes whose intelligence is at least their base

A line whose hero string can't be read turns red in the goal editor, and the line under the editor says why (an unknown field, a filter with no operator, a value it can't read). Such a line is left out. The other lines of that goal still count.

16NPC farming goals

Attacking the NPC camps around your city again and again for their resources and your heroes' experience: which levels, with what, how far out, and how often each camp is hit.

The least you need

Two things: config npc (the lowest level to farm) and an npctroops line for each level you want hit. A level with no npctroops line is never farmed. There are no built-in armies, because what a camp holds on Citavon is not what it held on the old server. Work out what each level needs from the game guide and your own battle reports.

A small farming setup
config npc:3,farmingcycle:8.4
npctroops 5 a:3k,t:200          // level 5: 3,000 archers, 200 transporters
npctroops 4 a:1500,t:100
npctroops 3 a:600,t:50
npcheroes any:level>=10
npcteams 6
distancepolicy 12
excludelist 120,340 122,341

How the bot picks a camp

Each pass, a city with config npc sends at most one NPC attack. It goes through the levels from 10 down to your config npc level and sends to the first level where everything is ready:

  1. Nothing happens in War Town Mode, when npcteams attacks are already out, when the Rally Spot is full, or when npclimit says the city has enough food.
  2. The level needs an npctroops line, and the city must hold that army at home plus what npclimits keeps back. If not, the bot tries the next level down.
  3. It needs an idle hero that npcheroes allows (see there for who is skipped). The one with the highest attack is chosen.
  4. The camps of that level: the npclist for it if there is one; otherwise every NPC on the map within range (farmingpolicy distances, else distancepolicy, else 10 miles), inside npcbounds if set. Not in the excludelist, and not a camp one of your attacks is already marching to.
  5. Of those, the nearest camp not hit within its cycle is chosen. If none is due and a minimum cycle applies (levels 1-5 only, see cycles), the camp that has rested longest past the minimum is chosen.
  6. The attack goes. Its march is tagged as NPC farming, so processingpolicy (task n) and rallypolicy (n, by level) can hold it.

So with one npctroops line covering levels 1-5, the bot hits the level-5 camps while any is due, then the level 4s, and so on down. If troops run short for a level, it drops to a level it can supply. The Engine view lists why the top levels wait.

The army sent is exactly the npctroops line (plus ballistas from ballsused). Nothing is scaled to the camp's loot.

Not stopped by an incoming attack

NPC farming does not stop by itself when an enemy attack is on its way. Use War Town Mode (config wartown), processingpolicy or the war goals to hold your troops home.

Cycles, and what resets them

The cycle is how long a camp rests between two of your hits. The bot remembers when it last sent to each camp, for the whole lord (all your cities share it, so two of your cities don't hit the same camp inside its cycle). The cycle for a level is the first of these that applies:

  1. config training:1 or 2 (levels 1-9) or config training10:1 (level 10): 1 hour.
  2. The /farmingcycle: of a farmingpolicy for that level (or one with no level).
  3. config farmingcycle.
  4. 8.4 hours. A camp's resources refill over 8 hours, so 8.4 hours finds it full.

For levels 1-5 only, a minimum can let a camp be hit early when nothing is due: farmingcyclemin, or 1 hour with smartfarming:2 or 3. A minimum that is not shorter than the cycle is ignored. Training mode has no minimum.

The memory of when each camp was hit lasts while the lord's bot runs. It is not cleared by the daily maintenance: the bot waits out the maintenance (and up to two minutes more, so not every bot logs back in at once), logs in again and carries on with the same cycles. If you restart the lord's bot, the memory starts empty and every camp in range counts as due.

The bot reads the map live, so it notices camps that appear or vanish. Every few days the maintenance turns some old camps into flats, and those just drop out of the list. (An npclist is the exception: see there.)

Training mode (hero experience)

On the old server, "training" meant hitting low camps every hour to level heroes fast. Here:

  • config training:1: levels 1-9 on a 1-hour cycle. The troops are still your npctroops lines.
  • config training:2: meant to work like 1 but leave transporters at home. At present it still sends them, so it acts the same as training:1. Leave the transporters out of your npctroops lines instead.
  • config training10:1: level 10 on a 1-hour cycle.
  • By default the bot keeps intelligence heroes and your spare politics hero at home. trainint:1 and trainpol:1 let them farm, to level them too.

Config keys

config npcConfig

Usage
config npc:<level>
Example
config npc:5
Values
The lowest NPC level to farm, 1-10. 0 is off.
Default
Off.
See also
npctroops, how a camp is picked

Turns NPC farming on for the city. The bot farms the highest level it can supply and works down to this level as troops or heroes run short or no camp is due. Only levels with an npctroops line are ever farmed. npc:5 with npctroops for levels 5 and 10 farms 10 first, then 5.

config npclimitConfig

Usage
config npclimit:<days>
Example
config npclimit:3
Values
Days of food (fractions allowed). 0 off.
Default
Off.

Stops sending NPC attacks while the city holds at least this many days of its troops' food use and its food income is not negative. Farming starts again once the food drops below it. A city whose troops eat nothing never stops this way.

config farmingcycleConfig

Usage
config farmingcycle:<hours>
Example
config farmingcycle:6
Values
Hours (fractions allowed) between two hits on the same camp.
Default
8.4 hours.
See also
farmingpolicy, cycles, valleyfarming

The cycle for every level that has no farmingpolicy cycle of its own and is not in training mode. It is also the rest time between hits on one valley for valley farming.

config farmingcycleminConfig

Usage
config farmingcyclemin:<hours>
Example
config farmingcyclemin:4
Values
Hours, more than 0.
Default
None (1 hour with smartfarming:2 or 3).

Levels 1-5 only. When no camp of a level is past its full cycle, a camp that has rested at least this long may be hit: the one that has rested longest. Keeps your teams busy when you have few camps nearby. Ignored if it is not shorter than the cycle, and in training mode.

config smartfarmingConfig

Usage
config smartfarming:<0-3>
Example
config smartfarming:2
Values
2 or 3: a 1-hour minimum cycle on levels 1-5 (as farmingcyclemin:1), unless farmingcyclemin is set. 0 and 1 change nothing.
Default
0.

On the old server, modes 1 and 3 also sized each run to the camp's loot. That part does nothing here: the bot can't know how far a camp has refilled, so it always sends the full npctroops army.

config trainingConfig

Usage
config training:<0|1|2>
Example
config training:1
Values
1 levels 1-9 on a 1-hour cycle. 2 the same, meant to leave transporters home (at present they still go). 0 off.
Default
0.
See also
training mode, training10

Overrides every other cycle for levels 1-9. The camps' troops grow back within the hour, so each hit is a full battle and full experience for the hero. The camps' resources do not refill that fast, so expect smaller loot.

config training10Config

Usage
config training10:<0|1>
Example
config training10:1
Default
0.

Level-10 camps on a 1-hour cycle, overriding every other cycle for level 10. You still need an npctroops 10 line.

config ballsusedConfig

Usage
config ballsused:<n>  or the old line  ballsused <l1>,<l2>,<l3>,<l4>,<l5>
Example
config ballsused:50
ballsused 25,50,170,250,500
Values
A whole number of ballistas.
Default
0.

As a config key: that many ballistas are added to every NPC run whose npctroops line names no ballistas (at every level). The city must have them.

As its own line (the old form), the five numbers are the ballistas for levels 1 to 5, and each is read as an npctroops line: ballsused 25,50,170,250,500 becomes npctroops 1 b:25, npctroops 2 b:50 and so on. A 0 is refused (it would send nothing but transport), so that level keeps its own line.

config trainintConfig

Usage
config trainint:<0|1>
Example
config trainint:1
Default
0: intelligence heroes stay home.

An intelligence hero (one whose intelligence is higher than both its attack and its politics) does not lead NPC runs unless this is 1. Applies to NPC farming only, not to valley runs.

config trainpolConfig

Usage
config trainpol:<0|1>
Example
config trainpol:1
Default
0: the spare politics hero stays home.

The idle hero with the most politics, if it has more than the mayor (or there is no mayor), is kept home so it can take the office. With trainpol:1 it may farm like any other hero. Applies to NPC farming only.

config mapscanConfig

Usage
config mapscan:<0|1>
Example
config mapscan:1

Accepted so old goal files read cleanly; it does nothing. Citavon Bot reads the map live whenever it looks for camps or valleys, so there is no saved map to fill.

Goal lines

Many NPC lines take an optional level first. Which levels a line without one covers depends on the goal:

GoalNo level written meansSeveral lines
npctroops, npcheroeslevels 1-5a line for the exact level beats a line with no level; the last such line wins
npclimitslevels 6-10
npclist, npcbounds, farmingpolicyevery levelthe same

The old level-10 lines still work: npc10troops is read as npctroops 10, npc10limit / npc10limits as npclimits 10, npc10list as npclist 10, and npcexcludelist / npc10excludelist as excludelist. The editor notes each one.

npctroopsGoal

Usage
npctroops [level] <troops>
Example
npctroops 5 a:2k,c:500,t:100
npctroops a:800,t:50 (levels 1-5)
npctroops 10 a:60k,b:5k,cp:1k
Values
Troops as code:amount joined by commas: w warriors, wo workers, s scouts, p pikemen, sw swordsmen, a archers, c cavalry, cata cataphracts, t transporters, b ballistas, r rams, cp catapults. Amounts take k and m.
Default
None: a level with no line is not farmed.

The exact army an NPC run at that level takes. A line with no level covers levels 1-5. Levels 6-10 need a line each. Before sending, the city must have this army at home on top of what npclimits keeps back; if not, the bot tries a lower level. Add transporters for more room to carry loot home.

npcheroesGoal

Usage
npcheroes [level] <heroes>
Example
npcheroes any:level>=10
npcheroes 10 !Merlin,any
npcheroes 6 Lancelot,Gawain|any:att>=300
Default
any
See also
homeheroes, trainint, trainpol, npc10heroes

Who may lead NPC runs at that level. A line with no level covers levels 1-5; levels 6-10 with no line of their own take any hero. The bot picks, among the city's idle heroes, the one with the highest attack (hero items counted here) that the line allows. Always left at home: the homeheroes, heroes already sent this pass, intelligence heroes (unless trainint:1), and the spare politics hero (unless trainpol:1). The mayor is never idle, so it never goes.

A shorter form than a full hero string

npcheroes reads its own, simpler form, not the full hero string:

  • The line is first cut at every comma. Each piece is a separate choice, and the hero needs to match one of them. !Name pieces rule that hero out.
  • A piece is any, an exact hero name (no * or ?), or name:filter / any:filter. Pieces may be joined with |.
  • Because of the comma cut, a piece holds one filter only. any:att>=100,lvl>=20 becomes two choices, "attack 100 or more" or a hero named "lvl>=20", so it is really just attack 100 or more.
  • Fields: att/attack, pol/politics, int/intel, lvl/level, base. Operators: >= <= > < =, with a plain number. Anything else (another field, best, loyalty, !=) is ignored, so that piece matches every hero.

npc10heroesGoal

Usage
npc10heroes <heroes>
Example
npc10heroes Lancelot,Gawain
See also
npcheroes

The older spelling of npcheroes 10 <heroes>, read the same way (the editor notes it). If the city has both, the npcheroes 10 line is used.

npclimitsGoal

Usage
npclimits [level] <troops>
Example
npclimits a:20k,p:10k (levels 6-10)
npclimits 3 a:5k
Default
Nothing is kept back.

Troops that must stay at home when the bot farms that level. A run goes only if the city holds the npctroops army plus these. A line with no level covers levels 6-10 (unlike npctroops). Same troop codes as npctroops.

npcteamsGoal

Usage
npcteams <n>
Example
npcteams 5
Default
10.
See also
rallypolicy

At most this many attacks out from the city at once before NPC farming waits. It counts every attack of the city on its way or coming back (valley runs and attacks you or a script sent too), but not troops camped somewhere. npcteams 0 stops NPC farming. Valley farming and medal hunting use the same number for their own catch-and-release runs (there, 0 counts as 10). The Rally Spot's free slots still limit everything.

npclistGoal

Usage
npclist [level] <x,y> [<x,y> …]
Example
npclist 5 101,220 104,225 98,231

With a list for a level, the bot farms only those camps at that level, nearest first, and does not look at the map for that level. A list with no level is used for every level.

The list is trusted as it is

The bot does not check what stands on a listed tile now: not its level, not the distance, not whether it is still an NPC (the maintenance sometimes turns old camps into flats). Give each list its level, so the right army goes, and remove tiles that have changed. The excludelist and the cycle still apply.

npcboundsGoal

Usage
npcbounds [level] <Xmin> <Xmax> <Ymin> <Ymax>
Example
npcbounds 90 130 200 240
npcbounds 10 0 200 0 200

Only camps inside this box are farmed (the distance limits still apply too). With 4 numbers it covers every level; with 5, the first is the level. The two X (or Y) values may be written in either order.

farmingpolicyGoal

Usage
farmingpolicy [level] [/level:<n>] [/mindistance:<miles>] [/maxdistance:<miles>] [/farmingcycle:<hours>]
Example
farmingpolicy 5 /maxdistance:15 /farmingcycle:6
farmingpolicy /level:10 /mindistance:5 /maxdistance:25 /farmingcycle:12
Values
SwitchMeaning
level or /level:nThe NPC level this line is for. No level: every level without a line of its own.
/mindistance:Skip camps nearer than this (miles). Default 0.
/maxdistance: (or /distance:)Skip camps further than this. Default distancepolicy's first number, else 10.
/farmingcycle: (or /cycle:, /maxcycle:, /cyclemax:)Hours between hits on one camp of this level. Beats config farmingcycle, loses to training mode.
/mincycle: /cyclemin: /safeballs: /teams:Accepted from old files; they do nothing. Use farmingcyclemin and npcteams.
See also
cycles

Distance and cycle for one NPC level. The bot never looks further than 60 miles, whatever the maximum.

distancepolicyGoal

Usage
distancepolicy <npc miles> [<npc-building miles>] [<valley miles>]
Example
distancepolicy 12 8 15
distancepolicy 20
Values
NumberUsed by
1stNPC farming's reach (when no farmingpolicy gives one) and acquireflats.
2ndbuildnpc's reach for flats (when no npcbuildpolicy gives one).
3rdValley goals: valley, valleyfarming (without its own line), safevalleyfarm; hunting looks three times as far.
Default
10 miles for each.

How far out, in miles, the goals look. Old files may carry more numbers after these; they are ignored. Write the numbers plainly. /npc:15 is also read as the first number, but then the numbers after it are not read in the right places, so use it only on its own. One line per city: a second one replaces the first. The bot never looks further than 60 miles.

excludelistGoal

Usage
excludelist <x,y> [<x,y> …]
Example
excludelist 120,340 122,341

NPC farming never attacks these tiles, at any level, even from an npclist. Several lines add up. Use it for an ally's camp or one you are taking over. The old npcexcludelist, npc10excludelist and noabandonflats lines are read as excludelist. It does not affect valley goals.

17Building NPCs

Making new NPC camps near your city: the bot takes a flat, founds a city on it, and gives that city up again, which leaves an NPC of the flat's level on the tile.

What the bot does

With config buildnpc set, every pass the city works these steps in order:

  1. Give up the cities it founded for this. Before it founds a city, the bot writes down the exact tile, and it keeps that list even across restarts. A city on such a tile is given up (an NPC of the flat's level then stands there) only when all of these hold:
    • it was founded at least /minage minutes ago (default 5) and no more than /maxage hours ago (default 24). An older one is left alone for good;
    • the lord keeps more than /keepcities cities (default 2);
    • it has no hero and no troops in it, and no march out;
    • it holds no more than /maxres of any resource, gold included (default 5m);
    • fewer than /perday cities were given up in the last 24 hours (default 4).
    Another city of yours with config buildnpc does this, not the new city itself. A claimed tile that has not become a city within an hour is dropped from the list.
  2. In War Town Mode it stops here.
  3. Found a city on a flat it holds. If the city holds a flat of a wanted level and fewer than /maxconcurrent flats are being turned (default 1), it sends a build march with 250 workers. It needs room for another city under your title, at least 10,000 of each of food, wood, stone, iron and gold, and 250 workers. Otherwise the Engine view says what is short.
  4. Take a flat. If a hold slot is free and no capture is already on its way, it attacks the nearest free flat of a wanted level within reach (npcbuildpolicy, else distancepolicy's second number, else 10 miles), from buildnpclist if you have one. The army is valleytroops for that level, else the built-in capture army (see valley armies); the hero and what stays home follow valleyheroes, valleylimit and homeheroes.

The capture and the build march are tagged as task b for processingpolicy and rallypolicy.

Giving up a city can't be undone

The bot only ever gives up a city on a tile it wrote down itself before founding it, within the age window, empty, and never below /keepcities. A city you captured or built by hand is never touched, however empty it looks. Even so: the new city starts with your account's new-city goals and script. If they train troops or hire a hero there, the city is never empty enough and is kept, and once it is older than /maxage it is kept for good.

config buildnpcConfig

Usage
config buildnpc:<0|1-5|10|15|20>
Example
config buildnpc:5
Values
1-5 flats of that level; 10 level 10; 15 levels 5 and 10; 20 every level 1-10; 0 off.
Default
Off.
See also
buildnpcpolicy, npcbuildpolicy, buildnpclist

Turns NPC building on for the city, for flats of those levels. A flat keeps its level while you hold it, and the new NPC gets that level. Any flat the city already holds at a wanted level is used too, including one taken with acquireflats.

buildnpcpolicyGoal

Usage
buildnpcpolicy [/maxconcurrent:n] [/keepcities:n] [/maxres:n] [/maxtroops:n] [/minage:min] [/maxage:h] [/perday:n]
Example
buildnpcpolicy /maxconcurrent:2 /keepcities:3 /perday:6
Values
SwitchDefaultMeaning
/maxconcurrent:1Flats being turned into NPCs at once (founded, not yet given up).
/keepcities:2Never give up a city while the lord has this many cities or fewer.
/maxres:5mA new city holding more than this of any resource (gold too) is not given up yet.
/maxtroops:250Accepted, but does nothing: any troop in the city keeps it.
/minage:5Minutes a new city stands before it is given up.
/maxage:24Hours: a city founded longer ago is never given up.
/perday:4Cities given up in any 24 hours, for the whole lord.

The safety limits of NPC building. One line per city; switches you leave out keep their defaults. Numbers take k, m, b. An unknown switch turns the line red in the editor; the other switches on it still count.

npcbuildpolicyGoal

Usage
npcbuildpolicy [/level:<n|a-b>] [/mindistance:<miles>] [/maxdistance:<miles>]
Example
npcbuildpolicy /level:5 /mindistance:3 /maxdistance:8
npcbuildpolicy /level:1-4 /maxdistance:5
Values
/level: one level or a range; left out, the line covers every level. /mindistance: default 0. /maxdistance: default the minimum plus 1.
Default
No line: 0 to distancepolicy's second number (else 10) miles.

How far out flats of each level are taken for NPC building. Several lines may be written; for each level the first line that covers it is used. Watch the default maximum: npcbuildpolicy /mindistance:6 alone means 6 to 7 miles.

buildnpclistGoal

Usage
buildnpclist <x,y> [<x,y> …]
Example
buildnpclist 105,214 107,216

Only these flats are taken for NPC building (they must still be free, of a wanted level and within reach). Several lines add up.

18Valley goals

Taking and holding valleys and flats, and "catch and release" runs on valleys for medals: valley farming, medal hunting and safe valley farming.

How the valley goals work

  • Each goal is off until you write its line. A city holds as many valleys and flats as its Town Hall allows. A winning attack with a slot free takes the tile.
  • Nothing goes out in War Town Mode or while an enemy attack the Beacon Tower sees is coming at the city.
  • Every run needs its army at home on top of valleylimit, an idle hero that valleyheroes allows (not one of the homeheroes; the one with the highest attack goes) and a free Rally Spot slot.
  • A tile another lord holds, or one an attack of yours is already marching to, is never a target (except a huntingpos valley, see there). The map is read live, so after the daily maintenance has moved the valleys you don't hold up a level, the bot finds them at their new level by itself.
  • A lost battle: the bot reads your battle reports. If a run of its own loses at a valley, that level (for flats, that flat level) is not attacked again. This lasts until the lord's bot is restarted, even if you add valleytroops for that level. So add the bigger army first, then restart the bot.
  • Marches are tagged for processingpolicy and rallypolicy: a valley and flat capture, v valley farming, m medal hunting, s safe valley farming (scouts too).

Medal hunting with valleys

Valley battles can drop medals. The farming goals use "catch and release": the bot attacks a valley, and if the battle is won and a slot was free (so the city now holds it), it lets that valley go again on the next pass. That keeps your slots free and puts the valley back for the next run. Three goals do this, and a city may run all three:

Medal hunting

config hunting: one valley, set by huntingpos or the nearest of a huntingtype, hit again as soon as the last attack on it has landed. No rest time.

Valley farming

config valleyfarming: every free valley of one level in reach, each at most once per farmingcycle (8.4 h by default). Several runs a pass.

Safe valley farming

safevalleyfarm: scouts first and hits only valleys the scouts saw lightly held, each at most once an hour.

Hunting and farming stop sending when npcteams (default 10) of these catch-and-release runs from the city are out. Their army is valleytroops for the level, else the built-in hunting army below. Which medals drop, and how often, is a game rule: see the game guide.

Built-in armies

Used for a level that has no valleytroops line. These are the old server's well-known sizes. Citavon's valleys at the highest levels may be held more strongly, so watch your first reports and write valleytroops where a run falls short. Each army also needs a hero.

LevelCapture (valley, acquireflats, buildnpc)Hunting and farming
150 archers50 archers
2100 archers100 archers
3200 archers200 archers
41,200 warriors, 400 archers400 archers
52,400 warriors, 800 archers1,000 archers
64,800 warriors, 1,600 archers2,000 archers
79,600 warriors, 3,200 archers5,000 archers
819,200 warriors, 6,400 archers10,000 archers, 1 ballista
938,400 warriors, 12,800 archers20,000 archers, 1,000 ballistas
1060,000 warriors, 19,990 archers25,000 archers, 2,000 ballistas

From level 4 up, the capture army also takes 1 scout, 1 pikeman and 1 swordsman, and the hunting army 1 warrior, 1 pikeman and 1 swordsman; from level 5 up both add 1 cavalry.

Config keys

config valleyConfig

Usage
config valley:<level>
Example
config valley:8
config valley:8,valleymin:5
Values
Valley level 1-10; 0 off.
Default
Off.
See also
valleymin, valleytroops, distancepolicy

Captures and holds valleys that feed the city's main resource. The bot counts the city's resource buildings and picks the kind it has most of: farms mean lakes, sawmills forests, quarries deserts, iron mines hills (with no resource buildings, lakes). One capture at a time, within distancepolicy's third number (default 10 miles), with the capture army for the level.

Without valleymin only valleys of exactly this level are taken. With it, the bot takes the nearest free valley of that kind whose level is anywhere from valleymin to this level. It doesn't hold out for the highest level. It stops when the city's valley slots are full (flats you hold don't count toward that).

config valleyminConfig

Usage
config valleymin:<level>
Example
config valley:9,valleymin:6
Values
Level 1-10, not above valley.
Default
The same as valley.

Only works with config valley. It sets the lowest level worth capturing, and it turns on upgrading: once every valley slot is full, the bot lets go of your lowest held valley below the valley level as soon as it sees a free valley of the right kind at a higher level (within the range), and captures that one on a later pass.

Let go first, captured after

The old valley is released before the new one is attacked. If the capture then loses (or someone else takes it), you are a valley short until the bot finds another.

config acquireflatsConfig

Usage
config acquireflats:<0|1|2>
Example
config acquireflats:1
Values
1 keep one flat held; 2 fill every free slot with flats; 0 off.
Default
Off.

Captures the nearest free flat (any level) within distancepolicy's first number (default 10 miles), one at a time, with the capture army for its level. It stops when it holds enough flats or the slots are full. Held flats are where you found new cities, or what buildnpc builds on.

config abandonflatsConfig

Usage
config abandonflats:<0|1>
Example
config abandonflats:1

Accepted, but does nothing: the bot never lets flats go for this. On the old server it released held flats before maintenance so they could level up. The Engine view says it has nothing to do.

config abandonConfig

Usage
config abandon:<0|1>
Example
config abandon:1
Default
Off.

Strips a city you mean to give up or hand over. Every pass it cancels the building under way, cancels the troops in training, demolishes every fortification, sets the tax to 100%, and sends every troop (as reinforcements) to your nearest other city. While it is on, the city's other valley goals do nothing. It does not give the city up; you do that yourself.

Costly, and it keeps going

Cancelled troops give back only part of their cost, and demolished fortifications are gone. It runs every pass until you remove the line. Put it only in the goals of the one city you mean, never in the account's prepend or append goals.

config huntingConfig

Usage
config hunting:<level>
Example
config hunting:5
Values
Valley level 1-10; 0 off.
Default
Off.
See also
huntingpos, huntingtype, medal hunting

Medal hunting on one valley. The valley is the one at huntingpos if set, otherwise the nearest free valley of this level of the huntingtype kind (default: the city's own kind, as for config valley). The bot looks up to three times distancepolicy's valley miles (30 by default). Each pass, if no attack of yours is on its way to it, a new run goes with the next free hero, and a win is let go at once. There is no rest time between hits.

With huntingpos, the level in this line is not checked against the valley: the run takes the army for the valley's real level.

config valleyfarmingConfig

Usage
config valleyfarming:<level>
Example
config valleyfarming:4
Values
Valley level 1-10; 0 off.
Default
Off.
See also
valleyfarming (the miles line), farmingcycle

Catch-and-release runs on every free valley of this level in reach, nearest first. Reach is the valleyfarming miles line if you have one, otherwise the city's own kind of valley within distancepolicy's valley miles. Several runs may go in one pass, until npcteams runs are out, the city's actions for the pass run low, or a run can't go. Each valley rests farmingcycle hours (8.4 by default) between hits.

Goal lines

valleyfarmingGoal

Usage
valleyfarming <forest> <desert> <hill> <swamp> <grassland> <lake>
Example
valleyfarming 15 0 0 10 10 20
Values
Six numbers, miles for each kind of valley in that order; 0 leaves that kind out.
Default
No line: only the city's own kind, within distancepolicy's valley miles.

Which kinds of valley config valleyfarming hits, and how far for each. The example farms forests up to 15 miles, swamps and grasslands up to 10, lakes up to 20, and no deserts or hills. It wants exactly six numbers. With fewer, the line turns red in the editor but is still used, and the missing kinds count as 0 (left out). Numbers past the sixth are ignored. One line per city.

safevalleyfarmGoal

Usage
safevalleyfarm <level>[,<level>…]  (also spelled safevalleyfarming)
Example
safevalleyfarm 3,4,5
safevalleyfarming 6
Values
One or more valley levels 1-10, joined by commas or spaces.

Catch-and-release with a look first. Within distancepolicy's valley miles, for free valleys (not flats) of these levels:

  1. The bot scouts a valley it hasn't scouted in the last 6 hours, with up to 10 scouts, one valley a pass.
  2. When the scout report comes in, it adds up the troops seen (a rough count like "Horde" counts as its top number). The valley is judged safe if the scouting succeeded and it saw no more than half the hunting army for that level.
  3. A safe valley not hit in the last hour gets a hunting-army run (or valleytroops), and a win is let go at once. Each valley is scouted again after 6 hours and judged afresh.

It needs scouts in the city. It judges the troops only, not the valley's hero.

huntingposGoal

Usage
huntingpos <x,y>
Example
huntingpos 143,287
See also
config hunting

The exact valley config hunting hunts on. It beats huntingtype. It must be within three times the valley miles of the city.

Who holds it is not checked

The bot hunts on this tile whoever holds it. If another lord takes the valley, your runs attack him there. Watch your reports, and change or remove the line when that happens.

huntingtypeGoal

Usage
huntingtype <forest|desert|hill|swamp|grassland|lake>
Example
huntingtype swamp
Values
Short forms: fo, d, h, s, g / grass, l; plurals work. Flats are refused.
Default
The city's own kind (as for config valley).

The kind of valley config hunting looks for, when there is no huntingpos.

valleyheroesGoal

Usage
valleyheroes <hero string>
Example
valleyheroes any:level<40
valleyheroes !Merlin,any:attack>=200
Default
any
See also
hero strings, homeheroes

Who may lead valley and flat runs: capture, acquireflats, buildnpc's captures, hunting and both kinds of valley farming. It takes a full hero string, and several lines add up. Among the idle heroes it allows (less the homeheroes), the one with the highest attack goes.

valleylimitGoal

Usage
valleylimit <troops>
Example
valleylimit a:20k,w:10k
Default
Nothing kept back.

Troops that stay home whatever valley runs want: a run goes only if the city has its army plus these. One word, no spaces (troop codes as in npctroops). One line per city.

valleytroopsGoal

Usage
valleytroops <level> <troops>
Example
valleytroops 8 a:15k,w:1,p:1,sw:1,c:1,b:500
Default
The built-in armies.

The army for every valley and flat run at that level: capture, acquireflats, buildnpc's captures, hunting and farming all use it. (There is no separate capture and hunting line.) The troops are one word with no spaces. Write one line per level; for the same level, the last line wins.

19Resource goals

Moving resources and troops between your cities, and buying and selling on the market: the six transfer goals, config trade, tradepolicy and resourcelimits.

How transfers work

There are two kinds of transfer line. A request line (requestresources, requesttroops) is written in the city that wants something, and pulls it from your other cities. A push line (sendresources, sendtroops, keepresources, keeptroops) is written in the city that has too much, and sends the surplus away. You can use either kind, or both: the bot makes sure the two never fight each other.

GoalWritten inMovesPicks the other city
requestresourcesthe city that wants itone resource, on carriersthe sender with the most to spare
requesttroopsthe city that wants themone troop type, as a reinforcementthe nearest sender that is free
sendresourcesthe city that has too muchone resource, on carriersthe nearest receiver that needs it
sendtroopsthe city that has too manyone troop type, as a reinforcementthe nearest receiver that needs them
keepresourcesthe city that has too muchseveral resources, each kept at a levelthe nearest receiver
keeptroopsthe city that has too manyseveral troop types, each kept at a levelthe nearest receiver

Things all six have in common:

  • Your own cities only, apart from one exception: a push line may name another lord's city by its x,y. Requests only ever draw from the cities of the same lord.
  • Where to or where from is any (all your other cities), a city name, or x,y. Join several with |, e.g. Rome|Carthage|210,377. A leading ! (as some NEAT files write it) is ignored. City names with spaces cannot be written here: use the city's x,y.
  • Amounts take k, m and b (500k, 1.5m, 2b). * means "no limit" for that amount.
  • Counting what is on its way. A city's stock includes what is already marching to it, so the bot does not send twice. For requestresources that is your transports heading to the city. For the other five it is your transports and reinforcements heading there, plus (for resources) market purchases on their way.
  • Carriers. Resources ride on transporters unless you name another troop type. Each carrier holds its load (more with Logistics), less the food the carriers eat on the road, which comes out of the hold.
  • The Rally Spot. Every transfer is a march from the sending city, so the sender needs a Rally Spot with a free slot, and one march carries at most the Rally Spot's limit (10,000 troops a level). What does not fit goes in a later march.
  • Policies. A resource transfer is task r and a troop transfer task t in the sending city's processingpolicy and rallypolicy. If the sender has that task turned off, or its slots for that kind are full, the transfer waits.
  • War Town Mode. A city in War Town Mode sends nothing: its push lines wait, and other cities' requests skip it. It still receives, and its own requests still pull.
  • When. Transfers run every pass (about every 15 seconds), inside the city's schedulepolicy hours, after building, research and training. A city does at most six things a pass, so a busy city may leave a transfer for the next pass.
Request and push lines respect each other

A push line never takes its city below the level at which that city's own request line would ask for the same thing back. A request or a push to any never fills a city past the level at which that city's own push line would send it on again. So sendresources in one city and requestresources in another can't bounce the same food back and forth.

requestresourcesGoal

Usage
requestresources <from> <type> <localAmount> <remoteAmount> [minBatch] [maxBatch] [troopType] [/below:<amount>] [/maxdist:<tiles>]
Example
requestresources any food 50m 100m 5m * t
requestresources Rome|Carthage iron 20m 5m 1m 10m cav /below:10m /maxdist:40
Values
ValueMeaning
fromany, a city name or x,y of your own cities, several joined by |.
typefood (f), wood (w, lumber, l), stone (s), iron (i), gold (g).
localAmountAsk only while this city holds less than this (counting transports on their way), and never fill it past this. *: no limit, take everything the senders can spare.
remoteAmountNever take a sending city below this. *: a sender may be emptied.
minBatchDon't send less than this at a time, unless this city is down to half of localAmount or less. Optional; * or left out: no minimum.
maxBatchAt most this much a send. Optional; * or left out: as much as one march can carry.
troopTypeWhat carries it. Optional; default transporters (t). Any troop word works, e.g. cav.
/below:Only start asking once the city is under this. Once a send has gone out, it keeps asking until localAmount is reached, then waits for the city to drop under /below again.
/maxdist:Only senders at most this many tiles away. /40 is short for /maxdist:40.
Default
None: the first four values are required.
See also
sendresources, keepresources, requesttroops

Each pass, each line is checked once. If the city holds localAmount or more, counting what is already on its way, nothing happens. Otherwise the bot looks at every city named in from, except this one, cities in War Town Mode, and cities further than /maxdist. A city can send if it holds more than remoteAmount, has at least one of the carrier troop at home, and has a Rally Spot with a free slot. Of those, the one with the most to spare sends.

The amount is the smallest of: what is missing up to localAmount, what the sender has above remoteAmount, maxBatch, and what one march can carry. The march uses the sender's carriers (up to the Rally Spot's limit), but only as many as the load needs. The food the carriers eat on the way is taken out of the hold first. If the amount is under minBatch and this city is not at half of localAmount or less, the line waits.

After a send the line rests for 30 seconds. After that the transport is counted as on its way, so the next pass only asks for the rest.

Unlike the push lines

requestresources does not keep any carriers back in the sender, and it doesn't look at the sender's own lines. Use remoteAmount to protect what the sender needs.

The /slots and /steps switches are accepted on this line but change nothing.

requesttroopsGoal

Usage
requesttroops <from> <troop> <localAmount> <remoteAmount> [minBatch] [maxBatch] [/slots:N] [/maxdist:<tiles>]
Example
requesttroops any a 200k 50k 10k
requesttroops 210,377 cata 50k 0 5k 20k /slots:2
Values
ValueMeaning
fromany, a city name or x,y of your own cities, joined by |.
troopA troop word: wo worker, w warrior, s scout, p pikeman, sw swordsman, a archer, t transporter, c cavalry, cata cataphract, b ballista, r battering ram, cp catapult (full names and plurals work too).
localAmountAsk while this city has fewer than this at home, counting reinforcements on their way; never fill it past this. *: no limit.
remoteAmountNever take a sending city below this. *: down to 0 (but see below).
minBatchDon't send fewer than this at a time, unless this city is at half of localAmount or less.
maxBatchAt most this many a send.
/slots:How many marches may be on the road at once between one sender and this city (going or coming back). Default 1.
/maxdist:Only senders at most this many tiles away (/40 works too).
Default
/slots:1; no batch limits.
See also
sendtroops, keeptroops, recall

The bot lists your other cities that have troops of that type to spare, nearest first. A sender's spare is its troops at home minus the larger of remoteAmount and the sender's own requesttroops level for the same troop, so a sender never gives away troops it would ask for straight back. The nearest sender that has fewer than /slots marches on the road to this city sends. Cities in War Town Mode and cities beyond /maxdist are skipped.

The troops go as a reinforcement and join this city. One send carries at most the Rally Spot's limit, and only troops at home count. Troops in training, out on a march or in another city are not counted on either side.

sendresourcesGoal

Usage
sendresources <to> <type> <localAmount> <remoteAmount> [minBatch] [maxBatch] [troopType] [/slots:N] [/maxdist:<tiles>]
Example
sendresources any stone 30m 20m 2m 10m
sendresources 155,402 food 200m * 10m 50m t (another lord's city: remoteAmount must be *)
Values
ValueMeaning
toany (all your other cities), a city name, or x,y, joined by |. An x,y that is not your city is another lord's.
typefood, wood, stone, iron or gold (or f w l s i g).
localAmountWhat this city keeps. Only what is above it is sent.
remoteAmountFill a receiver up to this at most. *: no limit. Must be * for a city that isn't yours, because the bot can't see its stock.
minBatchDon't send less than this at a time, unless the receiver is at half of remoteAmount or less.
maxBatchAt most this much a send.
troopTypeWhat carries it; default transporters.
/slots:Marches on the road at once between this city and one receiver (going or coming back). Default 1.
/maxdist:Only receivers at most this many tiles away.
Default
/slots:1; carriers: transporters.
See also
keepresources, requestresources

The surplus is what the city holds above localAmount. If the city also has a requestresources line for the same resource, it keeps at least that line's level too (its /below if it has one, else its localAmount). With no surplus, nothing happens.

Receivers are tried nearest first. A receiver is skipped when it already has /slots marches on the road from this city, or when it is full. For your own city "full" means it holds remoteAmount (counting what is on its way). For a receiver reached through any, it also means the level at which that city's own push line for the resource would send it on. The amount is the smallest of the surplus, the receiver's room and maxBatch. The first receiver that can take a send gets it: one send per line per pass.

A quarter of the city's carriers (at most 2,000) always stay home, for NPC runs. Only as many carriers go as the load needs, and they carry the food for the whole trip, there and back. A send to another lord's city is an ordinary transport, so what arrives is theirs.

sendtroopsGoal

Usage
sendtroops <to> <troop> <localAmount> <remoteAmount> [minBatch] [maxBatch] [/slots:N] [/maxdist:<tiles>]
Example
sendtroops Frontier a 20k 300k 10k 50k
Values
As sendresources, with a troop word in place of the resource: localAmount is how many this city keeps at home, remoteAmount how many a receiver is filled up to. There is no carrier, because the troops march themselves.
Default
/slots:1.
See also
keeptroops, requesttroops, recall

Works like sendresources, except the troops go as a reinforcement. A receiver's count is its troops at home plus reinforcements on their way. The city never sends below its own requesttroops level for that troop. One march carries at most the Rally Spot's limit.

Troops sent to your own city join it. Troops sent to another lord's city stay there as a garrison until you call them back (recall).

keepresourcesGoal

Usage
keepresources <to> <res:amount[,res:amount…]> [minBatch] [troopType] [/slots:N] [/maxdist:<tiles>]
Example
keepresources Capital f:1b,w:500m,s:500m,i:500m 50m
Values
res:amount: what this city keeps of each resource; the rest is sent. minBatch: the smallest send. troopType: the carrier, default transporters (when you write it, write minBatch before it). keepresource works as well.
See also
sendresources

A shorthand: each entry is read as its own sendresources line, with that amount as localAmount, remoteAmount *, the given minBatch and no maxBatch. The example is the same as four lines like sendresources Capital food 1b * 50m.

With any, the nearest city takes it all

A keep line has no remoteAmount. Sent to any, a receiver is only capped by its own push line for that resource. Your nearest city without one gets everything this city doesn't keep. Name the receiver, or use sendresources with a remoteAmount, if that is not what you want.

keeptroopsGoal

Usage
keeptroops <to> <troop:amount[,troop:amount…]> [minBatch] [/slots:N] [/maxdist:<tiles>]
Example
keeptroops Frontier a:50k,c:20k 5k
Values
troop:amount: how many of each this city keeps at home; the rest go. minBatch: the smallest send.
See also
sendtroops

Each entry is read as a sendtroops line with remoteAmount *. The example keeps 50,000 archers and 20,000 cavalry at home and sends every archer and cavalry above that to Frontier, at least 5,000 at a time.

The market

With config trade:1, a city with a Marketplace buys what it is short of and sells what it has too much of, to keep each resource between a minimum and a maximum. You set those with tradepolicy lines or one resourcelimits line. A resource you don't set keeps the built-in values:

ResourceBuilt-in minimum (bought up to)Built-in maximum (sold above)Smallest trade
Fooda day of your troops' food upkeep990b100k
Wood, stone, iron20m eachnone in practice (7.2 trillion)100k
Goldthe floor: a day of hero salariesgold has no maximumgold is never traded itself

So config trade:1 on its own keeps 20m each of wood, stone and iron and a day of food, using gold above a day of salaries.

config tradeConfig

Usage
config trade:<0|1>
Example
config trade:1
Values
1 the city trades; 0 it doesn't. Anything else is an error, and the city does not trade.
Default
0: no trading. tradepolicy and resourcelimits lines wait for it.
See also
tradepolicy, resourcelimits

Turns the trader on for the city. It needs a Marketplace. The Marketplace's level is how many market orders the city may have open at once (one per level), and that count includes orders you or a script placed. The trader works inside the city's schedulepolicy hours, reads the market at most once a minute, and places at most two trades a pass.

tradepolicyGoal

Usage
tradepolicy /type:<res> [/min:<amount|Nd>] [/max:<amount|Nd>] [/batch:<amount>] [/allowselltomin] [/donotautosellabovemax]
Example
tradepolicy /type:gold /min:2d
tradepolicy /type:food /min:1d /max:3d /batch:500k
tradepolicy /type:wood /min:5m /max:50m /batch:1m /allowselltomin
Values
SwitchMeaning
/type:Required. food, wood (lumber), stone, iron or gold, or their letters.
/min:Buy up to this. For gold it is the floor: no purchase ever takes the city's gold under it. Nd means N days: of troop food upkeep for food, of hero salaries for gold.
/max:Sell what is above this. Food may use Nd too. Gold can't have a /max.
/batch:The smallest trade worth making: the trader waits until it can buy or sell at least this much. Default 100k. Not on gold.
/allowselltominWritten on the line of a resource that runs short. When there is no gold above the floor and nothing anywhere above its /max, sell the other resources down to their /min to buy this one.
/donotautosellabovemaxWhen every resource is at its /max, keep what this resource has above its /max instead of selling it for gold.
Default
The built-in values in the table above.
See also
config trade, resourcelimits

Write one line per resource. The two flag switches may also be written /allowselltomin:1 or :0, and = may stand for :. Two lines for the same resource add up, and the later line wins for a switch both set. A /min above its /max is an error. A line with an error is not used at all, and the city's engine notes say so.

Days are worked out from the city's current rates: /min:2d on food is 48 hours of what your troops eat. If the bot can't read the upkeep yet, it says so and leaves that limit out for the pass.

resourcelimitsGoal

Usage
resourcelimits <food> <lumber> <stone> <iron>
Example
resourcelimits 2b 50m 2b 20m
Values
Exactly four amounts, in that order.
See also
tradepolicy, config trade

A one-line way to hold each resource at one level: each amount becomes both the /min and the /max of that resource, so the city buys when under it and sells when over it. The gold floor becomes a day of hero salaries. One per city; if you write two, the later one wins.

Lines are read top to bottom. A tradepolicy line after resourcelimits changes what it names. One before it loses its /min and /max to resourcelimits but keeps its /batch and flags.

How the trader decides

Each pass the trader first counts what the city has: its stock, plus purchases on their way, its own buy orders still waiting in the book, and your transports heading to the city. Then it works through these stages in order:

  1. Emergency. Gold under a day of hero salaries, or food under 30 minutes of troop upkeep. Every /min and /batch is set aside. Food is bought up to an hour of upkeep with whatever gold there is. Resources are sold for gold to get back to a day of salaries (plus an hour), first from what is above each resource's /min, then from anything. The trader accepts worse prices in an emergency (see below).
  2. Gold under its floor. Sell what is above /max for gold.
  3. A resource under its /min (the furthest under first). Buy it with gold above the floor. Failing that, sell what other resources hold above their /max. Failing both, with /allowselltomin on its line, sell the others down to their /min.
  4. Nothing under /min. Sell what is above /max. With the gold that brings in during the next hour, buy the resources that are still under their /max, shared by how far under they are. When every resource is at its /max, the surplus is sold and the gold kept, unless /donotautosellabovemax is on.

A trade buys or sells at prices already in the order book, so it fills at once. It takes the best price and at most one more price level, within 10% of the best. What doesn't fill waits in the book. The bot cancels its own waiting order after 20 minutes. The 0.5% market fee, paid in gold when the order is placed, is not given back.

What the trader never does

  • Take the city's gold under the floor, which is the gold /min plus the gold the builder is saving for its next job.
  • Sell what the builder is saving for its next building.
  • Buy or sell gold itself, or trade anything in a city without a Marketplace.
  • Pay more than twice the best buyer's price, or sell for less than half the best seller's price; a thin book is left alone. In an emergency the limits are 50% past the best price and four times the other side.
  • Make a trade under /batch, outside an emergency.
  • Place more than two trades a pass, have more than two of its own orders waiting in one city, or place a second order for a resource while its own order for that resource and side is still waiting.
  • Touch an order it didn't place. Yours and your scripts' are left alone, but they do count against the Marketplace's order limit.

20Combat goals

What the bot does when an attack comes at your city: hiding the troops, the gate, defence items, alliance chat, the Embassy, healing, and War Town Mode.

What your city knows about an attack

The bot only knows what the game shows your city, and that depends on the city's Beacon Tower. Each level adds to what the earlier levels show:

Beacon TowerWhat the city sees of an attack on its way
noneNothing at all. The bot can't react to an attack it isn't told about.
1That an army is coming.
2Its mission.
3When it lands.
4The lord and alliance sending it.
5Where it set out from.
6The troop types.
7Rough numbers, in the scout report's words (the bot counts each word as the top of its range).
8Exact numbers.
9The level of the hero leading it.
10The attacker's military research.

Scouts are never seen coming, at any level. What this means for the goals:

  • Under level 3 the landing time is unknown. hiding won't act blind on such an attack. The gate treats it as landing any moment.
  • Under level 7 the size is unknown. The gate's own choice is then to keep the gate closed, and defensepolicy treats the attack as a real one.
  • Under level 2 the mission is hidden, so every army coming counts as an attack.
Defence never sleeps

The combat goals run first in every pass, before anything else the city does. They also run outside the city's schedulepolicy hours, and processingpolicy and rallypolicy never hold a hiding march.

Hiding the troops

config hidingConfig

Usage
config hiding:<lead>
Example
config hiding:5 (5 minutes before the first attack lands)
config hiding:90s
Values
How long before the first attack lands the troops leave. A plain number is minutes (0.5 is 30 seconds); you can also write 30s, 2min or 1h. 0 turns it off.
Default
Off.
See also
hidingpolicy, config gate

When an attack whose landing the Beacon Tower shows is due within the lead, the city's troops leave. It is every troop at home, workers and transporters too, less what hidingpolicy /keep holds back.

With another city to go to. The troops go as a transport to your nearest city that has no attack on its way (or to hidingpolicy /target). They carry as much of the city's resources as they can hold: gold first, then food (after their own march food), iron, stone and wood. They leave the load in the safe city and camp, so they come home only after the last known wave has landed, plus /margin. A camp can be at most 24 hours, and the troops must carry the food for the march and the camp. Until both fit, the bot waits for the attack to come closer.

With no other city (a one-city lord). The troops go out on an attack with camp time, led by the lowest-level idle hero (never the keepatthome hero). It is aimed at the nearest level 1-2 NPC within 15 tiles that nobody holds and none of your marches is heading to. On Citavon a march waits out its camp time at home before it sets off, so the troops are out of the battle and a recall brings them back at once. The bot recalls the march once the waves have passed. If attacks are still coming when the march is about to set off, the bot recalls it 3 minutes before and sends a new one. If the bot were stopped and the recall never came, the troops would only meet a small NPC.

One march carries at most the Rally Spot's limit, so a big army leaves in several marches, one a pass, while there are free slots. The city needs a Rally Spot with a free slot, and enough food in the city for the trip.

Hiding ignores War Town Mode

A city in War Town Mode still sends its troops out to hide.

hiding 5 written as a line of its own is read as config hiding:5, and the editor says so.

hidingpolicyGoal

Usage
hidingpolicy [/target:x,y] [/margin:<time>] [/keep:<troops>]
Example
hidingpolicy /target:210,377 /margin:5 /keep:a:5k,w:1000
Values
SwitchMeaning
/target:The city to hide in, by x,y. It must be one of your own cities; any other place is refused and nothing hides. Without it: your nearest city with no attack on its way.
/margin:How long after the last wave lands the troops stay away. Minutes, or 90s and the like. Default 2 minutes.
/keep:Troops that stay home, e.g. a:5k,w:1000 (troop words as in requesttroops).
Default
Nearest safe city, 2 minutes, nothing kept.

Only used with config hiding. One per city. A /target city is used even when it is under attack itself.

The gate

config gateConfig

Usage
config gate:<lead>
Example
config gate:2
config gate:0.1 (6 seconds)
Values
How close an attack must be before it decides the gate: minutes, or 30s, 2min, 1h. 0 turns it off.
Default
Off: the bot never touches the gate. A gatepolicy line does nothing without it.
See also
gatepolicy

Each pass the bot looks at the attacks landing within the lead. An attack whose landing time is unknown (Beacon Tower under 3) counts as landing within it. From that it decides which situation the city is in, and opens or closes the gate as gatepolicy says. Without a gatepolicy line, every situation uses the bot's own choice.

With config gate on, the bot owns the gate

When no attack is near, the bot's choice is closed, and it puts the gate back to what its rules want on every pass. If you open or close the gate yourself, with the console's Gate Control or in the game, the bot changes it back on its next pass (at most once every /mintoggle). To run the gate by hand, take config gate out.

gatepolicyGoal

Usage
gatepolicy <noattack> <regular> <scoutbomb> <mixed> <maintenance> [/mintoggle:<s>] [/junk:<troops>] [/defenceratio:<x>] [/strongarchers:<n>]
Example
gatepolicy 0 0 0 0 0 /junk:20k /defenceratio:3 /mintoggle:30
Values

The five numbers are the five situations, in this order. Each is 0 (the bot's choice), 1 (always open) or 2 (always closed). A missing number is 0.

SituationWhenThe bot's choice (0)
noattackNo attack within the lead.Closed: the troops stay behind the walls.
regularAttacks within the lead.Open if the wave is small (at most /junk), or if your troops at home are at least /defenceratio times the wave. Closed otherwise, and closed while the wave's size is unknown (Beacon Tower under 7).
scoutbombOnly scouts within the lead.Open if the city has at least /strongarchers archers, else closed.
mixedScouts and attacks together.Closed.
maintenanceAccepted for NEAT files.Never comes up: does nothing.
SwitchMeaningDefault
/junk:A wave of at most this many troops is small enough to fight.5,000
/defenceratio:Fight when the troops at home are this many times the wave. /defenseratio works too.5
/mintoggle:The least time between two of the bot's gate changes. Seconds, or 1min.10 seconds
/strongarchers:Archers needed to open to scouts.300,000
/weakarchers:, /loyaltyattack:, /scoutratio:Accepted for NEAT files; they do nothing.-
Default
gatepolicy 0 0 0 0 0: the bot's choice everywhere.
See also
config gate

"The wave" is every attack landing within the lead, added up. With Beacon Tower 7 each word counts as the top of its range, so the size is an upper bound. "Troops at home" counts every troop in the city except workers, so transporters and scouts count as well.

No scouts on Citavon

Citavon never shows scouts coming, so scoutbomb and mixed never happen: an attack is always regular, and a quiet city is noattack. Their numbers, and /strongarchers, can be written but change nothing.

Worked example
Goals
config gate:2
gatepolicy 0 0 0 0 0 /junk:20k /defenceratio:3 /mintoggle:30

The city has a Beacon Tower at level 8 and 120,000 troops at home, not counting workers.

  1. Nothing is coming: noattack, rule 0, so the gate is closed.
  2. An attack of 15,000 is 5 minutes away. That is outside the 2-minute lead, so the gate stays closed.
  3. It comes within 2 minutes: regular, rule 0. 15,000 is under /junk:20k, a small wave, so the gate opens and the troops fight.
  4. Suppose it were 30,000 instead. That is over /junk, but 120,000 is at least 3 × 30,000 = 90,000, so the gate still opens.
  5. A second attack of 25,000 also comes within 2 minutes. The wave is now 55,000 and 3 × 55,000 = 165,000 is more than 120,000, so the gate closes, unless the last change was under 30 seconds ago (/mintoggle:30). Then it closes on a later pass.
  6. With a Beacon Tower at level 6 the city can't count the troops, so in steps 3 to 5 the gate stays closed.

To always fight when attacked, write gatepolicy 0 1. To keep the gate open when nothing is coming as well, write gatepolicy 1 1.

Defence items

defensepolicyGoal

Usage
defensepolicy [/junktroop:<troops>] [/usespeech:<loyalty>] [/usetruce:<loyalty>] [/usewarhorn] [/useivoryhorn] [/usecorselet] [/useultracorselet] [/usepenicillin]
Example
defensepolicy /junktroop:10k /usespeech:60 /usewarhorn /usecorselet /usepenicillin
Values
SwitchUsesWhen
/junktroop:-An attack under this many troops is junk and is ignored. Only when the Beacon Tower counts the troops (level 7+); an attack it can't count is taken as real. Default 0: every attack is real.
/usespeech:Rousing SpeechThe city's loyalty is at or below this (0-100). Not while you are under a truce.
/usetruce:Peace TreatyThe city's loyalty is at or below this, no army is marching on any of your cities, none of your armies is out, and your next truce is ready.
/usewarhornBattle HornA real attack is coming and no Battle Horn is running.
/useivoryhornIvory Battle HornA real attack is coming and no Ivory Battle Horn is running.
/usecorseletMail VestA real attack is coming and no Mail Vest is running.
/useultracorseletPlate VestA real attack is coming and no Plate Vest is running.
/usepenicillinField HospitalA real attack is coming and no Field Hospital is running.

The on/off switches are on when written bare, or :1; :0 is off.

Default
No items used.
See also
config defensecooldown

The policy acts only while a real attack is on its way to this city, or in the cooldown after one (defensecooldown). The Rousing Speech is tried first, then the Peace Treaty, then the horns, vests and Field Hospital in the order above. The horns, vests and Field Hospital are only used while an attack is on its way, not in the cooldown.

The bot uses at most one item a pass, and only items you hold: it never buys one. An item that was tried, whether used or refused, isn't tried again for 5 minutes. Each switch is checked on its own, so with both /usewarhorn and /useivoryhorn on, both horns get used. Pick one horn and one vest.

The Peace Treaty and the cooldown

A Peace Treaty can't start while an army is marching on you, so the bot can only use one in the cooldown after an attack. That cooldown is only tracked while config hiding is on and the Beacon Tower shows landing times (level 3+). Without both, /usetruce never fires.

config defensecooldownConfig

Usage
config defensecooldown:<minutes>
Example
config defensecooldown:60
Default
30 minutes.
See also
defensepolicy

How long after the last attack landed the city still counts as "just hit", for defensepolicy's Rousing Speech and Peace Treaty and for reservedbarrack. The landing time is only recorded while config hiding is on, for attacks whose landing the Beacon Tower shows. Without config hiding this setting has no effect.

Telling the alliance

config warrulesConfig

Usage
config warrules:<minutes>
Example
config warrules:5
Values
Minutes between updates (30s and the like work too). 0: off.
Default
Off.
See also
config attackgap

Posts the city's attacks in alliance chat. The first post goes out as soon as an attack is seen. After that, a new post goes out every X minutes while the picture changes (a new attack, or a landing time that moves), and a reminder every 5 × X minutes while it doesn't. A post reads like [war] Rome (210,377): 3 incoming in 2 wave(s), first in 4m 10s — Bob (Wolves) from Den (12,34) · 2,500 archer. It holds only what the Beacon Tower shows. A lord with no alliance is told so in the engine notes, and nothing is posted.

config attackgapConfig

Usage
config attackgap:<seconds>
Example
config attackgap:10
Default
6 seconds.

Attacks landing at most this many seconds apart count as one wave. On Citavon Bot this only changes how many waves the warrules post counts. The gate and hiding look at every attack on its own.

Embassy, healing and the home hero

config embassyConfig

Usage
config embassy:<0|1|2>
Example
config embassy:2
Values
1 let allied troops stay in the city; 2 keep them out; 0 leave the setting as it is.
Default
0.

Keeps the city's Embassy setting where you want it, putting it back on every pass if it is changed. It needs an Embassy in the city.

config nohealingConfig

Usage
config nohealing:<0|1>
Example
config nohealing:1
Default
0: the bot heals.

Without this setting the bot heals every wounded troop in the city as soon as the city has the gold for it, on every pass, around the clock. You don't need any other goal for that. config nohealing:1 leaves the wounded alone, so you can heal them yourself or keep the gold.

config keepatthomeConfig

Usage
config keepatthome:<0|1>
Example
config keepatthome:1
Default
0.

The city's hero with the highest attack (a captured hero doesn't count) stays home. NPC farming, valley runs and buildnpc marches never take it, and hiding never sends it out to lead the troops away. Scripts can still send it.

config monitorarmyConfig

Usage
config monitorarmy:<n>
Example
config monitorarmy:1

Does nothing. It is accepted so that a NEAT goal file reads without an error. It never did anything on NEAT either, so the editor shows the line as fine, and the engine notes say it does nothing.

War Town Mode

War Town Mode keeps a city's army at home: nothing marches out of it. You set it in two ways. The War Town Mode switch in the city's console has these choices:

SwitchMeans
AutoThe city's goals decide, through config wartown and wartownpolicy. This is the default.
OffOff, whatever the goals say.
On — hero may moveOn, as config wartown:1, whatever the goals say.
On — hero staysOn, as config wartown:2, whatever the goals say.

A city with the switch set by hand is marked with * in the console's city list.

config wartownConfig

Usage
config wartown:<0|1|2>
Example
config wartown:1
Values
ValueMeaning
0Off.
1On. The training hero may still come and go.
2On, and the training hero stays in the city it is in now.
Default
0.
See also
wartownpolicy

While War Town Mode is on:

  • No NPC farming, valley or buildnpc march leaves the city.
  • Its push lines (sendresources, keepresources and so on) wait, and other cities' request lines don't draw from it.
  • When the mode turns on, the city's marches that are still on their way out are recalled, once. Marches already coming back and garrisons in other places are left alone.
  • The city still receives: other cities may send to it, and its own request lines still pull.

It doesn't hold hiding, which still sends the troops away from an attack, and it doesn't hold your scripts.

wartownpolicyGoal

Usage
wartownpolicy <start> <end> [<start> <end> …]
Example
wartownpolicy 22:00 07:00
wartownpolicy 06:00 08:00 18:00 23:30
Values
Pairs of times, hh:mm, 24-hour clock. A window may run past midnight. 24:00 may end one.
Default
None: config wartown holds all day.
See also
config wartown, schedulepolicy

Limits config wartown to these hours. Outside every window the city acts as if config wartown:0. The times are on the clock of the computer the bot runs on, not the game's clock. Each window starts at its start time and ends just before its end time. One per city. It doesn't limit the console's switch: Off and the On choices hold at any time.

Each time the mode turns on, as a window opens, the city's outgoing marches are recalled once, as with the config line.

Friendly fire

Separate from the goals, the Director checks every attack your lords have on its way against the cities of all your lords. An attack heading at one of your own cities, for example a city another of your lords has just taken, shows up on the Alerts tab, once. Auto-recall is off by default, because such an attack is sometimes meant. With it on, the attack is recalled at once. Marking a target "on purpose" keeps it out of the alerts and the auto-recall for 24 hours.

21Intro to scripts

What a script is, where you write it, how you run, stop and test it, what you see while it runs, and how scripts can start on their own. A few complete scripts at the end show the language at work.

Scripts and goals

Citavon Bot has two ways to tell a city what to do:

Goals

Standing wishes ("keep 2m archers", "build every cottage to 9"). The engine reads them on every pass, works out what is missing and does the next step, for as long as the goal is there.

Scripts

A list of lines that runs once, top to bottom, in one city: send this attack, wait five minutes, buy that food, jump back to a label. Exactly what you wrote, in the order you wrote it.

Goals keep working while a script runs in the same city, so the two can both send orders. A script can also change the goals while it runs (goal, config, loadgoals). Scripts written for the NEAT bot mostly run as they are: the language, the command words and the switch spellings are the same.

The script editor

Open a lord's console and pick the city by its tab at the top. The editor at the top left has three icon buttons: Goals (the target), Script (the pencil) and Engine view. Click the pencil to see the city's scripts.

  • Loadouts. Each city has ten script slots, Load 1 to Load 10, picked from the drop-down under the editor. Each holds one script. If the first line of a loadout is a comment (// farm upgrades), that text is its name: other scripts and the Quick… list can run it by that name.
  • Save (or Ctrl+S) keeps the text in the slot. Switching city, tab or slot with unsaved changes asks first.
  • Line colours. As you type, every line is checked: green reads fine, red will not run, grey is a comment. Click a line (or move the cursor onto it) and the bar under the editor says why it is red, or shows a warning about it (a name that is never set, a gosub with no return, a function with no endfunction). With the cursor on a fine line the bar counts the working and red lines.
  • New-city script. On the Goals tab, the account drop-down has a New-city script: it runs by itself in every city the account gains (founded, captured), a few seconds after the city arrives.
One red line stops the whole script

A script with any red line does not start at all: Run lists the bad lines instead. Fix them (or turn them into comments) first.

Run, Stop and starting part-way

The bar under the editor holds the script controls:

ControlWhat it does
RunRuns the text in the editor (saved or not) in the open city. While it runs, the button turns into Stop and the log below switches to the Output tab.
StopEnds the run. It is checked before every line and several times a second during every wait (a sleep, a march waiting for troops, a build waiting for the builder), so it takes effect almost at once. An order already on its way to the game is not called back.
line boxWhere to start. Empty: the first line. A number: that line (or the first line after it that holds something). A word: the line of that label. A number past the end, or a label the script does not have, starts at line 1 with a note in the output.
dry runRuns the script without sending anything to the game (see below).
Quick…One-click scripts and Restart autorun (see below). Hidden when the list is empty.

A city runs one script at a time: Run in a city whose script is still going says "a script is already running in this city — stop it first". Different cities run their own scripts side by side. The console must be connected to the game.

Dry run

Tick dry run before Run to see what a script would do. Every command works out exactly what it would send, writes it to the output and adds [dry run] not sent. Goal lines are not added. Reading the game still happens (prices, the map, your city), so conditions are tested against the real state.

  • A loop or repeat without a count does not go round: it says "would go back … until you press Stop" and the run carries on below it. Counted loops and repeats do run their rounds.
  • sleep really sleeps.
  • A march still waits for a free Rally Spot slot, the troops and the hero, and a build or research still waits for the builder or the Academy, before it reports what it would send.
Tip

For a quick dry run of a long script, start it from the part you want to test with the line box, or add /nowait to build lines.

The Output tab

The log area under the editor has an Output tab: the open city's script output, newest at the bottom, each line stamped with the time on your computer. The last 200 lines are shown.

What a run looks like
14:02:11 line 3: train a:1k
14:02:11   ... what the command did, indented ...
14:02:12 line 4: sleep 2:00
14:04:12 line 7: echo "Archers at home:" city.troop.archer
14:04:12   Archers at home: 20000
14:04:12 done — 3 action(s)
  • Each command, echo, print, sleep and call line prints a header, line N: <the line>, with %vars% and {…} already filled in. What it did follows, indented. Labels, jumps, conditions that are false and assignments print nothing.
  • A line that fails prints FAILED: <why> and the script goes on with the next line. The reason is in $error, so the script can react to it.
  • A line that is only put together while the script runs (by execute, or a %var% whose value changed) and cannot be read prints PARSE ERROR — ….
  • A line starting with @ runs silently: no header and none of its output.
  • The run ends with done — N action(s) (N counts what was sent to the game), or stopped — the rest of the script was not run after Stop.

Lines that wait

Some lines do not fail when their moment has not come: they wait, and nothing below them runs until they go.

LineWaits while
A march (attack, scout, transport, reinforce, deploy and their big forms)the city has no Rally Spot or every march slot is in use; the troops are not all at home; no idle hero fits the hero you named (a hero this run sent in the last minute does not count as idle); the city does not hold the goods to carry. Checked every second.
A march with a landing time @:hh:mm:ssthen also until it is time to leave, so it lands at that time. Too late to make it is a refusal.
A build (create, upgrade, demo)the city's builder is busy. Checked every 2 seconds. With /nowait a busy builder is a refusal instead.
Research (startresearch)the Academy is busy, unless /nowait.
sleepthe time you gave.

A waiting line says why once (not yet: the Rally Spot is full (3/3 marches out) — waiting), again when the reason changes, and once a minute after that. Stop ends any wait; the line then fails.

When the game says no again and again

A loop can send the same refused order over and over. To protect your account and the server:

  • A line that failed last time waits 0.2 seconds before it runs again (through a goto, a loop or a repeat).
  • The same line refused by the game 10 times in a row ends the run: line N was refused 10 times in a row — stopped. A line that goes through starts the count again.
  • Market orders are the exception: a full marketplace or a city short of gold is an everyday answer there, so those refusals are paced but never end the run.

Quick scripts

The Quick… drop-down runs a script with one click, with no need to open its loadout. It is read afresh every time you open the Script tab, so an edit to its file shows at once.

  • Restart autorun is always first when any of the account's loadouts holds label autorun. Running a script by hand means stopping the one that was running, which ends that city's autorun; this puts it back in every city that has no script running, without restarting the console.
  • Every other entry comes from the file quick-scripts.txt in your scripts folder.
quick-scripts.txt
# Label | script | all
Clean the reports (every city) | clean-reports.txt | all
Beg (this city) | Load 3
Farm upgrades | farm upgrades
  • One entry a line: the label shown in the list, a |, the script, and optionally | all. Lines starting with # are comments.
  • The script is either a .txt file in the scripts folder (a plain file name, no folders), or one of the city's loadouts: Load 3, or the name on its first line.
  • Without all it runs in the open city. With all it runs in every city that has no script running; the bar says which cities were skipped.
  • A line naming a .txt file that is not there is left out of the list, and so is a script name with a double quote in it.
  • Picking an entry runs the one line call "<script>", so everything said under call applies.

The scripts folder is the scripts folder beside the program when you run it from its files. The packed program keeps it in your own data folder: %APPDATA%\CitavonBot\scripts on Windows, ~/.local/share/citavon-bot/scripts on Linux.

Autorun

Scripts can start by themselves when a console starts. It is off unless you switch it on in the Director's Start-up parameters (for every account, or one account's own, which win):

ParameterMeaning
-autoscripts 1Autorun on (1, yes, on or true; anything else is off).
-runscript <file>The file every city runs first, from the scripts folder. Without it, AutoRunScript.txt is used when the folder has one.
-autorun 0Not about scripts: the goal engine starts paused until you press Resume.
-<name> <value>Any other parameter is kept for your scripts as Config.<name>.

With autorun on, after the console's first login every city runs, one after the other:

  1. the start-up file (-runscript, else AutoRunScript.txt), from its top;
  2. then each loadout that holds a line label autorun, Load 1 first, each from that label: lines above it are skipped.
  • Each script waits for the one before it in that city to end. The cities run their autorun side by side.
  • Pressing Stop on one of them ends that city's autorun: the scripts after it are not started.
  • Autorun runs once per console start, never after a reconnect. A console that starts again within 10 minutes of the last autorun skips it, so a console that keeps restarting does not send the same orders again and again.
  • Use Quick… → Restart autorun to start it again by hand.
One loadout, two uses

Because autorun starts at label autorun, the lines above it run only when you press Run yourself (from the top). Put one-time set-up there, and the part that should always run below the label.

Example scripts

Paste any of these into an empty loadout, Save, tick dry run and Run to watch what it would do.

Upgrade every cottage to level 9, one at a time
// cottages to 9
label next
if city.getActiveBuilding() goto wait      // the builder is busy: look again soon
upgrade cottage lowestlevel 9 /nowait     // the lowest cottage still under level 9
if $error goto done                       // refused: none left, or not enough resources
label wait
sleep 30
goto next
label done
echo "Finished:" $error
Train archers until the city holds 20,000
label check
if city.troop.archer >= 20k goto done      // archers at home now
train a:1k                                // one batch of 1,000
sleep 2:00                                // two minutes
goto check
label done
echo "Archers at home:" city.troop.archer
Buy food while it is cheap (a function, a market price, a filled-in argument)
// cheap food
function cheap(res, limit)
  p = SellPrice(res)                      // the cheapest offer on the market now
  return p > 0 && p < limit              // an empty book gives NaN, which fails both
endfunction

label look
if !cheap("food", 1.5) goto wait
buy food 100k {SellPrice("food")}         // {…} is worked out when the line runs
label wait
sleep rnd:20:40                           // 20 to 40 seconds, at random
loop look                                 // back to the label, until you press Stop
One line about each of your cities
i = 0
label next
c = cities[i].cityManager
echo c.name "(" + c.coords + ")" "food" c.resource.food "archers" c.troop.archer
i++
if i < cities.length goto next
An autorun loadout: warn the alliance about attacks
// attack watch
echo "Started by hand, so this line ran too."
label autorun
if city.hasEnemyArmiesWithin(600) alliancechat Attack on {city.name} ({city.coords}) within 10 minutes
sleep 5:00
loop autorun                              // forever, from the label
A subroutine and a replacement variable
set target 312,145                        // %target% below becomes 312,145
gosub look
scout %target% none s:1                   // one scout, no hero
end
label look
echo "Distance to %target%:" FormatDistance(city.coords, "%target%")
return

22The script language

Every statement the script language has, one entry each; then variables, replacement variables, $result and $error, expressions and their operators, text, numbers, lists and comments. The game commands (attack, train, buy …) have sections of their own.

How a line is read

A script is read one line at a time. Leading spaces do not matter, so you may indent freely. For each line:

  1. Blank lines and comments are skipped (Comments).
  2. An @ at the very start makes the line silent (@: is a landing time, not this).
  3. %name% replacement variables are filled in (Variables).
  4. If the line starts with a name followed by =, +=, ++ and so on, it is an assignment.
  5. If its first word is one of the language's words (if, goto, echo …, the entries below), it is that statement. These words can never be taken by a game command.
  6. If its first word is a game command (attack, train, buy …), it is that command. Any {expression} in its arguments is worked out when the line runs: scout {target} none s:1.
  7. If it is an expression that calls something or assigns (list.push(5)), it is an expression line.
  8. If its first word is a goal word (troop a:2m, build c:10:9, config npc:5), the line is added to the city's goals as goal would.
  9. Anything else is an error: unknown command: <word>.

Words are read in any case: GOTO, Goto and goto are the same. There is one statement per line: a ; does not start a new one.

Statements

labelScript

Usage
label <name>
Example
label trainarchers
Values
name: one word of letters, digits and _ $ . ! -; any case (Top and top are the same label).
See also
goto, gosub, loop, autorun

Marks a place in the script for goto, gosub, loop and the Run box's start point to jump to. It does nothing when the run passes over it. Two labels with the same name are an error. A label cannot sit behind an if. A label inside a function belongs to that function: you cannot jump to it from outside, nor out of the function to a label outside.

The label autorun is special: autorun starts a loadout from it (Autorun).

gotoScript

Usage
goto <label>
Example
if $error goto retry
See also
label, gosub, ifgoto

Carries on from the line of that label. A label that does not exist is an error before the script starts. Use it with if for choices and with a label above it for loops.

gosubScript

Usage
gosub <label>
Example
if city.resource.food < 1m gosub buyfood
See also
return, ifgosub, function

Jumps to the label like goto, but remembers where it came from: the next return brings the run back to the line after the gosub. Subroutines may call other subroutines, up to 1,000 deep. A gosub to a label with no return anywhere after it gets a warning (it still runs).

Keep subroutines below an end, so the run does not walk into them by itself:

gosub report
train a:1k
end
label report
echo city.name "has" city.troop.archer "archers"
return

returnScript

Usage
return [expression]
also written gosubreturn
Example
return
return total * 2
See also
gosub, function, call

What it does depends on where the run is:

  • after a gosub: back to the line after that gosub (a value is ignored);
  • in a function: the function ends and gives the value (or undefined);
  • at the top level of a script run with call: back to the calling script, the value in its $result;
  • at the top level of the script you ran: the script ends.

ifScript

Usage
if (<condition>) <any line>
Example
if city.troop.archer < 20k goto trainarchers
if $error == null echo "it worked"
if a == 1 if b == 1 echo "both"
if x > 5 item = "big"
See also
Expressions, ifgoto, repeat

Works out the condition; when it is true the rest of the line runs, otherwise the run goes on with the next line. The brackets are optional: as much of the text after if as reads as one expression is the condition, and the rest is the line. That line can be anything (a command, goto, an assignment, another if …) except label, function, endfunction and endloop.

False are false, 0, "" (empty text), null, undefined and NaN; everything else is true, including the text "0" and an empty list. Inside a condition a single = compares, as == does.

There is no else. Jump over the other branch with a label, or pick a value with ?::

if city.resource.food > 5m goto rich
echo "poor"
goto after
label rich
echo "rich"
label after
mood = city.resource.food > 5m ? "rich" : "poor"

An if in front of repeat is checked again before each round: if !x repeat keeps going only while x stays false.

ifgotoScript

Usage
ifgoto (<condition>) <label>
Example
ifgoto (city.troop.archer < 5000) more
See also
if, goto

An older form of if (condition) goto label, kept so old scripts run. It does the same.

ifgosubScript

Usage
ifgosub (<condition>) <label>
Example
ifgosub (city.hasEnemyArmies) warn
See also
if, gosub

An older form of if (condition) gosub label. It does the same.

loopScript

Usage
loop [count] [label]
loop <count> … endloop
Example
loop
loop 5 farm
Values
FormWhat it does
loop, loop 0Back to the top of the script, forever (until Stop).
loop 5The whole script runs 5 times in all, then the run goes on below.
loop nameBack to label name, forever.
loop 5 name, loop name 5The part from label name runs 5 times in all.
loop 3 … endloopThe lines between run 3 times; without a count, forever. Blocks may sit inside each other.
See also
endloop, repeat, goto

A loop line without a label that an endloop further down closes starts a block; otherwise it jumps back. Counts are "in all": loop 5 at the bottom of a script makes it run five times, not six. When the count is used up the loop forgets it, so reaching the same loop again later counts afresh.

Inside a function, loop without a label goes back to the function's first line, not the script's. In a dry run a forever loop does not go round: it says what it would do and the run goes on.

Five scouts, a minute apart
loop 5
  scout 312,145 none s:1
  sleep 60
endloop

endloopScript

Usage
endloop
See also
loop

Closes the nearest open loop block above it: the run goes back to the line after that loop until its count is used up. An endloop with no loop to close is an error. It cannot sit behind an if; to leave a block early, goto a label below it.

repeatScript

Usage
repeat <count>
repeat or repeat 0
Example
train a:250 then repeat 4 — four batches of 250 archers
sell wood 1000 @0.55 then repeat
Values
count: how many times the line runs in all, counting the run just before: repeat 1 adds nothing, repeat 4 adds three more. No count, or 0: again and again until that line fails or you press Stop.
See also
loop, if

Runs again the last line that did something: a command, echo, print, sleep, an assignment or expression line, call, callfunc, command or a goal line. That is the last such line in time, not the line written above: after a gosub it is the last one the subroutine ran. Each round shows in the output as (run 2 of 4), or (repeat 3, until it fails or Stop).

  • A counted repeat runs every round whatever each one gets back. A repeat without a count waits 0.2 seconds between rounds and stops at the first round that fails (repeat ends — line N did not go through).
  • Behind an if, the condition is checked again before every round after the first, and the repeat ends when it no longer holds.
  • A repeat with nothing run before it, or right after a repeat that never ends, is an error. A repeat without a count is refused after buyitem: it would keep spending until it failed.
  • In a dry run a repeat without a count is skipped with a note; counted rounds run.

sleepScript

Usage
sleep <seconds | m:ss | h:mm:ss | @:hh:mm[:ss[.ms]] | rnd:max | rnd:min:max>
Example
sleep 5
sleep 1:30 — a minute and a half
sleep 1:00:00 — an hour
sleep @:14:15 — until 14:15
sleep rnd:300:600 — 5 to 10 minutes, at random
Values
FormWait
5, 0.5that many seconds (fractions allowed)
1:30minutes and seconds (the seconds always two digits)
1:00:00hours, minutes and seconds
@:14:15, @:14:15:30, @:14:15:30.500until that time of day, on a 24-hour clock; if it has passed today, until tomorrow
rnd:300a random time from 0 to 300 seconds
rnd:300:600a random time from 300 to 600 seconds (the second number may not be the smaller)

Pauses the script. Stop ends a sleep within a quarter of a second. The output shows the wait: for @: the time it waits for, for rnd: the time it drew.

Which clock

sleep @:hh:mm reads the time of day on the clock of the computer the bot runs on, as the output says ("on this machine's clock"). The game's own clock is UTC: if your computer is in another time zone, convert, or read m_context.serverHours.

sleep takes no expressions. To wait for a worked-out time, use a variable in percent signs (sleep %wait%, where wait = 30 * 60) or execute (execute "sleep " + wait). A dry run sleeps too.

echoScript

Usage
echo <expression> [expression …]
Example
echo "My city is at " + city.coords + " with" city.troop.lightCavalry "cavalry"
echo "Food in an hour: {city.resource.food + city.resource.food.increaseRate}"
See also
print, Text

Writes to the Output tab. Expressions side by side, separated by spaces, are each worked out and joined with one space. A bare word that nothing defines prints as written, so echo done now prints done now. Text with several lines prints as several lines.

  • If the line does not read as expressions side by side, it prints exactly as written. A comma between items does that: echo a, b prints a, b. Write echo a b.
  • A quote left open at the end of the line closes there.
  • A - between two items subtracts: echo 5 -3 prints 2. Put text in quotes.
  • A bare word that happens to be a known name prints that thing, not the word. Names are read in any case, so echo number, echo max or echo date print function Function() {}. Put words in quotes when in doubt.

echo does not change $result or $error.

printScript

Usage
print <text>
Example
print Sending to %target% now
See also
echo

Writes the rest of the line to the Output tab exactly as written. Only %name% replacement variables are filled in; quotes, {…} and names stay as they are.

setScript

Usage
set <name> <value>
Example
set target 312,145 then attack %target% any a:5k
Values
name: letters, digits and _, not starting with a digit; any case. value: the rest of the line, as plain text.
See also
Variables, assignment

Makes a replacement variable: from then on, %name% anywhere in a line (even inside quotes) is swapped for that text before the line is read. Set it again to change it; lines below use the new text when they run, so it can change inside a loop. The value is never worked out: set n 2+2 makes %n% the text 2+2. A %name% in the value is filled in when the set line runs.

A %name% that no set makes and no assignment gives a value is an error before the script starts: %x% is not set — put set x <value> above this line. Replacement variables are not handed to a script you call.

name = valueScript

Usage
<name> = <expression>
<name> += | -= | *= | /= | %= <expression>
<name>++, <name>--, ++<name>, --<name>
<object>.<key> = …, <list>[<index>] = …
Example
waves = 0
waves += 2
plan.target = "312,145"
list[0] = "first"
See also
Variables, Expressions

Gives a variable a value, making it if it is new. The right side is any expression. As a statement a single = assigns; inside an expression (an if condition) it compares.

  • You can change lists and objects your script made. Game objects (city, a hero, a report…) are copies you can read but not change: city.name = "x" fails.
  • The names of the game objects and constants (city, m_city, cities, player, m_context, Screen, Config, PI, BuildVersion …) cannot be assigned: … is a constant — it cannot be assigned.
  • A variable named like a function (max, date, round) hides that function for the rest of the run. Pick other names.

expression lineScript

Usage
<expression that calls something>
Example
targets.push("312,145")
cities.forEach(CreateFunction("c", "total += c.cityManager.troop.archer"))
See also
CreateFunction, callfunc

A line that is an expression on its own runs for what it does, and its value is thrown away. It must call something or change a variable; a line like x == 5 alone is an error (unknown command).

functionScript

Usage
function <name>(<a>, <b> …) … return <value> … endfunction
Example
see below
See also
return, endfunction, callfunc, CreateFunction

Defines a function of your own. Its body is every line up to endfunction (or end function); without one, up to the next function line or the end of the script, with a warning when lines follow the body's last return.

function troopsAt(c, kind)
  return c.cityManager.troop[kind]
endfunction

echo troopsAt(cities[0], "archer")
callfunc troopsAt(cities[1], "lightCavalry")
echo $result
  • Call it in any expression, y = name(1, 2), or on a line of its own with callfunc. It can be called from anywhere in the script, also above the line that defines it, and it can be handed to sort, map, forEach and the like.
  • When the run reaches a function line it skips over the body; the body only runs when called.
  • The parameters exist only inside the call; a missing argument is undefined. Every other name is the script's own: a function reads and changes the same variables as the rest of the script.
  • return value ends the call with that value; the end of the body gives undefined.
  • Labels inside a function belong to it; goto and gosub cannot cross its edge.
  • A function may call itself, up to 200 calls deep. Two functions with the same name are an error. Names are read in any case.

endfunctionScript

Usage
endfunction or end function
See also
function

Closes a function's body. Reached inside a call, the call ends and gives undefined. One without a function above it is an error.

callfuncScript

Usage
callfunc <name>(<arguments>)
Example
callfunc report(city.name, 5)
See also
function

Calls one of the script's own functions on a line of its own and puts what it returns in $result. The function must be in the same script.

callScript

Usage
call <loadout or file>
Example
call "farm upgrades"
call 3 or call "Load 3"
call clean-reports
call "night " + city.name
Values
What is looked for, in order: a loadout of this city by number (3, Load 3, load3); a loadout whose first line is the comment with that name (any case); a file of that name in the scripts folder (.txt is added when missing). A single bare word is the name itself, unless the script knows that name (a variable of yours, or one of the bot's own names such as date), in which case its value is used; anything else is an expression. Quotes are the safe way.
See also
return, execute, Quick scripts

Runs another script in the same city, then comes back to the next line when it ends or reaches a top-level return. Its return value lands in $result, and $error is cleared.

  • The called script shares your variables, both ways. Your set replacement variables are not passed.
  • It has its own labels and functions.
  • A called script with a red line does not run: the call fails with the first error (farm upgrades line 4: …). A name that matches nothing fails with there is no script "…" to call.
  • Scripts may call scripts up to 20 deep.
end ends everything

end, exit, die and stop inside a called script end the whole run, not just the called script. To come back early, use return.

executeScript

Usage
execute <expression>
Example
execute "train a:" + n
execute "goto step" + stage
execute "echo 1\necho 2"

Works out the expression to text and runs that text as if it were written on this line. Text with several lines runs as several lines, one after the other (a line with a bracket still open goes on into the next). A goto in it jumps as usual.

It cannot make a label, function, endfunction or endloop. A line that cannot be read fails as PARSE ERROR when it runs, not before the script starts. Handy for game commands whose argument you need to build, though {…} in a command's arguments often does the same more simply (train a:{n}).

commandScript

Usage
command <expression>
Example
command "who " + name
command "members"
See also
In-line commands, who

Runs one of the in-line commands (the ones you can also type into the chat box with a backslash, such as \who Bob). The expression gives the command's text; a leading backslash is allowed. Its output lines land in $result; a failure sets $error. An unknown in-line command fails, and $error lists the ones there are.

endScript

Usage
end
See also
exit, die, return

Ends the script here, quietly. Nothing may follow the word (except end function, which closes a function). Used to keep the run out of subroutines written below. Inside a called script it ends the whole run.

exitScript

Usage
exit
See also
end

Ends the script, and says so in the output (exit — the script ends here (the console stays on)). It never closes the console or logs out; for that see logout.

stopScript

Usage
stop
See also
end

Meant to pause the script until it is resumed. The console has no way to resume a paused script, so in Citavon Bot stop ends the script there, with the line stop — this run cannot be paused and resumed, so the script ends here. Not to be mixed up with the Stop button, which ends a run from outside.

dieScript

Usage
die [expression …]
Example
if !city.hasBuilding("rally spot") die "no Rally Spot in " + city.name
See also
end

Ends the script with an error. The message is read like an echo line, shown as die — <message>, and left in $error.

Comments, silent lines and pasted line numbers

  • A line starting with // or # is a comment.
  • // after code starts a comment too, unless it is inside quotes: echo "http://x" is safe. A # after code is not a comment.
  • An apostrophe inside a word (don't) does not open a quote.
  • @ at the start makes the line silent: @echo "quiet" prints nothing, and a silent command logs nothing. @: at the start is not this (it is a time).
  • A line number with a colon in front of a line, as scripts copied from a web page often have (12: sleep 5), is dropped.

Variables

The language has two kinds:

True variables

Made by an assignment: count = 5. They hold any value (number, text, list, object, a game object, a function) and are used by name in expressions: count + 1.

Replacement variables

Made by set: set target 312,145. They hold text, and %target% in a line is swapped for it before the line is read, anywhere, even inside a game command.

  • Names start with a letter, _ or $, then letters, digits, _ or $.
  • Your own variable names are case-sensitive: x and X are two variables. The bot's own names (functions, city, constants) are read in any case.
  • A name nobody set reads as undefined; the editor warns about it.
  • %name% with no set behind it falls back to the true variable of that name (in any case), as text: after n = 3, train a:%n%k trains 3,000 archers.
  • Variables live for the run. Every run starts empty.

$result and $error

Two special variables tell you how the last command went:

NameAfter a command that workedAfter one that failed
$errornullthe reason, as text (the game's message, or the bot's)
$resultwhat the command gives back (a list, a count, a price …), or the text it wrote to the outputthe same
  • They are set after every game command, goal line and command. callfunc and call set $result to what was returned (and call clears $error).
  • A line that fails for any other reason (a mistake in an expression, a missing label at run time) sets $error too.
  • Assignments, echo, jumps and conditions leave both alone, so you can test them a few lines later.
  • Both start out as "" and null. You may assign them yourself ($error = null).
attack 312,145 any a:5k
if $error == null goto sent
echo "Not sent:" $error
end
label sent
echo "On its way."

Expressions and operators

Expressions are used after if, on the right of =, in echo, in {…} inside text and command arguments, and as function arguments. They look like JavaScript or ActionScript. Operators, from the loosest to the tightest binding:

OperatorsMeaning
c ? a : ba when c is true, else b
|| orthe first value that is true, else the last one (name || "nobody")
&& andthe first value that is false, else the last one
|bitwise or
^bitwise exclusive or (not a power: use pow)
&bitwise and
== = != <> === !==equal and not equal. ==, = and !=, <> treat "5" and 5 as equal; === and !== also compare the type
< <= > >= is incompare; x is number tests a type; k in obj tests a key (see below)
<< >> >>>bit shifts
+ -add, subtract. + joins text when either side is text: "5" + 1 is "51"
* / % modmultiply, divide, remainder
! - + ~ ++x --xnot, minus, to a number, bitwise not, add or take one first
a.b a[i] f(x) x++ x--a member, an index, a call, add or take one after
  • and, or and mod may be written in any case; is and in only in lower case.
  • Brackets group: (a + b) * c. Two bracketed numbers side by side multiply: (a + b) (c - 1) (except in echo, where they are two items).
  • x is <type> knows string, number, int, uint, boolean, array, object, function, date, regexp, null, undefined (also void), in any case.
  • k in x asks whether x has the key k: for an object a property name, for a list an index. 3 in [1, 2, 3, 4] is true because index 3 exists; 5 in [5] is false. To find a value in a list use list.indexOf(v) >= 0 or list.includes(v).
  • = inside an expression compares. Assignment (=) is a statement of its own; +=, -=, *=, /=, %=, ++ and -- also work inside expressions (as in a CreateFunction body).
  • Every call waits for its answer, so functions that ask the game (GetDetailInfo, SellPrice) are used like any other.

Numbers and other values

WriteValue
12 1.5 .5 1e3numbers
0x1fa number in hexadecimal (31)
20k 1.5m 2bthousand, million, billion: 20000, 1500000, 2000000000 (any case)
5%a percentage: 0.05. Write the remainder operator with spaces, 7 % 3, or as 7 mod 3
true falseyes and no
null undefinednothing, and not set
NaN Infinitynot a number, and endless
[1, "a", [2]]a list (array); a comma after the last item is allowed
{a: 1, "b c": 2}an object; keys are names, text in quotes or numbers
/x+/gia regular expression with its flags
"text" 'text'text (see below)

Numbers in expressions take no thousands commas: 1,000 is not a number. Many functions also accept numbers given as text with the suffixes (max("20k", 5) is 20000).

Text (strings) and escapes

  • Double quotes fill in {expression}: "{city.name} has {city.troop.archer} archers". A { that does not hold a whole expression stays as it is; \{ is always a plain brace.
  • Single quotes fill in nothing: 'no {filling} here'.
  • Game command arguments are not expressions, but {expression} in them is filled in when the line runs: attack {targets[i]} any a:5k. Again \{ keeps a brace.
EscapeGives
\n \t \rnew line, tab, carriage return
\b \f \v \0backspace, form feed, vertical tab, the zero character
\x41 Ba character by its code (two or four hexadecimal digits)
\" \' \\ \{the character itself (a backslash before any other character gives that character)

Methods on text, numbers, lists and dates

Values have the usual JavaScript methods, from a fixed list. Method names may be written in any case (x.subStr(1, 2), s.toupperCase()).

ValueMembers
textlength, [i], charAt, charCodeAt, codePointAt, at, concat, endsWith, includes, indexOf, lastIndexOf, localeCompare, match, matchAll, normalize, padStart, padEnd, repeat, replace, replaceAll, search, slice, split, startsWith, substr, substring, toLowerCase, toUpperCase, toLocaleLowerCase, toLocaleUpperCase, trim, trimStart, trimEnd, toString, valueOf
numbertoFixed, toPrecision, toExponential, toString, toLocaleString, valueOf
listlength, [i], push, pop, shift, unshift, splice, slice, concat, indexOf, lastIndexOf, includes, reverse, fill, flat, at, join, toString, toArray (a copy), and with a function: forEach, map, filter, some, every, find, findIndex, reduce, sort, sortOn
dateevery get…, set… and to… method (getHours, getTime, toLocaleString …), valueOf
regular expressiontest, exec, toString; source, flags, global, ignoreCase, multiline, sticky, unicode, dotAll, lastIndex
  • A function handed to forEach, map, sort … can be your own function or one made with CreateFunction. sort without one sorts as text.
  • list.sortOn(name, options) sorts a list of objects by a property (or a list of properties). Options add up: 1 ignore case, 2 descending, 4 unique (gives 0 when two match), 8 give the order as a list of indexes, 16 numeric. bases.sortOn("prestige", 16 + 2) sorts by prestige, highest first.
  • localeCompare gives the difference of the first differing character codes (a sort only needs the sign).
  • Every regular-expression search may run for at most 2 seconds and search at most 1,000,000 characters; a pattern that takes longer fails its line instead of freezing the bot. Text built by a script may be at most 10 million characters long.
  • For safety, names beginning with __ and prototype, constructor cannot be read or set.

23Functions & objects

Every global function a script can call, and every object it can read: your city, your other cities, your lord, heroes, armies, map tiles, market orders and the constants. Names are read in any case.

Before you start

  • Everything here hands back a copy. Changing what you hold changes nothing in the game, and reading city.troop again later gives the new numbers.
  • Where a function wants a number, it also takes text with the suffixes: "20k", "1.5m", "5%". Text from a %var% often arrives that way.
  • A tile (a place on the map) can be given as a field id (a number), as "x,y" (also "x.y", "x:y", "x y" or "Name(x,y)"), as two numbers x, y, or as any object with x and y or a fieldId (a city, a map bean). The map is 800 by 800 tiles and wraps round at its edges; a field id is y × 800 + x.
  • The map functions read the map through your console's connection to the game: they need it online, and they keep what they read for 10 minutes, so a loop does not read the same ground again and again. One call may read at most 120 squares of 31 × 31 tiles; a search radius up to about 140 tiles always fits.
  • Words that a function names in its Usage with quotes must be given in quotes: AnyIdleHero("any:att>100"), not AnyIdleHero(any:att>100). Only the market price functions take an unquoted resource name.

Numbers and maths

absFunction

Usage
abs(n)
Example
abs(-5) → 5

The number without its sign. Also Math.abs.

ceilFunction

Usage
ceil(n)
Example
ceil(need / 500) — transporters for need goods at 500 each

Rounds up to a whole number. Also Math.ceil.

floorFunction

Usage
floor(n)
Example
floor(city.resource.food / 1000)

Rounds down to a whole number. Also Math.floor.

roundFunction

Usage
round(n[, places])
Example
round(6.666, 2) → 6.67
Default
places 0

Rounds to the nearest whole number, or to that many decimal places. Halves round up, and round(1.005, 2) is 1.01 as it should be. Also Math.round.

maxFunction

Usage
max(a, b, …)
Example
max(1, [5, 9], 3) → 9
See also
min

The largest of any number of values; a list counts as its values. Also Math.max.

minFunction

Usage
min(a, b, …)
Example
min(city.troop.archer, 5k)

The smallest of any number of values; a list counts as its values. Also Math.min.

powFunction

Usage
pow(base, exponent)
Example
pow(2, 10) → 1024

A power. (^ is not a power in scripts.) Also Math.pow.

sqrtFunction

Usage
sqrt(n)
Example
sqrt(dx * dx + dy * dy)

The square root. Also Math.sqrt.

randomFunction

Usage
random()
Example
pick = list[floor(random() * list.length)]

A random number from 0 up to (not including) 1. For random waits, sleep rnd:… is simpler. Also Math.random.

expFunction

Usage
exp(n)
Example
exp(1) → 2.718…

e (2.718…) to the power n. Also Math.exp. The reverse is log.

logFunction

Usage
log(n)
Example
log(100) / LN10 → 2

The natural logarithm of n. For a base-10 logarithm divide by LN10. Also Math.log.

sinFunction

Usage
sin(radians)
Example
y = round(cy + r * sin(a))

The sine of an angle in radians (PI radians is half a turn). With cos, handy for walking a circle round a city. Also Math.sin.

cosFunction

Usage
cos(radians)
See also
sin

The cosine of an angle in radians: x = round(cx + r * cos(a)). Also Math.cos.

tanFunction

Usage
tan(radians)
See also
sin

The tangent of an angle in radians. Also Math.tan.

asinFunction

Usage
asin(n)

The inverse sine, in radians. Also Math.asin.

acosFunction

Usage
acos(n)

The inverse cosine, in radians. Also Math.acos.

atanFunction

Usage
atan(n)

The inverse tangent, in radians. Also Math.atan.

atan2Function

Usage
atan2(y, x)
Example
angle = atan2(ty - city.y, tx - city.x)

The direction of the point (x, y) seen from 0,0, in radians. Note y comes first.

isNaNFunction

Usage
isNaN(value)
Example
if isNaN(SellPrice("iron")) goto nobook

True when the value is not a number. Text with suffixes counts as a number: isNaN("20k") is false. The market price functions give NaN when the book is empty, so this is how to test for that.

isFiniteFunction

Usage
isFinite(value)
Example
isFinite(price)

True when the value is a real, finite number (not NaN, not Infinity). Suffixes are read as for isNaN.

parseIntFunction

Usage
parseInt(text[, radix])
Example
parseInt("12 archers") → 12
See also
ParseInteger

Reads a whole number from the start of the text and ignores the rest, as JavaScript does: parseInt("12k") is 12, not 12,000. radix is the base (16 for hexadecimal).

parseFloatFunction

Usage
parseFloat(text)
Example
parseFloat("0.55 gold") → 0.55

Reads a number with decimals from the start of the text and ignores the rest.

NumberFunction

Usage
Number(value)
Example
Number("250") → 250; Number(date()) → the time in milliseconds

Turns a value into a number the strict way: the whole text must be a number, so Number("12k") is NaN. A date gives its milliseconds.

StringFunction

Usage
String(value)
String.fromCharCode(code, …)
Example
String(5) + "k" → "5k"; String.fromCharCode(65, 66) → "AB"

Turns a value into text. undefined gives "", null gives "null", a date its long form. String.fromCharCode makes text from character codes.

Text

CenterPadFunction

Usage
CenterPad(text, length[, pad])
Example
CenterPad("Report", 20, "=") → "=======Report======="
Default
pad a space

Pads the text on both sides to that length (the odd one goes on the right). Text already as long is returned as it is. No result may be over 1,000,000 characters.

LeftPadFunction

Usage
LeftPad(text, length[, pad])
Example
LeftPad("7", 3, "0") → "007"
Default
pad a space

Pads the text on the left to that length; good for lining up numbers in the output.

RightPadFunction

Usage
RightPad(text, length[, pad])
Example
RightPad(c.name, 16) + c.coords
Default
pad a space

Pads the text on the right to that length.

StringRepeatFunction

Usage
StringRepeat(count[, text])
Example
StringRepeat(20, "-")
Default
text a space

The text that many times over. Note the count comes first.

MergeFunction

Usage
Merge(a, b[, between])
Example
Merge("One plus One", "Two", " = ") → "One plus One = Two"
Default
between a space

Joins two pieces of text with the separator between, but only when both have text: Merge("", "b", ",") is "b". Handy for building a list one item at a time.

Upper1Function

Usage
Upper1(text)
Example
Upper1("archers") → "Archers"

The text with its first letter made a capital.

StringToObjectFunction

Usage
StringToObject(text, between_pairs, between_key_and_value[, into])
Example
StringToObject("home:312,145;bank:20,40", ";", ":").bank → "20,40"
Default
"," and ":"

Splits text into an object. Keys and values are trimmed and stay text; a part with no key separator gets the value "". Given an object as into, it fills that one and returns it.

ToCSVFunction

Usage
ToCSV(value, value, …)
Example
ToCSV(city.name, city.coords, date()) → "Alpha","312,145","Sat Oct 18 14:02:11 GMT+0200 2026"

One line for a spreadsheet: each value in double quotes (quotes inside doubled), separated by commas.

FormatNumberFunction

Usage
FormatNumber(n[, places[, commas]])
Example
FormatNumber(1234567, 2) → "1,234,567.00"
FormatNumber(1234567, 0, false) → "1234567"
Default
places 0 (at most 20), commas true

A number as text, rounded to that many places, with thousands commas unless commas is false, 0 or "no".

FormatNumber2Function

Usage
FormatNumber2(n[, places[, commas]])
Example
FormatNumber2(0.5) → "0.50"
Default
places 2

FormatNumber with two decimal places unless told otherwise.

FormatPercentFunction

Usage
FormatPercent(fraction[, places])
Example
FormatPercent(0.25, 2) → "25.00%"
Default
places 1

A fraction as a percentage: 0.25 is 25%.

FormatMilesFunction

Usage
FormatMiles(n)
Example
FormatMiles(351.8096) → "351.80 miles"
See also
FormatDistance

A distance with two decimals and the word miles. The decimals are cut, not rounded.

ParseIntegerFunction

Usage
ParseInteger(text, min[, max[, suffix]])
Example
ParseInteger("40s", 0, 40, "s") → 40
ParseInteger("abc", 0) → -1

Reads a whole number and checks it. With suffix the text must end in it (any case), and it is taken off first. Gives -1 when the text is not a whole number, or is below min or above max.

PrepareParametersFunction

Usage
PrepareParameters(text)
Example
PrepareParameters('attack "North Keep" /wait="2 min"') → ["attack", "North Keep", "/wait=2 min"]

Splits text into words at spaces. A run in single or double quotes keeps its spaces and loses its quotes, also inside a word.

GetResourcesFunction

Usage
GetResources(text) (older spelling getResources)
Example
need = GetResources("f:1m,w:500k,g:10k") then echo need.food
Values
codes f w (or l) s i g, or the names food, wood (lumber), stone, iron, gold; amounts with k/m/b
See also
resource bean

Reads a resource list into a resource bean (gold, food, wood, stone, iron). A code given twice is added up. Gives null for a list it cannot read. Given an object with those keys, it copies it.

Dates and time

dateFunction

Usage
date()
date(milliseconds), date("text"), date(other_date)
date(year, month, day[, hour, minute, second, ms])
Example
now = date()
date(2026, 9, 24, 10, 30) — 24 October 2026, 10:30
See also
date object, TimeDiff

A date. With nothing, now by the game's clock. Months count from 0 (January) to 11 (December), as in JavaScript. The parts are read in your computer's time zone, and the date prints in the form Sat Oct 18 14:02:11 GMT+0200 2026.

TimeDiffFunction

Usage
TimeDiff(time[, from])
Example
left = TimeDiff(city.getActiveBuilding().endTime) / 1000 — seconds until the builder is free

time minus from (now, by the game's clock, when left out), in milliseconds. Both may be dates or milliseconds. Negative when the time has passed.

JSON and XML

json_encodeFunction

Usage
json_encode(value[, indent])
Example
echo json_encode(city.heroes[0])
echo json_encode(city.getActiveBuilding(), 2)
Values
indent: true (2 spaces), a number of spaces 0-10, or a text to indent with

The value as JSON text: the quickest way to see everything a game object holds. Functions are left out, dates become ISO text, a loop back into itself shows as "[circular]", and very large or deep values are cut off ("[too big]", "[too deep]").

json_decodeFunction

Usage
json_decode(text)
Example
plan = json_decode('{"waves": 5, "target": "312,145"}')

Reads JSON text into lists and objects your script can change. Gives null when the text is not JSON.

xmlFunction

Usage
xml(text)
Example
r = xml(text) then echo r.scoutReport.troops

Reads XML text and gives its root element as an object: attributes and child elements become properties, a repeated child becomes a list. Given an object, it returns it as it is. Citavon's own reports do not come as XML, so this and the three …FromXML functions are for XML text you bring in yourself and for older scripts.

GetTroopsFromXMLFunction

Usage
GetTroopsFromXML(list[, countProperty])
Default
countProperty "count"

Turns a list of entries with a troop type number (typeId or type) and a count into a troop bean. Given the parent element, it uses its list. A count that is not a number (a scout's ? or a range) is kept as text. null when given nothing.

GetResourcesFromXMLFunction

Usage
GetResourcesFromXML(element)

Reads an element whose attributes are gold, food, wood (or lumber), stone and iron into a resource bean. null when given nothing.

The map

GetFieldIdFunction

Usage
GetFieldId("x,y") or GetFieldId(x, y)
Example
GetFieldId(12, 34) → 27212
See also
FieldIdToCoords

The field id of a tile (y × 800 + x). Coordinates past the edge wrap round. null for something that is not a tile.

FieldIdToCoordsFunction

Usage
FieldIdToCoords(tile) (older spellings fieldIdToCompareString, FieldIdToCompareString)
Example
FieldIdToCoords(27212) → "12,34"

A tile as "x,y" text, ready for a command line. null for something that is not a tile.

GetXFunction

Usage
GetX(tile) (older getX)
Example
GetX(27212) → 12

The x of a tile; null for something that is not a tile.

GetYFunction

Usage
GetY(tile) (older getY)
Example
GetY("12,34") → 34

The y of a tile; null for something that is not a tile.

GetLevelFunction

Usage
GetLevel(tile) (older getLevel)
Example
if GetLevel("312,145") >= 5 goto big

The level of what is on the tile (a valley, a flat, an NPC city), read from the map. null when the map has no level for it, or the console is offline.

GetTypeFunction

Usage
GetType(tile) (older getType)
Example
if GetType(t) == FieldTypes.Flat echo "a flat"
See also
FieldTypes

The tile's type number, read from the map: 1 forest, 2 desert, 3 hill, 4 swamp, 5 grassland, 6 lake, 10 flat, 11 a lord's city, 12 an NPC city. null when unknown.

GetZoneNameFunction

Usage
GetZoneName(tile) (older getZoneName)
Example
GetZoneName("450,300") → "Thuringia"
See also
StateCoords

The name of the state (region of the map) the tile lies in. Works without reading the map.

GetFieldTypeFunction

Usage
GetFieldType(name)
Example
GetFieldType("hill") → 3
Values
forest, desert, hill, swamp, grassland (grass), lake, flat, castle (city, player), npc (barbarian), their plurals, or a type number

The type number for a word; -1 for a word that is no tile type.

GetFieldNameFunction

Usage
GetFieldName(type)
Example
GetFieldName(6) → "Lake"

The name for a type number (Forest, Desert, Hill, Swamp, Grassland, Lake, Flat, Castle, NPC), or null.

MapDistanceFunction

Usage
MapDistance(x1, y1, x2, y2) or MapDistance(tile1, tile2)
Example
MapDistance(city.coords, "312,145")
See also
FormatDistance, getTravelTime

The straight-line distance in tiles, the way the game measures it, across the map's edge when that is shorter. NaN when either is not a tile.

FormatDistanceFunction

Usage
FormatDistance(tile1, tile2)
Example
FormatDistance("0,0", "3,4") → "5.00 miles"

MapDistance written as FormatMiles does.

StateCoordsFunction

Usage
StateCoords(state)
Example
StateCoords("Upper Lorraine") → "0,400 199,599"
StateCoords("all") → "0,0 799,799"
Values
a state name (any case, spaces optional), its number 0-15, or all

The corners of a state's square of the map, as "x1,y1 x2,y2", ready for a command such as scanmap. Each state is 200 by 200 tiles, numbered from the top-left, four to a row. null for an unknown state.

StateNameFunction

Usage
StateName(n) (older stateName)
Example
StateName(GetDetailInfo(t).state) → "truce"
See also
PlayerState

Not about map states: it names a lord's state number as a map bean gives it: 1 peace (normal), 2 truce, 3 beginner, 5 holiday, 6 dream (a Dream Truce). "" for other numbers. For a map state's name use GetZoneName.

FindFieldFunction

Usage
FindField(x, y, radius, type[, level])
Example
lakes = FindField(city.x, city.y, 15, "lake", 10)
npcs = FindField(city.x, city.y, 30, FieldTypes.NPC)
Values
type: a word or number as for GetFieldType. level: 0 or left out is any level.
See also
findfield (the command), FieldIdToCoords

The field ids of every tile of that type (and level) within the radius (a circle), in order of x, then y. Turn one into coordinates with FieldIdToCoords. An unknown type is an error.

list = FindField(city.x, city.y, 20, "npc", 5)
i = 0
label next
if i >= list.length end
echo FieldIdToCoords(list[i]) FormatDistance(city.coords, list[i])
i++
goto next

CastlesInRectangleFunction

Usage
CastlesInRectangle(x1, y1, x2, y2[, omitNpc[, byId]]) (also CastleInRectangle)
Example
near = CastlesInRectangle(city.x - 10, city.y - 10, city.x + 10, city.y + 10)
Default
omitNpc true, byId false
See also
map bean, MapCastles

The cities in that rectangle (cut off at the map's edge), as a list of map beans in field-id order. NPC cities are left out unless omitNpc is false. With byId true you get an object keyed by field id instead of a list.

AllCastlesFunction

Usage
AllCastles(corner1, corner2[, omitNpc])
Example
AllCastles("300,100", "340,140")

CastlesInRectangle with the corners given as tiles (field ids or "x,y").

MapCastlesFunction

Usage
MapCastles(x, y, radius)
Example
MapCastles(city.x, city.y, 15).length — lords' cities within 15 tiles

The lords' cities (no NPCs) within the radius of x,y, a circle, as map beans.

SearchEnemyCastlesFunction

Usage
SearchEnemyCastles([n])
Example
foes = SearchEnemyCastles(5) then echo foes[0].name foes[0].coords
Default
all it finds
See also
searchenemies

Cities of lords whose alliance yours has marked as an enemy, nearest first, at most n. It first asks the game for your alliance's current diplomacy, then looks at the map up to 124 tiles from this city in each direction (the most one call may read). Your own cities never count.

GetDetailInfoFunction

Usage
GetDetailInfo(tile[, priority[, expireSeconds[, sinceMs]]])
Example
b = GetDetailInfo("312,145") then if b.userName == null goto empty
b = GetDetailInfo(t, 0, 60) — nothing older than a minute
Values
priority is accepted and does nothing (every look is waited for). With expireSeconds, a reading must be newer than that many seconds before sinceMs (or now).
See also
map bean, UpdateDetailInfo

Everything known about one tile, as a map bean. Without an expiry, the last reading will do (the map is kept for 10 minutes); when there is none, or it is too old, the tile's part of the map is read afresh. Of two readings the newer wins. null when nothing can be learned (for example offline).

UpdateDetailInfoFunction

Usage
UpdateDetailInfo(tile) (older updateDetailInfo)

Reads the tile from the game now, whatever is kept, and gives the fresh map bean (null offline).

RelationIndexFunction

Usage
RelationIndex(mapBean)
Example
if RelationIndex(GetDetailInfo(t)) == 1 goto enemy
Values
0 you, 1 enemy, 2 your alliance, 3 friendly, 4 neutral, 5 another alliance, 6 no alliance (or not a bean)

How the owner of a tile stands with you, as one number. Note the numbers differ from the bean's own relation.

ResetMapFunction

Usage
ResetMap(x, y, radius) or ResetMap(x, y, width, height)
Example
ResetMap(city.x, city.y, 20)

Forgets what was read of that circle (or of the rectangle starting at x,y), so the next map function asks the game afresh. Gives null.

getTravelTimeFunction

Usage
getTravelTime(from, to, troops[, type])
Example
secs = getTravelTime(city.coords, "312,145", "a:5k,c:1k")
Values
troops: a troop list as text or a troop bean. type is accepted and does nothing.
See also
travelinfo

How many seconds the march takes: the slowest troop type sets the pace, with your Compass and Horseback Riding research, and the target's Relief Station when the target is one of your own cities. null when it cannot tell (no troops, not a tile).

Your city, heroes and items

GetTroopsFunction

Usage
GetTroops(text)
Example
wave = GetTroops("a:5k,c:1k") then echo wave.archer
See also
troop bean, TroopBeanToString

Reads a troop list (the same words as the commands: a, arch, archers …) into a troop bean. A bad list is an error.

TroopBeanToStringFunction

Usage
TroopBeanToString(bean[, separator])
Example
TroopBeanToString(city.troop) → "w:200,a:5000,c:100"
Default
separator ","

A troop bean written as a troop list a command can use, with the short codes (wo, w, s, p, sw, a, t, c, cata, b, r, cp) and only the types there are. An empty bean gives "a:0".

GetFortificationsFunction

Usage
GetFortifications(text)
Example
GetFortifications("tra:1k,ab:500,at:200").trap → 1000

Reads a fortification list (tra, ab, at, r, tre and their long names) into a fortification bean. A bad list is an error.

ItemCountFunction

Usage
ItemCount("item")
Example
if ItemCount("Peace Treaty") > 0 truce
See also
GetItem

How many of that item your lord holds. The item is named by its Citavon name, its key, or its old name; spaces, case and punctuation do not matter. 0 for an item it does not know.

GetItemFunction

Usage
GetItem("item")
Example
it = GetItem("Battle Horn") then echo it.name it.count

The item as {id, name, count} (its key, its Citavon name, how many you hold), or null for an item it does not know. Named as for ItemCount.

IsHeroInCastleFunction

Usage
IsHeroInCastle("hero spec")
Example
IsHeroInCastle("Bob"), IsHeroInCastle("any:att>200")
Values
See hero specs below.
See also
AnyIdleHero

True when this city has a hero matching the spec, whatever it is doing (idle, mayor, out marching). The spec must be in quotes.

AnyIdleHeroFunction

Usage
AnyIdleHero(["hero spec"])
Example
if AnyIdleHero("any:att>100") attack 123,456 any a:5k
Default
"any"

True when this city has an idle hero matching the spec. A hero this run sent on a march in the last minute does not count, even if the game still shows it at home. Use it before a march line so the line does not sit waiting for a hero.

Hero specMatches
any or emptyevery hero
Bobthe hero named Bob (any case)
any:att>100any hero with attack over 100
any:att>100,pol>=50all conditions must hold (comma = and)
Bob|any:lvl>20either spec (bar = or)

Conditions: att/attack, pol/politics, int/intel, lvl/level, and base (the hero's highest base stat); with > >= < <= = and a whole number. Attack, politics and intel include the hero's boosts. A condition it cannot read is ignored.

GetTechLevelFunction

Usage
GetTechLevel("research")
Example
GetTechLevel("lo"), GetTechLevel("Military Science")

The level of a research, named by its short code (ag, lu, mas, mi, met, in, ms, mt, ir, lo, com, ho, ar, st, med, con, en, mac, pr) or its name. Research belongs to your lord, so every city gives the same answer. 0 for a word it does not know.

is_researchingFunction

Usage
is_researching (no brackets)
Example
if !is_researching startresearch quickest

A value, not a call: true while this city's Academy is researching. Same as city.is_researching.

The market

BuyPriceFunction

Usage
BuyPrice([resource[, amount[, method]]])
Example
BuyPrice(food) — the best bid for food
BuyPrice("iron", 1m) — the price a sale of 1,000,000 iron would reach
BuyPrice("wood", 500k, 1) — the average price over that sale
Values
resource: 0-3 (food, wood, stone, iron) or a name; none at all is food. Unquoted only when it is the only argument. amount: default 1. method: 0 (default) the last price the amount reaches, 1 the average over it.
See also
SellPrice, Price, sell

The bids side of the market: what a sale gets right now. It walks down the bids until amount is covered. NaN when the bids shown do not cover the amount (the market shows the best 8 prices of each side) or there are none. The market is read at most every 15 seconds; a failed read keeps the last prices. Also city.buyPrice and m_context.buyPrice.

SellPriceFunction

Usage
SellPrice([resource[, amount[, method]]])
Example
SellPrice(food) — the cheapest offer of food
buy food 100k {SellPrice("food", 100k)}
See also
BuyPrice, buy

The offers side: what a purchase pays right now, walking up the offers until amount is covered. Arguments and NaN as for BuyPrice.

PriceFunction

Usage
Price(resource, fraction)
Example
Price(0, 2%) — just above the best food bid
Price("iron", 1 - 2%) — just under the cheapest iron offer

A price between the best bid (fraction 0) and the cheapest offer (fraction 1). NaN when a side it needs is empty. The fraction is required.

Other functions

CreateFunctionFunction

Usage
CreateFunction("parameters", "body")
Example
big = list.filter(CreateFunction("v", "v > 10"))
cities.forEach(CreateFunction("c", "total += c.cityManager.troop.archer"))
beans.sort(CreateFunction("a,b", "b.prestige - a.prestige"))
See also
function, list methods

Makes a small function on the spot, mostly to hand to forEach, map, filter, sort and the like. The parameters are names separated by commas. The body is one expression (it may assign with =, +=, ++ …), and its value is what the function gives back. It reads and changes the script's variables when it runs.

The body cannot hold statements or game commands: CreateFunction("c", "echo c.name") fails when called. For more than one expression, write a function and hand that over by name.

setCityTimerFunction

Usage
setCityTimer("key")
Example
setCityTimer("lastbeg")
See also
cityTimingAllowed

Starts (or restarts) a named clock for this city, now. Gives null.

cityTimingAllowedFunction

Usage
cityTimingAllowed("key", seconds[, test])
Example
if cityTimingAllowed("beg", 3600) alliancechat Food please at {city.coords}

True when this city's clock of that name was never started, or at least seconds have passed since; it then restarts the clock, unless test is true. A simple way to do something at most once an hour from a script that loops faster. The clocks are kept per city while the console runs, across script runs, and are gone after a restart.

Constants

Fixed values a script can read but not assign:

NameValue
PI E SQRT2 SQRT1_2 LN2 LN10 LOG2E LOG10Ethe usual mathematical constants (also on Math)
NaN Infinitynot a number, and endless
RESOURCETYPE_FOOD … _WOOD _STONE _IRON0, 1, 2, 3: the market's resource numbers
MAX_TRADE99,999,999: the most one market order takes
BuildVersion9999: higher than any NEAT build, so old scripts' version checks pass
BuildDatethe date of this Citavon Bot build, like October 18, 2026
BuildNamelike Citavon Bot Version 10-18-2026.897e451

Objects

cityObject

Usage
city.<property>, city.<method>(…)
also m_city, city.cityManager, cities[i].cityManager
Example
echo city.name city.coords city.troop.archer
if city.resource.food < 1b gosub feed

The city the script runs in. m_city and city.cityManager are the same object (old scripts use both); cities[i].cityManager is the same kind of object for any of your cities. Every read is fresh: a city held in a variable shows the live numbers each time you read from it.

Property or methodGives
id, castleIdthe city's id
nameits name
x, y, fieldIdwhere it is
coords, cityCoords"x,y"
cityNameCoords()"Name(x,y)"
resourceresources, population, tax and loyalty: see city.resource
estResourcewhat it holds now, as a resource bean
hasResource(list)true when it holds at least that much: city.hasResource("f:1m,g:50k")
troop, troops, getAvailableTroop()the troops at home, a troop bean
troopStillInProductiontroops still being trained, a troop bean
fortificationthe fortifications on the walls, a fortification bean
buildingsa list of {typeId, type, level, positionId, name}, one per building
getBuildingLevel(type)the highest level of that building type, 0 if none
countBuilding(type[, min[, max]])how many of that type have a level from min (0) to max (99)
hasBuilding(type[, level])true when one is at least that level (1)
getBuildingByTypeId(type), getBuildingByPosId(plot)that building as the game sends it (with type, level, plot), or null
getTownHallLevel(), getWallLevel()those two levels
getActiveBuilding()the builder's job, {type, typeId, positionId, level, toLevel, endTime} (end time in milliseconds), or null when the builder is free
getEmptyPositions(type)the free plots where that building type could go (default cottage)
rallySpotAvailable()how many march slots are free now
researchesan object, research → level
getTechLevel(t), GetTechLevel(t), hasTech(t[, level])a research's level, or whether it is at least level (1); see GetTechLevel
getActiveResearch(){tech, toLevel, endTime} or null
is_researchingtrue while the Academy is busy
heroesthe city's heroes, a list of hero beans
findHeroByName(n), heros(n)that hero (any case), or null
getMayor()the mayor, or null
IsHeroInCastle(spec), AnyIdleHero(spec)see IsHeroInCastle, AnyIdleHero
selfArmies, myArmiesthis city's armies out, a list of armies
enemyArmiesattacks on their way to this city, as far as its Beacon Tower sees: a list of incoming attacks
hasEnemyArmiestrue when any attack is on its way
hasEnemyArmiesWithin(seconds)true when one lands within that many seconds. An attack whose landing time the tower cannot show counts as within.
NumberOfRealAttackshow many attacks are on their way
tradesArraythis city's open market orders, trade beans
transingTradesArrayits purchases on their way, delivery beans
buyPrice(…), sellPrice(…)BuyPrice, SellPrice
gateOpentrue when the city gate is open
loyaltythe city's loyalty
castlethe city exactly as the game sends it (for json_encode and digging)
cityManagerthe same object again

Building and research types are named by their short codes or full names, as in the commands: "c", "cottage", "house", "Feasting Hall", "lo".

city.resourceObject

Usage
city.resource.<property>
Example
if city.resource.food < 1b gosub feed
echo city.resource.food.increaseRate "food an hour"

The city's resources and people, as they stand now (the last figures from the game, run on at the hourly rates up to the storage limit).

PropertyGives
food, wood, stone, ironeach a small object that acts as the amount in sums and comparisons and prints as a whole number, with .amount, .max (the storage limit), .increaseRate (per hour; negative when food runs down) and .storeRercent (how full, in percent; the old spelling is kept)
goldgold, a whole number
goldRategold an hour
curPopulation, maxPopulationpeople now and the most there can be
idlePopulation, workPeopleidle people, and people at work
texRatethe tax rate (old spelling)
supportloyalty
complaintgrievance
troopCostFoodthe troops' food upkeep

citiesObject

Usage
cities[i].cityManager, cities[i].name, cities.length
Example
echo cities.length "cities; the first is" cities[0].name

A list of all your cities, in the game's order. Each entry has id, name, coords and cityManager, the full city object. Lists methods work on it: cities.map(CreateFunction("c", "c.name")).

playerObject

Usage
player.playerInfo.<property>, player.<property>
also m_context.Player
Example
echo player.playerInfo.userName player.playerInfo.prestige

Your lord.

PropertyGives
playerInfo.userNameyour lord's name
playerInfo.prestige, .honor, .rank, .titleas in the game
playerInfo.medalyour coins
playerInfo.allianceyour alliance's name, or ""
playerInfo.allianceLevelyour rank in it, or ""
castlesa list of {id, name, x, y, fieldId}, one per city
itemsan object, item key → how many you hold (see ItemCount to name items by name)
name, coins, prestige, honor, rank, title, alliance …the other things the game sends about your lord (alliance is {id, role, name} or null); json_encode(player) lists them all

m_contextObject

Usage
m_context.<property>
Example
if m_context.serverHours == 6 goto beforemaintenance
if !m_context.marketReady() goto later

A few things about the session, kept under the old scripts' name.

Property or methodGives
Playerthe player object
trucedtrue while your lord is under a truce
ItemCount(item)see ItemCount
serverHours, serverMinutes, serverSecondsthe game's clock (UTC) at the moment you read m_context
findFirstCity()the city the script runs in
buyPrice(…), sellPrice(…)BuyPrice, SellPrice
marketReady()true when the market's prices have been read in the last 15 seconds; otherwise it tries, waits up to 2 seconds and gives false

ScreenObject

Usage
Screen.mainLog.buffer, Screen.cityLog.buffer, Screen.mainLog.addEvent(text)
Example
if Screen.cityLog.buffer.includes("refused") echo "something was refused"

The console's logs as text. mainLog is everything the console logged, cityLog this city's lines; .buffer gives the last 200 lines, one per line. .addEvent(text) writes a line to the script output. aChat, wChat, pChat and sChat are there for old scripts, but chat is not kept in the console log, so their buffers are empty.

ConfigObject

Usage
Config.<name>
Example
with the start-up parameter -home 312,145: transport {Config.home} t:5k f:*

The console's start-up parameters (see Autorun), each under its name in lower case, as text, plus server, the game server the console uses. A parameter that was not given reads as undefined.

MathObject

Usage
Math.<function>(…), Math.PI
Example
Math.floor(Math.random() * 6) + 1

The maths functions (abs, ceil, floor, round, max, min, pow, sqrt, random, exp, log, the angle functions) and constants under one name, for scripts written that way. Each works exactly as its global twin.

troop beanObject

Usage
city.troop.archer, GetTroops("a:5k").lightCavalry
Example
if city.troop.lightCavalry >= 10k attack 312,145 any c:10k

A count of every troop type, under the old keys. Given by city.troop, GetTroops, an army's troops and GetTroopsFromXML.

KeyTroopCode
peasantsWorkerwo
militiaWarriorw
scouterScouts
pikemenPikemanp
swordsmenSwordsmansw
archerArchera
carriageTransportert
lightCavalryCavalryc
heavyCavalryCataphractcata
ballistaBallistab
batteringRamBattering Ramr
catapultCatapultcp

It also has foodConsumeRate (the food these troops eat), toString([separator]) (the same as TroopBeanToString, which is also how it prints) and add(otherBean) (a new bean with both added up). Keys are exact: lightCavalry, not lightcavalry.

fortification beanObject

Usage
city.fortification.trap
Example
echo city.fortification.arrowTower "towers"

A count of each fortification: trap (Trap), abatis (Abatis), arrowTower (Arrow Tower), rollingLogs (Rolling Logs), rockfall (Rock Fall). Given by city.fortification, GetFortifications and GetFortsFromXML.

resource beanObject

Usage
city.estResource.food, GetResources("f:1m").food
Example
echo city.estResource → f:5203117,w:880000,s:120000,i:95000,g:410000

Plain numbers for gold, food, wood, stone and iron. It prints as a resource list (f:…,w:…,s:…,i:…,g:…, whole numbers), and toString(separator) lets you choose the separator. Given by city.estResource, GetResources and GetResourcesFromXML.

hero beanObject

Usage
city.heroes[i], city.findHeroByName("Bob"), city.getMayor()
Example
m = city.getMayor() then if m echo m.name m.politics
PropertyGives
id, name, levelas in the game
attack (power), politics (management), intel (stratagem)the stats with boosts; the second names are the old ones
basePower, baseManagement, baseStratagemthe base stats
experience, upgradeExpexperience, and what the next level needs
remainPointpoints not yet spent
loyaltyloyalty
statewhat it is doing, in a word: idle, mayor, march, camp, garrison, prisoner, returning
statusthe same as an old number: 0 idle, 1 mayor, 3 away (march, camp, garrison), 4 prisoner, 5 returning
isIdle, isMayortrue or false
castleIdits city's id

armyObject

Usage
city.selfArmies[i]
Example
echo city.selfArmies.length "armies out"

One of this city's armies away from home. Times are in milliseconds (compare with date() or use TimeDiff).

PropertyGives
idthe army's id (for idrecall)
missionattack, scout, transport, reinforce or build
toX, toYwhere it is going or stays
troopsa troop bean
cargothe goods it carries
heroIdits hero's id, or null
stateout, back (coming home) or garrison (staying)
sentAt, leftAt, arriveAt, campUntil, returnAtits times
hostthe city it stays in (name, x, y), when it does

incoming attackObject

Usage
city.enemyArmies[i]
Example
a = city.enemyArmies[0] then echo a.lord a.fromCity TimeDiff(a.arriveAt) / 1000

An attack on its way to this city. Only attacks are listed, never scouts, and only what the city's Beacon Tower can see is filled in; the rest is null or missing:

PropertyShown from Beacon Tower level
id, toX, toY, beacon (the tower level that saw it)1
mission2
arriveAt, campUntil (milliseconds)3
lord, alliance4
fromCity, fromX, fromY5
troops: the types, each "?"6
troops: rough numbers in words ("pack", "horde" …)7
troops: exact numbers8
heroLevel9
techs (the attacker's military research)10

map beanObject

Usage
GetDetailInfo(t).userName, MapCastles(x, y, r)[i].prestige
Example
b = GetDetailInfo("312,145") then if b.canScout scout {b.coords} none s:1

One tile of the map, as GetDetailInfo, CastlesInRectangle, MapCastles and SearchEnemyCastles give it.

PropertyGives
id, x, y, coordsthe tile
type, levelits type number and level
namethe city's name, or the tile type's name
userName, allianceNamethe owner and the owner's alliance, or null
prestige, honorthe owner's
relation0 your alliance (and your own cities), 1 friendly, 2 neutral, 3 enemy, 6 no standing or nobody's (see also RelationIndex)
statethe owner's state, a PlayerState number (1 for an empty tile)
canScoutwhether you could scout it: an NPC city, or another lord's city in its normal state
npc, furlough, flagan NPC city; on holiday; the owner's flag
zoneNamethe map state it lies in
lastUpdatedwhen it was read, in milliseconds

trade beanObject

Usage
city.tradesArray[i]
Example
execute "canceltrade " + city.tradesArray[0].id
See also
canceltrade

One of this city's open market orders: id, tradeType (0 a bid to buy, 1 an offer to sell) and tradeTypeName ("Bid" or "Offer"), resType (0-3) and resourceName, amount, price, dealedAmount (filled so far), dealedTotal (gold for that), and createdAt (milliseconds). The list is refreshed in the background when it is more than 2 seconds old.

delivery beanObject

Usage
city.transingTradesArray[i]

Goods this city bought that are on their way: id, resType, resourceName, amount (also total), endTime (when they arrive, in milliseconds); price is always null.

date objectObject

Usage
d = date() then d.getHours()
Example
if date().getDay() == 0 goto sunday

What date gives. All the get…, set… and to… methods work (getHours, getMinutes, getTime …, in your computer's time zone; the getUTC… ones in game time). It prints as Sat Oct 18 14:02:11 GMT+0200 2026; toUTCString() gives Sat Oct 18 12:02:11 2026 UTC, toTimeString() the time part, toNumber() the milliseconds. In sums and comparisons it acts as its milliseconds, so date() - start is the time passed.

BuildingTypesObject

Usage
BuildingTypes.Cottage, BuildingTypes["Town Hall"]

Building type numbers by name: Cottage 1, Barracks 2, Warehouse 3, Sawmill 4, Quarry 5, Ironmine 6, Farm 7, Stable 20, Inn 21, Forge 22, Marketplace 23, Relief Station 24, Academy 25, Workshop 26, Feasting Hall 27, Embassy 28, Rally Spot 29, Beacon Tower 30, Town Hall 31, Walls 32. Names with a space are also there without it (BuildingTypes.TownHall).

ResearchTypesObject

Usage
ResearchTypes.Logistics

Research numbers by name: Agriculture 1, Lumbering 2, Masonry 3, Mining 4, Metal Casting 5, Informatics 7, Military Science 8, Military Tradition 9, Iron Working 10, Logistics 11, Compass 12, Horseback Riding 13, Archery 14, Stockpile 15, Medicine 16, Construction 17, Engineering 18, Machinery 19, Privateering 20 (also without spaces).

FieldTypesObject

Usage
FieldTypes.Lake

Tile type numbers: Forest 1, Desert 2, Hill 3, Swamp 4, Grassland 5, Lake 6, Flat 10, Castle 11 (a lord's city), NPC 12.

PlayerStateObject

Usage
PlayerState.truce
Example
if GetDetailInfo(t).state == PlayerState.peace goto hit

A lord's state numbers, as a map bean's state gives them: peace 1 (normal), truce 2, beginner 3, holiday 5, dream 6. StateName turns a number back into the word.

AbbreviationsObject

Usage
Abbreviations.troops.c → "cavalry"

The short codes the commands accept, in five groups: buildings, research, troops, fortifications and resources, each mapping a code to its full name (Abbreviations.research.lo is "logistics").

SpeedUpItemsObject

Usage
SpeedUpItems[i].seconds

The six speed-up items, shortest first: the 15-minute, 1-hour, 2.5-hour and 8-hour speed-ups, the 10-30 hour one and the one that takes a share off. Each has id, name and seconds (what one takes off); the 10-30 hour one also has maxSeconds, and the last has percent (30) instead. The names here are the old ones; give the Citavon names to the commands.

ResourceNames, ResourceIntNamesObject

Usage
ResourceNames[RESOURCETYPE_IRON] → "Iron"
ResourceIntNames[1] → "wood"

The market's four resources in its order (0 food, 1 wood, 2 stone, 3 iron): ResourceNames with capitals ("Food" …), ResourceIntNames in lower case, ready for a buy or sell line.

24Deployment scripts

Every script command that sends, times, watches or calls back an army: the four marches and their big and deploy forms, recalls, march look-ups, and the background attacks that run beside your script (spamattack, loyaltyattack, capture, guardedattack, setguard).

What every march line shares

The march commands (attack, scout, transport, reinforce, their big forms, deploy, bigdeploy and construct) all read the rest of the line the same way:

The shape of a march line
<command> <target> [hero] [troops] [resources] [@:hh:mm:ss | camp] [/big] [/horde] [from <city>]

The target always comes first. After it, the hero, the troops and the resources go in that order; the time and the switches may sit anywhere after the target; from <city> always goes last.

The target

  • Coordinates: 312,455 (a dot works too: 312.455). No spaces inside.
  • One of your own cities, by name (any case): transport Rivergate t:5k f:*. A name with spaces goes in quotes: "North Keep" or 'North Keep'. Other lords' cities are named by their coordinates only.

A target the bot cannot find fails the line with "there is no … to march to"; nothing is sent.

The hero

The first word after the target that is not a troop list, a resource list, a time or a switch is the hero. It must come before the troops: a plain word after the troops is an error.

You writeThe bot takes
any, att, atk, attackthe idle hero with the highest attack
pol, politicsthe idle hero with the highest politics
int, intel, intelligencethe idle hero with the highest intelligence
a name, e.g. Aldricthat hero, if idle (any case; quote a name with spaces)
a hero string, e.g. !Aldric,any:attack>180of the idle heroes that match, the one with the highest attack (see Hero strings)
none, or leave it outno hero

Only idle heroes of the sending city are picked: never the mayor, never one already marching. A hero this script sent in the last minute is also skipped, so two lines in a row never try to send the same hero. An attack must have a hero; for the other marches the hero is optional.

Troops and resources

Troops are word:count pairs joined by commas, no spaces: a:50k,c:10k,s:500. Counts take k, m and b (1.5m is 1,500,000).

TroopWords
Workerwo, work, worker, peasant
Warriorw, warr, warrior, militia
Scouts, scout, scouter
Pikemanp, pike, pikeman, pikemen
Swordsmansw, sword, swordsman, swordsmen
Archera, arch, archer
Cavalryc, cav, cavalry
Cataphractcata, phract, cataphract
Transportert, trans, transport, transporter
Ballistab, ball, ballista
Battering Ramr, br, ram
Catapultcp, cat, pult, catapult

Plurals of the longer words work too (archers, rams). Watch out: cata is the Cataphract, the Catapult is cp.

Resources are the second list: f food, w or l wood, s stone, i iron, g gold (or the full words): f:1m,w:500k,g:20k. A * fills the hold: f:* loads as much food as the troops can carry after the food the march itself eats. Several * share the free room equally (w:*,s:*), after any fixed amounts on the same list. A * never takes more than the city holds.

The first list on the line is the troops; a second is the resources; a third is an error. Every march takes food for the road from the city as well: each troop's upkeep, twice over, for every hour of the one-way march and the camp.

Timed landing and camp

  • @:hh:mm:ss lands the march at that time of day, 24-hour, on your computer's clock (the same clock sleep @: reads). Seconds may carry a fraction: @:14:30:07.500. @:14:30 and one-digit parts (@:9:5) work. The bot works out the march time and sends the army that long before. If that time today has passed, it means tomorrow. If the march is too long to make it, the line fails with "too late to land at that time".
  • A camp time is a length of time, written h:mm:ss or m:ss, with or without an @ in front but with no colon after it: 1:30:00 or @1:30:00 (an hour and a half), 5:00 (five minutes). On Citavon the camp happens at home, before the march sets off: the troops leave the city's defence at once, wait out the camp, then march. Citavon counts camp in whole minutes, so the bot rounds it up. The game allows a day of camp at most.
The script waits on a timed line

A line with @: holds the script until its send time, then the next line runs. To land several waves on the same second, put the longest march first: a later line whose march is longer than the one before it will already be too late.

/big, /horde and from

  • /big uses a Rally Banner: this march may hold 25% more troops than your Rally Spot allows (Rally Spot level × 10,000). The big… commands are the same as /big.
  • /horde uses a Warlord's Standard: ten times what the Rally Spot allows (1,000,000 at level 10; 1,250,000 with /big as well).
  • The game refuses either item when the march would fit without it, so you never waste one.
  • from <city> sends from another of your cities instead of the script's own. Everything after from is the city's name, spaces and all, so no quotes are needed: from North Keep.
  • /fullhold, /within… and /tries… are accepted so old scripts load, and do nothing.

What a march line waits for

A march line does not fail when the city is not ready: it waits, checking every second, and says once in the Log why ("not yet: … — waiting"), again each minute it is still waiting. It waits while:

  1. the sending city has no Rally Spot, or every Rally Spot slot is in use (one slot per Rally Spot level; marches coming home and troops stationed elsewhere hold their slot too);
  2. the troops on the line are not all at home;
  3. no idle hero fits the hero you asked for;
  4. the city lacks a resource on the line.

Then, for an @: line, it waits for the send time. Stop ends any wait. A wait has no time limit: a hero name that does not exist waits forever, so check your spelling. The bot does not check the troop limit per march or the food for the road before sending; the game refuses a march that breaks them, and the line fails.

Script marches are not held back by the rallypolicy goal, but they do count against it by their mission (attack as NPC farming, transport as resources, reinforce as troops, scout as safe valley farming, construct as buildnpc), so your goals send less while your script's armies are out.

Transports into a stronger alliance mate's city

A transport to a city of a lord in your alliance whose prestige is more than 2.5 times yours is not sent: barbarians would take most of the goods and carriers on the way. The line fails with a message starting "ambush:".

$result and $error after a line

  • A march that went: $error is null and $result is the new march's id (for idrecall).
  • A march the game refused: $error holds the refusal, e.g. FAILED (ok=-1) - a march takes at most 30,000 troops (Rally Spot 3).
  • A line the bot cannot read at all (a bad troop word, an attack with no hero) stops the script from starting, with the reason.
  • The same march line refused 10 times in a row (by repeat, goto or loop) ends the run.
Keeping a march's id
attack 312,455 any a:20k,c:5k
if $error goto failed
army = $result
sleep 10:00
idrecall %army%      // call it back after ten minutes
end
label failed
echo "not sent: " $error

The marches

attackScript

Usage
attack <x,y | city> <hero> <troops> [resources] [@:hh:mm:ss | camp] [/big] [/horde] [from <city>]
Example
attack 312,455 any a:40k,c:10k
attack 312,455 any:attack=best a:99k,b:1k @:07:00:00.500
attack 280,190 Aldric c:12k /big from North Keep
Values
As in What every march line shares. The hero is required.
See also
bigattack, deploy, spamattack, guardedattack

Sends an attack. It waits for a free slot, the troops, an idle hero that fits and any resources on the line, then sends. An attack may carry goods if you list them (they take room the loot would use). The game refuses attacks on your own city, on lords of your alliance or of an alliance yours has as an Ally, and while truce or beginner protection stops it.

attack … / repeat 8 sends the same attack 8 times in all, each waiting for its slot.

scoutScript

Usage
scout <x,y | city> [hero | none] <troops> [@:hh:mm:ss | camp] [/big] [from <city>]
Example
scout 312,455 s:500
scout 312,455 none s:2k @:06:59:30
See also
bigscout, guardedattack

Sends a scouting. The troops must include Scouts (s:); other troops may go along, but only the Scouts scout, and the rest die if the Scouts lose. The hero is optional. A scouting is refused on your own city or on a valley you already hold.

transportScript

Usage
transport <x,y | city> [hero] <troops> <resources> [@:hh:mm:ss | camp] [/big] [from <city>]
Example
transport Rivergate t:10k f:*
transport 140,77 t:5k w:2m,s:1m from North Keep
See also
bigtransport, dumpresource

Carries goods to a city: one of yours or one of your alliance's. Both lists are required. The goods plus the road food must fit what the troops carry (Transporters carry the most), or the game refuses it; f:* and friends work that out for you. See the ambush warning in What a march line waits for.

reinforceScript

Usage
reinforce <x,y | city> [hero] [troops] [resources] [@:hh:mm:ss | camp] [/big] [from <city>]
Example
reinforce Rivergate a:20k,p:20k f:*
reinforce 301,452 Brenna c:5k
See also
bigreinforce, evacuatetown, recall

Sends troops (and goods, if listed) to stay: in one of your cities, in an alliance mate's or ally's city that takes them, or in a valley or flat the sending city holds (they then defend it). The bot accepts a line with no troops, but the game wants at least one troop in every march, so always list some. Troops stationed in another city keep their Rally Spot slot until they come home; recall brings them back.

bigattackScript

Usage
bigattack <x,y | city> <hero> <troops> [resources] [@:hh:mm:ss | camp] [/horde] [from <city>]
Example
bigattack 312,455 any a:125k
See also
attack, /big and /horde

attack with a Rally Banner: the march may hold 25% more troops (125,000 at Rally Spot level 10). Exactly the same as attack … /big. The game refuses it, and keeps your Banner, if the troops would fit without it.

bigscoutScript

Usage
bigscout <x,y | city> [hero | none] s:<scouts> [@:hh:mm:ss | camp] [from <city>]
Example
bigscout 312,455 none s:125k
See also
scout

scout with a Rally Banner (scout … /big).

bigtransportScript

Usage
bigtransport <x,y | city> [hero] t:<transports> <resources> [@:hh:mm:ss | camp] [from <city>]
Example
bigtransport Rivergate t:125k f:*
See also
transport

transport with a Rally Banner (transport … /big).

bigreinforceScript

Usage
bigreinforce <x,y | city> [hero] [troops] [resources] [@:hh:mm:ss | camp] [from <city>]
Example
bigreinforce Rivergate a:125k
See also
reinforce

reinforce with a Rally Banner (reinforce … /big).

deployScript

Usage
deploy <at|bu|re|sc|tr> <x,y | city> [hero] <troops> [resources] [@:hh:mm:ss | camp] [/big] [/horde] [from <city>]
Example
deploy at 312,455 any a:40k,c:10k
deploy tr Rivergate t:10k f:*
deploy bu 318,460 wo:250
Values
Mission wordSame as
at, atk, attackattack
sc, sct, scoutscout
tr, transporttransport
re, rei, reinforcereinforce
bu, bld, build, constructconstruct
See also
bigdeploy

Any march, with its mission named first. Everything after the mission word works exactly as on the matching command. Handy when the mission sits in a variable: deploy %mission% %target% any %army%.

bigdeployScript

Usage
bigdeploy <at|bu|re|sc|tr> <x,y | city> …
Example
bigdeploy at 312,455 any a:125k
See also
deploy

deploy with a Rally Banner (deploy … /big).

constructScript

Usage
construct <x,y> [hero] wo:<workers> [@:hh:mm:ss | camp] [from <city>]
Example
construct 318,460 wo:250
See also
buildcity, deploy bu

Sends Workers to build a new city on a flat this account holds. The game wants Workers only, at least 250 of them, and takes the founding goods (10,000 each of food, wood, stone, iron and gold) from the sending city on its own; any resource list you add is ignored. Your title must allow one more city. A hero is not needed. Same as deploy bu.

Calling armies back

A march still on its way turns round and takes as long to come home as it has marched so far. One still camping at home has not left, so it is back at once. Troops stationed in another city or a valley leave it and march home.

recallScript

Usage
recall <x,y | city> [all]
Example
recall 312,455
recall Rivergate all
Values
all: every march to that place, not just the first.
See also
recallall, idrecall

Calls back this city's march to the target: one on its way there, or troops stationed there. Without all only the first one found goes; with all, every one. Only the script's own city counts (there is no from here). Nothing to recall is not an error: the Log says "nothing to recall".

recallallScript

Usage
recallall
Example
recallall
See also
recall

Calls back every march of this city that is out or stationed somewhere, wherever it went. Marches already coming home are left alone.

idrecallScript

Usage
idrecall <armyId>
Example
idrecall 48213
idrecall %army% (after army = $result on a march line)
See also
marchcheck, $result

Calls back one march by its id, from any of your cities. The id is the $result of the line that sent it, or the # number marchcheck prints. A march already coming home is refused by the game ("it is already coming home").

recallheroScript

Usage
recallhero <hero name>
Example
recallhero Aldric
See also
waithero

Calls back every march led by the hero with that name (any case), from any of your cities, unless it is already coming home. Give the hero's full name: any, filters and wildcards are not read here.

waitheroScript

Usage
waithero <hero name>
Example
waithero Aldric
See also
recallhero, waitherolost

Holds the script until the named hero is back in this city and idle (or the mayor). It checks every 2 seconds, with no time limit; Stop ends the wait. A hero that is not in this city at all is waited for too (the Log says so), so use the exact name. Full names only, no hero strings.

Looking at marches

travelinfoScript

Usage
travelinfo <x,y | city> <troops> [from <city>]
Example
travelinfo 312,455 a:40k,c:10k

Prints the distance in tiles, the march time, the food the march takes for the one-way trip, and how much the troops can carry:

Rivergate -> 312,455: 23.4 tiles, march 41m 12s, food 1,374,000, carries 5,500,000

$result is the march time in seconds. It counts your Compass, Horseback Riding and Logistics research and the Relief Station on marches between your own cities; it does not count items that speed up or slow down marches.

attackstatusScript

Usage
attackstatus
Example
attackstatus
See also
marchcheck, Background attacks

First lists the background attacks running on this console, then every attack and scouting of the whole account:

#3 loyaltyattack 312,455 from Rivergate: 14 waves sent, loyalty 38, for 7m 5s
#48213 Rivergate attack -> 312,455 out 12m 40s · 40,000 Archer, 10,000 Cavalry

Each march line shows its id, the sending city, the mission, the target, its state (out, back or garrison), the time left until it lands (or, coming back, until it is home), and the troops. $result is the number of attacks and scoutings listed.

marchcheckScript

Usage
marchcheck
Example
marchcheck

Lists every march of the account, of every mission, in the same form as attackstatus (without the background attacks). $result is how many there are; "no marches" when there are none.

buildstatusScript

Usage
buildstatus
Example
buildstatus

One line per city: what is being built, to which level, the time left, and how many more builds wait in its queue.

Rivergate: cottage -> 9, 1h 04m 10s left (+2 waiting)
North Keep: nothing building

$result is that text.

Background attacks

spamattack, loyaltyattack, capture, guardedattack and setguard start a job that runs beside your script. The line starts it and returns at once; the script goes on. What these jobs share:

  • The target is always coordinates (x,y), never a city name, and never one of your own cities. They send from the script's own city; there is no from.
  • They go on after the script ends. The console's Stop does not end them: use endspamattack, endloyaltyattack or endguardedattack. They do not survive a restart of the console.
  • One job per kind, target and city. Starting the same one again starts nothing and tells you it is already running. At most 10 jobs run on one console.
  • Their messages go to the console's Log under the city. While the console is offline they wait.
  • They learn what happened from your battle and scouting reports about the target, read without marking them read.
  • Unlike march lines, they do not wait for a free Rally Spot slot or for troops: they send, and if the game refuses 3 waves in a row the job ends.
  • $result is the job's number (the # in attackstatus).

The heroes for spamattack, loyaltyattack and capture come from the city's spamheroes goal; with none, any hero of base 69 or lower and below level 50. Each wave takes the first idle one that fits and was not sent in the last 15 seconds. With none free, the job waits and says so.

spamattackScript

Usage
spamattack <x,y> <troops> <waves>
Example
spamattack 312,455 c:500,s:500 10
Values
troops: the troops of each wave (required). waves: how many, a plain whole number (no k).
See also
endspamattack, spamheroes, getspamhero

Sends that many attack waves at the target, one after another, 3 seconds apart. Each wave is led by an idle SpamHero whose loyalty is 100; a hero below 100 is passed over. It does not read reports or stop on a result: it ends when all waves are sent, when its city is gone, when the game refuses 3 waves in a row, or at endspamattack. The end line reads like "all 10 waves sent — done (10 of 10 waves sent, 0 refused)".

loyaltyattackScript

Usage
loyaltyattack <x,y> [troops | cavalry] [/waves=N] [/hours=N]
Example
loyaltyattack 312,455
loyaltyattack 312,455 3000 (3,000 Cavalry a wave)
loyaltyattack 312,455 s:100,c:5k /waves=300 /hours=24
Values
PartMeaningDefault
troopsa troop list, or a bare number of Cavalry (3k works)500 Cavalry
/waves=Nmost waves it sends, 1 to 10,000100
/hours=Nlongest it runs, up to 168 (a week); fractions allowed12
See also
capture, endloyaltyattack

Wears down a city's loyalty: a wave every 30 seconds, each with an idle SpamHero (any loyalty), and your reports about the target read every 10 seconds. Citavon's battle report tells the city's loyalty after each battle, so no scouting is needed first.

Once the loyalty is known and the waves are lowering it, it holds back while the waves already on their way should be enough to bring it to 7 or lower (it judges by the average drop per wave so far), and sends again when they are not.

It stops when:

  • a report shows the loyalty at 7 or lower: this city's attacks still on their way there are recalled;
  • any battle of yours there is lost: this city's attacks on their way there are recalled (other cities' are left);
  • the city is taken: waves still on their way are left to land;
  • it has sent /waves waves or run /hours hours;
  • 3 reports about the target in a row could not be read;
  • the game refuses 3 waves in a row, its city is gone, or endloyaltyattack ends it (waves already out are not recalled then).

captureScript

Usage
capture <x,y> [troops | cavalry] [/waves=N] [/hours=N]
Example
capture 312,455 c:8k,s:100 /waves=200
Default
500 Cavalry a wave, 100 waves, 12 hours.
See also
loyaltyattack, endloyaltyattack

The same as loyaltyattack, but it never holds back and does not stop at loyalty 7: it sends a wave every 30 seconds until a report says the city was taken, a battle there is lost (this city's waves on their way are then recalled), or one of the other limits is reached. endloyaltyattack ends it.

guardedattackScript

Usage
guardedattack <x,y> <troops> <scouts> <their troops> <their defenses>
Example
guardedattack 312,455 cav:99000,s:1000 10 a:500000 ab:1
Values
PartMeaning
troopsyour attack
scoutshow many Scouts follow it, a plain whole number
their troopsa troop list: the attack is called off if they have this many or more of any one of these
their defensesa fortification list, the same rule: tra Trap, ab Abatis, at Archer Tower, r Rolling Log, tre Defensive Trebuchet (e.g. ab:1 or at:5k,tre:2k)
All four are required.
See also
setguard, endguardedattack

Sends the attack now, led by the idle hero with the highest attack (the line fails if there is none). Then it sends the Scouts, with no hero, timed to land 15 to 30 seconds (a random time) before the attack; if that moment has already passed, they go at once. When their report comes in, the bot checks it against your limits: if any one count reaches its limit, or the Scouts were beaten, the attack is recalled; if everything is under, it is let through and the job ends.

The attack is also recalled if the Scouts cannot be sent, if the city that sent it is gone, or if no scouting report has come in 3 seconds before the attack lands. When the report only gives a word for a count, the bot reads it as the top of its range, so it errs toward calling off:

WordRead as
Few24
Pack49
Lots99
Horde249
Throng499
Swarm999
Zounds2,499
Legion4,999
Bulk9,999
Gigano limit (always calls off)

endguardedattack before the Scouts go leaves the attack on its way; call it back with recall if you need to.

setguardScript

Usage
setguard <x,y> <their troops> <their walls>
Example
setguard 312,455 a:60000,cav:50000 ab:100
Values
As in guardedattack. Both lists are required.
See also
guardedattack, endguardedattack

Guards attacks you have already sent. It watches every attack from this city now on its way to the target (there must be at least one, or the line fails) and waits for a scouting report there that is newer than those attacks. It sends no Scouts: send them yourself, timed to land before the attack.

Attack, scout, guard
attack 312,455 any a:90k,c:9k
scout 312,455 none s:2k
setguard 312,455 a:60000,c:50000 ab:100

If the report shows any count at or over its limit, or the Scouts were beaten, every watched attack still on its way is recalled. If no report has come 3 seconds before the first of them lands, they are all recalled. Otherwise they go on.

endspamattackScript

Usage
endspamattack [all]
Example
endspamattack
Values
all: every city's, not only this city's.
See also
spamattack

Ends this city's spamattack jobs (all cities' with all) and waits up to 5 seconds for them to finish. Waves already sent go on. $result is how many jobs it ended; none running is not an error.

endloyaltyattackScript

Usage
endloyaltyattack [all]
Example
endloyaltyattack all
See also
loyaltyattack, capture

Ends this city's loyaltyattack and capture jobs (all cities' with all). Waves already on their way are not recalled. $result is how many jobs it ended.

endguardedattackScript

Usage
endguardedattack [all]
Example
endguardedattack
See also
guardedattack, setguard

Ends this city's guardedattack and setguard jobs (all cities' with all). The attacks they guarded are left on their way, unguarded. $result is how many jobs it ended.

Heroes for marches, and the rest

getspamheroScript

Usage
getspamhero [power|atk | management|pol | stratagem|int]
Example
getspamhero
getspamhero pol
Values
power, atk, attack: attack. management, pol, politics: politics. stratagem, int, intel: intelligence.
Default
attack
See also
hire, spamheroes

Hires, from this city's Inn, the hero with the highest of that stat, paying its gold fee. It is hire best <stat> under another name: it does not check your spamheroes rule, so the hero it hires may be too strong to count as a SpamHero. With nobody at the Inn the line fails ("nobody at the Inn").

waitherolostScript

Usage
waitherolost <hero1,hero2,...>
Example
waitherolost Aldric,Brenna
See also
waithero

Holds the script until one of the named heroes is no longer yours: captured in battle, or dismissed. It watches all your cities (a hero that moves to another city by reinforcing is still yours), checks every second, and counts a hero as lost once it has been missing from every city for 10 seconds while the console is online. $result is the lost hero's name.

Names are full names, any case, separated by commas. If none of them is a hero of yours, the line fails at once. Stop ends the wait and the script.

Pull everything home if the war hero is taken
waitherolost Aldric
echo $result " was captured"
recallall

herorouteScript

Usage
heroroute
Example
heroroute
See also
traininghero

Shows where each traininghero goes next. For every hero named on a traininghero goal in any city, it prints the city that holds it now and, in your cities' order, the cities whose troop goals are not yet met:

traininghero Aldric (in Rivergate now): cities still training, in order: North Keep -> Stonebridge

"none — it stays" means every city's troops are done. It changes nothing. $result is the list (hero, where it is, the cities to come).

setballsusedScript

Usage
setballsused <n,n,n,n,n>
Example
setballsused 20,50,130,200,400
See also
npctroops, config ballsused

Retired. The line loads, so old scripts still start, but it changes nothing: it fails with a message pointing you to the npctroops goal, which sets the troops sent to each NPC level.

More march commands elsewhere

Some commands that send armies live with the city and market commands: buildcity and cancelbuildcity, dumptroop, evacuatetown and endevacuate, and dumpresource.

25Building scripts

The script commands that put up, raise, take down and hurry the buildings of a city, and the rules every city line shares: which city it works on, when it waits, /nowait, /speedup=, and what it leaves in $result and $error.

How city lines run

  • The city. Every command in this section and the four after it works on the city the script is running in, unless its entry says otherwise. None of them takes from <city>: to work on another city, run the script there.
  • Waiting for the builder. create, build, upgrade and demo wait until nothing is being built in the city. The bot looks every two seconds and says why it waits once, then again once a minute: not yet: the builder is busy (cottage -> 5) — waiting. Stop ends the wait. The bot never queues a building behind another with a Builder's Hammer, and never uses the second builder that Twin Foremen give: it waits until the builder is idle.
  • Waiting for the Academy. startresearch and research wait the same way until this city's Academy has nothing under way.
  • /nowait turns the wait into a refusal: if the builder (or Academy) is busy, the line fails at once, nothing is sent, and $error is builder busy (or academy busy).
  • /speedup=<item>[,<item>…] on create, build, upgrade and startresearch: once the job is accepted, each item in the list is spent on it, in the order written. free is the free finish. A name with spaces goes in quotes: /speedup="Speed-up 1 hour". A word the bot does not know as an item is skipped with no item "…" in the log; the job still counts as started. See Speed-up items.
  • $error is null after a line that worked. When the bot refused the line itself (nothing was sent), it holds a short reason, listed in each entry below (builder busy, no plot, none…). When Citavon said no, it holds the game's answer, e.g. FAILED (ok=-1) - not enough wood.
  • $result is the value an entry names under Returns; where it names none, it is the text the line wrote to the log (its lines joined).
  • A line that finds nothing to do (a cancel with nothing queued, a speed-up with nothing being built) says so in the log and counts as having worked: $error stays null.
  • A line written with a colon after the first word, like build c:10:9 or research lo:5, is not this command at all: it is the goal of the same name (build goal, research goal).

Plots

Some lines take a plot: write it at 12 or @12.

PlotsWhat stands there
0 – 31Inside the walls: every building except the Town Hall, the Walls and the four fields.
1001 – 1040Outside: Farm, Sawmill, Quarry, Ironmine. 13 are open at Town Hall level 1, 3 more each level (all 40 at level 10).
-1The Town Hall.
-2The Walls.

Building words

A building may be named by its full name (any case, with or without spaces: feastinghall or "Feasting Hall"), a plural of a word of four letters or more (cottages), or these short words:

BuildingWords
Cottagec house houses
Barracksb barrack rax
Warehousewh
Sawmills saw lumbermill
Quarryq quary
Ironminei iron mine
Farmf
Stablest
Inninn tavern
Forgefo
Marketplacem market
Relief Stationrs relief
Academya
Workshopws
Feasting Hallfh feast
Embassye
Rally Spotr rally rallypoint
Beacon Towerbe beacon
Town Hallt th
Wallsw wall

An unknown word stops the script from starting, with unknown building: ….

Speed-up items

The words buildingspeedup, researchspeedup and /speedup= accept. An item may be named by its short word, its Citavon name, or its old-server name; case, spaces and dashes do not matter (speed1h, "Speed-up 1 hour" and speedup1hour are the same item). Each one named is used once; to use three, name it three times: speed1h,speed1h,speed1h.

WordCitavon itemWhat it does to the job
free(no item)Finishes it at once, free — only a job whose normal time (before research and the mayor) is 5 minutes or less. A longer job is refused.
speed15mSpeed-up 15 min15 minutes off.
speed1hSpeed-up 1 hour1 hour off.
speed2hSpeed-up 2.5 hours2 hours 30 minutes off.
speed8hSpeed-up 8 hours8 hours off.
speedbigSpeed-up 10-30 hoursA random 10 to 30 hours off.
speed30Builder's Ledger30% of the time left off.
stonecutterStonecutter's MasterworkHalf the time left off.

All of these work on buildings and on research. Drillmaster's Diary (drill) and Engineer's Notes (engnotes) are for troop and wall batches: on a building or research Citavon refuses them. A job that reaches its end this way finishes at once. The speed-up always goes on the job the builder (or Academy) is working on now. You must hold the item: these lines never buy one (see buyitem).

The building commands

createScript

Usage
create <building> [plot] [/speedup=<items>] [/nowait]
Example
create cottage
create barracks 14 /speedup=free
create farm @1020 /nowait
Values
building: a building word (not any). plot: a plot number, written plain (14), at 14 or @14. /speedup=, /nowait: see How city lines run.
Default
No plot: the first free plot of the right kind — inside (0–31) for a city building, the first open outside plot for a field.
Returns
$error: no plot (no free plot of that kind), builder busy (with /nowait), or Citavon's refusal.
See also
build, upgrade, build goal

Puts up a new level 1 building. A plot counts as taken when a building stands on it or a job in the build queue is for it. The bot waits for the builder first (unless /nowait), then asks Citavon to build; Citavon checks the rest — the cost, what the building needs, whether a second one of its kind is allowed — and refuses if anything is missing. With a plot given, that plot is used as written, even if it is taken (then Citavon refuses).

buildScript

Usage
build <building> [at <plot>] [/speedup=<items>] [/nowait]
Example
build academy
build inn at 7
See also
create, build goal

Without a colon, build is create with another name: the same words, the same waiting, the same results. With a colon (build c:10:9, build t:9,w:9) the line is the build goal instead, and is handed to the goals.

upgradeScript

Usage
upgrade [<building> | any] [levelX | lowestlevel [X] | highestlevel [X]] [at <plot>] [/speedup=<items>] [/nowait]
Example
upgrade cottage — the lowest cottage, one level up
upgrade farm highestlevel 8 — the highest farm still under level 8
upgrade any level3 — any building at level 3
upgrade b @14 /speedup=free,speed15m
Values
WordMeaning
<building>Only buildings of that kind. any, or nothing at all: every kind, but only buildings below level 9.
levelXOnly buildings at exactly level X (one word: level5).
lowestlevelPick the lowest level first (this is the default).
highestlevelPick the highest level first.
lowestlevel X / highestlevel XThe same, among buildings below level X only.
at <plot> / @plotOnly the building on that plot.
Default
any, lowest level first. Between buildings of the same level, the lowest plot number goes first (so the Walls, then the Town Hall, then plot 0…).
Returns
$error: none (nothing matches), builder busy (with /nowait), or Citavon's refusal.
See also
create, demo, build goal

Raises one building one level. A building at level 10 is never picked. When you name a kind, a level 9 building of that kind can be picked and taken to 10 — that uses a Master Builder's Script, which you must hold. any never picks a building at level 9, so it never spends a Script.

The building is chosen when the line starts, then the bot waits for the builder (unless /nowait). The level filter must follow the building word: upgrade level5 is read as a building called "level5" and stops the script; write upgrade any level5.

Every cottage up to level 9, one after another
label more
upgrade cottage lowestlevel 9 /speedup=free
if $error goto done      // "none": every cottage is at 9 or more
goto more
label done

demoScript

Usage
demo <building | any> [levelX | lowestlevel | highestlevel] [@plot] [/dynamite] [/nowait]
Example
demo cottage — the lowest cottage down one level
demo farm highestlevel
demo @1012 /dynamite
Values
building: a building word, or any; it may be left out when a plot is given. levelX: only buildings at exactly that level. lowestlevel / highestlevel: which end to take first. @plot or at plot: only that plot. /dynamite: use Blasting Powder. /nowait: refuse if the builder is busy.
Default
Lowest level first; between equal levels, the highest plot number first.
Returns
$error: none (nothing like that stands), builder busy, or Citavon's refusal.
See also
demosite, cancelbuilding

Without /dynamite, it takes the building down one level, as a job for the builder: the bot waits for the builder first, as for an upgrade. Taking a level 1 building down clears the plot. The Town Hall and the Walls are never picked.

With /dynamite, one Blasting Powder brings the whole building down at once, with nothing back. It does not wait for the builder. You must hold the Blasting Powder.

A number after lowestlevel or highestlevel is read but has no effect here. A /speedup= on this line is read but not used.

Check the words

demo any takes down the lowest-level building in the city, whatever it is. Name the kind or the plot unless that is really what you want.

demositeScript

Usage
demosite [/dynamite] <plot>
Example
demosite 12
demosite /dynamite @1004
See also
demo

demo for one plot, whatever stands on it: one level down (waiting for the builder), or the whole building at once with /dynamite. The plot may be written plain, at 12 or @12; without one, the script does not start. Results as for demo.

cancelbuildingScript

Usage
cancelbuilding [@plot]
Example
cancelbuilding
cancelbuilding @14
Default
No plot: the last job in the city's build queue (the one that would finish last).

Cancels a building job, or a level being taken down. Citavon gives back 95% of what the job cost. With @plot (or at plot), the job on that plot. A plain number (cancelbuilding 14) is not read as a plot: write the @. With nothing being built, the log says nothing is being built and the line counts as worked.

buildingspeedupScript

Usage
buildingspeedup <item>[,<item>…]
Example
buildingspeedup free
buildingspeedup speed1h,speed15m
buildingspeedup Speed-up 8 hours
Values
The words in Speed-up items: free, speed15m, speed1h, speed2h, speed8h, speedbig, speed30, stonecutter, or the items' names. Several, comma-separated, are used in that order.
See also
researchspeedup, Speed-up items

Spends speed-ups on the building job under way in this city. Each item's answer is logged on its own line (speed-up speed1h -> ok); one refused does not stop the next. An unknown item word is skipped with no item "…". With nothing being built, it logs nothing is being built and spends nothing.

An @plot is accepted, but has no effect: the speed-up always goes on the job the builder is working on now.

26Research scripts

Starting, choosing, cancelling and hurrying research in a city's Academy.

Research words

A research may be named by its full name (any case, spaces or not: "Metal Casting", metalcasting) or these short words:

ResearchWordsResearchWords
Agricultureag agriLogisticslo
LumberingluCompasscom
MasonrymasHorseback Ridingho horse horseback
MiningmiArcheryar
Metal Castingmet metalStockpilest sp
Informaticsin infoMedicinemed
Military SciencemsConstructioncon
Military TraditionmtEngineeringen eng
Iron WorkingirMachinerymac
Privateeringpr

An unknown word stops the script from starting, with unknown research: …. Research is the lord's: a level learned in one city counts in all of them. Each city's Academy works on one research at a time, and the same research cannot be under way in two cities at once.

The research commands

startresearchScript

Usage
startresearch <research | quickest | cheapest | dearest> [/nowait] [/speedup=<items>]
Example
startresearch lo
startresearch quickest /speedup=free
startresearch "Military Science" /nowait
Values
WordStarts
a research wordthe next level of that research
quickestof what can start now (as checkresearch lists it), the one whose next level has the shortest normal time
cheapestthe one whose next level costs the fewest resources in all (food, wood, stone, iron and gold added up)
dearestthe one that costs the most
/nowait and /speedup=: see How city lines run.
Returns
$result: the research started, as its one-word name (logistics, militaryscience). $error: no academy (this city has none), academy busy (with /nowait), none (quickest, cheapest or dearest found nothing to start), or Citavon's refusal (not enough resources, a requirement missing, already at the top level, under way in another city).
See also
research, checkresearch, research goal

Starts the next level of one research in this city's Academy. The bot first waits until this Academy is free (unless /nowait); quickest, cheapest and dearest are then chosen from what this city can start at that moment. They do not look at whether you can pay for it: if the pick costs more than the city holds, Citavon refuses and nothing else is tried.

A research named outright is sent as it is: the bot does not check its requirements first, Citavon does.

Start whatever is quickest, and say what it was
startresearch quickest /speedup=free
if $error == null echo "Researching " + $result

researchScript

Usage
research <research | quickest | cheapest | dearest> [/nowait] [/speedup=<items>]
Example
research agriculture
See also
startresearch, research goal

Without a colon, the same as startresearch. With a colon (research lo:5, research lo:5,ho:5) the line is the research goal instead.

cancelresearchScript

Usage
cancelresearch
Example
cancelresearch

Cancels the research under way in this city's Academy; Citavon gives back 95% of its cost. Nothing after the word is read. With nothing being researched here, the log says so and the line counts as worked.

checkresearchScript

Usage
checkresearch
Example
checkresearch
Returns
$result: the research this city could start now, comma-separated, as one-word names (agriculture,lumbering,masonry); empty when there is none. The log shows the same list, or nothing.
See also
startresearch

A research is on the list when it has a level left, is not under way in any of your cities, and this city's buildings and your research meet what its next level needs. The list does not look at resources, and does not care whether this Academy is busy right now. Nothing is sent to the game.

checkresearch
if $result == "" echo "Nothing left to research here"

researchspeedupScript

Usage
researchspeedup <item>[,<item>…]
Example
researchspeedup free
researchspeedup speed8h,speed8h,stonecutter
Values
The words in Speed-up items, comma-separated.
See also
buildingspeedup

Spends speed-ups, in the order written, on the research under way in this city's Academy. As buildingspeedup: each answer logged, an unknown word skipped, nothing spent (and no error) when nothing is being researched here. free works only on a research whose normal time is 5 minutes or less.

27Troop & wall scripts

Training and dismissing troops, healing the wounded, building and taking down wall fortifications, and the two old-bot helpers: the trebuchet loop for training a hero, and the troop dump.

Fortification words

Troops are written as troop strings, a:5k,c:1k (see the troop words with the march lists). Fortifications have words of their own:

Citavon fortificationWords
Traptra tr trap traps
Abatisab abatis
Archer Towerat tower arrowtower archertower (and plurals)
Rolling Logr rl log logs rollinglog rollinglogs
Defensive Trebuchettre treb trebuchet dt defensivetrebuchet rf rock rocks rockfall (and plurals)

Note that r means Rolling Log here, but a Battering Ram in a troop string. Counts take k, m and b: 5k is 5,000.

The troop and wall commands

trainScript

Usage
train <troops> [hero] [all | idle | <barracks plot>] [minimum]
train <troop> <amount> [hero] [all | idle | <barracks plot>] [minimum]
Example
train a:50k
train a 10k
train a:20k,c:5k Eldian idle
train cp:2k any:attack>150 3 500 — barracks on plot 3, at least 500
Values
PartMeaning
troopsA troop string (a:5k,c:1k), or a troop word and an amount (archer 5000).
heroA hero to be mayor while the order is placed: a name, any/att/pol/int, or a hero string. It must be idle in this city, or already its mayor.
allSplit the order evenly over every barracks that can train it and has room in its queue.
idleSplit it over the barracks that have nothing queued.
a number 0–31The barracks on that plot only.
minimumTrain nothing of a kind unless at least this many fit.
How numbers are read: one plain number of 31 or less is a barracks plot; any other single number (above 31, or written 5k) is the minimum; two numbers are the plot, then the minimum. More than two stops the script.
Default
all barracks; no hero (the mayor stays as it is); minimum 1.
Returns
$error: no hero (the hero is not idle in this city), Citavon's refusal, or the bot's own refusal for a kind that does not fit, e.g. FAILED (ok=-1) - only 1,200 Archer fit (resources, idle population 1,200) — under the minimum 5,000. The other kinds on the line are still trained.
See also
disband, canceltroopqueues, troop goal, traininghero

For each kind of troop in the line, in order, the bot works out how many the city can pay for and has idle people for, and trains that many, up to what you asked: only 3,000 of the 5,000 fit — training those. If fewer than the minimum fit (or none), that kind is skipped with a refusal and the next kind is tried.

With a hero, the hero is made mayor before the order (so its attack sets how fast the troops train) and afterwards the old mayor is put back — or the city is left with no mayor, if it had none. This happens even if the order fails.

The city must have at least one barracks (with a plot, a barracks on that plot), or the kind is refused with no barracks there. Citavon checks the rest: what the troop needs, the barracks' level, a full queue.

disbandScript

Usage
disband <troops>
disband /keep <troops>
Example
disband w:25k — dismiss 25,000 Warriors
disband /keep s:1000,w:0 — dismiss all Scouts but 1,000, and every Warrior
Values
troops: a troop string; several may also be written with spaces between them. /keep (first, before the troops): the numbers are what to keep, not what to dismiss.

Dismisses troops at home in this city. Without /keep, it dismisses the number given, or all you have if you have fewer. With /keep, it dismisses everything above the number. A kind with nothing to dismiss is passed over in silence. Dismissed troops go back to the population, as far as there is room for them; they are gone as troops.

No way back

Dismissed troops cannot be called back. Check a /keep line twice: disband /keep a:0 dismisses every archer at home.

healtroopsScript

Usage
healtroops
Example
healtroops

Heals every wounded troop waiting in this city, all at once, for gold; they are back at home straight away. Citavon refuses when nobody is wounded here, or the city lacks the gold. Nothing after the word is read.

canceltroopqueuesScript

Usage
canceltroopqueues [n]
canceltroops [n]
Example
canceltroopqueues — every batch
canceltroopqueues 2 — the two newest batches
Default
Every troop batch queued in this city.
See also
cancelfortifications

Cancels troop batches in this city's barracks, newest first, across all its barracks. Each cancelled batch gives back 95% of its cost and its people. Each one is logged (cancel 5,000 archer -> ok); with nothing queued, the log says nothing queued.

cancelfortificationsScript

Usage
cancelfortifications [n]
cancelwalls [n]   clearwallqueue [n]
Example
cancelfortifications 1 — the newest wall batch
Default
Every wall batch queued in this city.
See also
canceltroopqueues, walldefense

Cancels fortification batches on this city's walls, newest first, 95% of their cost back. Logged and counted as for canceltroopqueues.

walldefenseScript

Usage
walldefense [/demo | /keep] <fort>:<count>[,<fort>:<count>…]
walldefense <fort> [count] [build | demo | keep]
Example
walldefense tra:10k,ab:5k,at:2k
walldefense /demo tra:0,at:4k
walldefense trap 5000 keep
Values
ModeBelow the countAbove the count
build (default)builds the differenceleft alone
/demo or demobuilds the differencetakes the extra down
/keep or keepleft alone (nothing is built)takes the extra down
fort: a fortification word. In the second form the count may be left out; it is then 0.
Default
Mode build.
See also
wall, cancelfortifications, fortification goal

Brings each fortification named to the count you give. What counts as "have" when building: the ones standing plus the ones already queued, so running the same line again does not build twice. What counts when taking down: only the ones standing. The difference is sent as one order per kind; Citavon refuses it if there is not room on the walls, the walls' queue is full, or the city cannot pay — the bot does not build a smaller amount instead.

Taking down is final

Fortifications taken down are gone at once, and nothing comes back. walldefense trap keep (no count) takes down every trap.

wallScript

Usage
wall <fort> <amount>
walls <fort> <amount>
Example
wall trap 2000
wall at 1.5k
See also
walldefense

Queues that many more of one fortification on this city's walls, whatever already stands — unlike walldefense, the amount is what to add, not a total. Citavon refuses if the walls lack room, their queue is full, or the city cannot pay.

trebloopScript

Usage
trebloop <tra|ab|at|r|tre>:<qty> <batch> <queen> <trainee> [slow hero]
Example
trebloop tre:1 10999 Isolde Bram
trebloop tra:50 5000 Isolde Bram Oswin
Values
tra|ab|at|r|tre:qty: the "slow" batch — Trap, Abatis, Archer Tower, Rolling Log or Defensive Trebuchet, and how many. batch: how many Defensive Trebuchets to queue (at least 1). queen: the hero who is mayor while the trebuchets are queued. trainee: the hero to be trained. slow hero: a hero made mayor while the slow batch is queued.
Returns
$result: the batch size, when every step went through. Otherwise $error: N of M trebloop request(s) not ok, or no hero named "…" in … (nothing sent).
See also
mayor, traininghero

Trains a hero by building. In Citavon, the hero who is mayor when a job finishes earns experience from it, while a job's time is fixed by the mayor when it is queued. One trebloop line sends, in this order:

  1. the slow hero becomes mayor (only if you named one);
  2. the slow batch is queued on the walls (always — with no slow hero, under the mayor of the moment);
  3. the queen becomes mayor;
  4. batch Defensive Trebuchets are queued, behind the slow batch, timed by her politics;
  5. the trainee becomes mayor, so it is mayor when they finish.

The heroes are found by name (any case) among this city's heroes; a name cannot hold a space here. All five steps are sent even if one is refused; each answer is logged. One line is one round: to go round again, loop it, keeping the walls' queue (5 batches) and room in mind.

label round
trebloop tre:1 10999 Isolde Bram
if $error goto stop
sleep 30:00
goto round
label stop

dumptroopScript

Usage
dumptroop <x,y> <when troops> <send troops>
Example
dumptroop 111,222 a:99000,s:50000 a:20000,s:15000
Values
x,y: where to send them (not this city). when troops: send only once this city holds at least all of these at home. send troops: what to send. Exactly these three parts.
Returns
$result: the number of troops sent (0 when Citavon refused the march). $error: not yet (the city does not hold the "when" troops; $result 0), short (it holds fewer than the "send" troops), self (x,y is this city).
See also
reinforce, dumpresource

A check and a send in one line. If this city holds at least the "when" troops at home, it reinforces x,y with the "send" troops, with no hero; if not, it logs not yet: … and sends nothing. It does not wait: put it in a loop to keep watching.

label watch
dumptroop 111,222 a:99000 a:20000
sleep 5:00
goto watch

28City scripts

Running the city itself: fields, tax, comforting and levies, its name, moving it, building and giving up cities and the land they hold, and emptying a city in a hurry.

productionScript

Usage
production <food> <wood> <stone> <iron>
produce <food> <wood> <stone> <iron>
Example
production 100 100 50 0
production 100% 100% 100% 100%
Values
Four whole numbers from 0 to 100, in this order: food, wood, stone, iron — the share of each kind of field that is worked. A % after each is allowed.

Sets the Town Hall's production rates for this city, one resource at a time. A refused one is logged by name; the others still go. The log ends with what was asked: fields worked: food 100%, wood 100%, stone 50%, iron 0%. Anything but exactly four numbers stops the script from starting.

taxScript

Usage
tax <0-100>
settaxrate <0-100>
Example
tax 20
settaxrate 0%
See also
taxpolicy

Sets this city's tax rate. Citavon takes whole numbers only (tax 12.5 is refused). The log shows the old rate: set tax rate to 20% (now 10%). More than one number stops the script from starting.

comfortScript

Usage
comfort <1-4 | relief | pray | bless | popraise>
Example
comfort pray
comfort 4
Values
WordActionWhat it does
1 reliefDisaster relief+5 loyalty, less grievance; costs food.
2 prayPray+25 loyalty, a little less grievance; costs food.
3 blessBlessGuards the city against its next disaster; costs food and gold.
4 popraise raiseRaise population+5% of the population limit in people; costs food.
See also
levy, comfortpolicy

One Town Hall comfort action in this city. Each action has its own timer: once every 15 minutes per city. Citavon refuses a second one too soon, or one the city cannot pay for.

levyScript

Usage
levy <1-5 | gold | food | wood | stone | iron>
Example
levy gold
levy 2 — food
Values
1 gold, 2 food, 3 wood, 4 stone, 5 iron; or a resource word (g, f, w or l for wood, s, i, or the full name).
See also
comfort

Levies one resource from this city's people: a sum based on its population comes in at once, and loyalty drops by 20. Each resource has its own 15-minute timer. Citavon refuses a levy while loyalty is under 15, or while you are on holiday.

setfocusScript

Usage
setfocus [cycles]
Example
setfocus 5

Accepted so old scripts run, and does nothing: Citavon Bot looks after every city on every pass, so there is no focus to set. Anything after the word is ignored.

renamecityScript

Usage
renamecity <new name>
Example
renamecity Rivergate
renamecity "North Keep"

Gives this city a new name: 1 to 20 letters, digits, spaces, _, ' or -. A name with spaces must be in quotes — without them only the first word is used. A city can be renamed once every 24 hours; Citavon refuses sooner, and says when it can be done again.

teleportScript

Usage
teleport <x,y>
teleport <state>
teleport random
Example
teleport 312,455
teleport Tuscany
teleport North March
Values
You writeItem usedWhere the city goes
x,ySurveyor's MapThat free flat.
a stateWayfarer's MapA free flat picked at random in that state.
randomWayfarer's MapA free flat in a state picked at random.
The states: Friesland, Saxony, North March, Bohemia, Lower Lorraine, Franconia, Thuringia, Moravia, Upper Lorraine, Swabia, Bavaria, Carinthia, Burgundy, Lombardy, Tuscany, Romagna (any case).
See also
warteleport, autoteleport

Moves this city with one map item, which you must hold. Every army of the city must be home first, and no allied troops stationed in it; this line does not call anything back (autoteleport does). A city moved with a Surveyor's Map or a Siege Map cannot do so again for 12 hours; the Wayfarer's Map has no such wait. A city that moves lets go of its valleys.

warteleportScript

Usage
warteleport <x,y>
Example
warteleport 288,301
See also
teleport

Moves this city onto the NPC city at x,y with a Siege Map; the NPC city is gone. Only coordinates are accepted. Citavon refuses if x,y is not an NPC city, the city's armies are not home, or it moved by map in the last 12 hours.

buildcityScript

Usage
buildcity <x,y> [troops]
newcity <x,y> [troops]
Example
buildcity 205,318
buildcity 205,318 wo:300
Default
250 Workers.
Returns
$result: the march's id.
See also
construct, cancelbuildcity

Sends workers from this city to build a new city on a flat you hold. It is a march like any other: it waits for a free Rally Spot slot and for the troops to be at home (see march waits). The troops are the first word holding a colon; a hero word is accepted for old scripts but no hero goes.

cancelbuildcityScript

Usage
cancelbuildcity [x,y]
Example
cancelbuildcity
cancelbuildcity 205,318
See also
buildcity

Calls back city-building marches still on their way out — to x,y, or all of them without it. This looks at the marches of all your cities, not only the script's. With none out, the log says no build march out.

abandonScript

Usage
abandon <x,y>
Example
abandon 207,320
See also
abandontown

Lets go of a valley or flat you hold (held by any of your cities). Troops stationed there are sent home. Citavon refuses a tile you do not hold. This never gives up a city: that is abandontown.

abandontownScript

Usage
abandontown <x,y | city> confirm
Example
abandontown 205,318 confirm
abandontown "Old Fort" confirm
Values
x,y | city: one of your cities, by coordinates or name. confirm: must be the last word, in lower case, or the script does not start.
Returns
$error: protected (not marked with allowabandon), off (switched off for this bot), no city, or Citavon's refusal.
See also
allowabandon, evacuatetown

Gives the city up for good: it becomes an NPC city of its flat's level, and the valleys it held are let go. Three locks must all be open:

  1. the city has been marked with allowabandon;
  2. the bot was started with the setting GERMBOT_ALLOW_ABANDON_TOWN=1 (without it the line is refused with off);
  3. Citavon agrees: it is not your last city, no troops or heroes are in it, all its armies are home, and no allied troops are stationed there.
There is no undo

The city, its buildings and everything stored in it are lost. Move out what you want to keep first.

allowabandonScript

Usage
allowabandon <x,y | city> confirm [off]
Example
allowabandon 205,318 confirm
allowabandon "Old Fort" confirm off — protected again
Returns
$result: the city's name. $error: no city.
See also
abandontown

Marks one of your cities as one abandontown may give up; with off, takes the mark away. Without confirm the script does not start (the message says what the line would do). The mark is kept for this account until you take it off, across runs and restarts. Marking changes nothing in the game.

evacuatetownScript

Usage
evacuatetown <x,y> [confirm]
Example
evacuatetown 300,412
Returns
$result: the number of troops sent. $error: none (no troops at home), self (x,y is this city), nothing sent.
See also
endevacuate, reinforce

Sends every troop at home in this city to reinforce x,y, with no hero (heroes stay), carrying all they can. It takes as many marches as needed: each is as large as the Rally Spot allows, with the same share of every kind of troop, and between marches the bot waits for a free Rally Spot slot (Stop ends it). Each march carries gold first, then food (after the food the march itself eats), then wood, stone and iron.

It stops early if the city cannot feed the next march, or Citavon refuses one; the log says how many went and what is still at home. A trailing confirm is accepted but not needed: the troops can be called back with endevacuate.

endevacuateScript

Usage
endevacuate [x,y]
Example
endevacuate
endevacuate 300,412
Returns
$result: how many marches were called back. $error: which (no x,y and no evacuation sent from this city in this run).

Calls back this city's reinforcement marches to x,y that are on their way or stationed there. Without x,y it uses the places evacuatetown sent to from this city earlier in the same run. With none still out, it says so and counts as worked.

autoteleportScript

Usage
autoteleport [<state> | random] [all confirm] [/tries=5] [/every=5:00] [/norecall]
Example
autoteleport Tuscany
autoteleport random /tries=10 /every=1:00
autoteleport Lower Lorraine all confirm
Values
PartMeaning
stateOne of the 16 states (any case; see teleport), or random.
all confirmEvery one of your cities, not just this one. all needs confirm, and confirm is only for all.
/tries=NTries per city, 1 to 50.
/every=TThe wait between tries: m:ss, h:mm:ss or seconds.
/norecallDo not call the armies home first.
Default
No state: the -teleport start-up parameter of the console (a state or random). /tries=5, /every=5:00, armies called home.
Returns
$result: this city's coordinates afterwards (x,y). $error: how many cities were not moved, or which (no state and no start-up parameter).
See also
teleport

Moves a city to a state with Wayfarer's Maps, doing the preparation for you. For each city:

  1. A city already in the state is skipped (with random, none is).
  2. With no Wayfarer's Map left, it stops there and says so; nothing more is sent.
  3. Unless /norecall: every march of the city that is out or stationed somewhere is called back, and the bot waits until all its armies are home (Stop ends the run).
  4. It uses a map. If Citavon refuses (no free flat found, allied troops inside…), it waits /every and tries again, up to /tries times, as long as a map is left.

The log ends with N moved, N already there, N not moved.

29Hero scripts

Listing, hiring, firing and appointing heroes, rewarding and levelling them, spending their points and items, and bringing captured heroes home.

Naming a hero

The hero commands work on the heroes of the script's city (except where an entry says otherwise). A hero is named by its name, in any case; a name with spaces goes in quotes ("Red Bram"). These words pick a hero for you, among the idle heroes of the city:

WordPicks
any, att, atk, attackthe idle hero with the highest attack
pol, politicsthe idle hero with the highest politics
int, intelthe idle hero with the highest intelligence

The hero commands on this page do not read hero strings; train and the march commands do. A name is matched whatever the hero is doing (idle, mayor, out on a march, or a prisoner held here). When no hero matches, the line fails with no hero … in … and $error is no hero.

Where a hero's stats appear, the bot writes the three words Citavon uses: attack, politics, intelligence. Lines that take a stat accept attack, att, atk, power, politics, pol, management, intel, int, intelligence and stratagem.

The hero commands

heroesScript

Usage
heroes   herolist
Example
heroes
Returns
$result: the number of heroes in the city.
See also
listallheroes

Lists this city's heroes, one a line: name, level, politics, attack, intelligence, what it is doing, and its unplaced points if any — Eldian L42 pol 18 att 96 int 25 idle (2 points). What it is doing is idle, mayor, march, or captive for a prisoner you hold. No heroes: no heroes.

listallheroesScript

Usage
listallheroes
Example
listallheroes
See also
heroes, \listallheroes

The heroes list for every one of your cities, each line starting with the city's name. Its $result is the list's text.

innScript

Usage
inn   tavern
Example
inn
Returns
$result: how many heroes the Inn offers.
See also
hire, innrefresh

Lists the heroes this city's Inn offers now: slot 2: Oswin L8 pol 31 att 12 int 9 — 8,000 gold (the fee). With none, it says no Inn (or no Feasting Hall). Nothing is sent to the game.

innrefreshScript

Usage
innrefresh   refreshinn
Example
innrefresh

Brings a new set of heroes to this city's Inn at once, using one Recruiting Notice. Citavon refuses without an Inn or without a Recruiting Notice; this line does not buy one. Without it the Inn gets a new list by itself every hour.

hireScript

Usage
hire <hero name>
hire best [attack | politics | intel]
Example
hire Oswin
hire best politics
Default
hire best alone: the highest attack. An unknown stat word also means attack.
Returns
$error: none (that hero is not at the Inn, or the Inn is empty), or Citavon's refusal.
See also
inn, innrefresh

Hires a hero from this city's Inn and pays its fee in gold (level × 1,000). The name is everything after hire, so no quotes are needed. best takes the offer highest in that stat, whatever it costs. Citavon refuses when the Feasting Hall has no free seat, the city lacks the gold, or you are on holiday.

findheroScript

Usage
findhero <atk | pol | int>
Example
findhero pol
Returns
$result: the hero's name.

Finds the hero highest in that stat across all your cities, whatever it is doing, and logs where it is: Isolde in Rivergate: politics 212. Any stat word works (see Naming a hero). Prisoners you hold are counted too. With no heroes at all, it logs no heroes.

fireScript

Usage
fire <hero>   firehero <hero>
Example
fire Oswin
Returns
$error: no hero, or Citavon's refusal.

Dismisses one of this city's heroes for good.

Name the hero

A fired hero is gone. The words any, att, pol and int work here too, so fire att fires your best idle attack hero. Write the name.

releaseScript

Usage
release <prisoner>   releasehero <prisoner>
Example
release Garrick
See also
persuadehero

Lets a hero you hold prisoner in this city go. It is gone for good, for you and for its old lord. Citavon refuses a hero that is not your prisoner.

persuadeheroScript

Usage
persuadehero <prisoner>   persuade <prisoner>
Example
persuadehero Garrick
See also
release

Persuades a prisoner held in this city to join you. It costs gold (the hero's level × 1,000) and, for higher-level heroes, medals, and needs a high enough title; Citavon refuses and says what is missing. The hero joins with loyalty 10, so reward it soon (rewardheroes). Its old lord can still bring it home with a Seeking Stone.

mayorScript

Usage
mayor <hero>   appoint <hero>   setmayorbyname <hero>
Example
mayor Isolde
mayor pol — the idle hero with the highest politics
See also
setmayor, unmayor

Makes a hero of this city its mayor; the old mayor goes back to idle. Citavon refuses a hero that is out on a march, or a prisoner (persuade it first).

setmayorScript

Usage
setmayor <att | pol | int>
setmayor none   setmayor remove
Example
setmayor pol
Returns
$error: none (no hero at home).
See also
mayor

Makes the hero at home (idle, or the mayor now) highest in that stat the mayor. If the mayor already is that hero, it says so and sends nothing. none or remove is unmayor. Any stat word works.

unmayorScript

Usage
unmayor   unappoint   dischargemayor
Example
unmayor

Leaves this city with no mayor; the mayor goes back to idle. Fine to run when there is none.

rewardheroesScript

Usage
rewardheroes [/medal[=<medal>]]
Example
rewardheroes
rewardheroes /medal
rewardheroes /medal=lion
Values
You writeEach hero getsLoyalty
(nothing)gold from this city: the hero's level × 100+5
/medalthe first medal you hold, Cross first (the lowest)that medal's
/medal=crossa Cross Medal+5
/medal=rosea Rose Medal+10
/medal=liona Lion Medal+15
/medal=honoran Honor Medal+20
/medal=couragea Courage Medal+25
/medal=wisdoma Wisdom Medal+30
/medal=freedoma Freedom Medal+40
/medal=justicea Justice Medal+50
/medal=nationa Nation Medal+60
Loyalty never goes past 100.
Default
Gold.
See also
persuadehero

Rewards each hero in this city whose loyalty is under 100, once each. A hero can take a reward only once every 15 minutes: one rewarded less than 15 minutes ago is skipped, and the log ends with how many wait. Each reward is logged with the hero's loyalty before it. Citavon refuses a reward the city cannot pay for, or a medal you do not hold; the next hero is still tried.

renameheroScript

Usage
renamehero <hero> <new name>   changeheroname <hero> <new name>
Example
renamehero Oswin Bram
renamehero "Old Tom" "Red Bram"

Gives one of this city's heroes a new name, using one Herald's Scroll (you must hold it). The new name is 1 to 20 letters, digits, spaces, _, ' or -; with spaces, put it in quotes, or only its first word is used.

levelupScript

Usage
levelup <hero | all> [attack | politics | intel | auto]
Example
levelup Eldian
levelup Eldian attack
levelup all auto
Values
hero: a hero of this city, or all for every one. attack | politics | intel (any stat word): put all the hero's unplaced points into that stat afterwards. auto: into the stat the hero is highest in at that moment.
Default
No stat: the points are left unplaced.
See also
uplevelheroes, addpoint

Levels a hero up as many times as its experience allows, one level at a time; each level gives one point. A hero without the experience for its next level is passed over quietly. With a stat, all the hero's unplaced points — the new ones and any it had before — then go into that stat.

uplevelheroesScript

Usage
uplevelheroes
Example
uplevelheroes
See also
levelup

The same as levelup all: every hero in this city gains every level its experience allows, and the points are left unplaced.

addpointScript

Usage
addpoint <hero> <attack | politics | intel> [n]   addpoints …
Example
addpoint Eldian attack 5
addpoint Isolde pol
Default
1 point.

Puts n of a hero's unplaced points into one stat. Citavon refuses more points than the hero has.

useheroitemScript

Usage
useheroitem <hero> <item> [repeat <n>]   heroitem …
Example
useheroitem Eldian Grand Strategy
useheroitem Eldian xp1 repeat 20
Values
hero: one word, or quoted. item: the rest of the line up to repeat, by its short word or name. repeat n: use it n times.
Default
Once.
Returns
$error: no hero, no item (the bot does not know the item), or Citavon's refusal.
See also
heroitems, waterhero

Uses an item on a hero, once or n times; it stops at the first refusal (for example, when you run out). Citavon takes these items on a hero:

ItemWordEffect
Field Manualxp11,000 experience, or 8% of what the next level needs if that is more.
Officer's Handbookxp210,000 experience, or 30% of the next level.
Grand Strategyxp3100,000 experience, or a whole next level.
Clear Spring WaterholywaterResets the hero's points (one bottle per 10 levels begun). The points are left unplaced: waterhero does the same and places them.

Experience is not a level: follow with levelup. Other items are refused on a hero here (rename a hero with renamehero).

heroitemsScript

Usage
heroitems
Example
heroitems

Lists the hero items you hold and how many: experience books, Clear Spring Water, the hero boosts (Champion's Blade, Treatise on Strategy, Book of Statecraft) and Herald's Scrolls — Grand Strategy (xp3): 4. Nothing held: none. Nothing is sent to the game.

waterheroScript

Usage
waterhero <hero> [/heropoints="<stages>" | /heropoints=off]
Example
waterhero Eldian
waterhero Eldian /heropoints="att"
waterhero Isolde /heropoints="pol:300 att"
waterhero Eldian /heropoints=off
Values
hero: the name (no quotes needed) of a hero in any of your cities. /heropoints=: where the points go after the reset, in stages, separated by spaces or commas. Each stage is a stat (att, pol, int, or attack/power, politics/management, intel/stratagem), with :N to stop that stat at N. off: leave the points unplaced.
Default
Every point into the stat the hero is highest in after the reset.
Returns
$result: the hero's name. $error: no hero, busy (not at home), short (not enough Clear Spring Water).
See also
useheroitem, buyitem

Resets a hero's points with Clear Spring Water and spends them again. The hero must be idle or mayor. It takes one bottle for every 10 levels begun (1 + level ÷ 10, rounded down: a level 42 hero takes 5); the bot checks you hold enough before it sends anything, and never buys them. After the reset the hero has as many points as its level.

The stages are filled in order: "pol:300 att" raises politics to 300 (or as far as the points go), then puts the rest into attack. A stage whose stat is already at its number is skipped. If every stage has a number, points left over stay unplaced.

lostheroesScript

Usage
lostheroes
Example
lostheroes
Returns
$result: a list of the names of your heroes held by others.
See also
recover

Shows how many Seeking Stones you hold, then each hero of yours that another lord holds: its level, whether it is that lord's prisoner or was persuaded to serve them, the city and coordinates, the city of yours it would come home to, when it can come home (24 hours after it was lost) or that it is out with an army, and how many medals its holder would be paid. A hero that was fired or released is gone for good and is not listed.

recoverScript

Usage
recover <hero>
Example
recover Eldian
Returns
$result: the hero's name. $error: no stone, not held (no hero of yours by that name is held), not yet (under 24 hours, or out with an army).
See also
lostheroes

Brings a hero of yours that another lord holds — as a prisoner, or persuaded to serve them — back home with one Seeking Stone. The bot checks first, before any stone is spent: you hold a stone, the hero is on the lostheroes list, 24 hours have passed since it was lost, and it is not out with an army. Its holder is paid medals for it.

The hero comes home to the city it was lost from, or the first of your cities with room; you cannot choose. recover Eldian to Rivergate is accepted, but the to part only logs a note that the city cannot be chosen. The name is the rest of the line, no quotes needed.

30Account scripts

Script commands for the lord's own business: buying and using items, truces, quests, the daily gift, reports, the lord's name, the security code and logging out for a while.

Naming an item

Every command here that takes an item accepts it three ways: by Citavon's short key (speed1h, treaty, charm), by its name as the shop shows it (Speed-up 1 hour, Peace Treaty), or by the name the old server used, so NEAT scripts written for it still work. Case, spaces and punctuation are ignored: peacetreaty, "Peace Treaty" and PEACE-TREATY are the same item. NEAT's twelve amulets (amulet5, amulet 3, any … amulet) all mean Citavon's one Lucky Charm.

An item the bot does not know stops the line with no item "…". listitems shows every item you hold with its key.

Dry runs

In a dry run, every command in this section says what it would do and sends nothing. Lines that only read (packages, securitycode with no word after it) still show the real answer.

buyitemScript

Usage
buyitem [/count=N] <item> [N] [confirm]
Example
buyitem "Peace Treaty"
buyitem treaty 5
buyitem /count=20 speed1h
buyitem charm 500 confirm
Values
/count=N or a number after the item: how many. confirm as the last word: needed for more than 100 at once.
Default
1
See also
useitem, listitems

Buys items from the shop with coins. The log line says how many, which item and its price in coins each, then the game's answer. The coins come off at once and the items land in your item list.

A number at the end is the count only when something comes before it: buyitem treaty 5 buys five Peace Treaties. When both are given, the trailing number wins over /count=.

More than 100 at once without confirm is refused before the script starts (buyitem: 500 at once takes confirm at the end). The game itself sells 1 to 1,000 in one purchase, so 1,001 or more is refused by the game even with confirm. It also refuses an item that is not for sale, one sold only in its season or during a promotion, and a buy you lack the coins for. Bundles that open as you buy them (for example Town Crier (10)) open straight away.

useitemScript

Usage
useitem [/count=N] <item> [N]
Example
useitem "Lucky Charm" 50
useitem /count=3 "Gold Medal Chest"
useitem "Militia Muster"
Values
/count=N or a trailing number: how many to use.
Default
1
See also
buyitem, truce, packages

Uses items in the script's city. As in NEAT, what you are short of is bought from the shop first: holding 2 and asking for 5 buys 3, and the log says so (hold 2 Lucky Charm: buying 3 for 15 coins (5 each)). Items the shop does not sell are never bought. If that purchase is refused (not enough coins), the bot still tries to use what you have.

The whole text is tried as an item name first; only when that is no item is a trailing number read as the count. So useitem amulet 3 is NEAT's "third amulet" (one Lucky Charm), while useitem "Lucky Charm" 3 uses three.

Items where one more simply gives more of the same (Lucky Charms, chests, packages, musters, hoards, hero helms, boosts and the like) go up to 1,000 at a time in one request; the game stops at the first one it refuses and the bot stops there too. Every other item is used one request at a time. Some items cannot be used this way at all, and the game says where they are used instead: speed-ups (on a job), Town Criers (by speaking in world chat), Rally Banners and Warlord's Standards (with a march), Master Builder's Scripts (when building past level 9), medals (for promotions and persuading).

$result is the number actually used.

Truces and items on other lords

truceScript

Usage
truce
Example
if city.hasEnemyArmiesWithin(3600) == false truce
See also
dreamtruce, holiday

Uses one Peace Treaty: 12 hours in which no lord can attack or scout your cities, and you can attack and scout only valleys and flats. It does not buy one: with none held the game refuses. The game also refuses while any of your armies is out, while an attack is on its way to you, and for 12 hours after your last truce ended.

dreamtruceScript

Usage
dreamtruce <hour 0-23> | dreamtruce /cancel
Example
dreamtruce 22
dreamtruce 6:00
dreamtruce /cancel
Values
The hour the daily 10-hour truce starts, in server time (UTC). 22, 22:00 and 22:00:00 are the same; minutes are ignored. /cancel stops it.

A Dream Truce gives a 10-hour truce every day at the hour you pick, one day per Dream Truce used. The command does what NEAT's did:

  • None running: uses one Dream Truce starting at that hour (today, or tomorrow if today's window would already be over).
  • One already running: moves it to the new hour and uses no item. The game allows a move once every 72 hours and not while a truce window is on. To add more days, use the item: useitem "Dream Truce" 3.
  • /cancel: stops it. A window running now runs to its end; the days not yet begun come back as Dream Truces, and the log says how many. With none set, the line is refused: no Dream Truce is set.

useangelitemScript

Usage
useangelitem <lord> <item>
Example
useangelitem Bob "Swift Boots"
useangelitem "Big Bob" "Philosopher's Lens"
Values
<lord>: one word, or in quotes when it has spaces. <item>: Swift Boots, Draught of the Undying or Philosopher's Lens.

Uses a helping item on another lord: a member of your alliance or of an allied one, never yourself. Swift Boots make their marches 35% faster for 4 hours, Draught of the Undying gives their troops 5% more life for 12 hours, Philosopher's Lens makes all their heroes 10% stronger for 2 hours. The game limits how many can be on one lord at once and refuses the rest.

usedevilitemScript

Usage
usedevilitem <x,y> <item>
Example
usedevilitem 312,455 "Wanderer's Fog"
Values
<item>: Black Rot, Wanderer's Fog, Tainted Banquet or Shattered Bar.
See also
breakgates

Uses a harmful item on the city at x,y. It must be another lord's city that is not under protection, and its lord gets a report. Black Rot kills the city's whole population, Wanderer's Fog slows armies marching out of it by 20% for 4 hours, Tainted Banquet makes its heroes 20% weaker for 2 hours, Shattered Bar holds its gates open for an hour. The game's daily and stacking limits apply.

breakgatesScript

Usage
breakgates <x,y>
Example
breakgates 312,455
See also
usedevilitem

Short for usedevilitem x,y "Shattered Bar": the city's gates are held open for 1 hour, so its troops cannot hide behind them. Up to 5 times a day on one city. On one of your own cities it lifts a Shattered Bar someone put on you.

changeflagScript

Usage
changeflag <flag>
Example
changeflag WAR

Spends a Banner Cloth to change the text on your flag, shown over all your cities on the map. A flag is 1 to 4 letters or digits; the game refuses anything else, or the change when you hold no Banner Cloth (it is not bought for you).

Quests, gifts and packages

completequestsScript

Usage
completequests [routine | daily | title | rank] [types] [/mode=…] [/type="…"] [/name="…"]
Example
completequests
completequests routine Housing,Fields
completequests /type="Town Hall,Walls"
completequests /name="Archer"
completequests daily
completequests title
Values
Word or switchWhat it does
(nothing)Claims every quest that is done and not yet claimed: the ordinary ones and the season's.
routine or /mode=routineOnly the ordinary quests, not the season's.
daily or /mode=dailyOnly the season's quests. With no types or names after it, it also claims the free daily gift first.
title or /mode=titlePromotes the lord to the next noble title (Knight, Baronet, Baron …). No quests are claimed.
rank or /mode=rankPromotes the lord to the next military rank (Captain, Major, Colonel …). No quests are claimed.
types, or /type=Only quests in these families, comma separated. A family with a space goes in quotes. Can be given more than once.
/name=Only quests whose name holds this text (case ignored); comma separated for several.
/query=Accepted for NEAT scripts and ignored.
See also
daily

Citavon's quest families are: Beginner, Housing, Fields, Comfort, Levies, Running the city, Trade, Town Hall, Research, Alliance, Letters and chat, Heroes, Army, Scouting, Walls, Valleys, New cities, Storage, Transport, Watch, Population, Production, Prestige, Shop, War, Speed-ups and Medals. A season's quests are in the family named after the season (for example "Harvest season"). Names are matched without regard to case.

Rewards go into the script's city. Each claim is logged by the quest's name. When nothing matches, the log says so and lists the families that do have quests waiting: nothing to claim of walls (done and waiting: Army, Housing).

A promotion (title or rank) spends the medals and gold it needs from the script's city. A rank also needs a high enough Town Hall in that city; a title needs the right rank and enough prestige. The game says what is missing when it refuses. An unknown switch, or a /mode= that is none of the four, stops the script before it starts.

$result: nothing useful; the number of claims counts toward the run's actions.

dailyScript

Usage
daily
Example
daily

Claims the free daily gift: one Lucky Charm, plus the season's token while a season runs. The day turns at the daily maintenance, 07:00 server time. A second claim the same day is refused (today's gift is already taken); the gift does not roll over.

packagesScript

Usage
packages (also inventory)
Example
packages
See also
listitems, useitem

Lists the things you hold that open into something else: packages, medal chests, locked chests, hoards, hero helms and musters, one line each with the count (Bronze Chest: 4), or none. $result is how many kinds there are.

cleanreportsScript

Usage
cleanreports [all | text[,text…]]
Example
cleanreports
cleanreports scout,transport
Default
all
See also
cleannpcreports

Deletes reports. With nothing (or all) it deletes every report you have. With text it reads your newest 200 reports and deletes those whose title or kind holds any of the words (case ignored); the log says how many, or none match. Deleted reports are gone for good.

cleannpcreportsScript

Usage
cleannpcreports
Example
cleannpcreports

The same as cleanreports npc: deletes the reports among your newest 200 that mention NPC, the usual clutter of a farming script.

The lord, the account and logging out

changeplayernameScript

Usage
changeplayername <new name> confirm
Example
changeplayername "Iron Duke" confirm

Spends a Royal Warrant to rename the lord for good. The name is 3 to 20 letters, digits, spaces, _ or -, and no other lord may have it. Without confirm as the last word, or with a name that breaks the rule, the script is refused before it starts.

When it runs, the bot checks you hold a Royal Warrant (it does not buy one: no Royal Warrant held — buyitem "Royal Warrant") and that the name is not already yours. Once the game accepts it, the Director's account is moved to the new name too, so the console keeps logging in.

resetplayerScript

Usage
resetplayer { unlockcode:"IReallyWantToDeleteThisAccount"[, player:"name", city:"city name", flag:"flag", zone:"state"] }
Example
resetplayer { unlockcode:"IReallyWantToDeleteThisAccount", player:"Iron Duke", city:"Haven", flag:"ID", zone:"Saxony" }
resetplayer { unlockcode:"IReallyWantToDeleteThisAccount", player:null }
Values
KeyMeaningWhen left out
unlockcodeMust be exactly IReallyWantToDeleteThisAccount.The script is refused.
playerThe new lord's name (3-20 letters, digits, spaces, _, -). null or "" closes the account instead.The same name.
cityThe new city's name."<name>'s city".
flag1 to 4 letters or digits.The old flag.
zoneThe state to start in: its name (Friesland, Saxony, North March, Bohemia, Lower Lorraine, Franconia, Thuringia, Moravia, Upper Lorraine, Swabia, Bavaria, Carinthia, Burgundy, Lombardy, Tuscany, Romagna), its number 0-15, or random.The game picks.
No way back

Everything the lord has goes: cities, troops, heroes, items, alliance seat. A closed account is gone. There is no second chance and no undo.

Starts the lord again from nothing, or closes the account. It works only from a script run in the lord's console, because the game asks for the account's password and the console sends the one stored in the Director. NEAT's sex and runscript keys are accepted and left out (the log says so).

The game refuses while any army is out (bring your armies home first), and while the lord is host of an alliance that has other members. A new name moves the Director's account to it; a closed account is switched off in the Director. The script ends after this line.

securitycodeScript

Usage
securitycode | securitycode set <code> | securitycode clear | securitycode check
Example
securitycode set 4711
securitycode check

The security code is Citavon's second password: it guards restarting the lord, abandoning a city, dismissing troops, dismissing heroes and changing the tax. When the game asks for it, Citavon Bot gives the code stored for this account in the Director by itself. This command manages that stored copy only. Setting, changing or removing the game's own code is done by you in the game's Overview window; the bot never sends that.

FormWhat it does
securitycodeSays what the game guards for this lord (and whether the code is being removed or something is unlocked now), and whether a code is stored in the Director. $result: a number for what is guarded, 0 when no code is set.
securitycode set <code>Stores the code in the Director. Nothing is sent to the game.
securitycode clearForgets the stored code.
securitycode checkTries the stored code on the game without unlocking anything: the stored code is right, or the game's refusal. Refused when nothing is stored or the game has no code set.

Works only from a script run in the lord's console.

logoutScript

Usage
logout now <back> | logout <when> <back>
Example
logout now @:14:35
logout now 1:05:00
logout @:01:30:31 @:06:35:00
logout 1:00 29:00
Values
A time is either a clock time in server time (UTC), @:hh:mm or @:hh:mm:ss, or a wait: 90 (seconds), 1:30 (minutes:seconds), 1:05:00 (hours:minutes:seconds). The first time may be now.

Takes the lord off the game for a while; the console logs back in by itself. A clock time for going out is its next occurrence; a clock time for coming back is its next occurrence after going out, and a wait for coming back counts from going out. Less than a minute off is refused.

  • logout now … logs out at once and ends the script there.
  • logout <when> … waits until then, logs out, waits until the console is back in, and the script carries on with the next line. Pressing Stop before it logs out leaves you logged in.

The log line says when it goes out, when it comes back (server time) and for how long. Works only from a script run in the lord's console.

31Market scripts

Placing, cancelling and pacing market orders, reading the books, and moving goods once a city holds enough.

How an order works on Citavon

Citavon's market is a real order book per resource (food, wood, stone, iron), traded for gold. What the bot knows about it:

RuleOn Citavon
Price0.001 to 150 gold a unit, kept to three decimals. The bot rounds a buy price down and a sell price up to three decimals, so an order never pays more, or takes less, than the price you wrote. When it had to round, the log says so.
Amount1 to 99,999,999 in one order (the bot's limit). 10000, 10,000, 20k, 1.5m all work. A smaller cap can be set with the bot's -maxtrade start-up setting in the Director; a bigger order is then not sent.
Fee0.5% of the order's value (price × amount), rounded up, paid in gold when the order is placed. A cancel never gives it back.
What you put upA buy: price × amount in gold, plus the fee. A sell: the goods, plus the fee in gold. Both come out of the script's city.
FillingAn order fills at once against the best opposite orders, at their prices (a buyer gets back what it bid above the seller's price). Whatever does not fill rests in the book until someone takes it or you cancel.
Open ordersA city keeps as many open orders as its Marketplace level (1 to 10). A city with no Marketplace cannot trade. A full Marketplace is refused with a level 5 Marketplace keeps 5 order(s) open.
DeliveryBought goods arrive in the city 30 minutes after the order fills. They show in city.transingTradesArray while on their way.
The book you seeThe best 8 prices on each side. The bot keeps one read of all four books for 15 seconds, then reads again.

A market refusal (a full Marketplace, a city short of gold) never ends a script, however many there are in a row: in a trading loop that is an everyday answer. The line is marked failed ($error holds why), the same refusal is said again at most once a minute, and the script carries on. If the game stops answering, each order waits longer before the next (doubling, up to a minute).

Prices for scripts come from BuyPrice, SellPrice and Price; your open orders are city.tradesArray.

The commands

buyScript

Usage
buy <food|wood|stone|iron|0-3> <amount> <price> [x<orders>]
Example
buy food 10000 6
buy lumber 1.5m @6
buy 3 500k 22.5 x5
Values
Resource: a name (food, wood or lumber, stone, iron, or f w l s i) or a number, 0 food, 1 wood, 2 stone, 3 iron. Gold cannot be traded. The price may be written with or without @, and with @ it may come anywhere among the three. x10 or *10 last: place that many identical orders at once (1 to 20).
See also
sell, canceltrade, waitslot

Places a bid. The log line shows the order, the city, the gold it ties up with the fee, and how it went: placed — filled at once, placed — 120,000 filled at once, the rest in the book, or placed (all resting). After a buy that filled, the bot reads the market again so the delivery shows on its way.

A missing price, a price over 150 or under 0.001, an amount over 99,999,999 or under 1, or an unknown resource stops the script before it starts, with what to write instead.

$result: for one order, ok or the refusal; with x<orders>, how many were placed (the line counts as done when at least one was).

sellScript

Usage
sell <food|wood|stone|iron|0-3> <amount> <price> [x<orders>]
Example
sell food 20000 8
sell wood 1000 @0.55
sell stone 99999999 140 x10

Places an offer, the same way as buy: the goods and the 0.5% fee leave the city at once, it fills against the best bids at their prices, and what is left rests in the book.

Keep a city's Marketplace full of iron offers
label top
waitslot 30 // wait up to 30 s for an order to fill
sell iron 500k 30
goto top

canceltradeScript

Usage
canceltrade [tradeId …] | canceltrade [buy|sell] [food|wood|stone|iron]
Example
canceltrade
canceltrade 123456 123457
canceltrade sell iron
execute "canceltrade " + city.tradesArray[0].id
Values
Order ids, or a side (buy/bid/bids, sell/offer/offers) and/or a resource. Not ids and a side together. all is allowed and means nothing extra.
Default
Every open order of the script's city.

Cancels orders. The bot first reads your orders as they are now. Without ids it cancels this city's orders that match the side and resource; with ids it cancels those orders, wherever they are (an id you do not have is named, together with the ids this city does have).

What had not filled comes back (the gold of a bid, the goods of an offer); the fee paid when it was placed does not, and the log gives roughly how much fee stays paid. With nothing to cancel the log says so and the line still counts as fine. $result is how many were cancelled.

marketupdateScript

Usage
marketupdate [0-3 | food | wood | stone | iron | all]
Example
marketupdate
marketupdate wood
Default
All four books.

Reads the books now (not the 15-second copy) and prints one line a resource: the best bid and best offer with their amounts, how many price levels are shown on each side, the total wanted and offered, the reference price and the day's average price. $result is those lines. A failed read is reported as FAILED - ….

waitslotScript

Usage
waitslot <seconds> [N]
Example
waitslot 0.3
waitslot 60 10
Values
<seconds>: the longest to wait (fractions allowed). N: wait until the city has fewer than N open orders.

Waits for room in this city's Marketplace. Without N it waits until one of the orders the city had when the line started goes (fills or is cancelled). With N it returns at once if the city already has fewer than N, otherwise waits until it does. It wakes as soon as the game reports a fill, and checks at least twice a second.

$result is 1 when a slot came free, 0 when the time ran out (or Stop was pressed). It never fails.

tradepaceScript

Usage
tradepace <seconds>
Example
tradepace 1

Waits until that many seconds have passed since this run's last order or cancel, then carries on (at once if they already have, or if the run has sent none). Use it in a loop to keep orders from going out faster than you want. $result is how many milliseconds it waited.

dumpresourceScript

Usage
dumpresource <x,y | city> <when> <send>
Example
dumpresource 111,222 f:11000,g:44000 f:3000,g:9000
dumpresource "Second City" i:2m i:1.5m
Values
<when>: the amounts the city must hold first. <send>: what to send. Both in resource form (f w s i g, k/m allowed). The target is a place x,y or one of your cities by name.
See also
transport

Once the city holds at least the <when> amounts, it sends the <send> amounts by transporters, as many as the load needs, counting the food they eat on the way there and back. The example sends 3,000 food and 9,000 gold to 111,222 once the city has 11,000 food and 44,000 gold. The march itself is a normal transport line (the log shows it), so it waits for a free Rally Spot slot like any march.

Not there yet: the log says what is short (not yet — food 8,200 of 11,000; nothing sent), the line is marked failed and $result is 0, so it fits a loop. It stops with an error when the city cannot send what you asked, has too few transporters, or the target is so far that a transporter would eat more than it carries. $result is the total sent.

holidaysnipeScript

Usage
holidaysnipe [dry] | holidaysnipe stop | holidaysnipe status

Left out of Citavon Bot. The line is accepted so old scripts still load, but every form does nothing: it prints holidaysnipe is not on Citavon Bot: … with its reason, and the line is marked failed with that text in $error. It never ends the script.

32Information scripts

Commands that only look: a practice battle, your buffs, items and medals, the command list, the map and other lords.

simulateScript

Usage
simulate <troops> [vs <troops and fortifications>] [/atk=N] [/int=N] [/defatk=N] [/defint=N] [/walls=N] [/techs=N]
Example
simulate a:50k,c:10k vs w:20k,trap:5k,at:1k /walls=10
simulate b:20k,a:30k vs p:40k,sw:10k /atk=300 /defatk=150 /techs=10
simulate cp:5k
Values
SwitchMeaningDefault
/atk=NThe attacking hero's attack (0-100,000).0
/int=NThe attacking hero's intelligence.0
/defatk=NThe defending hero's attack.0
/defint=NThe defending hero's intelligence.0
/walls=NThe defender's Walls level (0-10).0
/techs=NEvery research at level N (0-10), on both sides.Your own researches, on both sides.
Numbers may use k and m.

The Rally Spot's practice battle: Citavon works the fight out with the expected draws, so the same line always gives the same answer, and nothing is sent or lost. The script's city needs a Rally Spot.

Troops use the usual words (wo w s p sw a t c cata b r cp and their long names). Fortifications go only after vs: trap/tra, ab, at (Archer Tower), rl or logs (Rolling Log), tre or rocks (Defensive Trebuchet). Note that r here is always a Battering Ram, never Rolling Logs: write rl. No vs means an empty defender (only walls, if /walls= is given). Fortifications on the attacking side, an unknown word, or no attacking troops are refused.

What it prints (the shape; the numbers depend on the fight)
the attacker wins in 4 round(s)
attacker lost archer 812/50,000, cavalry 0/10,000 (worth 1,047,480)
defender lost warrior 20,000/20,000, trap 5,000/5,000, archertower 1,000/1,000 (worth 9,550,000)

Each loss is dead/sent; "worth" is what the dead cost to make. $result is the whole answer as JSON (winner, rounds, lost, and each side unit by unit), so a script can read it with json_decode; the line counts one action when the attacker wins.

listbuffsScript

Usage
listbuffs
Example
listbuffs

Lists the boosts working on you now, one a line: what it is, its percentage when it has one, and the time left (hornday 20% — 3h 12m 05s left), or none. $result is how many.

listitemsScript

Usage
listitems
Example
listitems

Lists every item you hold with its key and count (Peace Treaty (treaty): 3), or none. The key is the shortest way to name an item in other commands. $result is how many kinds.

listmedalsScript

Usage
listmedals
Example
listmedals

Lists the medals you hold (Rose Medal: 12), or none. $result is how many kinds.

listcommandsScript

Usage
listcommands [word]
Example
listcommands
listcommands trade

Prints the usage line of every script command, or only those whose name or one of whose words holds word. It is the bot's own list, so it is always up to date. $result is how many were listed.

scanmapScript

Usage
scanmap x,y radius | scanmap x1,y1 x2,y2 (also rescanmap)
Example
scanmap 300,400 20
rescanmap 300,400 20
scanmap 0,0 199,199
See also
scanrec, findfield

Reads the square of map from x−radius,y−radius to x+radius,y+radius, and says what is on it: 1681 tiles: 12 NPC, 34 cities, 210 flats, 980 valleys. $result is the number of tiles. The second form, two corners, is the same as scanrec.

The bot reads Citavon's map live and keeps each piece it has read for 10 minutes, so later map look-ups in that area (findfield, the map functions) do not read it again. rescanmap forgets what it kept for that area first and reads it afresh.

scanrecScript

Usage
scanrec x1,y1 x2,y2 (also rescanrec)
Example
scanrec 200,200 260,240

Like scanmap, for the rectangle between two corners (in either order). rescanrec reads it afresh. $result is the number of tiles.

findfieldScript

Usage
findfield <type> <level> <radius> [<hero> <troops>]
Example
findfield npc 5 15
findfield lake 0 10
findfield hill 10 20 any s:100000
Values
Type wordFinds
forest, forests, 1Forests
desert, deserts, 2Deserts
hill, hills, 3Hills
swamp, swamps, 4Swamps
grassland, grasslands, grass, 5Grasslands
lake, lakes, 6Lakes
flat, flats, 10Flats
castle, castles, city, cities, player, 11Lords' cities
npc, npcs, barbarian, 12NPC cities
level 0 means any level. The radius is a straight-line distance from the script's city.

Finds every tile of that type and level within the radius of the script's city, nearest first. The log shows how many and the first 20; $result holds all of them as x,y separated by spaces, ready for a loop.

With a hero and a troop string after the radius (both or neither), it also prints a ready-made attack line for each one, with the distance and the march time, to copy into a script:

attack 312,455 any s:100000 //Distance: 4.12 Mission time: 1m 23s

findScript

Usage
find <lord name>
Example
find Bob
See also
who

Looks a lord up in the prestige rankings, meant to print their place, prestige and alliance, with the ranking row as $result. A name no lord has is refused by the game (no lord of that name).

Use who for now

At present find answers <name> not found even for a lord who exists. command "who Bob" gives the same facts and more.

getScript

Usage
get <variable or expression> | get "<http(s) address>"
Example
get city.resource.food
get "https://example.com/targets.txt"

With a variable (any expression in one word), prints its value and puts it in $result. With a web address, fetches the page and puts its text in $result (up to 1,000,000 characters); the log says how many characters came. A page that cannot be fetched marks the line failed. Put the address in quotes, since // outside quotes starts a comment.

33Chat & mail scripts

Speaking in the chats, whispering, mail, friends and blocks, and three helpers that talk to you or to the outside world: say, post and play.

The message of alliancechat, worldchat, whisper and say is read the way echo reads its line: plain words come out as written, text in quotes is literal, {expr} inside quotes is filled in, and expressions side by side are joined with a space. A chat line is cut at 300 characters by the game.

alliancechat "Enemy armies near " + city.name + " at " + city.coords
alliancechat "Food at {city.resource.food}"
worldchat Selling iron, mail me

alliancechatScript

Usage
alliancechat <message>
Example
alliancechat "Need reinforcements at {city.coords}"

Says the message in your alliance's chat. Free. Refused when you are in no alliance.

worldchatScript

Usage
worldchat <message>
Example
worldchat Recruiting for our alliance, whisper me

Says the message in world chat. Each world line uses one Town Crier; with none held the game refuses (world chat takes a Town Crier (3 coins in the shop)). The bot does not buy one for you: buyitem crier10 first.

whisperScript

Usage
whisper <name> <message>
Example
whisper Bob "Your city at {city.coords} is under attack"
whisper "Big Bob" hello

Sends a private chat line to one lord. A name with spaces goes in quotes. Should the game have no private chat, the bot sends the message as a mail instead (its first 40 characters as the subject) and says so in the log.

mailScript

Usage
mail <name> "<subject>" <message>
Example
mail Bob "Iron" I can sell you 2m iron at 30
See also
command "mail …", listmail

Sends a mail. The first word is the lord (quotes when it has spaces), the second the subject (quotes when it has spaces), and the rest the body, word by word. %vars% are filled in; expressions are not, so build the line with execute if you need them.

addfriendScript

Usage
addfriend <name> (also friendadd)
Example
addfriend Bob

Puts the lord on your friends list.

blockScript

Usage
block <name>
Example
block Spammer

Puts the lord on your block list.

removefriendScript

Usage
removefriend <name> | unblock <name>
Example
removefriend Bob
unblock Spammer

removefriend takes the lord off your friends list; unblock takes them off your block list. A name not on that list is refused: Bob is not on the list.

sayScript

Usage
say "<text>"
Example
say "Farming round done at {date()}"

Writes the text in the console's log. Nothing is sent to the game.

postScript

Usage
post <http(s) address> [data]
Example
post https://example.com/hook "food " + city.resource.food

Sends data to a web address (an HTTP POST), for your own tools or a chat webhook. The data is an expression, or the text as written when it is not one; data that starts with { or [ is sent as JSON, anything else as plain text. The log shows the answer's status. $result is the reply's text (up to 100,000 characters); a reply that is not a success marks the line failed.

playScript

Usage
play <file> | play "<http(s) link>"
Example
if city.hasEnemyArmiesWithin(1800) play alarm.mp3
play "https://example.com/horn.mp3"

Plays a sound in every open page of this lord's console. A file is a .mp3, .wav or .ogg in the bot's media folder; a link must be in quotes (// outside quotes starts a comment) and may not hold a user name or password. If no console page is open, the log says so. $result is how many pages it was sent to.

34Changing goals from a script

A script can add goal lines to its city, or switch the city to another set of goals, for as long as the console runs.

What a script sets lives in the console's memory, on top of the goals you saved: the saved text is never changed. It lasts until resetgoals, loadgoals 0, or the console restarts. The account's Prepend and Append goals still run before and after, whatever the city runs. These commands work only in scripts run in the lord's console; the city is the script's city.

Any line whose first word is a goal (troop a:2m, config npc:5, npc 5 …) is also a goal line in a script, without goal in front.

goalScript

Usage
goal <goal line> | goal <expression whose text holds goal lines>
Example
goal troop a:2m,c:500k
goal plan (where plan is a variable holding goal lines, one per line)

Adds the goal line to this city's running goals. When the first word is not a goal word, the text is worked out as an expression first, so a variable can carry several lines at once; if that fails, the text is used as written. The log shows the lines added (several joined with |). $result is the text added.

configScript

Usage
config <key>:<value>[,<key>:<value>…]
Example
config npc:5
config hunting:1,npc:10

Adds a config goal line, the same as goal config …. The keys are the goals' config keys, described with their goals. A line with no : is refused before the script starts.

buildinggoalsScript

Usage
buildinggoals <build goal>
Example
buildinggoals c:10,f:10

Adds a build goal line: buildinggoals c:10 is goal build c:10.

techgoalsScript

Usage
techgoals <research goal>
Example
techgoals lo:10

Adds a research goal line: techgoals lo:10 is goal research lo:10.

loadgoalsScript

Usage
loadgoals [1-9 | city name | city id | 0]
Example
loadgoals 3
loadgoals "Second City"
loadgoals
Default
0: back to the city's saved goals.

Makes this city run another goal text instead of its own: one of the account's nine goal sets (written in the console's goal editor under Goal set 1 to Goal set 9), or the goals of another of your cities, by name or id. Lines a script added before are dropped. A word that is neither a set nor one of your cities is refused: no goal set or city "…".

Switch to war goals while enemies are near
if city.hasEnemyArmiesWithin(3600) loadgoals 2
if city.hasEnemyArmiesWithin(3600) == false loadgoals 0

resetgoalsScript

Usage
resetgoals
Example
resetgoals

Drops everything scripts set for this city (added lines and a loaded set); the city runs its saved goals again. The same as loadgoals 0.

35In-line commands

Quick commands for the alliance, reports, mail, the map and holidays, typed into the console's chat box with a backslash or run from a script with command "…".

Two ways to run them

  1. In the chat box. In a lord's console, type a backslash and the command into the chat box under the chats, then press Enter or Send: \who Bob. It runs in the city whose tab is open, and its lines show just above the chat box. A line that starts with \ is never sent as chat. (A line that starts with /name is a whisper: /Bob see you at 8.)
  2. From a script. command "who Bob". The text is an expression, so it can be built: command "who " + name. A leading backslash is allowed and ignored. The lines it prints are in $result (joined by line breaks); a refusal is in $error. An unknown word fails the line and lists the in-line commands there are.

Names with spaces go in quotes: \who "Big Bob", command 'who "Big Bob"'. In a dry run, commands that would change something say what they would do and send nothing; commands that would open reports or mails (marking them read) leave them closed.

confirm

Anything that changes the alliance for good or costs coins needs confirm as its last word. Without it nothing is sent: the command says what it would do and gives the exact line to type.

Needs confirmWhy
expelThe member is out at once.
quitallianceYou leave; as the last member you disband it.
resignYou give up your rank.
sethostYou hand the alliance over and become vice host.
setvicehostA vice host can expel, change ranks and set diplomacy.
declare … redWar.
holidayCosts coins and stops the account.

(Among script commands, buyitem over 100, changeplayername and resetplayer have their own safety words; see Account scripts.)

Commands that name a lord or alliance to act on (apply, declare, expel, invite and the rank commands) want one exact name: any, a name with *, ? or a comma, or one over 40 characters is refused.

The alliance

allianceCommand

Usage
\alliance <alliance name>
Example
\alliance Wolves

Shows any alliance: Alliance info: Wolves, host: Bob, founder: Bob, members: 34/50, prestige: 1234567, honor: 890, cities: 61, rank: 3, standing: enemy, then its introduction, and for your own alliance its notice. The standing is how your alliance stands with it.

membersCommand

Usage
\members

Lists your alliance's members, one a line: Lord, Position, Prestige, Title, Cities. Nothing may follow the word.

applicantsCommand

Usage
\applicants
See also
accept

Lists the lords who have applied to your alliance (Name, Prestige). Members below officer may see an empty list.

acceptCommand

Usage
\accept <name>
Example
\accept Bob

Accepts a lord's application into your alliance. For officers and above. A name with no application is refused, pointing you to applicants.

applyCommand

Usage
\apply <alliance name>
Example
\apply Wolves

Applies to join an alliance; its officers decide.

inviteCommand

Usage
\invite <name>
Example
\invite Bob

Invites a lord to your alliance.

invitesCommand

Usage
\invites

In an alliance: the invitations it has sent (Name, Prestige, Rank, Invited by, Invited, State). Outside one: the alliances that have invited you.

joinCommand

Usage
\join <alliance name>
Example
\join Wolves

Accepts an alliance's invitation. Refused when you are already in one, or when that alliance has not invited you (the refusal lists who has).

createallianceCommand

Usage
\createalliance <name>
Example
\createalliance "Iron Wolves"

Founds an alliance from the open city. The name is 3 to 20 letters, digits, spaces, _ or -. The city needs an Embassy of level 2, and founding costs 10,000 gold from it.

declareCommand

Usage
\declare <alliance> red|blue|grey|none [confirm]
Example
\declare Wolves blue
\declare Ravens red confirm
Values
red (also enemy, war, hostile): enemy, needs confirm. blue (also ally, friend, friendly): friendly. grey, gray, neutral, none, clear, drop, remove: no standing.

Sets your alliance's standing toward another alliance. Only the ranks allowed to set diplomacy can.

expelCommand

Usage
\expel <name> confirm (also eject)
Example
\expel Bob confirm

Puts a member out of your alliance at once. The name must be a member.

quitallianceCommand

Usage
\quitalliance confirm

Leaves your alliance. A host who is its only member disbands it (the warning says so). A host with other members must hand it over first (sethost); the game refuses otherwise.

resignCommand

Usage
\resign confirm

A vice host, presbyter or officer steps down to member. Prints resigned: officer -> member. A host hands over with sethost instead.

sethostCommand

Usage
\sethost <name> confirm
Example
\sethost Bob confirm

The host hands the alliance to another member and becomes vice host.

setvicehostCommand

Usage
\setvicehost <name> confirm

Makes a member vice host. An alliance has at most 2.

setpresbyterCommand

Usage
\setpresbyter <name>

Makes a member presbyter. An alliance has at most 5.

setofficerCommand

Usage
\setofficer <name>

Makes a member officer. An alliance has at most 10.

setmemberCommand

Usage
\setmember <name>

Takes a member's rank away, back to plain member.

For all the rank commands: the name must be a member of your alliance, and you can only give or take ranks below your own.

Reports and mail

armyreportCommand

Usage
\armyreport [page]
Example
\armyreport 2
Default
Page 1

Your reports, newest first, 10 a page (from the newest 200). Each one is opened, which marks it read, and printed in full:

Page: 1/4
[5521]BATTLE Attack on 312,455: won on Sat Oct 17 2026 2:14:05 PM
Info: winner: attacker
Info: The Loyalty of this city is 42.
attackers: archer:49188/50000
defenders: warrior:0/20000
Loot: food 120,000, wood 80,000
Info: found a Rose Medal

Units are shown as left/sent. Info lines cover the winner, the defender, a capture, the city's loyalty, a hero taken, medals and other finds; a scout report adds the troops, fortifications and resources it saw.

quickarmyreportCommand

Usage
\quickarmyreport [page]

The same list as armyreport, headings only, with the report ids. Nothing is opened, so nothing is marked read.

readreportCommand

Usage
\readreport <report id>
Example
\readreport 5521

Opens one report (marking it read) and prints it as armyreport does. quickarmyreport lists the ids.

warreportCommand

Usage
\warreport [page]

Your alliance's War Reports: its members' battles and scouts against other lords. Each starts ATT or DEF, the other side's alliance, the event, the time and where from and to, followed by that report's lines.

listmailCommand

Usage
\listmail [page]

Your inbox, a page at a time: [id:from>to] subject on date, each followed by its text. Each mail is opened to read it, so it is marked read.

listsentmailCommand

Usage
\listsentmail [page]

The mails you sent, as listmail shows them.

listsystemmailCommand

Usage
\listsystemmail [page]

The game's own letters to you, as listmail shows them (and marked read the same way).

mailCommand

Usage
\mail <name> <subject> <text>
Example
\mail Bob "Iron deal" 2m at 30, still on?
See also
mail (script)

Sends a mail. A subject (or name) with spaces goes in quotes; everything after it is the text.

The map, lords and heroes

whoCommand

Usage
\who <name>
Example
\who Bob

A lord's facts: Player info: Bob, alliance: Wolves, castle: 3, pres: 123456, honor: 789, rank: 57, pos: Officer, title: Baron, pop: 21000. castle is the number of cities, rank the place in the prestige rankings, pos the alliance position.

locCommand

Usage
\loc x,y
Example
\loc 312,455

What is at one place: Location: 312,455: Castle(312,455) peace, Haven SAXONY, belongs to Bob (Wolves). For a valley or flat it gives the kind and level and its holder, or none. The state word is the lord's: peace, truce, beginner, holiday or dream.

listcastlesCommand

Usage
\listcastles x,y x,y [max cities] [min prestige]
Example
\listcastles 280,420 340,480 50 100k
Default
At most 1,000 cities; any prestige.

Lords' cities in the rectangle between two corners, nearest to the open city first, at most max of them and only those with at least min prestige. One a line under a heading: Coords, State, Distance, Castle, Owner, Alliance, Prestige, Honor, e.g. Castle(312,455), peace, 4.12 miles, Haven, Bob Wolves, pres 123456, honor 789.

searchcastleCommand

Usage
\searchcastle <alliance | city | lord>
Example
\searchcastle Wolves

Every city on the whole map whose alliance, city name or lord is exactly that word (case ignored), nearest first, in the listcastles layout. It reads the whole map, so the first search takes a while; the map it read is kept for 10 minutes.

searchenemiesCommand

Usage
\searchenemies [max results]
Example
\searchenemies 20
Default
All found

Cities of lords whose alliance yours stands against as enemy (red), within 124 tiles of the open city, nearest first, in the listcastles layout.

searchalliancesCommand

Usage
\searchalliances <name>|* [members|prestige|honor] [page]
Example
\searchalliances * members
\searchalliances wolf prestige 2
Default
Sorted by prestige, page 1.

Searches the 50 alliances Citavon ranks: * for all, or those whose name holds the text. Sorted by the column you pick, highest first, 10 a page: Rank, Name, Members, Prestige, Honor.

searchheroesCommand

Usage
\searchheroes <name>|* lvl|atk|pol|int [page]
Example
\searchheroes * atk
Default
Sorted by level, page 1.

Searches the heroes of all lords (not prisoners): * for all, or those whose name holds the text. It reads up to the 2,000 highest-level heroes and says so when there are more. Sorted by level, attack, politics or intelligence, 10 a page: Rank, Name, Owner, Level, Atk, Int, Pol.

listallheroesCommand

Usage
\listallheroes

Every hero in every one of your cities: Haven: Arthur L45 pol 30 att 120 int 40 idle (5 points). The same as the listallheroes script command.

Holiday

holidayCommand

Usage
\holiday <days> confirm [/autoextend] | \holiday /exit
Example
\holiday 7 confirm
\holiday 3 /autoextend confirm
\holiday /exit
Values
<days>: 2 to 7, at 10 coins a day. /autoextend (or /auto): renews itself at its end while the coins last. /exit: ends the holiday now (no confirm needed, nothing else with it).

Puts the account on holiday: nobody can attack or scout your cities, and they build, research, train and march nothing until it ends. The game refuses while anything is being built, researched, trained or fortified, while an army is out, or while a market order is open; it also refuses a second holiday. Without confirm the command says what it would cost and gives the line to type. If enemy armies are marching on you, it notes how many before it goes.

36A–Z index

Every goal, setting, script command, function and in-line command in this guide (435 of them), in alphabetical order. The search box on the left finds them too.

37Troubleshooting

Click a problem to open it.

"no lord of that name" or "wrong password"

Check the spelling of the lord name, and that the password is your Citavon password. The console stops until you fix it: click ✎ on the lord's row, correct it, Save.

The sign-in page says "Wrong password."

That page wants the Director password (the one you chose in Setup or Settings), not your Citavon password. If none is set, set one in ⋯ → Settings on the computer the bot runs on.

"Windows protected your PC"

The program isn't code-signed. Click More info → Run anyway. To be sure the file is genuine, check its SHA-256 first.

A lord keeps getting kicked

Something else is logged in as that lord: you playing by hand, another bot, or another computer running Citavon Bot with the same lord. The console shows logged in elsewhere and waits 30 minutes before it logs back in. Switch the lord off (untick On) while you play it, and make sure only one bot runs each lord.

Every lord went offline at the same time each day

That's Citavon's daily maintenance, at 07:00 server time for about 15 minutes. The consoles show server maintenance and the time they'll be back, wait until the game opens again, then log back in within about 2 minutes so the whole fleet doesn't rush in at once. You don't need to do anything.

"Citavon Bot is already running"

Nothing's wrong. The Director is already running, so starting it again just opens its window. On Windows, look for the black window on the taskbar.

"could not open port 8720"

Usually the Director is already running (see above). If another program uses port 8720, start the bot on another port with GERMBOT_PORT. Windows, in a Command Prompt in the program's folder:

set GERMBOT_PORT=8730
CitavonBot.exe

Linux: GERMBOT_PORT=8730 ./citavon-bot --no-window (for the service, add Environment=GERMBOT_PORT=8730). Then open http://127.0.0.1:8730.

"refused: a request from this machine for …"

On the bot's own computer, open it as http://127.0.0.1:8720 (or localhost), not by the computer's name. From other devices, use Tailscale.

A lord says it was logged out for good

The lord was handed to another account, or a friend took back your access to a shared lord. It won't log in again until you press 🌐 Connect in its console.

38Support

Found a problem, or something unclear? Please report it in the Citavon support rooms. Say what you did, what you expected, and what happened. Copy the relevant lines from the console's Log tab (they never contain your passwords).

Citavon Bot 2026.10.18-d31b01b