- version v0.0.3

- Updated README
- Added AOT_AUTO_RES and AOT_MINIMIZED env variables (see README.md)
This commit is contained in:
Skylar Sadlier 2024-03-27 19:58:44 -06:00
parent ea006568e2
commit 3f4911b448
6 changed files with 100 additions and 44 deletions

View File

@ -11,6 +11,8 @@ ENV WINEPREFIX /root/prefix32
ENV AOTDIR "$WINEPREFIX/drive_c/Program Files (x86)/AgeOfTime"
ENV RESOLUTION "1024x768x24"
ENV AOT_CPU_LIMIT="0"
ENV AOT_MINIMIZED="false"
ENV AOT_AUTO_RES="true"
WORKDIR /root/
COPY webaudio.js /root/

View File

@ -1,39 +1,39 @@
## aot-wine-x11-novnc-docker
## aot-wine-x11-novnc-docker Overview
![Docker Image Size (tag)](https://img.shields.io/docker/image-size/skylord123/aot-wine-x11-novnc-docker/latest)
![Docker Pulls](https://img.shields.io/docker/pulls/skylord123/aot-wine-x11-novnc-docker)
This docker image will run AgeOfTime game client under wine in an Ubuntu container with a novnc server for you to view the application. Uses supervisor to automatically restart failed processes.
This Docker image facilitates running the AgeOfTime game client within an Ubuntu container, utilizing Wine for application compatibility. It includes a noVNC server for browser-based application access, and employs Supervisor for process management to ensure failed processes are automatically restarted.
Runs a small script in the background that will automatically kill the process if a wine "Program Error" dialog is displayed (since it starts winedbg instead of just quitting).
This script also runs cpulimit against the PID of the AgeOfTime.exe process to limit how much CPU it can consume (only if `AOT_CPU_LIMIT` env variable is defined and not zero).
**Key Features:**
This container runs:
- **Automated Process Management:** Implements a script designed to automatically terminate the game process upon detection of a Wine "Program Error" dialog. This ensures that in the event of a crash, where Age Of Time might not exit cleanly and thus remain unresponsive, the system intervenes to stop the process, enabling Supervisor to recognize the failure and restart the application as needed.
- **CPU Usage Control:** Employs `cpulimit` on the AgeOfTime.exe process based on the `AOT_CPU_LIMIT` environment variable (when defined and non-zero), ensuring efficient CPU resource utilization.
* Xvfb - X11 in a virtual framebuffer
* x11vnc - A VNC server that scrapes the above X11 server
* [noNVC](https://kanaka.github.io/noVNC/) - A HTML5 canvas vnc viewer
* pulseaudio - Audio server (AOT crashes without proper audio)
* audiostream & websockify_audio - these are supposed to pass audio to the VNC web session but currently doesn't work
* Fluxbox - a small window manager
* AgeOfTime.exe - The game executable
* aot-monitor.sh - Bash script that runs in the background to kill the game process if any `Program Error` dialogs pop up (since the game doesn't fully exit supervisor wont detect it crashed). This script also applies `cpulimit` if `AOT_CPU_LIMIT` env variable is used.
**Components:**
This is a [trusted build](https://registry.hub.docker.com/u/skylord123/aot-wine-x11-novnc-docker/)
on the Docker Hub.
- **Xvfb:** Provides an X11 server within a virtual framebuffer.
- **x11vnc:** A VNC server capturing the X11 server output for remote access.
- **[noVNC](https://kanaka.github.io/noVNC/):** A web-based VNC viewer utilizing HTML5 canvas for display.
- **PulseAudio:** An audio server to handle game audio requirements. Note: AgeOfTime experiences crashes without proper audio support.
- **Audio Streaming (Under Development):** Components like audiostream and websockify_audio aim to forward audio to the VNC web session, though currently non-functional.
- **Fluxbox:** A lightweight window manager to manage application windows.
- **AgeOfTime.exe:** The game's executable file.
- **aot-monitor.sh:** A background script ensuring the game process is terminated upon detecting "Program Error" dialogs. This script also manages the application of `cpulimit` based on the `AOT_CPU_LIMIT` environment variable.
## env
This Docker image is available as a [trusted build on Docker Hub](https://registry.hub.docker.com/u/skylord123/aot-wine-x11-novnc-docker/), ensuring easy deployment and reliability.
There are a few env variables that can be set on the container:
## Environment Variables
- `AOT_CPU_LIMIT` (default value: `0`)
- This is essentially the `-l` option for `cpulimit` which description states:
> percentage of CPU allowed from 1 up. Usually 1 - 100, but can be higher on multi-
core CPUs.
- By default, the `docker-compose.yaml` file limits the cpus to 2. You should be limiting how many CPUs the container has access to (one or two cores should work fine) and not just relying on this env variable.
- If set to a number this will be written to a file in the AgeOfTime directory called `aot_cpu_limit` that will be used for controlling the cpu limit dynamically (updated every second).
- `RESOLUTION` (default value: `1024x768x24`)
- Sets the resolution for x11 and AgeOfTime. On container startup this variable is read before starting supervisor and used to update the `baes/client/prefs.cs` AgeOfTime file with the resolution.
The container supports several environment variables that you can set to customize its behavior:
- **`AOT_CPU_LIMIT`**: Specifies the percentage of CPU allowed for the container's use, mimicking the `-l` option of `cpulimit`. Acceptable values are from 1 upwards, typically ranging from 1 to 100, though values can exceed 100 on multi-core CPUs. The default setting is `0`, indicating no specific limit. However, it's recommended to manage CPU access by limiting the number of available CPUs to the container via `docker-compose.yaml` (e.g., to one or two cores) rather than solely relying on this variable. If a value is set, it is recorded in the `AgeOfTime` directory within a file named `aot_cpu_limit`, which is utilized to dynamically control the CPU limit (updated every second).
- **`RESOLUTION`**: Sets the display resolution for X11 (and Age of Time if `AOT_AUTO_RES` is enabled), with a default value of `1024x768x24`. This impacts the display resolution of both the X11 environment and the Age of Time game when `AOT_AUTO_RES` is set to `true`.
- **`AOT_AUTO_RES`**: By default set to `true`, this variable ensures that upon container startup, the `baes/client/prefs.cs` file within Age of Time is updated with the resolution specified by the `RESOLUTION` environment variable. It also enables fullscreen mode for the Age of Time game.
- **`AOT_MINIMIZED`**: With a default value of `false`, setting this variable to `true` will cause the game to start in a minimized state. This action halts rendering processes, thus conserving CPU resources. It achieves this by switching focus to the `AgeOfTime.exe` console window.
## Run It

View File

@ -7,20 +7,26 @@ services:
# limit cpu usage to 50% of a single core
AOT_CPU_LIMIT: 0
# sets the resolution of x11
# on container startup this is parsed into
# AgeOfTime's client/prefs.cs file to match
# good resolution options:
# - 640x480x24
# - 1024x768x24
RESOLUTION: 640x480x24
# game file base/client/prefs.cs gets updated on
# container startup by default if you want to disable this
# set this to false
AOT_AUTO_RES: false
# if set to true we will switch away from the game window
# which causes AgeOfTime to stop a bunch of rendering steps
# saving precious CPU cycles
AOT_MINIMIZED: true
# uncomment if you want to volume mount AgeOfTime
# volumes:
# - '/path/on/host/AgeOfTime:/root/prefix32/drive_c/Program Files (x86)/AgeOfTime'
deploy:
# resources:
# limits:
# cpus: '0.50'
# memory: 512M
# reservations:
# cpus: '0.25'
# memory: 512M
resources:
limits:
cpus: '2'
memory: 1G
reservations:
cpus: '2'
memory: 1G

View File

@ -4,8 +4,50 @@ export DISPLAY=:0
export WINEARCH=win64
export HOME=/root
export LANG=en_US.UTF-8
#export WINEDEBUG="+alsa,+pulse,+winealsa,+winepulse,+d3d,+ddraw,+opengl,+winediag",
cd "/root/prefix32/drive_c/Program Files (x86)/AgeOfTime"
sleep 5 # give the x server time to start
# have to start with wineconsole as wine will cause a crash
# get current active window name
# $ xdotool getactivewindow getwindowname
# set age of time console as active window (reduces CPU usage)
# $ xdotool search --name "AgeOfTime.exe" windowactivate
# set age of time window as active window (more CPU but you can view the game)
# $ xdotool search --name "Age Of Time" windowactivate
# background task to minimize Age Of Time by switching
# to the AgeOfTime.exe console window
if [ "$AOT_MINIMIZED" == "true" ]; then
(
while true; do
# Check if a window with name "Age Of Time" exists
# as the console window spawns first and we want to
# switch back to it after the game window starts
AGE_OF_TIME_WIN_ID=$(xdotool search --name "Age Of Time")
if [ ! -z "$AGE_OF_TIME_WIN_ID" ]; then
# Get current active window name
ACTIVE_WIN_NAME=$(xdotool getactivewindow getwindowname)
# If the active window is not AgeOfTime.exe, try to set it to AgeOfTime.exe
if [[ "$ACTIVE_WIN_NAME" != *"AgeOfTime.exe"* ]]; then
xdotool search --name "AgeOfTime.exe" windowactivate
else
break # Active window is AgeOfTime.exe, exit the loop
fi
fi
sleep 1 # Wait for a second before checking again
done
) &
BG_TASK_PID=$!
fi
# Run AgeOfTime.exe with wineconsole
wineconsole AgeOfTime.exe
# Ensure the background task is stopped when AgeOfTime.exe quits, only if it was started
if [ ! -z "$BG_TASK_PID" ] && kill -0 $BG_TASK_PID 2>/dev/null; then
kill $BG_TASK_PID
fi

View File

@ -1,13 +1,18 @@
#!/bin/bash
# set age of time to use fullscreen
sed -i 's/\$pref::Video::fullScreen = "0";/\$pref::Video::fullScreen = "1";/g' /root/AgeOfTime/base/client/prefs.cs
if [ "$AOT_AUTO_RES" == "true" ]; then
# Extract the width and height from RESOLUTION env variable
WIDTH=$(echo $RESOLUTION | cut -d'x' -f1)
HEIGHT=$(echo $RESOLUTION | cut -d'x' -f2)
# set age of time to use fullscreen
sed -i 's/\$pref::Video::fullScreen = "0";/\$pref::Video::fullScreen = "1";/g' /root/AgeOfTime/base/client/prefs.cs
# Use sed to replace the line in settings.txt
sed -i "s/\$pref::Video::resolution = \".*\";/\$pref::Video::resolution = \"${WIDTH} ${HEIGHT} 32\";/g" /root/AgeOfTime/base/client/prefs.cs
# Extract the width and height from RESOLUTION env variable
WIDTH=$(echo $RESOLUTION | cut -d'x' -f1)
HEIGHT=$(echo $RESOLUTION | cut -d'x' -f2)
# set the resolution to match x11
sed -i "s/\$pref::Video::resolution = \".*\";/\$pref::Video::resolution = \"${WIDTH} ${HEIGHT} 32\";/g" /root/AgeOfTime/base/client/prefs.cs
echo "Updated game resolution to match x11"
fi
/usr/bin/supervisord

View File

@ -93,6 +93,7 @@ user=root
redirect_stderr=true
priority=200
environment=
AOT_MINIMIZED="%(ENV_AOT_MINIMIZED)s",
LANGUAGE="en_US.UTF-8",
WINEARCH="win64",
HOME="/root",