RPG Systems Part 7

How you got that crappy sword that you vendored


Yesterday and today I made the minimap and finished up the item generation/loot system so that now it’s possible to get generated armor and weapon drops from monsters. There’s a lot more to do like generating spells, creating skill trees for the player, integrating reputation, creating quest systems, better creature spawns, better faction spawns and faction AI.

Looting a sword from a monster is really a pain touching a huge number of systems

  1. Begin with data. Start in the data editor.
  2. There is an ItemCategory list that gets generated/updated when the editor starts up based off a list of public const int values in ItemCategory. Those categories include armor, weapons and various reagents.
  3. The ItemCategories get lists of CraftingStats that tell how many of what kinds of stats those items give when used in crafting. These values are based off percentages of expected stats at a given level, so I only need one value per stat per item category.
  4. There is an EquipmentSlot list that gets created/updated from the set of public const int values inside of the EquipmentSlot class.
  5. Each element of the EquipmentSlot list has lists of words for creating Light, Medium and Heavy items of that type that were entered by hand.
  6. For each reagent type there are lists of quality words and level words that are used to create reagent ItemTypes of different qualities at different levels.
  7. For each EquipmentSlot and (Light/Medium/Heavy) armor weight pair, a single generated ItemType placeholder is created.
  8. Recipes are created for each of the placeholder equipment items that require Cloth, Leather or Metal Bars. Then, there are about a dozen slots for optional reagents of all kinds.
  9. Recipes are generated for a lot of the reagents to upgrade into each other (like 2x ore ->1 bar or 4x small gem -> medium gem)
  10. Spawn tables are generated for each reagent type, and then into larger categories of related types (there is a Red Gem spawn table and a Gem spawn table that randomly picks from one of the colored gem tables)
  11. Creature types are generated from a list of public const int values, and have data like food they like to eat that’s currently random but will be set by hand.
  12. FactionStubs are generated from a list of public const int values, and they like and hate other factions.
  13. Then, a world gets generated in the editor.
  14. The world generates a bunch of zones.
  15. Each ZoneType has a list of CreatureTypes that like or hate that kind of zone. It’s random for now, but can be done by hand later on.
  16. The zones get initial creature populations created based on the ZoneType’s creature affinities.
  17. The World and Zones get saved and we can exit the editor.
  18. A player enters the game and is playing on the Client.
  19. This currently generates a Server inside of Unity, but later on it will be set up to have remote Servers.
  20. There is no data shared between the Client and Server and they communicate through an interface that can wrap either delegates inside the same process or sockets when it’s really doing remote networking.
  21. The Server generates Creatures for the Zone based on the Zone data.
  22. The Server sends the creature data down to the client.
  23. The player enters the Zone and wanders around.
  24. The player fires in the direction of a creature and creates a Projectile based on the Spell they were currently casting. (Player spells will be created by hand eventually, but creature spells will be generated using lists of words and types that each CreatureType/RaceType/FactionType have.
  25. A message is sent to the Server and the Server checks the player’s stats and creates a Projectile on the Server if it’s ok. The Server does not update the Projectiles.
  26. If the client detects that the Projectile hit a Creature, it sends a message to the server. If the Server still thinks the Projectile exists and that it’s in a reasonable position (based on dead reckoning), it calculates damage based on the Spell attached to the Projectile.
  27. The Creature on the Server gets damaged and a message is sent down to the client.
  28. If the Creature runs out of Health, it dies. (Everything from now on is done on the Server until I say we are sending a message to the client that the item was created)
  29. When it dies, loot is rolled on an associated SpawnTableId. Creatures can also have a secondary optinal SpawnTableId that can be used for special events or quests.
  30. If an ItemTypeId pops out of the SpawnTable system, then the ItemType is looked up. If it is a generated ItemType, we enter the generation system.
  31. The item generation system looks at the level and power of the incoming request. Monsters can have a Power associated with them, so if their Power is > 0, that can be used as the incoming power, otherwise it can be randomly determined within certain ranges.
  32. The item generation system looks up the ItemType of the generated item and then its ItemCategory, if that fails, nothing is generated.
  33. It then checks that there is a Recipe that can generate this item, if that fails, nothing is generated.
  34. An empty list of reagents is created and all required reagents from the recipe are added to the list.
  35. Then zero or more optional reagents are added to the list depending on the item’s level and power. This tends to add 3-6 reagents, which is a lot.
  36. This list of reagents is then passed into the crafting system where the reagents and the ItemCategory.CraftingStats data are used to create stats for this item.
  37. This creation process was described in Part 6 I think, and for each ItemType, the ItemCategory associated with it is found.
  38. The CraftedStats values from the ItemCategory and the Power of the item and the GeneratedStatScaling from the EquipmentSlot is also used. (So rings don’t provide as many stats as a breastplate does.)
  39. These stats are added up and then put into a list to return to the generation process.
  40. After the list of stats is created, some of them are discarded since the system often ends up using a lot of reagents.
  41. The higher the level the item is and the more power the item has, the most stats remain.
  42. Those stats are used to generate an actual Item from the ItemType.
  43. This ItemType bubbles back up to the monster loot system.
  44. It gets passed into the WorldItem generation system creates a version of the item on the Server, and sends a message to the Client that the item was created.
  45. Back on the Client, the message is received that contains the Item and its position. The Client looks up the ArtURL on the ItemType for the Item and uses that to represent it in the world. (Currently all items just use a treasure chest).
  46. When the player on the Client moves near the item on the ground, it sends a message to the Server and if the Server still sees the item in its list, it adds the item to the player’s inventory and sends a message down to all Clients that the item is gone.
  47. The Server simulation for a given zone is single-threaded using an event queue system since there will be few players in the zone and a lot of the simulation is only done on the client. Race conditions here are not an issue (unless I really screwed something up).
  48. The Client then gets the message that the item was picked up and puts a message in the player’s chat log.

Email me when johnarras publishes or recommends stories