Jump to content

GorBot Cluster: Difference between revisions

From Gor Wiki
Created page with "{{DISPLAYTITLE:Reliable Infrastructure}} __NOTOC__ <div style="width:calc(100% - 40px); max-width:1500px; margin:-42px auto 30px auto; padding:0; font-family:Georgia, 'Times New Roman', serif; color:#e8dfcf;"> <div style="overflow:hidden; border:1px solid #7d5b37; border-radius:8px; background:#17110d; box-shadow:0 4px 18px rgba(0,0,0,0.55);"> <!-- ========================================================= --> <!-- HEADER --> <!-- ========================================..."
 
No edit summary
 
Line 10: Line 10:
<div style="margin:0; padding:24px 24px 20px 24px; text-align:center; line-height:1.2; background:linear-gradient(180deg,#3b2118 0%,#1b120e 100%); border-bottom:1px solid #7d5b37;">
<div style="margin:0; padding:24px 24px 20px 24px; text-align:center; line-height:1.2; background:linear-gradient(180deg,#3b2118 0%,#1b120e 100%); border-bottom:1px solid #7d5b37;">
<div style="margin:0; padding:0; font-size:36px; line-height:1.18; font-weight:bold; letter-spacing:2px; color:#e0b45d; text-shadow:2px 2px 4px #000;">RELIABLE INFRASTRUCTURE</div>
<div style="margin:0; padding:0; font-size:36px; line-height:1.18; font-weight:bold; letter-spacing:2px; color:#e0b45d; text-shadow:2px 2px 4px #000;">RELIABLE INFRASTRUCTURE</div>
<div style="margin:10px 0 0 0; padding:0; font-size:18px; line-height:1.35; color:#c9bba6; font-style:italic;">Managed Discord nodes, shared state, failover, load sharing, centralized updates, and web-based control built to grow beyond one machine.</div>
<div style="margin:10px 0 0 0; padding:0; font-size:18px; line-height:1.35; color:#c9bba6; font-style:italic;">Multiple managed Discord nodes, shared authoritative state, failover, load sharing, centralized updates, and web-based control built to grow beyond one machine.</div>
</div>
</div>


Line 19: Line 19:


<div style="padding:30px 42px 18px 42px; font-size:16px; line-height:1.8;">
<div style="padding:30px 42px 18px 42px; font-size:16px; line-height:1.8;">
<div style="font-size:22px; color:#d9b36c; margin:0 0 12px 0; font-weight:bold;">GorBot Is Designed to Survive the Loss of a Single Machine</div>
<div style="font-size:22px; color:#d9b36c; margin:0 0 12px 0; font-weight:bold;">Built Beyond a Single Discord Machine</div>


The modern '''GorBot infrastructure''' is built around a managed cluster rather than one Discord bot process running on one computer.
Modern '''GorBot infrastructure''' is designed around a managed cluster rather than one Discord bot process permanently tied to one computer.


Multiple GorBot Discord nodes can share Gateway work, remain ready to take over for one another, use RackNerd SQL as shared authoritative state, receive centralized software updates, participate in rolling maintenance, and report health back to a web-based control plane.
Multiple GorBot Discord nodes can share Gateway work, remain ready to take over for one another, use shared authoritative state, receive centrally managed software releases, and continue operating as one coordinated platform.


The result is a platform that can continue growing without treating a single Discord node as the permanent center of the system.
This architecture allows GorBot to grow without making one machine the permanent center of the Discord service.


<div style="margin:24px 0 6px 0; padding:20px 24px; background:#241813; border-left:4px solid #9e2f26; border-radius:4px;">
<div style="margin:24px 0 6px 0; padding:20px 24px; background:#241813; border-left:4px solid #9e2f26; border-radius:4px;">
<div style="font-size:19px; font-weight:bold; color:#e0b45d; margin-bottom:7px;">RackNerd is the control plane. Managed GorBot nodes are the workers.</div>
<div style="font-size:19px; font-weight:bold; color:#e0b45d; margin-bottom:7px;">The goal is continuity, not just duplication.</div>
The web platform, authoritative state, releases, backups, provisioning, and cluster coordination remain centralized while Discord Gateway work can move between managed nodes.
Running multiple nodes only matters if they can share state, divide work, detect failure, and take over real Discord connections when another node becomes unavailable.
</div>
</div>
</div>
</div>
Line 40: Line 40:
<div style="padding:30px 42px 10px 42px;">
<div style="padding:30px 42px 10px 42px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d; text-shadow:1px 1px 3px #000;">HOW THE CLUSTER IS ORGANIZED</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d; text-shadow:1px 1px 3px #000;">HOW THE PLATFORM IS ORGANIZED</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Different parts of the system have different responsibilities.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">The game world, Discord nodes, and shared web infrastructure serve different technical roles.</div>
</div>
</div>


Line 47: Line 47:
|-
|-
| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:21px; font-weight:bold;">RackNerd Control Plane</div>
<div style="font-size:21px; font-weight:bold;">Shared Web Infrastructure</div>
<div style="margin-top:9px; line-height:1.6;">Hosts the public GorBot website, [[Dashboard|Web Dashboard]], Admin Gateway, authoritative SQL state, cluster control, releases, backups, provisioning, runtime-secret vault, and private tooling.</div>
<div style="margin-top:9px; line-height:1.6;">RackNerd hosts the public GorBot web services, shared SQL state, releases, backups, provisioning services, and other central infrastructure that should remain independent of any one Discord node.</div>


| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:21px; font-weight:bold;">Managed Discord Nodes</div>
<div style="font-size:21px; font-weight:bold;">Managed Discord Nodes</div>
<div style="margin-top:9px; line-height:1.6;">Independent GorBot siblings run the Discord runtime, own assigned Gateway shards, maintain hot standby capability, process supported live-control work, and report health to the control plane.</div>
<div style="margin-top:9px; line-height:1.6;">Independent GorBot siblings run the Discord runtime, own assigned Gateway shards, maintain hot-standby capability, and report health back to the shared platform.</div>


| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:21px; font-weight:bold;">RunUO Game World</div>
<div style="font-size:21px; font-weight:bold;">RunUO Game World</div>
<div style="margin-top:9px; line-height:1.6;">The Gor Ultima RunUO server is part of the same overall ecosystem but is not a GorBot cluster sibling. Its game-side BridgeOnly role remains separate from the managed Discord node fleet.</div>
<div style="margin-top:9px; line-height:1.6;">The Gor Ultima RunUO server is part of the same overall ecosystem but is not a managed GorBot Discord sibling. Its game-side integration remains separate from the Discord node fleet.</div>
|}
|}
</div>
</div>
Line 68: Line 68:
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">HIGH AVAILABILITY</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">HIGH AVAILABILITY</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">The platform is designed so one node can fail without becoming the failure of the entire system.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">One failed node should not automatically mean GorBot is offline.</div>
</div>
</div>


<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
GorBot's managed cluster uses multiple independent Discord nodes so work can be redistributed when one node becomes unavailable.
GorBot uses multiple independent Discord nodes so active work can be redistributed when one node becomes unavailable.


The current cluster foundation includes:
The current high-availability model includes:


* automatic failover;
* automatic failover;
* weighted load sharing;
* weighted load sharing;
* gradual rebalancing;
* gradual rebalancing;
* hot standby behavior;
* hot-standby behavior;
* serialized rolling updates;
* heartbeat-based health monitoring;
* heartbeat-based health monitoring;
* centralized release management;
* centralized releases;
* centralized backups;
* centralized backups;
* managed node provisioning.
* managed node provisioning;
* rolling software updates.


The web control plane is intentionally hosted separately from the Discord nodes. That means RackNerd can remain available for administration even if every Discord node is temporarily offline.
The shared web infrastructure is intentionally separate from the Discord nodes so the broader platform does not disappear simply because one Discord machine fails.
</div>
</div>
</div>
</div>
Line 98: Line 98:
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">DISCORD GATEWAY SHARDS</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">DISCORD GATEWAY SHARDS</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Discord work is divided so it can be distributed between multiple managed nodes.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Discord work can be divided and distributed between healthy managed nodes.</div>
</div>
</div>


Line 104: Line 104:
The current GorBot cluster operates with '''4 Discord Gateway shards'''.
The current GorBot cluster operates with '''4 Discord Gateway shards'''.


Those shards can be divided among healthy managed nodes instead of all being forced onto one machine.
Those shards can be distributed between healthy nodes instead of all being forced onto one machine.


With two equally weighted active nodes, the expected distribution is approximately:
With two equally weighted nodes, the expected distribution is approximately:


'''100 / 100 → 2 shards / 2 shards'''
'''100 / 100 → 2 shards / 2 shards'''


A different weight can intentionally shift more work toward one node:
If one node is given a lower relative weight:


'''100 / 50 → approximately 3 shards / 1 shard'''
'''100 / 50 → approximately 3 shards / 1 shard'''


These weights are relative rather than absolute capacity percentages.
Weights influence relative workload and are not literal CPU percentages.
</div>
</div>
</div>
</div>
Line 126: Line 126:
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">WEIGHTED LOAD SHARING</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">WEIGHTED LOAD SHARING</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Not every node has to carry the same amount of Discord work.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Different machines can carry different amounts of Discord work.</div>
</div>
</div>


Line 137: Line 137:
| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:21px; font-weight:bold;">Unequal Weight</div>
<div style="font-size:21px; font-weight:bold;">Unequal Weight</div>
<div style="margin-top:9px; line-height:1.6;">A stronger or preferred node can receive a larger relative weight so it normally carries more Gateway work.</div>
<div style="margin-top:9px; line-height:1.6;">A preferred or more capable node can receive a higher relative weight so it normally carries more Gateway work.</div>


| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:21px; font-weight:bold;">Weight 0 Standby</div>
<div style="font-size:21px; font-weight:bold;">Weight 0 Standby</div>
<div style="margin-top:9px; line-height:1.6;">A healthy node can remain fully started with weight 0 and no normal shard assignment, ready to participate when failover or configuration changes require it.</div>
<div style="margin-top:9px; line-height:1.6;">A healthy node can remain fully started with no normal shard assignment while staying ready to participate when failover or configuration changes require it.</div>
|}
|}
</div>
</div>
Line 153: Line 153:
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">HOT STANDBY</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">HOT STANDBY</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Standby does not have to mean shut down.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Standby capacity can remain ready without opening duplicate Discord sessions.</div>
</div>
</div>


Line 159: Line 159:
A healthy GorBot node can remain fully started even when it currently owns no Discord Gateway shards.
A healthy GorBot node can remain fully started even when it currently owns no Discord Gateway shards.


A hot standby node can keep:
A hot-standby node can keep:


* its node agent running;
* its node agent running;
* the GorBot process running;
* the GorBot process running;
* the DiscordBot runtime loaded;
* the DiscordBot runtime loaded;
* secrets validated;
* runtime configuration validated;
* cluster communication active;
* cluster communication active;
* update capability active;
* update capability available.
* backup and rollback support available.


Only assigned Discord Gateway shards open sessions.
Only assigned Discord Gateway shards open active Discord sessions.


This reduces takeover delay while avoiding duplicate Gateway ownership.
This makes standby capacity ready for takeover without creating duplicate shard ownership.
</div>
</div>
</div>
</div>
Line 183: Line 182:
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#b65a50;">FAILOVER</div>
<div style="font-size:28px; font-weight:bold; color:#b65a50;">FAILOVER</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Reassigning work is only the first half of a successful takeover.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Moving an assignment is not enough — the replacement connection has to work.</div>
</div>
</div>


Line 189: Line 188:
The current cluster uses an Agent heartbeat of approximately '''10 seconds''' and an offline threshold of approximately '''45 seconds'''.
The current cluster uses an Agent heartbeat of approximately '''10 seconds''' and an offline threshold of approximately '''45 seconds'''.


When a node is considered unavailable, the control plane can reassign its Gateway shards to healthy capacity.
When a node is considered unavailable, its Gateway shards can be reassigned to healthy capacity.


However, GorBot does '''not''' treat shard ownership alone as proof of successful failover.
However, GorBot does '''not''' treat shard ownership alone as proof of successful failover.


A real takeover must also show that the replacement Discord sessions actually connected.
A successful takeover should include:
 
Successful failover should include:


* Agent heartbeat present;
* Agent heartbeat present;
Line 205: Line 202:
* visible online behavior in the affected Discord communities.
* visible online behavior in the affected Discord communities.


<div style="margin-top:16px; color:#c9bba6; font-style:italic;">A scheduler saying “this node owns shard 3” is not enough if shard 3 never reaches Discord READY.</div>
<div style="margin-top:16px; color:#c9bba6; font-style:italic;">A shard being assigned to a node is not the same as that shard actually being connected to Discord.</div>
</div>
</div>
</div>
</div>
Line 216: Line 213:
<div style="padding:30px 42px 10px 42px;">
<div style="padding:30px 42px 10px 42px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">HEALTH IS MORE THAN “ONLINE”</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">MULTI-LAYER HEALTH</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Different layers of the node can be healthy or unhealthy independently.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">A reliable node must be healthy at more than one level.</div>
</div>
</div>


Line 224: Line 221:
| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:21px; font-weight:bold;">Agent Online</div>
<div style="font-size:21px; font-weight:bold;">Agent Online</div>
<div style="margin-top:9px; line-height:1.6;">The managed node agent is alive and communicating with the control plane.</div>
<div style="margin-top:9px; line-height:1.6;">The managed node agent is alive and still communicating with the shared platform.</div>


| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:21px; font-weight:bold;">Bot Running</div>
<div style="font-size:21px; font-weight:bold;">Bot Running</div>
<div style="margin-top:9px; line-height:1.6;">The GorBot child process is running on the node and its runtime has started.</div>
<div style="margin-top:9px; line-height:1.6;">The GorBot process is running and its runtime has started successfully.</div>


| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:33.33%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:21px; font-weight:bold;">Discord READY</div>
<div style="font-size:21px; font-weight:bold;">Discord READY</div>
<div style="margin-top:9px; line-height:1.6;">The assigned Discord Gateway sessions actually connected and reached a healthy Discord state.</div>
<div style="margin-top:9px; line-height:1.6;">Assigned Gateway sessions have actually connected and reached a usable Discord state.</div>
|-
|-


| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:21px; font-weight:bold;">Assigned vs Connected Shards</div>
<div style="font-size:21px; font-weight:bold;">Assigned vs Connected Shards</div>
<div style="margin-top:9px; line-height:1.6;">The control plane can compare how many shards a node should own with how many are actually connected.</div>
<div style="margin-top:9px; line-height:1.6;">The system can distinguish how many shards a node should own from how many are actually connected.</div>


| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:21px; font-weight:bold;">Heartbeat ACK</div>
<div style="font-size:21px; font-weight:bold;">Heartbeat ACK</div>
<div style="margin-top:9px; line-height:1.6;">Per-shard Gateway heartbeat acknowledgement helps show that a connected session is still communicating properly with Discord.</div>
<div style="margin-top:9px; line-height:1.6;">Per-shard heartbeat acknowledgements help confirm that connected Gateway sessions remain responsive.</div>
|}
|}
</div>
</div>
Line 253: Line 250:
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">SHARED AUTHORITATIVE STATE</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">SHARED AUTHORITATIVE STATE</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">The cluster should share one source of truth instead of becoming several unrelated copies of the bot.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Multiple nodes should still behave like one service.</div>
</div>
</div>


<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
RackNerd SQL is the authoritative shared state for the managed GorBot platform.
RackNerd SQL acts as the authoritative shared state for the managed GorBot platform.


This allows important DiscordBot state to remain shared even when requests are processed by different healthy nodes.
This allows important persistent data to remain consistent even when requests are handled by different healthy nodes.


The cluster does not depend on one node's local cache being the permanent source of truth.
Shared state is especially important for systems such as:
 
This shared-state model is especially important for systems such as:


* [[Character System|Characters & Profiles]];
* [[Character System|Characters & Profiles]];
* [[NPC Database]];
* [[NPC Database]];
* community features;
* community configuration;
* persistent DiscordBot configuration;
* persistent DiscordBot state;
* other state that must survive node replacement or failover.
* other data that must survive node replacement or failover.


Local runtime caching can still be used for performance, while authoritative persistence remains centralized.
Local runtime caching can still improve performance, but authoritative persistence remains centralized.
</div>
</div>
</div>
</div>
Line 277: Line 272:


<!-- ========================================================= -->
<!-- ========================================================= -->
<!-- DASHBOARD RELAY -->
<!-- WEB CONTROL -->
<!-- ========================================================= -->
<!-- ========================================================= -->


<div style="padding:30px 42px 10px 42px;">
<div style="padding:30px 42px 10px 42px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">HIGH-AVAILABILITY DASHBOARD CONTROL</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">WEB-BASED CONTROL</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">The [[Dashboard|Web Dashboard]] can reach live Discord runtime functions without depending on one fixed machine.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">The [[Dashboard|Web Dashboard]] can work with live GorBot services without depending permanently on one fixed Discord machine.</div>
</div>
</div>


<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
GorBot uses an outbound managed relay model for live dashboard control.
Some web-based GorBot features need to communicate with the live Discord runtime.
 
Healthy shard-owning nodes participate in the fast relay pool, while healthy non-owner nodes can remain lower-frequency standby relays.
 
This allows the web dashboard to perform supported live Discord actions without exposing a public inbound management port on every GorBot machine.


The scalable relay model distinguishes:
The modern infrastructure supports this through managed outbound communication between healthy Discord nodes and the shared web platform.


* '''Dashboard Relay Ready''' — active fast relay;
This allows supported live web actions to continue using healthy cluster capacity rather than being permanently tied to a single node.
* '''Dashboard Relay Standby''' — healthy scalable standby;
* '''Waiting / Recovery''' — relay state that actually needs recovery.


A standby node can be promoted to the fast relay tier when it receives Discord shards.
The design also avoids requiring every managed Discord node to expose a public inbound management service for normal web control.
</div>
</div>
</div>
</div>
Line 311: Line 300:
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">CENTRALIZED UPDATES</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">CENTRALIZED UPDATES</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">A cluster is easier to maintain when nodes do not have to be updated one machine at a time by hand.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Managed nodes can receive coordinated software updates without rebuilding every machine manually.</div>
</div>
</div>


Line 318: Line 307:
| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:21px; font-weight:bold;">Managed Agent Updates</div>
<div style="font-size:21px; font-weight:bold;">Managed Agent Updates</div>
<div style="margin-top:9px; line-height:1.6;">The node-management runtime can be updated centrally. Version-aware deployment skips matching versions unless a reinstall is intentionally requested.</div>
<div style="margin-top:9px; line-height:1.6;">The node-management runtime can be updated centrally and independently from the Discord application itself.</div>


| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:21px; font-weight:bold;">NodeApp Updates</div>
<div style="font-size:21px; font-weight:bold;">NodeApp Updates</div>
<div style="margin-top:9px; line-height:1.6;">Approved GorBot NodeApp releases can be uploaded centrally and rolled through managed nodes in a controlled sequence.</div>
<div style="margin-top:9px; line-height:1.6;">Approved GorBot NodeApp releases can be distributed to managed nodes as their own application release stream.</div>
|}
|}


<div style="margin:0 12px; padding:22px 26px; background:#241813; border:1px solid #6a4b2d; border-left:4px solid #9e2f26; border-radius:6px;">
<div style="margin:0 12px; padding:22px 26px; background:#241813; border:1px solid #6a4b2d; border-left:4px solid #9e2f26; border-radius:6px;">
<div style="font-size:22px; font-weight:bold;">Agent and NodeApp versions are separate component streams.</div>
<div style="font-size:22px; font-weight:bold;">Agent and NodeApp versions are separate components.</div>
<div style="margin-top:9px; line-height:1.7;">Updating the managed node runtime does not automatically mean the DiscordBot application itself changed, and a NodeApp release does not require changing the RunUO game-side BridgeOnly installation.</div>
<div style="margin-top:9px; line-height:1.7;">Updating one does not automatically imply that the other changed, and standalone GorBot node updates do not automatically require updating the RunUO game-side BridgeOnly installation.</div>
</div>
</div>
</div>
</div>
Line 338: Line 327:
<div style="padding:30px 42px 10px 42px;">
<div style="padding:30px 42px 10px 42px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">SERIALIZED ROLLING MAINTENANCE</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">ROLLING MAINTENANCE</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Update one managed node while healthy capacity continues carrying the service.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Update nodes in sequence while healthy capacity continues carrying service.</div>
</div>
</div>


<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
GorBot's managed update system performs serialized fleet updates rather than intentionally restarting every node at the same time.
GorBot's managed update model supports serialized rolling deployment rather than intentionally restarting every node at once.


A controlled rolling update can:
A controlled update can:


* select one node;
* prepare one node;
* drain or prepare it as required;
* apply the update;
* apply the update;
* verify that it returns;
* verify that it returns;
* continue to the next managed node.
* continue to the next node.


The system is also designed to refuse unsafe rolling-update behavior when sufficient redundancy is not available.
This helps reduce service interruption while allowing the fleet to move forward together.
</div>
</div>
</div>
</div>
Line 365: Line 353:
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">BACKUPS AND ROLLBACK</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">BACKUPS AND ROLLBACK</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Reliability includes recovering from a bad update, not only surviving a failed machine.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Reliability also means being able to recover from a bad update.</div>
</div>
</div>


Line 371: Line 359:
The managed platform includes centralized backup and rollback support.
The managed platform includes centralized backup and rollback support.


The current operating policy includes scheduled backups and retained rollback history so a deployment problem does not automatically become permanent.
Scheduled backups and retained release history provide recovery options when an update or local node problem causes unexpected behavior.


Release retention and backup retention are intentionally managed separately, giving administrators both software rollback options and node-level recovery history.
This complements failover:
 
* failover handles loss of active service capacity;
* rollback handles bad software or broken deployment state.
</div>
</div>
</div>
</div>
Line 384: Line 375:
<div style="padding:30px 42px 10px 42px;">
<div style="padding:30px 42px 10px 42px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">GENERATED MANAGED NODES</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">MANAGED NODE PROVISIONING</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Adding capacity should become a repeatable deployment process rather than a custom installation project every time.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Adding capacity should be repeatable instead of becoming a custom installation project every time.</div>
</div>
</div>


<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
The Admin Gateway can generate managed GorBot node packages for supported deployment modes.
GorBot supports generated managed-node packages intended to simplify deployment.


The generated-node model is designed around a near-turnkey process:
The design goal is a near-turnkey process:


# generate a node;
# generate a node package;
# download the package;
# download it;
# extract it;
# extract it;
# start it;
# start it;
# allow the node to enroll and retrieve its approved runtime configuration;
# allow the node to enroll and retrieve its approved runtime configuration;
# verify Agent, Bot, Relay, and Discord health.
# verify Agent, Bot, and Discord health.


Supported deployment work has included:
Supported deployment work has included:
Line 406: Line 397:
* Docker.
* Docker.


A generated node uses its own managed credential and should run only one execution mode at a time.
Each generated node uses its own managed credential and should only run one execution mode at a time.
</div>
</div>
</div>
</div>
Line 417: Line 408:
<div style="padding:30px 42px 10px 42px;">
<div style="padding:30px 42px 10px 42px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">SECURE PROVISIONING AND CONTROL</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">SECURE PROVISIONING AND RUNTIME CONFIGURATION</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Infrastructure automation should not require placing long-lived secrets inside public downloads.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">Managed deployment should not require placing long-lived secrets inside reusable downloads or runtime images.</div>
</div>
</div>


<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
Managed nodes enroll through the cluster and retrieve the runtime information they require through authenticated provisioning paths.
Managed nodes enroll through authenticated cluster services and retrieve the runtime information they require through protected provisioning paths.
 
Private tooling and runtime secrets remain protected by the control plane rather than being treated as public website assets.
 
The generated-node design avoids embedding long-lived secrets inside reusable runtime images.
 
The modern dashboard-control model also uses outbound authenticated relay communication so managed nodes do not need a publicly exposed inbound management port for normal dashboard control.
</div>
</div>
 
 
<!-- ========================================================= -->
<!-- WEB SURVIVES NODES -->
<!-- ========================================================= -->
 
<div style="padding:30px 42px 10px 42px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">THE WEB PLATFORM IS NOT THE DISCORD NODE</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">The management plane should remain reachable even during Discord-node outages.</div>
</div>
 
<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
One of the most important design choices in GorBot is keeping RackNerd's control plane separate from the managed Discord-node fleet.
 
If a Discord node is offline, the Admin Gateway can still report the failure.


If multiple Discord nodes are offline, the control plane can still retain shared state, releases, backups, diagnostics, provisioning, and management information.
Private tooling and runtime secrets remain protected rather than being treated as public web assets.


Even if every Discord node were temporarily unavailable, RackNerd is intended to remain the place from which the platform can be inspected and recovered.
The generated-node model is designed so reusable runtime packages and container images do not need to contain long-lived production secrets.
</div>
</div>
</div>
</div>
Line 456: Line 423:


<!-- ========================================================= -->
<!-- ========================================================= -->
<!-- NODE REMOVAL -->
<!-- WEB INDEPENDENCE -->
<!-- ========================================================= -->
<!-- ========================================================= -->


<div style="padding:30px 42px 10px 42px;">
<div style="padding:30px 42px 10px 42px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">DRAIN, REMOVE, AND REPLACE</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">THE SHARED WEB PLATFORM IS INDEPENDENT OF THE DISCORD NODES</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">A reliable cluster also needs a safe way to retire machines.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">The web layer should remain available even during Discord-node outages.</div>
</div>
</div>


<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
A managed node should normally be drained before removal.
One of the most important architectural choices in GorBot is keeping shared web services separate from the managed Discord-node fleet.


The intended retirement process is:
If one Discord node fails, the shared platform remains available.


# drain the node;
If several Discord nodes fail, shared SQL state, releases, backups, and web services remain independent of those individual machines.
# wait for assigned shards to reach zero;
# verify replacement shards are actually connected and READY elsewhere;
# stop the retiring node if it is being physically removed;
# revoke its credentials;
# remove the node from the control plane;
# generate a clean replacement when needed;
# restore the desired weight after qualification.


This prevents administrative cleanup from being mistaken for a successful service handoff.
This keeps recovery and continuity from depending on the same node that just failed.
</div>
</div>
</div>
</div>
Line 490: Line 450:
<div style="padding:30px 42px 10px 42px;">
<div style="padding:30px 42px 10px 42px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">DESIGNED TO SCALE BEYOND TWO NODES</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">BUILT TO GROW</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">The current fleet may be small, but the control model is designed with larger fleets in mind.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">The infrastructure should remain practical as more managed nodes are added.</div>
</div>
</div>


<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
<div style="padding:24px 28px; background:#211712; border:1px solid #5f452e; border-radius:7px; line-height:1.8;">
GorBot's relay and cluster behavior has been designed so adding more standby capacity does not require every node to behave like an active Discord shard owner.
The GorBot cluster model is designed so additional managed nodes can add capacity, redundancy, or standby coverage without changing the basic service model.


Fast relay work is concentrated on the nodes that need it, while healthy non-owner capacity can remain in a lower-frequency standby tier until promoted.
A larger fleet can include active shard-owning nodes and healthy standby capacity.


This helps the architecture remain practical if the managed fleet grows from a small qualification pair into a much larger collection of Windows, Linux, or containerized nodes.
This allows the platform to grow from a small number of qualification nodes into a larger mixed fleet of Windows, Linux, or containerized systems while still sharing one authoritative state and one coordinated Discord service.
</div>
</div>
</div>
</div>
Line 519: Line 479:
The RunUO server provides the persistent game world.
The RunUO server provides the persistent game world.


GorBot's managed infrastructure provides the Discord cluster, web dashboard, shared state, automation, roleplay profiles, NPC systems, administration, and high-availability services around that community.
GorBot's managed infrastructure provides the Discord cluster, web services, shared state, automation, roleplay profiles, NPC systems, and the high-availability services surrounding the community.


The RunUO server is '''not''' a GorBot Discord sibling and should not be treated as one merely because game-side integration exists.
The RunUO server itself is '''not''' a managed GorBot Discord sibling.
</div>
</div>
</div>
</div>
Line 533: Line 493:
<div style="text-align:center; margin-bottom:24px;">
<div style="text-align:center; margin-bottom:24px;">
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">COMMON QUESTIONS</div>
<div style="font-size:28px; font-weight:bold; color:#e0b45d;">COMMON QUESTIONS</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">A support-ready starting point for understanding the GorBot cluster.</div>
<div style="margin-top:6px; color:#a99a87; font-style:italic;">A quick guide to the GorBot cluster model.</div>
</div>
</div>


Line 540: Line 500:
| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:20px; font-weight:bold;">What happens if one GorBot node goes offline?</div>
<div style="font-size:20px; font-weight:bold;">What happens if one GorBot node goes offline?</div>
<div style="margin-top:8px; line-height:1.6;">After the node is considered offline, healthy capacity can be assigned its Gateway shards. The takeover is only considered successful when those replacement shards actually connect to Discord and reach READY.</div>
<div style="margin-top:8px; line-height:1.6;">Healthy capacity can be assigned its Gateway shards. The takeover is only considered successful when those replacement shards actually connect to Discord and reach READY.</div>


| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:20px; font-weight:bold;">Does every node need the same weight?</div>
<div style="font-size:20px; font-weight:bold;">Does every node need the same weight?</div>
<div style="margin-top:8px; line-height:1.6;">No. Weights are relative and can be used to prefer one node, balance two nodes equally, or keep a node at weight 0 as hot standby.</div>
<div style="margin-top:8px; line-height:1.6;">No. Weights are relative and can be used to balance nodes equally, prefer one node, or keep a node at weight 0 as hot standby.</div>
|-
|-


| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:20px; font-weight:bold;">Does “Online” mean Discord is healthy?</div>
<div style="font-size:20px; font-weight:bold;">Does “Online” automatically mean Discord is healthy?</div>
<div style="margin-top:8px; line-height:1.6;">Not by itself. Agent heartbeat, bot process state, Discord READY, connected shard count, and Gateway heartbeat acknowledgements all matter.</div>
<div style="margin-top:8px; line-height:1.6;">No. Agent heartbeat, bot process state, Discord READY, connected shard count, and Gateway heartbeat acknowledgements all matter.</div>


| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:20px; font-weight:bold;">Can the dashboard remain available if the Discord nodes fail?</div>
<div style="font-size:20px; font-weight:bold;">Can the web platform stay available if a Discord node fails?</div>
<div style="margin-top:8px; line-height:1.6;">Yes. RackNerd is intentionally the independent web/control plane and is designed to remain available even if the managed Discord fleet is temporarily offline.</div>
<div style="margin-top:8px; line-height:1.6;">Yes. Shared web services and authoritative state are intentionally hosted independently from any one managed Discord node.</div>
|-
|-


| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:20px; font-weight:bold;">Is the RunUO server one of the GorBot nodes?</div>
<div style="font-size:20px; font-weight:bold;">Is the RunUO server one of the GorBot Discord nodes?</div>
<div style="margin-top:8px; line-height:1.6;">No. The game server is part of the same Gor Ultima ecosystem, but the RunUO server itself is not a managed GorBot Discord sibling.</div>
<div style="margin-top:8px; line-height:1.6;">No. It is part of the same Gor Ultima ecosystem, but the game server itself is not a managed GorBot Discord sibling.</div>


| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
| style="width:50%; vertical-align:top; padding:22px; background:#211712; border:1px solid #5f452e; border-radius:6px;" |
<div style="font-size:20px; font-weight:bold;">Can updates be applied centrally?</div>
<div style="font-size:20px; font-weight:bold;">Can GorBot nodes be updated centrally?</div>
<div style="margin-top:8px; line-height:1.6;">Yes. Managed Agent and NodeApp updates can be coordinated centrally and applied through serialized rolling deployment.</div>
<div style="margin-top:8px; line-height:1.6;">Yes. Managed Agent and NodeApp releases can be coordinated centrally and rolled through the fleet in sequence.</div>
|}
|}
</div>
</div>
Line 574: Line 534:
<div style="font-size:25px; font-weight:bold; color:#e1bf7a;">A community platform should be able to outlive the machine that happens to be running it today.</div>
<div style="font-size:25px; font-weight:bold; color:#e1bf7a;">A community platform should be able to outlive the machine that happens to be running it today.</div>
<div style="margin-top:10px; font-size:17px; color:#c9bba6;">Managed nodes. Shared state. Hot standby. Failover. Weighted load. Central updates. Backups. Web control.</div>
<div style="margin-top:10px; font-size:17px; color:#c9bba6;">Managed nodes. Shared state. Hot standby. Failover. Weighted load. Central updates. Backups. Web control.</div>
<div style="margin-top:16px; font-size:14px; color:#998b79; font-style:italic;">GorBot's cluster foundation is built so the platform can grow, recover, and be maintained without depending on one permanent Discord machine.</div>
<div style="margin-top:16px; font-size:14px; color:#998b79; font-style:italic;">GorBot's infrastructure is built so the platform can grow, recover, and remain maintainable without depending on one permanent Discord machine.</div>
</div>
</div>


</div>
</div>
</div>
</div>

Latest revision as of 02:43, 17 August 2026



RELIABLE INFRASTRUCTURE
Multiple managed Discord nodes, shared authoritative state, failover, load sharing, centralized updates, and web-based control built to grow beyond one machine.


Built Beyond a Single Discord Machine

Modern GorBot infrastructure is designed around a managed cluster rather than one Discord bot process permanently tied to one computer.

Multiple GorBot Discord nodes can share Gateway work, remain ready to take over for one another, use shared authoritative state, receive centrally managed software releases, and continue operating as one coordinated platform.

This architecture allows GorBot to grow without making one machine the permanent center of the Discord service.

The goal is continuity, not just duplication.

Running multiple nodes only matters if they can share state, divide work, detect failure, and take over real Discord connections when another node becomes unavailable.


HOW THE PLATFORM IS ORGANIZED
The game world, Discord nodes, and shared web infrastructure serve different technical roles.
Shared Web Infrastructure
RackNerd hosts the public GorBot web services, shared SQL state, releases, backups, provisioning services, and other central infrastructure that should remain independent of any one Discord node.
Managed Discord Nodes
Independent GorBot siblings run the Discord runtime, own assigned Gateway shards, maintain hot-standby capability, and report health back to the shared platform.
RunUO Game World
The Gor Ultima RunUO server is part of the same overall ecosystem but is not a managed GorBot Discord sibling. Its game-side integration remains separate from the Discord node fleet.


HIGH AVAILABILITY
One failed node should not automatically mean GorBot is offline.

GorBot uses multiple independent Discord nodes so active work can be redistributed when one node becomes unavailable.

The current high-availability model includes:

  • automatic failover;
  • weighted load sharing;
  • gradual rebalancing;
  • hot-standby behavior;
  • heartbeat-based health monitoring;
  • centralized releases;
  • centralized backups;
  • managed node provisioning;
  • rolling software updates.

The shared web infrastructure is intentionally separate from the Discord nodes so the broader platform does not disappear simply because one Discord machine fails.


DISCORD GATEWAY SHARDS
Discord work can be divided and distributed between healthy managed nodes.

The current GorBot cluster operates with 4 Discord Gateway shards.

Those shards can be distributed between healthy nodes instead of all being forced onto one machine.

With two equally weighted nodes, the expected distribution is approximately:

100 / 100 → 2 shards / 2 shards

If one node is given a lower relative weight:

100 / 50 → approximately 3 shards / 1 shard

Weights influence relative workload and are not literal CPU percentages.


WEIGHTED LOAD SHARING
Different machines can carry different amounts of Discord work.
Equal Weight
Nodes with the same weight are candidates for approximately equal shard distribution.
Unequal Weight
A preferred or more capable node can receive a higher relative weight so it normally carries more Gateway work.
Weight 0 Standby
A healthy node can remain fully started with no normal shard assignment while staying ready to participate when failover or configuration changes require it.


HOT STANDBY
Standby capacity can remain ready without opening duplicate Discord sessions.

A healthy GorBot node can remain fully started even when it currently owns no Discord Gateway shards.

A hot-standby node can keep:

  • its node agent running;
  • the GorBot process running;
  • the DiscordBot runtime loaded;
  • runtime configuration validated;
  • cluster communication active;
  • update capability available.

Only assigned Discord Gateway shards open active Discord sessions.

This makes standby capacity ready for takeover without creating duplicate shard ownership.


FAILOVER
Moving an assignment is not enough — the replacement connection has to work.

The current cluster uses an Agent heartbeat of approximately 10 seconds and an offline threshold of approximately 45 seconds.

When a node is considered unavailable, its Gateway shards can be reassigned to healthy capacity.

However, GorBot does not treat shard ownership alone as proof of successful failover.

A successful takeover should include:

  • Agent heartbeat present;
  • GorBot process running;
  • Discord Gateway READY;
  • assigned shard count;
  • connected shard count;
  • recent per-shard heartbeat acknowledgement;
  • visible online behavior in the affected Discord communities.
A shard being assigned to a node is not the same as that shard actually being connected to Discord.


MULTI-LAYER HEALTH
A reliable node must be healthy at more than one level.
Agent Online
The managed node agent is alive and still communicating with the shared platform.
Bot Running
The GorBot process is running and its runtime has started successfully.
Discord READY
Assigned Gateway sessions have actually connected and reached a usable Discord state.
Assigned vs Connected Shards
The system can distinguish how many shards a node should own from how many are actually connected.
Heartbeat ACK
Per-shard heartbeat acknowledgements help confirm that connected Gateway sessions remain responsive.


SHARED AUTHORITATIVE STATE
Multiple nodes should still behave like one service.

RackNerd SQL acts as the authoritative shared state for the managed GorBot platform.

This allows important persistent data to remain consistent even when requests are handled by different healthy nodes.

Shared state is especially important for systems such as:

Local runtime caching can still improve performance, but authoritative persistence remains centralized.


WEB-BASED CONTROL
The Web Dashboard can work with live GorBot services without depending permanently on one fixed Discord machine.

Some web-based GorBot features need to communicate with the live Discord runtime.

The modern infrastructure supports this through managed outbound communication between healthy Discord nodes and the shared web platform.

This allows supported live web actions to continue using healthy cluster capacity rather than being permanently tied to a single node.

The design also avoids requiring every managed Discord node to expose a public inbound management service for normal web control.


CENTRALIZED UPDATES
Managed nodes can receive coordinated software updates without rebuilding every machine manually.
Managed Agent Updates
The node-management runtime can be updated centrally and independently from the Discord application itself.
NodeApp Updates
Approved GorBot NodeApp releases can be distributed to managed nodes as their own application release stream.
Agent and NodeApp versions are separate components.
Updating one does not automatically imply that the other changed, and standalone GorBot node updates do not automatically require updating the RunUO game-side BridgeOnly installation.


ROLLING MAINTENANCE
Update nodes in sequence while healthy capacity continues carrying service.

GorBot's managed update model supports serialized rolling deployment rather than intentionally restarting every node at once.

A controlled update can:

  • prepare one node;
  • apply the update;
  • verify that it returns;
  • continue to the next node.

This helps reduce service interruption while allowing the fleet to move forward together.


BACKUPS AND ROLLBACK
Reliability also means being able to recover from a bad update.

The managed platform includes centralized backup and rollback support.

Scheduled backups and retained release history provide recovery options when an update or local node problem causes unexpected behavior.

This complements failover:

  • failover handles loss of active service capacity;
  • rollback handles bad software or broken deployment state.


MANAGED NODE PROVISIONING
Adding capacity should be repeatable instead of becoming a custom installation project every time.

GorBot supports generated managed-node packages intended to simplify deployment.

The design goal is a near-turnkey process:

  1. generate a node package;
  2. download it;
  3. extract it;
  4. start it;
  5. allow the node to enroll and retrieve its approved runtime configuration;
  6. verify Agent, Bot, and Discord health.

Supported deployment work has included:

  • Windows bare metal;
  • Ubuntu/Linux bare metal;
  • Docker.

Each generated node uses its own managed credential and should only run one execution mode at a time.


SECURE PROVISIONING AND RUNTIME CONFIGURATION
Managed deployment should not require placing long-lived secrets inside reusable downloads or runtime images.

Managed nodes enroll through authenticated cluster services and retrieve the runtime information they require through protected provisioning paths.

Private tooling and runtime secrets remain protected rather than being treated as public web assets.

The generated-node model is designed so reusable runtime packages and container images do not need to contain long-lived production secrets.


THE SHARED WEB PLATFORM IS INDEPENDENT OF THE DISCORD NODES
The web layer should remain available even during Discord-node outages.

One of the most important architectural choices in GorBot is keeping shared web services separate from the managed Discord-node fleet.

If one Discord node fails, the shared platform remains available.

If several Discord nodes fail, shared SQL state, releases, backups, and web services remain independent of those individual machines.

This keeps recovery and continuity from depending on the same node that just failed.


BUILT TO GROW
The infrastructure should remain practical as more managed nodes are added.

The GorBot cluster model is designed so additional managed nodes can add capacity, redundancy, or standby coverage without changing the basic service model.

A larger fleet can include active shard-owning nodes and healthy standby capacity.

This allows the platform to grow from a small number of qualification nodes into a larger mixed fleet of Windows, Linux, or containerized systems while still sharing one authoritative state and one coordinated Discord service.


INFRASTRUCTURE IN THE GOR ULTIMA ECOSYSTEM
One project, with clear technical boundaries between the game world and the managed Discord fleet.

Gor Ultima and GorBot are part of the same overall project and ecosystem.

The RunUO server provides the persistent game world.

GorBot's managed infrastructure provides the Discord cluster, web services, shared state, automation, roleplay profiles, NPC systems, and the high-availability services surrounding the community.

The RunUO server itself is not a managed GorBot Discord sibling.


COMMON QUESTIONS
A quick guide to the GorBot cluster model.
What happens if one GorBot node goes offline?
Healthy capacity can be assigned its Gateway shards. The takeover is only considered successful when those replacement shards actually connect to Discord and reach READY.
Does every node need the same weight?
No. Weights are relative and can be used to balance nodes equally, prefer one node, or keep a node at weight 0 as hot standby.
Does “Online” automatically mean Discord is healthy?
No. Agent heartbeat, bot process state, Discord READY, connected shard count, and Gateway heartbeat acknowledgements all matter.
Can the web platform stay available if a Discord node fails?
Yes. Shared web services and authoritative state are intentionally hosted independently from any one managed Discord node.
Is the RunUO server one of the GorBot Discord nodes?
No. It is part of the same Gor Ultima ecosystem, but the game server itself is not a managed GorBot Discord sibling.
Can GorBot nodes be updated centrally?
Yes. Managed Agent and NodeApp releases can be coordinated centrally and rolled through the fleet in sequence.


A community platform should be able to outlive the machine that happens to be running it today.
Managed nodes. Shared state. Hot standby. Failover. Weighted load. Central updates. Backups. Web control.
GorBot's infrastructure is built so the platform can grow, recover, and remain maintainable without depending on one permanent Discord machine.