- Joined
- Apr 25, 2009
- Messages
- 12
- Reaction score
- 9
Hi There,
I am the Original Project Manager of the RoseZA server WAY WAY back a million years ago... And I stepped away from the Project to work on my other passion, Linux Development which has been very fun... ( you can check it out here :
To view the content, you need to sign in or register
) I am also the creator of Electra AI ( check it out here
To view the content, you need to sign in or register
).RoseZA was an Evo project, and it is sad to see the state of the project and how badly it has degraded by those it was entrusted to continue, it looks like a bulldozer went through this project.
I intend to revive it, not only revive it but make it awesome again...
Public Repository :
To view the content, you need to sign in or register
I have recently started working on it again, a lot of things need fixing and I am in the process of doing just that. But i will also be adding some more fun stuff... like :
AI Player Bots :
The PlayerBot AI system designed for the ROSE Online server :
Architecture & Resource Optimization
To ensure the server's resource footprint does not skyrocket:- Socket-less World Injection:
- Bots are instantiated as authentic CPlayer objects and added to CMap:
layerList. - Each bot is assigned a dummy CClientSocket with isActive = false and sock = INVALID_SOCKET. Whenever packet broadcasting functions send packets to the bot, SendPacket() immediately exits, avoiding network sockets, buffers, and system calls.
- Bots are instantiated as authentic CPlayer objects and added to CMap:
- Zero Extra OS Threads:
- Bots run synchronously inside the server's existing MapProcess loop while MapMutex and PlayerMutex are held.
- Bot AI decision cycles are throttled to 500ms ticks (CLOCKS_PER_SEC / 2), preventing unnecessary CPU cycles while keeping bot movement and combat smooth.
- Database Integrity:
- Bot characters are flagged with is_bot = true. CPlayer::savedata() immediately returns for bots, preventing dummy records from polluting MySQL character tables.
- Seamless World Integration:
- Because bots exist in map->PlayerList, existing monsters' AIP aggro detection naturally detects bots, attacks them, and awards exp/drops when defeated.
- Visible real players automatically receive standard spawn (0x793), movement (0x79a), and combat (0x798) packets.
Core State Machine (
- BOT_STATE_IDLE: Scans surroundings for low HP/MP, nearby loot drops, or hostile monsters.
- BOT_STATE_ROAM: Wanders within an anchor radius looking for monsters or items with stuck detection and recovery.
- BOT_STATE_COMBAT: Closes in on targets, triggers normal auto-attacks, and defends itself when aggroed.
- BOT_STATE_LOOT: Approaches dropped Zulies or items, picks them up into its inventory, and chains to next nearby drops.
- BOT_STATE_REST: Sits down (Stance = 1) when HP < 40% or MP < 30% for 3× regeneration speed until reaching 95%.
- BOT_STATE_FOLLOW: Follows the GM/leader player, assists the leader in combat, and teleports if too far away (> 50 units).
- BOT_STATE_DEAD: Upon defeat, waits 5 seconds and revives with full HP/MP at its spawn anchor.
- Auto-Progression: Automatically spends stat points on level up based on class archetype (Soldier: STR/CON, Muse: INT/SEN, Hawker: DEX/SEN, Dealer: CON/SEN).
Currently working on :
- Dynamic World Spawner: Automatically spawns 8–10 bots around any player within ±4±4 levels.
- Auto-Accept Party Invites: Bots accept group invites, follow the leader, and assist in combat.
- Class Spells & Level-Tiered Gear: Bots cast class skills/spells in combat and wear gear matching their level.
And this is only the Begining....
Also a Million bugs to fix... (and im not even joking, probably is a million.... combat system, stat system, quests, zones... there is a lot of work here to be done, and im already quite far along with those ), then add some cool stuff ( already in the works )...
I should have some stuff ready in the coming weeks for people to play with... you are welcome to follow this thread. feel free to comment and put in any requests below...
And btw, I will not be calling this RoseZA this time around, i'm still pondering a new name to use....
PS. As for Source Code, I know everyone is gonna ask about it so ill address it now... this is a tough one, the non AI stuff i can release, the AI stuff is a different story... So ill address that when we get to that bridge... for now I'm just having fun getting this stuff off the ground again.
ill post some more info as it becomes available, maybe a couple of videos as well ...
To be clear, my work will mostly just be server side. Ill only touch the client if i absolutely must.... I also work in Linux only.
feel free to comment if you have anything to say below.
Key PlayerBot System Details Implemented :
1. Automatic World Entry & Ambient Population
- Startup: Bots auto-populate the world upon server initialization without requiring manual GM commands.
- Ambient Hubs: Baseline bot populations patrol major towns and starting fields:
- Map 22 (Adventurer's Plains): Levels 1–10 (Novice/Beginner)
- Map 1 (Valley of Lux): Levels 10–20 (First Jobs)
- Map 21 (Zant City): Levels 15–25 (First Jobs)
- Map 23 (Breezy Hills): Levels 20–35 (First Jobs)
- Map 25 (El Vergel): Levels 35–50 (First Jobs)
- Map 2 (Junon Polis): Levels 50–70+ (Second Jobs: Knight, Champion, Mage, Cleric, Raider, Scout, Bourgeois, Artisan)
2. Dynamic Player Proximity Spawning & Despawning
- Proximity Population (8–10 Bots): Whenever a real player is in the world, the spawner maintains 8–10 playerbots within 80m of that player.
- Level Scaling: Dynamically spawned bots are configured within ±4±4 levels of the nearby player.
- Resource Management (Orphan Pruning): Dynamic bots that remain more than 120m away from real players for longer than 60 seconds (and are not in a player's party) are automatically recycled to maintain low CPU and memory footprints.
3. Party Auto-Accept, Follow & Group Assist
- Party Auto-Accept: When a player sends a party invite to a bot (0x7d0), the bot auto-accepts immediately (0x7d1), sends an in-game message ("I'm with you! Let's hunt together!"), and enters follow mode (BOT_STATE_FOLLOW).
- Target Assist & Defense:
- The bot assists the party leader by focusing on whichever mob the leader attacks.
- If a mob attacks the leader, the bot detects the threat and counter-attacks.
- Party Healer AI: Muse and Cleric bots monitor party members' HP. If any party member falls below 60% HP, the bot casts Cure, Recovery, or Party Heal.
4. Stats, Skills & Combat Spells
- Skill Progression: Bots automatically learn class-appropriate spells matching their job and level (Soldier: Double Attack, Fatal Thrust, Voltage Crash; Muse: Mana Bolt, Ice Bolt, Cure; Hawker: Double Arrow, Triple Arrow, Stun Arrow; Dealer: Twin Shot, Triple Shot).
- Skill Points & Stat Points: Allocated automatically as bots level up. Skill ranks scale up to rank 10 based on level.
- Combat Rotation: Bots cast offensive spells when MP >15>15, respect cooldowns, and smoothly resume weapon attacks.
5. Tiered Visual Gear Matching Level
- Equipment upgrades automatically across 4 level tiers:
- Tier 1 (Lvl 1–19): Wooden/Bronze sets, Toy Bow, Air Gun, Wooden Staff, Two-Handed Sword.
- Tier 2 (Lvl 20–39): Copper/Adventurer sets, Short Bow, Iron Gun, Iron Staff, Broadsword.
- Tier 3 (Lvl 40–69): Steel/Hunter sets, Long Bow, Rifle, Battle Staff, Claymore.
- Tier 4 (Lvl 70+): Mithril/Grandmaster sets, Wing Bow, Shotgun, White Staff, Slayer.
- Bots broadcast visual equip packets (0x7a5) so players see their armor, weapons, and shields in real time, and bots are flagged with infinite ammo so ranged classes never run out of arrows or bullets.
Stability & Bug Fixes Applied
- Map Bounds Fix: Replaced a fixed 0..500 index loop in CBotManager::CheckProximitySpawns with iteration over GServer->MapList.Map, preventing out-of-bounds heap reads.
- Combat Skill Cast Throttling: Added isStartingCast guard in DoAttack so SKILL_ATTACK does not re-trigger attack logging and monster AI scripts every 10ms10ms while casting.
- Monster Death Null Pointers: Added monster != NULL checks before accessing monster->TD in battle.cpp lines 82, 837, and 2025.
- Crash Reporting: Added <execinfo.h> stack trace logging in Signal.cpp to output function frames if any signals occur.
Work continues....
SUCCESS !!!!
The Bots are connected and working... ( see video, its just me and bunch of bots ). now the real fun begins...
<iframe width="560" height="315" src="" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
Fixed the combat radius issue where players would see other players standing on top of a monster while fighting :
Is this happening in real-time or is it just what other people see?
It is actually happening in both:- Real-time server coordinates: In the server's movement loop, attacking entities (bots, players, and monsters) had their destination coordinate set to the exact center of the monster (mob->x, mob->y). Because the logic to stop moving when reaching attack distance was commented out, characters continued walking every tick (50 times/second) until their distance dropped below 0.01m, physically merging them onto the exact same coordinates.
- Visual client glitch: When initiating an attack or moving to engage, packets 0x798 and 0x79a broadcast the monster's center coordinates to all nearby clients. Furthermore, no stop packet was broadcast when reaching melee reach, so observing clients rendered characters walking straight into the monster's model.
Can it be fixed?
Yes. I have prepared a comprehensive implementation plan in implementation_plan.md to implement combat spacing across the server:- Vector-based Combat Standoff: Characters calculate a combat arrival point at proper weapon standoff distance (~1.8m – 2.2m for melee, or weapon reach ×× 0.85 for ranged/magic) rather than the monster's center.
- Immediate Combat Halt: The moment an entity enters weapon/skill reach, the server halts their movement immediately and broadcasts a stop packet to visible clients, preventing momentum from carrying them into the monster's model.
- Bot Combat Spacing: PlayerBots compute standoff waypoints so they never sprint into the mob's center during the 500ms AI decision interval.
The combat space radius and overlapping collision issue has been resolved.
What Was Fixed
- Combat Standoff Position (GetCombatPosition):
- Added CCharacter::GetCombatPosition to calculate a target approach coordinate offset along the approach vector: u⃗=Pattacker−Ptarget∥Pattacker−Ptarget∥u=∥Pattacker−Ptarget∥Pattacker−Ptarget Pdest=Ptarget+u⃗×combatDistancePdest=Ptarget+u×combatDistance
- Melee characters stop 1.8m – 2.2m away from the target; ranged characters and spellcasters stop at 85% of their attack reach (e.g., ~15m for bow/magic).
- Packet Broadcasts (0x798, 0x7b3):
- StartAction now broadcasts the standoff coordinate rather than the exact center of the target.
- If an entity is already within attack range, they do not step forward into the monster.
- Immediate Combat Halt (UpdatePosition & DoAttack):
- In character.cpp:UpdatePosition and battle.cpp
oAttack, when IsTargetReached() becomes true, moving characters immediately stop and broadcast a stop packet (0x79a for players/bots, 0x797 for monsters). This prevents momentum from carrying them into the monster while waiting for attack cooldown timers.
- In character.cpp:UpdatePosition and battle.cpp
- PlayerBot AI Standoff Navigation:
- In PlayerBot.cpp:HandleCombat, bots now move to GetCombatPosition rather than the monster's exact coordinate, ensuring they never sprint into the monster during the 500ms AI interval.
Done and dusted... Another bug fixed ! See the video, notice how bots/ players and monsters now keep the required combat gap while fighting.
<iframe width="560" height="315" src="" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
Last edited:



