cleanup: remove references to prole/workstation

This commit is contained in:
chrisfu 2026-02-05 14:51:35 -08:00
parent 620ce63190
commit 82dc879116
49 changed files with 641 additions and 1564 deletions

6
.gitignore vendored
View File

@ -67,10 +67,4 @@ deploy/gcp/terraform-setup.txt
htmlcov/
.pytest_cache/
# Unreal Engine artifacts
/workstation/Prole/Binaries/
/workstation/Prole/Intermediate/
/workstation/Prole/Saved/
/workstation/Prole/DerivedDataCache/
/workstation/Prole/Build/
/ssh-keys/

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,6 @@ hiddenimports = [
'installer.deploy',
'installer.screen',
'installer.main',
'installer.workstation',
'installer.ncurses_ui',
'installer.ncurses_installer',
'curses',

View File

@ -7,7 +7,6 @@ monolithic `install.py`.
Modules:
- config: shared paths, dependency catalog, platform helpers, version utils.
- build: Prole app build command composition.
- workstation: Docker workstation helpers (version parsing, docker build cmd).
- deploy: host-side deploy helpers (Xcode tools check, app build flow).
- screen: (optional) UI controller placement point.
@ -18,7 +17,6 @@ continues to work, but now delegates to `installer.*` modules.
__all__ = [
"config",
"build",
"workstation",
"deploy",
"screen",
]

View File

@ -4,8 +4,7 @@ Deploy/build helpers for the Prole installer (root-level package).
Encapsulates Xcode tools check and building the native Prole app.
Also defines the Deploy page (final milestone):
- Mark completed: Build Prole macOS App, Build Prole Workstation Docker Image, Verify Dependencies
- New: Start Prole Workstation (show docker run command in the black console, wait for Enter, run, verify)
- Mark completed: Build Prole macOS App, Verify Dependencies
- New: Install Prole.app (drag-to-install pop-up; mark complete when closed)
"""
from __future__ import annotations
@ -20,7 +19,6 @@ from tkinter import ttk, messagebox
from . import main as inst_main
from . import screen as ui
from . import workstation as ws
from . import config as cfg
@ -113,8 +111,7 @@ def create_deploy_page(app):
"""Create the Deploy page UI and register it via installer.main.
Final milestone flow for Deploy page:
- Show 3 completed steps from earlier phases
- Start Prole Workstation (docker run)
- Show completed steps from earlier phases
- Install Prole.app (drag-to-install pop-up)
"""
f = ttk.Frame(app.page_area)
@ -203,9 +200,7 @@ def create_deploy_page(app):
# ----- Final steps (on the same merged page) -----
app.deploy_steps = [
{'name': 'Build Prole macOS App', 'status': 'completed'},
{'name': 'Build Prole Workstation Docker Image', 'status': 'completed'},
{'name': 'Verify Dependencies', 'status': 'completed'},
{'name': 'Start Prole Workstation', 'status': 'pending'},
{'name': 'Install Prole.app', 'status': 'pending'},
]
app.deploy_widgets = {}
@ -223,33 +218,8 @@ def create_deploy_page(app):
except Exception:
pass
# Compose docker run command for workstation
project_root = cfg.PROJECT_ROOT
version = ws.get_workstation_version(project_root)
# Ports and volume mapping per spec
port_flags = (
"-p 127.0.0.1:5901:5901 "
"-p 127.0.0.1:6667:6667 "
"-p 127.0.0.1:6697:6697"
)
host_prole = os.path.expanduser('~/dev/prole')
docker_run_cmd = (
f"docker rm -f prole-workstation >/dev/null 2>&1 || true; "
f"docker run -d --name prole-workstation --restart unless-stopped "
f"{port_flags} -v \"{host_prole}\":/prole prole-workstation:{version}"
)
# Show the command preview and wait for Enter
try:
user = os.environ.get('USER') or 'user'
host = (platform.node() or 'host').split('.')[0]
preview_line = f"[{user}@{host}]# {docker_run_cmd}"
if hasattr(app, '_console_set_preview'):
app._console_set_preview(preview_line)
except Exception:
pass
# Handlers for steps 4 and 5
# Handlers for step 3
state = {'started': False}
def _open_drag_install():
@ -310,41 +280,6 @@ def create_deploy_page(app):
# Even if popup fails, don't crash the deploy page
pass
def _start_workstation_and_verify():
# Kick off docker run and then verify container is running
try:
_update_step(app, 'Start Prole Workstation', 'running')
except Exception:
pass
try:
app._append_console("\nStarting Prole Workstation container...\n")
except Exception:
pass
try:
subprocess.run(["bash", "-lc", docker_run_cmd])
except Exception:
pass
# Verify container is running
import time as _t
ok = False
for _ in range(30): # ~30 * 0.5s = 15s
try:
r = subprocess.run(["bash", "-lc", "docker inspect -f '{{.State.Running}}' prole-workstation || echo false"], capture_output=True, text=True, timeout=4)
if r.returncode == 0 and 'true' in (r.stdout or '').lower():
ok = True
break
except Exception:
pass
_t.sleep(0.5)
try:
if ok:
_update_step(app, 'Start Prole Workstation', 'success')
app._append_console("Prole Workstation is running.\n")
else:
_update_step(app, 'Start Prole Workstation', 'error')
app._append_console("Failed to start Prole Workstation. See Docker for details.\n")
except Exception:
pass
def _on_enter(_evt=None):
# Only handle once
@ -355,16 +290,11 @@ def create_deploy_page(app):
app._console_press_enter()
except Exception:
pass
# While docker deploy is running, pop up the drag-to-install window
# While deploy is running, pop up the drag-to-install window
try:
threading.Thread(target=_open_drag_install, daemon=True).start()
except Exception:
_open_drag_install()
# Start docker run + verification in background
try:
threading.Thread(target=_start_workstation_and_verify, daemon=True).start()
except Exception:
_start_workstation_and_verify()
# Bind Enter to trigger the start when the user is ready
try:
@ -442,30 +372,3 @@ def _ensure_docker_running(timeout: int = 120) -> bool:
return False
def _ensure_workstation_container() -> bool:
"""Run or start the prole-workstation container with required ports."""
version = ws.get_workstation_version(cfg.PROJECT_ROOT)
# If container exists and is running → success
try:
exists = subprocess.run(["bash", "-lc", "docker ps -a --format '{{.Names}}' | grep -w prole-workstation"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if exists.returncode == 0:
# Check running state
running = subprocess.run(["bash", "-lc", "docker ps --format '{{.Names}}' | grep -w prole-workstation"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if running.returncode == 0:
return True
# Start it
started = subprocess.run(["bash", "-lc", "docker start prole-workstation"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return started.returncode == 0
except Exception:
pass
cmd = (
"docker run -d --name prole-workstation "
"-p 5901:5901 -p 6667:6667 -p 6697:6697 "
f"prole-workstation:{version}"
)
try:
res = subprocess.run(["bash", "-lc", cmd], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return res.returncode == 0
except Exception:
return False

View File

@ -1,70 +0,0 @@
"""
Workstation (Docker) build helpers for the Prole installer (root-level).
Compose a deterministic Docker build command and derive the image tag version
from the workstation/Dockerfile. Includes helpers to check if the current
image tag already exists locally to avoid redundant builds.
"""
from __future__ import annotations
from pathlib import Path
import re
import subprocess
from . import config as cfg
def get_workstation_version(project_root: Path) -> str:
"""Parse the workstation Dockerfile for a version.
Looks for one of the following (first match wins):
- ARG WORKSTATION_VERSION=1.2.3
- LABEL org.opencontainers.image.version="1.2.3"
Falls back to "0.1.0" if none found.
"""
ws = Path(project_root) / "workstation" / "Dockerfile"
default_ver = "0.1.0"
try:
text = ws.read_text(encoding="utf-8")
except Exception:
return default_ver
# ARG pattern
m = re.search(r"^\s*ARG\s+WORKSTATION_VERSION\s*=\s*([\w\.-]+)\s*$", text, re.MULTILINE)
if m:
return m.group(1)
# LABEL pattern
m2 = re.search(r"org\.opencontainers\.image\.version\s*=\s*\"?([\w\.-]+)\"?", text)
if m2:
return m2.group(1)
return default_ver
def get_docker_build_command(project_root: Path) -> str:
"""Return the canonical Docker build command for the workstation image.
docker build -t prole-workstation:<version> .
Includes platform flags for Apple Silicon when appropriate.
"""
ws = Path(project_root) / "workstation"
version = get_workstation_version(project_root)
platform_args = cfg.get_docker_build_platform_args()
plat = (" ".join(platform_args) + " ") if platform_args else ""
return f"cd \"{ws}\" && docker build {plat}-t prole-workstation:{version} ."
def is_workstation_image_current(project_root: Path) -> bool:
"""Return True if the local Docker image prole-workstation:<version> exists.
This checks only for the presence of the tag. It does not verify whether
the image is up-to-date with the Dockerfile. For most installer scenarios,
skipping a rebuild when the tag exists is sufficient and saves time.
"""
version = get_workstation_version(project_root)
try:
r = subprocess.run(
["bash", "-lc", f"docker image inspect prole-workstation:{version} >/dev/null 2>&1"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
return r.returncode == 0
except Exception:
return False

View File

@ -11,16 +11,13 @@ let package = Package(
],
dependencies: [
// NozeIO SwiftNIO IRC Client
.package(url: "https://github.com/NozeIO/swift-nio-irc-client", branch: "main"),
// RoyalVNCKit via SwiftPM instead of local xcframework
.package(url: "https://github.com/royalapplications/royalvnc", branch: "main")
.package(url: "https://github.com/NozeIO/swift-nio-irc-client", branch: "main")
],
targets: [
.executableTarget(
name: "Prole",
dependencies: [
.product(name: "IRC", package: "swift-nio-irc-client"),
.product(name: "RoyalVNCKit", package: "royalvnc")
.product(name: "IRC", package: "swift-nio-irc-client")
],
path: "Sources",
resources: [

View File

@ -11,11 +11,10 @@
```
Prole
— macOS status and control surface for Prole endpoints, with a path to an integrated virtual workstation harness.
— macOS status and control surface for Prole endpoints.
Overview
- Prole provides live reachability and latency signals for Prole service endpoints. It operates in two modes: a regular application window for situational awareness and a minimalist statusbar overlay for persistent ataglance status.
- The application will evolve to include a virtual workstation surface to coordinate work across a network of Prolelinked LLMs. The current scope is operational visibility and control of endpoints.
Supported platform
- macOS 12.0+ (Monterey or newer) on Apple Silicon (arm64) and Intel (x86_64). Universal builds are supported by the build script.
@ -115,8 +114,5 @@ Diagnostics & troubleshooting
Security & signing
- The `.app` bundle is adhoc signed by default. For distribution, replace with a Developer ID signature and notarize as appropriate for your environment.
Roadmap
- Integration of a virtual workstation to orchestrate a network of Prolelinked LLMs from within the Prole surface.
License
- See the repository `LICENSE` file.

View File

@ -15,7 +15,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
private var overlayWindowController: OverlayWindowController!
private var mainWindowController: MainWindowController!
private var dbStatusWindowController: DBStatusWindowController!
private var workstationWindowController: WorkstationWindowController!
private var ircWindowController: IRCWindowController!
private var hotKeyManager: HotKeyManager!
private var serviceChecker: ServiceChecker!
@ -71,10 +70,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
))
dlog("DBStatusWindowController created")
// Workstation window (VNC viewer) shown to the right of Prole Status when not in status bar mode
workstationWindowController = WorkstationWindowController()
dlog("WorkstationWindowController created")
// IRC window short vertically, long horizontally, positioned below Prole Status
ircWindowController = IRCWindowController()
dlog("IRCWindowController created")
@ -160,7 +155,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
mode = .statusBar
mainWindowController.hide()
dbStatusWindowController.hide()
workstationWindowController.hide()
ircWindowController.hide()
overlayWindowController.showOverlayNow()
NSApp.setActivationPolicy(.accessory)
@ -178,9 +172,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
// Position database status window slightly down and to the left of the main window
if let ref = mainWindowController.window { dbStatusWindowController.position(relativeTo: ref) }
dbStatusWindowController.show()
// Position workstation window to the right of the main window and show it
if let ref = mainWindowController.window { workstationWindowController.position(rightOf: ref) }
workstationWindowController.show()
// Position IRC window below the main window and show it
if let ref = mainWindowController.window { ircWindowController.position(below: ref) }
ircWindowController.show()
@ -206,18 +197,15 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
if mainWindowController.isVisible {
mainWindowController.hide()
dbStatusWindowController.hide()
workstationWindowController.hide()
ircWindowController.hide()
if mode == .appWindow { mode = .statusBar }
} else {
mainWindowController.show()
if let ref = mainWindowController.window {
dbStatusWindowController.position(relativeTo: ref)
workstationWindowController.position(rightOf: ref)
ircWindowController.position(below: ref)
}
dbStatusWindowController.show()
workstationWindowController.show()
ircWindowController.show()
mode = .appWindow
overlayWindowController.hideOverlay()

View File

@ -1,150 +0,0 @@
import AppKit
import RoyalVNCKit
// A secondary window that hosts the Prole Workstation (VNC viewer)
// Version 1: viewer-only (no interactive session wiring yet)
final class WorkstationWindowController: NSWindowController {
private let viewer = VNCViewerHostView()
init() {
let style: NSWindow.StyleMask = [.titled, .closable, .miniaturizable, .resizable]
// Reasonable default for a VNC desktop view
let initialRect = NSRect(x: 0, y: 0, width: 1024, height: 768)
let window = NSWindow(contentRect: initialRect, styleMask: style, backing: .buffered, defer: false)
super.init(window: window)
window.isReleasedWhenClosed = false
window.title = "Prole Workstation"
window.center()
window.level = .normal
window.collectionBehavior = [.canJoinAllSpaces]
window.appearance = NSAppearance(named: .aqua)
let content = NSView()
content.translatesAutoresizingMaskIntoConstraints = false
window.contentView = content
viewer.translatesAutoresizingMaskIntoConstraints = false
content.addSubview(viewer)
NSLayoutConstraint.activate([
viewer.topAnchor.constraint(equalTo: content.topAnchor),
viewer.leadingAnchor.constraint(equalTo: content.leadingAnchor),
viewer.trailingAnchor.constraint(equalTo: content.trailingAnchor),
viewer.bottomAnchor.constraint(equalTo: content.bottomAnchor)
])
// Configure default connection (localhost:5901)
viewer.connectDefault()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
func show() {
guard let window = window else { return }
window.makeKeyAndOrderFront(nil)
NSApp.activate(ignoringOtherApps: false)
}
func hide() { window?.orderOut(nil) }
var isVisible: Bool { window?.isVisible ?? false }
// Position this window to the right of a reference window with a small gap.
func position(rightOf refWindow: NSWindow, gap: CGFloat = 12) {
guard let this = window else { return }
let refFrame = refWindow.frame
var newFrame = this.frame
newFrame.origin.x = refFrame.maxX + gap
// Align tops if possible, else keep current y
newFrame.origin.y = refFrame.origin.y + (refFrame.height - newFrame.height)
this.setFrame(newFrame, display: true, animate: false)
}
}
// Host view that embeds RoyalVNCKit viewer.
final class VNCViewerHostView: NSView {
private var framebufferView: VNCCAFramebufferView?
private var connection: VNCConnection?
// Keep a strong reference to the delegate; VNCConnection holds it weakly
private var connectionDelegateStrongRef: VNCConnectionDelegate?
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
wantsLayer = true
layer?.backgroundColor = NSColor.windowBackgroundColor.cgColor
// The actual framebuffer view will be created when the connection creates the framebuffer
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
func connectDefault() {
connect(hostname: "localhost", port: 5901)
}
func connect(hostname: String, port: Int) {
// Construct full settings according to current RoyalVNCKit API
let settings = VNCConnection.Settings(
isDebugLoggingEnabled: false,
hostname: hostname,
port: UInt16(port),
isShared: true,
isScalingEnabled: true,
useDisplayLink: true,
inputMode: .forwardKeyboardShortcutsIfNotInUseLocally,
isClipboardRedirectionEnabled: true,
colorDepth: .depth24Bit,
frameEncodings: .default
)
let conn = VNCConnection(settings: settings)
self.connection = conn
// Minimal delegate to attach framebuffer to a view
class Delegate: VNCConnectionDelegate {
weak var host: VNCViewerHostView?
init(host: VNCViewerHostView) { self.host = host }
func connection(_ connection: VNCConnection, stateDidChange connectionState: VNCConnection.ConnectionState) {
// No-op for now; could update UI
}
func connection(_ connection: VNCConnection, credentialFor authenticationType: VNCAuthenticationType, completion: @escaping (VNCCredential?) -> Void) {
// For now, no auth
completion(nil)
}
func connection(_ connection: VNCConnection, didCreateFramebuffer framebuffer: VNCFramebuffer) {
guard let host = host else { return }
DispatchQueue.main.async {
let fbView = VNCCAFramebufferView(frame: host.bounds, framebuffer: framebuffer, connection: connection)
fbView.translatesAutoresizingMaskIntoConstraints = false
host.subviews.forEach { $0.removeFromSuperview() }
host.addSubview(fbView)
NSLayoutConstraint.activate([
fbView.topAnchor.constraint(equalTo: host.topAnchor),
fbView.leadingAnchor.constraint(equalTo: host.leadingAnchor),
fbView.trailingAnchor.constraint(equalTo: host.trailingAnchor),
fbView.bottomAnchor.constraint(equalTo: host.bottomAnchor)
])
host.framebufferView = fbView
}
}
func connection(_ connection: VNCConnection, didResizeFramebuffer framebuffer: VNCFramebuffer) {
// VNCCAFramebufferView queries connection/framebuffer for size; nothing required here
}
func connection(_ connection: VNCConnection, didUpdateFramebuffer framebuffer: VNCFramebuffer, x: UInt16, y: UInt16, width: UInt16, height: UInt16) {
// View should handle drawing updates internally
}
func connection(_ connection: VNCConnection, didUpdateCursor cursor: VNCCursor) {
// Cursor updates handled by the framebuffer view
}
}
let delegate = Delegate(host: self)
self.connectionDelegateStrongRef = delegate
conn.delegate = delegate
conn.connect()
}
}

View File

@ -28,9 +28,6 @@ LOG_DIR="$BUILD_DIR/logs"
ARCH_CURRENT="$(uname -m)" # arm64 or x86_64
# Mandatory dependency sources (auto-fetched)
URL_ROYALVNC="https://github.com/royalapplications/royalvnc/archive/refs/tags/1.0.1.tar.gz"
# Deps staging directories
DEPS_DIR="$BUILD_DIR/deps"
DEPS_SRC_DIR="$DEPS_DIR/src"
@ -61,10 +58,9 @@ Examples:
./build.sh package
Dependencies:
IRC and RoyalVNC are built via Swift Package Manager.
IRC is built via Swift Package Manager.
Environment overrides (optional):
ROYALVNCKIT_XCFRAMEWORK If set, use this RoyalVNCKit.xcframework instead of building
KEEP_DEPS=1 Keep the deps staging directory after the build (for debugging)
PROLE_VERBOSE=1 Stream verbose output from SwiftPM/xcodebuild and echo commands
EOF
@ -270,199 +266,10 @@ copy_extra_resources() {
fi
}
# --- Dependency preparation (RoyalVNCKit) ---
have_cmd() { command -v "$1" >/dev/null 2>&1; }
fetch_tarball() {
local url="$1"; local out_tar="$2"
echo "[deps] Fetching: $url"
if have_cmd wget; then
wget -q -O "$out_tar" "$url"
else
curl -LsSf -o "$out_tar" "$url"
fi
}
extract_tarball() {
local tarpath="$1"; local destdir="$2"
mkdir -p "$destdir"
tar -xzf "$tarpath" -C "$destdir"
}
# Run a command and tee stdout/stderr to a logfile, returning the command's exit status
log_exec() {
local logfile="$1"; shift
mkdir -p "$(dirname "$logfile")"
echo "[log] → $logfile"
"$@" 2>&1 | tee "$logfile"
return ${PIPESTATUS[0]}
}
xc_archive_one() {
local proj_dir="$1"; local scheme="$2"; local arch="$3"; local outdir="$4"
local archive_path="$outdir/${scheme}-macos-${arch}.xcarchive"
echo "[xcodebuild] archive scheme=$scheme arch=$arch"
local proj_opt=()
# If an explicit Xcode project matching the scheme exists, use it (rare for SwiftPM)
if [[ -d "$proj_dir/${scheme}.xcodeproj" ]]; then
proj_opt=( -project "${scheme}.xcodeproj" )
fi
local logfile="$LOG_DIR/xcode-archive-${scheme}-${arch}.log"
if [[ "$scheme" == "RoyalVNCKit" ]]; then logfile="$DEPS_LOGS_DIR/royalvnc-archive-${arch}.log"; fi
pushd "$proj_dir" >/dev/null || return 1
# Per-scheme extra flags / xcconfig
local extra_args=()
if [[ "$scheme" == "RoyalVNCKit" ]]; then
# Enable distribution interfaces so SPM can import the Swift module, but disable verification to avoid toolchain issues
local xcflags_file="$outdir/royalvnc-archive-overrides.xcconfig"
cat > "$xcflags_file" <<'XCCONFIG'
BUILD_LIBRARY_FOR_DISTRIBUTION = YES
SWIFT_EMIT_MODULE_INTERFACE = YES
SWIFT_SERIALIZE_DEBUGGING_OPTIONS = NO
OTHER_SWIFT_FLAGS = $(inherited) -no-verify-emitted-module-interface
XCCONFIG
extra_args+=( -xcconfig "$xcflags_file" )
fi
log_exec "$logfile" xcodebuild archive \
-scheme "$scheme" \
-destination 'generic/platform=macOS' \
-configuration Release \
-archivePath "$archive_path" \
-sdk macosx \
-disableAutomaticPackageResolution \
SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES ARCHS="$arch" ONLY_ACTIVE_ARCH=NO \
SWIFT_VERSION=5.0 \
SWIFT_STRICT_CONCURRENCY=minimal \
MACOSX_DEPLOYMENT_TARGET="${MIN_MACOS}" \
${extra_args[@]:-} \
${proj_opt[@]:-} \
|| { popd >/dev/null; return 1; }
popd >/dev/null
}
# Build one framework w/ xcodebuild (not archive), outputting a .framework into outdir
xc_build_framework_one() {
local proj_dir="$1"; local scheme="$2"; local arch="$3"; local outdir="$4"; local product_name="$5"
local build_dir="$outdir/${scheme}-macos-${arch}-build"
mkdir -p "$build_dir"
local logfile="$DEPS_LOGS_DIR/${scheme}-build-${arch}.log"
pushd "$proj_dir" >/dev/null || return 1
# Prepare xcconfig to disable interface emission/verification
local xcflags_file="$outdir/${scheme}-build-overrides.${arch}.xcconfig"
cat > "$xcflags_file" <<'XCCONFIG'
// Emit module interfaces suitable for distribution so the Swift module can be imported by SPM
BUILD_LIBRARY_FOR_DISTRIBUTION = YES
SWIFT_EMIT_MODULE_INTERFACE = YES
SWIFT_SERIALIZE_DEBUGGING_OPTIONS = NO
// But do not verify emitted module interfaces to avoid toolchain-specific failures
OTHER_SWIFT_FLAGS = $(inherited) -no-verify-emitted-module-interface
XCCONFIG
# Important: write all xcodebuild output to the log to keep stdout clean (we echo only the path below)
xcodebuild build \
-scheme "$scheme" \
-destination 'generic/platform=macOS' \
-configuration Release \
-sdk macosx \
ARCHS="$arch" ONLY_ACTIVE_ARCH=NO \
SWIFT_VERSION=5.0 \
SWIFT_STRICT_CONCURRENCY=minimal \
MACOSX_DEPLOYMENT_TARGET="${MIN_MACOS}" \
CONFIGURATION_BUILD_DIR="$build_dir" \
-xcconfig "$xcflags_file" \
>"$logfile" 2>&1 || { popd >/dev/null; return 1; }
popd >/dev/null
# Accept both plain build dir and SwiftPM PackageFrameworks location
if [[ -d "$build_dir/${product_name}.framework" ]]; then
echo "$build_dir/${product_name}.framework"
return 0
fi
if [[ -d "$build_dir/PackageFrameworks/${product_name}.framework" ]]; then
echo "$build_dir/PackageFrameworks/${product_name}.framework"
return 0
fi
return 1
}
build_royalvnc_xcframework() {
if [[ -n ${ROYALVNCKIT_XCFRAMEWORK:-} && -d ${ROYALVNCKIT_XCFRAMEWORK} ]]; then
echo "[deps] Using provided RoyalVNCKit.xcframework: ${ROYALVNCKIT_XCFRAMEWORK}"
return 0
fi
local work="$DEPS_SRC_DIR/RoyalVNC-src"
local tar="$DEPS_DIR/royalvnc.tar.gz"
rm -rf "$work"; mkdir -p "$work"
fetch_tarball "$URL_ROYALVNC" "$tar"
extract_tarball "$tar" "$work"
local src_root
src_root="$(find "$work" -maxdepth 1 -type d -name 'royalvnc-*' | head -n1)"
if [[ -z "$src_root" ]]; then
echo "[deps] error: RoyalVNC source not found after extract" >&2
exit 1
fi
pushd "$src_root" >/dev/null
local build_tmp="$DEPS_OUT_DIR/RoyalVNC-build"
rm -rf "$build_tmp"; mkdir -p "$build_tmp"
local have_arm=0; local have_x86=0
local fw_arm=""; local fw_x86=""
local want_arches=(arm64 x86_64)
if [[ "${PROLE_BUILD_ARCH:-}" == "arm64" ]]; then
want_arches=(arm64)
elif [[ "${PROLE_BUILD_ARCH:-}" == "x86_64" ]]; then
want_arches=(x86_64)
fi
for dep_arch in "${want_arches[@]}"; do
if [[ "$dep_arch" == "arm64" ]]; then
# Prefer archive to produce proper Swift module interfaces; fall back to build if archive fails
if xc_archive_one "$PWD" RoyalVNCKit arm64 "$build_tmp"; then
fw_arm="$build_tmp/RoyalVNCKit-macos-arm64.xcarchive/Products/Library/Frameworks/RoyalVNCKit.framework"
have_arm=1
elif fw_arm=$(xc_build_framework_one "$PWD" RoyalVNCKit arm64 "$build_tmp" RoyalVNCKit); then
have_arm=1
fi
else
if xc_archive_one "$PWD" RoyalVNCKit x86_64 "$build_tmp"; then
fw_x86="$build_tmp/RoyalVNCKit-macos-x86_64.xcarchive/Products/Library/Frameworks/RoyalVNCKit.framework"
have_x86=1
elif fw_x86=$(xc_build_framework_one "$PWD" RoyalVNCKit x86_64 "$build_tmp" RoyalVNCKit); then
have_x86=1
fi
fi
done
local out_xc="$DEPS_OUT_DIR/RoyalVNCKit.xcframework"
rm -rf "$out_xc"
if [[ $have_arm -eq 1 && $have_x86 -eq 1 ]]; then
log_exec "$DEPS_LOGS_DIR/royalvnc-create-xcframework.log" xcodebuild -create-xcframework \
-framework "$fw_arm" \
-framework "$fw_x86" \
-output "$out_xc"
elif [[ $have_arm -eq 1 ]]; then
log_exec "$DEPS_LOGS_DIR/royalvnc-create-xcframework.log" xcodebuild -create-xcframework \
-framework "$fw_arm" \
-output "$out_xc"
elif [[ $have_x86 -eq 1 ]]; then
log_exec "$DEPS_LOGS_DIR/royalvnc-create-xcframework.log" xcodebuild -create-xcframework \
-framework "$fw_x86" \
-output "$out_xc"
else
echo "[deps] error: failed to build RoyalVNCKit for any macOS arch" >&2
exit 1
fi
export ROYALVNCKIT_XCFRAMEWORK="$out_xc"
echo "[deps] Built RoyalVNCKit.xcframework at $ROYALVNCKIT_XCFRAMEWORK"
# Provide a stable path within the package for SwiftPM binaryTarget resolution
local vendor_dir="$ROOT_DIR/Vendor"
mkdir -p "$vendor_dir"
rm -rf "$vendor_dir/RoyalVNCKit.xcframework"
cp -R "$ROYALVNCKIT_XCFRAMEWORK" "$vendor_dir/"
echo "[deps] Mirrored RoyalVNCKit.xcframework to $vendor_dir"
popd >/dev/null
}
# --- Dependency preparation ---
prepare_dependencies() {
ensure_dirs
echo "[deps] (deprecated) RoyalVNCKit manual build not required; managed by SwiftPM"
}
cleanup_dependencies() {
@ -565,7 +372,7 @@ build_one_arch() {
built_bin=$(spm_build_binary "$arch" | tail -n1) || { echo "[spm] build failed" >&2; exit 1; }
mkdir -p "$MACOS_DIR"
cp "$built_bin" "$MACOS_DIR/${APP_NAME}"
# Embed any SwiftPM dynamic libs (e.g., RoyalVNCKit) into the app bundle
# Embed any SwiftPM dynamic libs into the app bundle
embed_spm_dylibs "$arch"
# Ensure the app binary can locate embedded dylibs in Contents/Frameworks at runtime
echo "[rpath] Adding @executable_path/../Frameworks to app binary rpaths"

View File

@ -38,7 +38,6 @@ hiddenimports = [
'installer.deploy',
'installer.screen',
'installer.main',
'installer.workstation',
'installer.ncurses_ui',
'installer.ncurses_installer',
'curses',

View File

@ -1,152 +0,0 @@
# ====================================================================================
# Monster image: Unreal Engine (Linux) + Synapse (Matrix homeserver)
# ====================================================================================
FROM ubuntu:22.04
# Version tag for the workstation image
ARG WORKSTATION_VERSION=0.1.0
LABEL org.opencontainers.image.version="${WORKSTATION_VERSION}"
ENV DEBIAN_FRONTEND=noninteractive \
TZ=Etc/UTC \
UE_ROOT=/opt/UnrealEngine \
SYNAPSE_VENV=/opt/synapse \
SYNAPSE_CONFIG_PATH=/data/homeserver.yaml
# ------------------------------------------------------------------------------
# Base OS deps
# ------------------------------------------------------------------------------
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
wget \
unzip \
python3 \
python3-pip \
python3-venv \
libffi-dev \
libssl-dev \
libjpeg-dev \
libpq-dev \
sqlite3 \
tini \
supervisor \
locales \
less vim \
&& rm -rf /var/lib/apt/lists/*
# Set UTF-8 locale
RUN locale-gen en_US.UTF-8 && update-locale LANG=en_US.UTF-8
ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
# ------------------------------------------------------------------------------
# Unreal Engine: install from local ZIP
# ------------------------------------------------------------------------------
# Place Linux_Unreal_Engine_5.7.1.zip next to this Dockerfile before building
COPY Linux_Unreal_Engine_5.7.1.zip /tmp/ue.zip
RUN mkdir -p "${UE_ROOT}" \
&& unzip -q /tmp/ue.zip -d "${UE_ROOT}" \
&& rm /tmp/ue.zip
# If the ZIP unpacks with an extra top-level directory, you may want to normalize:
# RUN mv "${UE_ROOT}"/Linux_Unreal_Engine_*/* "${UE_ROOT}"/ && rmdir "${UE_ROOT}"/Linux_Unreal_Engine_*
# ------------------------------------------------------------------------------
# Synapse (Matrix homeserver) in a virtualenv
# ------------------------------------------------------------------------------
RUN python3 -m venv "${SYNAPSE_VENV}" \
&& "${SYNAPSE_VENV}/bin/pip" install --upgrade pip wheel \
&& "${SYNAPSE_VENV}/bin/pip" install matrix-synapse
# Data directory for Synapse config, keys, DB, etc.
RUN mkdir -p /data \
&& chown -R root:root /data
# ------------------------------------------------------------------------------
# Runtime scripts
# ------------------------------------------------------------------------------
# Synapse start script: expects /data/homeserver.yaml to already exist
# You can mount /data as a volume and pre-generate config per client
RUN mkdir -p /opt/scripts
RUN cat <<'EOF' > /opt/scripts/run-synapse.sh
#!/usr/bin/env bash
set -e
VENV="${SYNAPSE_VENV:-/opt/synapse}"
CONFIG="${SYNAPSE_CONFIG_PATH:-/data/homeserver.yaml}"
if [ ! -f "$CONFIG" ]; then
echo "ERROR: Synapse config not found at $CONFIG"
echo "You must generate homeserver.yaml and mount /data or set SYNAPSE_CONFIG_PATH."
exit 1
fi
exec "$VENV/bin/python" -m synapse.app.homeserver \
--config-path "$CONFIG"
EOF
RUN chmod +x /opt/scripts/run-synapse.sh
# Unreal start script: adjust for your packaged app
# TODO: Replace the command with your actual cooked Linux server/client binary
RUN cat <<'EOF' > /opt/scripts/run-unreal.sh
#!/usr/bin/env bash
set -e
UE_ROOT="${UE_ROOT:-/opt/UnrealEngine}"
# Example placeholder; replace with your actual binary & project path
# For example, if you have a packaged server:
# "$UE_ROOT/YourGame/Binaries/Linux/YourGameServer-Linux-Shipping"
if [ ! -x "$UE_ROOT/Engine/Binaries/Linux/UnrealEditor" ]; then
echo "WARNING: UnrealEditor not found or not executable. Fix /opt/scripts/run-unreal.sh."
fi
# Placeholder: just sleep to avoid crash-loop if you haven't wired in your app yet
# Replace this with the actual Unreal command.
exec "$UE_ROOT/Engine/Binaries/Linux/UnrealEditor" || exec sleep 3600
EOF
RUN chmod +x /opt/scripts/run-unreal.sh
# ------------------------------------------------------------------------------
# Supervisor config: run Synapse + Unreal together
# ------------------------------------------------------------------------------
RUN mkdir -p /etc/supervisor/conf.d
RUN cat <<'EOF' > /etc/supervisor/conf.d/supervisord.conf
[supervisord]
nodaemon=true
logfile=/var/log/supervisord.log
pidfile=/var/run/supervisord.pid
[program:synapse]
command=/opt/scripts/run-synapse.sh
autostart=true
autorestart=true
priority=10
stdout_logfile=/var/log/synapse.log
stderr_logfile=/var/log/synapse.err
[program:unreal]
command=/opt/scripts/run-unreal.sh
autostart=true
autorestart=true
priority=20
stdout_logfile=/var/log/ueapp.log
stderr_logfile=/var/log/ueapp.err
EOF
# ------------------------------------------------------------------------------
# Ports
# ------------------------------------------------------------------------------
# Synapse: 8008 (http), 8448 (federation / tls, if enabled)
# Unreal: youll add ports here depending on your game/server (e.g. 7777, 5901 for VNC, etc.)
EXPOSE 8008 8448
WORKDIR /opt
# Use tini as PID 1 for better signal handling
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RiderProjectSettingsUpdater">
<option name="singleClickDiffPreview" value="1" />
<option name="unhandledExceptionsIgnoreList" value="1" />
<option name="vcsConfiguration" value="3" />
</component>
</project>

View File

@ -1,167 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoGeneratedRunConfigurationManager">
<projectFile>Prole.uproject</projectFile>
</component>
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="071bcd00-3948-4252-9b28-e1b37a6558c6" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/../../prole-db/bulk_insert.sql" beforeDir="false" afterPath="$PROJECT_DIR$/../../prole-db/bulk_insert.sql" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="DpaMonitoringSettings">
<option name="firstShow" value="false" />
</component>
<component name="EmbeddingIndexingInfo">
<option name="cachedIndexableFilesCount" value="1312" />
<option name="fileBasedEmbeddingIndicesEnabled" value="true" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/../.." />
</component>
<component name="ProjectColorInfo"><![CDATA[{
"associatedIndex": 2
}]]></component>
<component name="ProjectId" id="36Y7WKe0zvKRzlPD6aJiWB9fTGc" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
"ModuleVcsDetector.initialDetectionPerformed": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.git.unshallow": "true",
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
"Uproject.Prole.executor": "Run",
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
"git-widget-placeholder": "main",
"junie.onboarding.icon.badge.shown": "true",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"to.speed.mode.migration.done": "true",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="RunManager">
<configuration name="Prole" type="Uproject" factoryName="rider.uproject">
<configuration_1 setup="1">
<option name="CONFIGURATION" value="DebugGame Editor" />
<option name="PLATFORM" value="Mac" />
<option name="CURRENT_LAUNCH_PROFILE" value="Local" />
<option name="EXECUTABLE_PATH" value="$PROJECT_DIR$/../../../../../Shared/Epic Games/UE_5.7/Engine/Binaries/Mac/UnrealEditor-Mac-DebugGame.app/Contents/MacOS/UnrealEditor-Mac-DebugGame" />
<option name="MANDATORY_PROGRAM_PARAMETERS" value=" &quot;$PROJECT_DIR$/Prole.uproject&quot;" />
<option name="CUSTOM_PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../../../../../Shared/Epic Games/UE_5.7" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="TERMINAL_INTERACTION_BEHAVIOR" value="FORCE_CONSOLE" />
<option name="PROJECT_FILE_PATH" value="$PROJECT_DIR$/Prole.uproject" />
</configuration_1>
<configuration_2 setup="1">
<option name="CONFIGURATION" value="DebugGame" />
<option name="PLATFORM" value="Mac" />
<option name="CURRENT_LAUNCH_PROFILE" value="Local" />
<option name="EXECUTABLE_PATH" value="$PROJECT_DIR$/Binaries/Mac/Prole-Mac-DebugGame.app/Contents/MacOS/Prole-Mac-DebugGame" />
<option name="MANDATORY_PROGRAM_PARAMETERS" value="" />
<option name="CUSTOM_PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../../../../../Shared/Epic Games/UE_5.7" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="TERMINAL_INTERACTION_BEHAVIOR" value="FORCE_CONSOLE" />
<option name="PROJECT_FILE_PATH" value="$PROJECT_DIR$/Prole.uproject" />
</configuration_2>
<configuration_3 setup="1">
<option name="CONFIGURATION" value="Development Editor" />
<option name="PLATFORM" value="Mac" />
<option name="CURRENT_LAUNCH_PROFILE" value="Local" />
<option name="EXECUTABLE_PATH" value="$PROJECT_DIR$/../../../../../Shared/Epic Games/UE_5.7/Engine/Binaries/Mac/UnrealEditor.app/Contents/MacOS/UnrealEditor" />
<option name="MANDATORY_PROGRAM_PARAMETERS" value=" &quot;$PROJECT_DIR$/Prole.uproject&quot;" />
<option name="CUSTOM_PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../../../../../Shared/Epic Games/UE_5.7" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="TERMINAL_INTERACTION_BEHAVIOR" value="FORCE_CONSOLE" />
<option name="PROJECT_FILE_PATH" value="$PROJECT_DIR$/Prole.uproject" />
</configuration_3>
<configuration_4 setup="1">
<option name="CONFIGURATION" value="Development" />
<option name="PLATFORM" value="Mac" />
<option name="CURRENT_LAUNCH_PROFILE" value="Local" />
<option name="EXECUTABLE_PATH" value="$PROJECT_DIR$/Binaries/Mac/Prole.app/Contents/MacOS/Prole" />
<option name="MANDATORY_PROGRAM_PARAMETERS" value="" />
<option name="CUSTOM_PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../../../../../Shared/Epic Games/UE_5.7" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="TERMINAL_INTERACTION_BEHAVIOR" value="FORCE_CONSOLE" />
<option name="PROJECT_FILE_PATH" value="$PROJECT_DIR$/Prole.uproject" />
</configuration_4>
<configuration_5 setup="1">
<option name="CONFIGURATION" value="Shipping" />
<option name="PLATFORM" value="Mac" />
<option name="CURRENT_LAUNCH_PROFILE" value="Local" />
<option name="EXECUTABLE_PATH" value="$PROJECT_DIR$/Binaries/Mac/Prole-Mac-Shipping.app/Contents/MacOS/Prole-Mac-Shipping" />
<option name="MANDATORY_PROGRAM_PARAMETERS" value="" />
<option name="CUSTOM_PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../../../../../Shared/Epic Games/UE_5.7" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="TERMINAL_INTERACTION_BEHAVIOR" value="FORCE_CONSOLE" />
<option name="PROJECT_FILE_PATH" value="$PROJECT_DIR$/Prole.uproject" />
</configuration_5>
<option name="DEFAULT_PROJECT_PATH" value="$PROJECT_DIR$/Prole.uproject" />
<option name="PROJECT_FILE_PATH" value="$PROJECT_DIR$/Prole.uproject" />
<option name="AUTO_SELECT_PRIORITY" value="10010" />
<method v="2">
<option name="Build" />
</method>
</configuration>
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="071bcd00-3948-4252-9b28-e1b37a6558c6" name="Changes" comment="" />
<created>1765171684321</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1765171684321</updated>
<workItem from="1765171684792" duration="3409000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="UnityProjectConfiguration" hasMinimizedUI="false" />
<component name="VcsManagerConfiguration">
<option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<breakpoint enabled="true" type="DotNet_Exception_Breakpoints">
<properties exception="System.OperationCanceledException" breakIfHandledByOtherCode="false" displayValue="System.OperationCanceledException" />
<option name="timeStamp" value="1" />
</breakpoint>
<breakpoint enabled="true" type="DotNet_Exception_Breakpoints">
<properties exception="System.Threading.Tasks.TaskCanceledException" breakIfHandledByOtherCode="false" displayValue="System.Threading.Tasks.TaskCanceledException" />
<option name="timeStamp" value="2" />
</breakpoint>
<breakpoint enabled="true" type="DotNet_Exception_Breakpoints">
<properties exception="System.Threading.ThreadAbortException" breakIfHandledByOtherCode="false" displayValue="System.Threading.ThreadAbortException" />
<option name="timeStamp" value="3" />
</breakpoint>
</breakpoints>
</breakpoint-manager>
</component>
</project>

View File

@ -1,87 +0,0 @@
[/Script/EngineSettings.GameMapsSettings]
EditorStartupMap=/Game/SimBlank/Levels/SimBlank
+EditorTemplateMapOverrides=(Thumbnail="/Game/SimBlank/Levels/Thumbnails/SimBlank_Thumbnail.SimBlank_Thumbnail",Map="/Game/SimBlank/Levels/SimBlank.SimBlank",DisplayName=NSLOCTEXT("[/Script/EngineSettings]", "C47C7345459213852543F1906820C22C", "Simulation Default"))
GameDefaultMap=/Game/Main
[/Script/Engine.RendererSettings]
r.DefaultFeature.AutoExposure.ExtendDefaultLuminanceRange=True
r.DefaultFeature.AutoExposure.ExtendDefaultLuminanceRange=True
r.AllowStaticLighting=False
r.Shadow.Virtual.Enable=1
r.GenerateMeshDistanceFields=True
r.DynamicGlobalIlluminationMethod=1
r.ReflectionMethod=1
r.SkinCache.CompileShaders=True
r.RayTracing=True
r.RayTracing.RayTracingProxies.ProjectEnabled=True
r.Substrate=True
r.Substrate.ProjectGBufferFormat=0
r.DefaultFeature.LocalExposure.HighlightContrastScale=0.8
r.DefaultFeature.LocalExposure.ShadowContrastScale=0.8
[/Script/WindowsTargetPlatform.WindowsTargetSettings]
DefaultGraphicsRHI=DefaultGraphicsRHI_DX12
DefaultGraphicsRHI=DefaultGraphicsRHI_DX12
-D3D12TargetedShaderFormats=PCD3D_SM5
+D3D12TargetedShaderFormats=PCD3D_SM6
-D3D11TargetedShaderFormats=PCD3D_SM5
+D3D11TargetedShaderFormats=PCD3D_SM5
Compiler=Default
AudioSampleRate=48000
AudioCallbackBufferFrameSize=1024
AudioNumBuffersToEnqueue=1
AudioMaxChannels=0
AudioNumSourceWorkers=4
SpatializationPlugin=
SourceDataOverridePlugin=
ReverbPlugin=
OcclusionPlugin=
CompressionOverrides=(bOverrideCompressionTimes=False,DurationThreshold=5.000000,MaxNumRandomBranches=0,SoundCueQualityIndex=0)
CacheSizeKB=65536
MaxChunkSizeOverrideKB=0
bResampleForDevice=False
MaxSampleRate=48000.000000
HighSampleRate=32000.000000
MedSampleRate=24000.000000
LowSampleRate=12000.000000
MinSampleRate=8000.000000
CompressionQualityModifier=1.000000
AutoStreamingThreshold=0.000000
SoundCueCookQualityIndex=-1
[/Script/WorldPartitionEditor.WorldPartitionEditorSettings]
CommandletClass=Class'/Script/UnrealEd.WorldPartitionConvertCommandlet'
[/Script/Engine.UserInterfaceSettings]
bAuthorizeAutomaticWidgetVariableCreation=False
FontDPIPreset=Standard
FontDPI=72
[/Script/Engine.Engine]
+ActiveGameNameRedirects=(OldGameName="TP_SIM_Blank",NewGameName="/Script/Prole")
+ActiveGameNameRedirects=(OldGameName="/Script/TP_SIM_Blank",NewGameName="/Script/Prole")
+ActiveClassRedirects=(OldClassName="TP_SIM_BlankGameModeBase",NewClassName="ProleGameModeBase")
[/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings]
bEnablePlugin=True
bAllowNetworkConnection=True
SecurityToken=58F2889EEC4D55C9FB36CF943D45EDC1
bIncludeInShipping=False
bAllowExternalStartInShipping=False
bCompileAFSProject=False
bUseCompression=False
bLogFiles=False
bReportStats=False
ConnectionType=USBOnly
bUseManualIPAddress=False
ManualIPAddress=

View File

@ -1,16 +0,0 @@
[/Script/EngineSettings.GeneralProjectSettings]
ProjectName=SimBlank
ProjectID=A648E968304C158BCB917C938EFE06BB
[/Script/CommonUI.CommonUISettings]
CommonButtonAcceptKeyHandling=TriggerClick
[/Script/EngineSettings.GameMapsSettings]
GlobalDefaultGameMode=/Script/Prole.ProleGameModeBase
GameDefaultMap=/Game/SimBlank/Levels/Main.Main
EditorStartupMap=/Game/SimBlank/Levels/Main.Main
[/Script/Engine.RendererSettings]
; Ensure vsync and fullscreen hints (actual fullscreen handled via command line: -Fullscreen)
r.VSync=1

View File

@ -1,86 +0,0 @@
[/Script/Engine.InputSettings]
-AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f))
-AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f))
-AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f))
-AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f))
-AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f))
-AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f))
-AxisConfig=(AxisKeyName="Mouse2D",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f))
+AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MouseWheelAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_LeftTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_RightTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_Special_Left_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_Special_Left_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Mouse2D",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Vive_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Vive_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Vive_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Vive_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Vive_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Vive_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Touch",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
bAltEnterTogglesFullscreen=True
bF11TogglesFullscreen=True
bUseMouseForTouch=False
bEnableMouseSmoothing=True
bEnableFOVScaling=True
bCaptureMouseOnLaunch=True
bEnableLegacyInputScales=True
bEnableMotionControls=True
bFilterInputByPlatformUser=False
bShouldFlushPressedKeysOnViewportFocusLost=True
bAlwaysShowTouchInterface=False
bShowConsoleOnFourFingerTap=True
bEnableGestureRecognizer=False
bUseAutocorrect=False
DefaultViewportMouseCaptureMode=CapturePermanently_IncludingInitialMouseDown
DefaultViewportMouseLockMode=LockOnCapture
FOVScale=0.011110
DoubleClickTime=0.200000
DefaultPlayerInputClass=/Script/EnhancedInput.EnhancedPlayerInput
DefaultInputComponentClass=/Script/EnhancedInput.EnhancedInputComponent
DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks
-ConsoleKeys=Tilde
+ConsoleKeys=Tilde

View File

@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<Group
location = "container:" name = "Engine">
<FileRef
location = "group:Intermediate/ProjectFiles/UnrealEditor (IOS).xcodeproj">
</FileRef>
<FileRef
location = "group:Intermediate/ProjectFiles/UnrealGame (IOS).xcodeproj">
</FileRef>
</Group>
<Group
location = "container:" name = "Games">
<Group
location = "container:" name = "Prole">
<FileRef
location = "group:Intermediate/ProjectFiles/Prole (IOS).xcodeproj">
</FileRef>
</Group>
</Group>
<Group
location = "container:" name = "Programs">
<Group
location = "container:" name = "Automation">
</Group>
<Group
location = "container:" name = "Shared">
</Group>
<Group
location = "container:" name = "UnrealBuildTool.Plugins">
</Group>
</Group>
<Group
location = "container:" name = "Rules">
</Group>
</Workspace>

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>DisableBuildSystemDeprecationWarning</key>
<true/>
<key>DisableBuildSystemDeprecationDiagnostic</key>
<true/>
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
<false/>
</dict>
</plist>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Original</string>
<key>BuildLocationStyle</key>
<string>UseTargetSettings</string>
<key>CustomBuildLocationType</key>
<string>RelativeToDerivedData</string>
<key>DerivedDataLocationStyle</key>
<string>Default</string>
<key>IssueFilterStyle</key>
<string>ShowAll</string>
<key>LiveSourceIssuesEnabled</key>
<true/>
<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
<true/>
<key>SnapshotLocationStyle</key>
<string>Default</string>
</dict>
</plist>

View File

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<Group
location = "container:" name = "Engine">
<FileRef
location = "group:Intermediate/ProjectFiles/UnrealEditor (Mac).xcodeproj">
</FileRef>
<FileRef
location = "group:Intermediate/ProjectFiles/UnrealGame (Mac).xcodeproj">
</FileRef>
</Group>
<Group
location = "container:" name = "Games">
<Group
location = "container:" name = "Prole">
<FileRef
location = "group:Intermediate/ProjectFiles/Prole (Mac).xcodeproj">
</FileRef>
<FileRef
location = "group:Intermediate/ProjectFiles/ProleEditor (Mac).xcodeproj">
</FileRef>
</Group>
</Group>
<Group
location = "container:" name = "Programs">
<Group
location = "container:" name = "Automation">
</Group>
<Group
location = "container:" name = "Shared">
</Group>
<Group
location = "container:" name = "UnrealBuildTool.Plugins">
</Group>
</Group>
<Group
location = "container:" name = "Rules">
</Group>
</Workspace>

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>DisableBuildSystemDeprecationWarning</key>
<true/>
<key>DisableBuildSystemDeprecationDiagnostic</key>
<true/>
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
<false/>
</dict>
</plist>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Original</string>
<key>BuildLocationStyle</key>
<string>UseTargetSettings</string>
<key>CustomBuildLocationType</key>
<string>RelativeToDerivedData</string>
<key>DerivedDataLocationStyle</key>
<string>Default</string>
<key>IssueFilterStyle</key>
<string>ShowAll</string>
<key>LiveSourceIssuesEnabled</key>
<true/>
<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
<true/>
<key>SnapshotLocationStyle</key>
<string>Default</string>
</dict>
</plist>

View File

@ -1,30 +0,0 @@
{
"FileVersion": 3,
"EngineAssociation": "5.7",
"Category": "",
"Description": "",
"Modules": [
{
"Name": "Prole",
"Type": "Runtime",
"LoadingPhase": "Default"
}
],
"Plugins": [
{
"Name": "ModelingToolsEditorMode",
"Enabled": true,
"TargetAllowList": [
"Editor"
]
},
{
"Name": "SunPosition",
"Enabled": true
},
{
"Name": "GeoReferencing",
"Enabled": true
}
]
}

View File

@ -1,15 +0,0 @@
// Copyright Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
using System.Collections.Generic;
public class ProleTarget : TargetRules
{
public ProleTarget( TargetInfo Target) : base(Target)
{
Type = TargetType.Game;
DefaultBuildSettings = BuildSettingsVersion.V6;
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_7;
ExtraModuleNames.AddRange( new string[] { "Prole" } );
}
}

View File

@ -1,24 +0,0 @@
// Copyright Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class Prole : ModuleRules
{
public Prole(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
// Add modules we will likely use for audio and simple runtime visuals
PrivateDependencyModuleNames.AddRange(new string[] { "AudioMixer" });
// Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
}
}

View File

@ -1,6 +0,0 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "Prole.h"
#include "Modules/ModuleManager.h"
IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, Prole, "Prole" );

View File

@ -1,6 +0,0 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"

View File

@ -1,109 +0,0 @@
// ProleDisplayActor.cpp
#include "ProleDisplayActor.h"
#include "Components/TextRenderComponent.h"
#include "Components/AudioComponent.h"
#include "Sound/SoundBase.h"
#include "Misc/Paths.h"
#include "Misc/FileHelper.h"
AProleDisplayActor::AProleDisplayActor()
{
PrimaryActorTick.bCanEverTick = true;
Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
SetRootComponent(Root);
CrawlText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("CrawlText"));
CrawlText->SetupAttachment(Root);
CrawlText->SetHorizontalAlignment(EHTA_Center);
CrawlText->SetVerticalAlignment(EVRTA_TextTop);
CrawlText->SetTextRenderColor(FColor::Yellow);
CrawlText->SetWorldSize(24.f);
AudioComp = CreateDefaultSubobject<UAudioComponent>(TEXT("AudioComp"));
AudioComp->SetupAttachment(Root);
}
void AProleDisplayActor::BeginPlay()
{
Super::BeginPlay();
// Initialize transform for the crawl
SetActorLocation(StartLocation);
const FRotator Tilt(TiltAngleDegrees, 0.f, 0.f);
SetActorRotation(Tilt);
LoadTextFromProle();
TryPlayWavFromProle();
}
void AProleDisplayActor::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
// Move text along local axes to create crawl effect
const FVector LocalDelta = FVector(DepthSpeed * DeltaSeconds, -CrawlSpeed * DeltaSeconds, 0.f);
AddActorLocalOffset(LocalDelta);
}
void AProleDisplayActor::LoadTextFromProle()
{
// Look for /prole/input.txt first, else first .txt in /prole
FString BaseDir = TEXT("/prole/");
FString PrimaryFile = FPaths::Combine(BaseDir, TEXT("input.txt"));
FString TextData;
bool bLoaded = false;
if (FPaths::FileExists(PrimaryFile))
{
bLoaded = FFileHelper::LoadFileToString(TextData, *PrimaryFile, FFileHelper::EHashOptions::None);
}
else
{
// Fallback: find any .txt
TArray<FString> FoundFiles;
IFileManager::Get().FindFiles(FoundFiles, *(FPaths::Combine(BaseDir, TEXT("*.txt"))), true, false);
if (FoundFiles.Num() > 0)
{
const FString AnyTxt = FPaths::Combine(BaseDir, FoundFiles[0]);
bLoaded = FFileHelper::LoadFileToString(TextData, *AnyTxt, FFileHelper::EHashOptions::None);
}
}
if (bLoaded)
{
LastLoadedText = TextData;
CrawlText->SetText(FText::FromString(LastLoadedText));
}
else
{
UE_LOG(LogTemp, Warning, TEXT("ProleDisplayActor: No text file found in /prole"));
CrawlText->SetText(FText::FromString(TEXT("PROLE DISPLAY\nPlace input.txt in /prole")));
}
}
void AProleDisplayActor::TryPlayWavFromProle()
{
// NOTE: Runtime loading of WAV to USoundWave requires parsing; stub for now.
// We search for a packaged asset reference via soft path placed at /prole/sound.assetpath
FString BaseDir = TEXT("/prole/");
FString AssetRefPath = FPaths::Combine(BaseDir, TEXT("sound.assetpath"));
FString AssetRef;
if (FPaths::FileExists(AssetRefPath) && FFileHelper::LoadFileToString(AssetRef, *AssetRefPath))
{
FSoftObjectPath SoftPath(AssetRef.TrimStartAndEnd());
if (UObject* Obj = SoftPath.TryLoad())
{
if (USoundBase* Sound = Cast<USoundBase>(Obj))
{
AudioComp->SetSound(Sound);
AudioComp->Play();
return;
}
}
}
UE_LOG(LogTemp, Warning, TEXT("ProleDisplayActor: WAV runtime loader not implemented. Place an asset reference in /prole/sound.assetpath to play."));
}

View File

@ -1,52 +0,0 @@
// ProleDisplayActor.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ProleDisplayActor.generated.h"
class UTextRenderComponent;
class UAudioComponent;
UCLASS()
class PROLE_API AProleDisplayActor : public AActor
{
GENERATED_BODY()
public:
AProleDisplayActor();
virtual void BeginPlay() override;
virtual void Tick(float DeltaSeconds) override;
protected:
UPROPERTY(VisibleAnywhere)
USceneComponent* Root;
// Star Wars style crawl text
UPROPERTY(VisibleAnywhere)
UTextRenderComponent* CrawlText;
// Audio output (will attempt to play wav from /prole)
UPROPERTY(VisibleAnywhere)
UAudioComponent* AudioComp;
// Configurable parameters
UPROPERTY(EditAnywhere, Category = "Crawl")
float CrawlSpeed = 50.f; // units per second along local -Y
UPROPERTY(EditAnywhere, Category = "Crawl")
float DepthSpeed = 15.f; // units per second along local +Z
UPROPERTY(EditAnywhere, Category = "Crawl")
float TiltAngleDegrees = 20.f; // tilt back like the movie crawl
UPROPERTY(EditAnywhere, Category = "Crawl")
FVector StartLocation = FVector(0.f, 0.f, 30.f);
private:
void LoadTextFromProle();
void TryPlayWavFromProle();
FString LastLoadedText;
};

View File

@ -1,22 +0,0 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "ProleGameModeBase.h"
#include "ProleDisplayActor.h"
#include "Engine/World.h"
void AProleGameModeBase::BeginPlay()
{
Super::BeginPlay();
UWorld* World = GetWorld();
if (!World)
{
return;
}
FActorSpawnParameters Params;
Params.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
World->SpawnActor<AProleDisplayActor>(AProleDisplayActor::StaticClass(), FVector::ZeroVector, FRotator::ZeroRotator, Params);
}

View File

@ -1,18 +0,0 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "ProleGameModeBase.generated.h"
/**
*
*/
UCLASS()
class PROLE_API AProleGameModeBase : public AGameModeBase
{
GENERATED_BODY()
public:
virtual void BeginPlay() override;
};

View File

@ -1,15 +0,0 @@
// Copyright Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
using System.Collections.Generic;
public class ProleEditorTarget : TargetRules
{
public ProleEditorTarget( TargetInfo Target) : base(Target)
{
Type = TargetType.Editor;
DefaultBuildSettings = BuildSettingsVersion.V6;
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_7;
ExtraModuleNames.AddRange( new string[] { "Prole" } );
}
}

View File

@ -1 +0,0 @@
docker build -t prole-workstation:0.1.0 .

View File

@ -1,10 +0,0 @@
!#/bin/bash
PROLE_HOME=~/dev/prole/
docker run -it --rm \
-v $PROLE_HOME:/prole \
-p 8008:8008 \
-p 8448:8448 \
-p 5901:5901 \
prole-workstaton:0.1.0