Instructions
A) Setup autorun script: Put autorun_gameprod.sh in /home/aoi/ B) Setup autorun script to autorun: Put autorun_gameprod.service in /etc/systemd/system/autorun_gameprod.service C) Reload systemd and start the service sudo systemctl daemon-reload sudo systemctl enable --now autorun_gameprod.service D) Verify it stays up sudo systemctl status autorun_gameprod.service sudo journalctl -fu autorun_gameprod.service E) Should just run now automatically upon boot up. F) That said, to troubleshoot, or for reference: To run AOI's autorun script: ./autorun & To stop AOI's autorun script: touch a file called .killscript in the same directory, which will stop the script the next time it autostarts the MUD. To run AOI just one time: ./test &
Two files needed; reference copies below
1) autorun_gameprod.sh
steve@aoi:/home/aoi$ cat autorun_gameprod.sh
#!/bin/bash
##############################################################################
# CircleMUD 2.2-compatible autorun script
# Adapted from the Circle 3.1 script by J. Elson et al. (1996)
##############################################################################
#hey to anyone modifying this.. there's a “cd bin” command to get into
#the right dir before starting the binary. this is b/c running bin/test
#breaks something that expect our current directory to be bin/ not ./
#so… make sure to review that & edit if you are trying to use this script
#to launch any other instance of AOI in a different dir.
#love,
#steve
#5-31-2025
# — TUNE THESE ————————————————————-
PORT=4000 # port your MUD listens on
BIN=test # relative path to the server binary
FLAGS= # default runtime flags (-q = quiet boot)
BACKLOGS=9 # how many rotated syslogs to keep
# log-file pattern list: name:maxlines(0 = unlimited):grep-pattern LOGFILES=' delete:0:self-delete dts:0:death trap rip:0:killed restarts:0:Running levels:0:advanced rentgone:0:equipment\ lost usage:0:usage newplayers:0:new\ player errors:0:SYSERR godcmds:0:(GC) badpws:0:Bad\ PW ' LEN_CRASHLOG=30 # lines of syslog to save as syslog.CRASH # —————————————————————————
ulimit -c unlimited # keep core dumps umask 077 # log files ⇒ rw——-
proc_syslog () {
[ -s syslog ] || return # make crash snapshot [ "$LEN_CRASHLOG" -gt 0 ] && tail -n "$LEN_CRASHLOG" syslog > syslog.CRASH
OLD_IFS=$IFS; IFS=$'\n'
for rec in $LOGFILES; do
name=log/$(echo "$rec" | cut -d: -f1)
len=$(echo "$rec" | cut -d: -f2)
pat=$(echo "$rec" | cut -d: -f3-)
grep -F "$pat" syslog >> "$name"
# truncate if needed
[ "$len" -gt 0 ] && tail -n "$len" "$name" > "$name.tmp" && mv "$name.tmp" "$name"
done
IFS=$OLD_IFS
# rotate syslogs
if [ -s log/syslog."$BACKLOGS" ]; then
idx=$((BACKLOGS+1))
else
idx=1; while [ -s log/syslog."$idx" ]; do idx=$((idx+1)); done
fi
for ((y=idx; y>1; y--)); do mv -f log/syslog.$((y-1)) log/syslog.$y 2>/dev/null; done
mv -f syslog log/syslog.1
}
# If a stale syslog exists (unclean shutdown), rotate it first [ -s syslog ] && echo “autorun noticed unclean exit $(date)” » syslog && proc_syslog
echo “==⇒ Starting autorun loop on port $PORT; binary $BIN”
while :; do
date > syslog echo "Running $BIN $FLAGS $PORT" >> syslog
(
cd bin || { echo "autorun: cannot cd to bin" >> syslog; exit 1; }
./"$BIN" $FLAGS $PORT >> ../syslog 2>&1
)
# honour .killscript / .fastboot / pause sentinel files
if [ -e .killscript ]; then
echo "$(date) : autorun killed" >> syslog
rm .killscript
proc_syslog
exit 0
fi
#default is typically 60, not 15. but this makes us come back faster after crashes.
[ -e .fastboot ] && delay=5 || delay=15 rm -f .fastboot sleep "$delay"
while [ -e pause ]; do sleep 60; done proc_syslog
done ''
2) autorun_gameprod.service
steve@aoi:/home/aoi$ cat autorun_gameprod.service # /etc/systemd/system/autorun_gameprod.service [Unit] Description=AOI CircleMUD production instance After=network.target
[Service] Type=simple #— run as an unprivileged account if it exists — #User=aoi WorkingDirectory=/home/aoi ExecStart=/home/aoi/autorun_gameprod.sh
# Restart autorun itself if it ever dies Restart=always RestartSec=5
# Journald handles all logging; no separate files needed StandardOutput=journal StandardError=journal
# (optional hardening-flags you can re-add once it starts) #NoNewPrivileges=yes #PrivateTmp=yes #ProtectSystem=full #ProtectHome=yes
[Install] WantedBy=multi-user.target
