Monday, December 31, 2012

Hellcore MOO On Demand Room System Tutorial, Part 1


On Demand Room System


Problem:  You have an ASCII/ANSI based MOO that represents many rooms graphically, often.  Storing an object for each room consumes database space.  Database space is loaded into RAM at a cost of approx. (object's size in bytes) * 2.  On Wayfar, with 9 planets at 100x100, this would be nearly 10,000 objects per planet, almost 100,000 objects just to store blank space.

Solution:  Only store the rooms that players or other objects are using.  Procedurally generate other rooms as required.  The savings are huge!  This is a rough guide to implementing such a system in MOO.  There will be a lot of variation based on your specific gameworld.

Step 1:  Track spawned rooms and delete unused space.


On Wayfar, an object named $ods (on demand spawn) is used to track the status of spawned rooms.  The active rooms are stored in a hash property called spawned_rooms.

Each room must have a unique identifier for easy tracking.  I did this by creating a verb to concatenate a string together from the room's planet/location, and x, y, z co-ordinates.  Example:

$ods:key_string(OBJ room)
room = args[1];
key = tostr(room.location, "-", room.x, "-", room.y,"-", room.z);
return key;


This would return a string along these lines: #4444-1-3--1 for a room located in object #4444 at 1, 3, -1.  This key will let you refer to the active rooms in $ods.spawned_rooms easily.

Next we create a spawning verb for getting the rooms.  This part varies heavily according to how your rooms are setup, and how they are generated.  On Wayfar, we use a simple biome grid generated at planetary creation.  We always know the terrain type for a given X, Y location on a planet, and from that we can generate the appropriate resources and creatures.  This could be improved by proceduralizing all aspects of the room, so that even a despawned room would be re-created exactly from spawn to spawn.  Rough example:

$ods:spawn_3d_room(OBJ location, INT x, INT y, INT z)
{planet, x, y, z} = args;

room_key = $ods:key_string(planet,x,y,z);
"if the room already exists, we can just return it";
if(room_key in keys($ods.spawned_rooms))
  room = $ods.spawned_rooms[room_key];
  if(gamevalid(room) && is_a(room,$room))
    return room;
  endif
endif
"otherwise, we should create a new room and return that";
room = $room:populate();
"on hellcore, that might be: room = $rpg:spawn($room)";
room:set_point(x, y, z);
room:moveto(planet);
$ods.spawned_rooms[room_key] = room;


Now we need to clean up unused rooms.  Example:

$halfhourly:clean_ods
rooms = $ou:leaves_suspended($room);
for r in (rooms)
yield;
if(length(r.contents) < 1)
"you could also add, as we have on Wayfar, a timer check to keep rooms persistent for some period of time";
$rpg:junk(r);
endif
endfor


Important note:  Once the elements above are implemented for your system, you still need to hook them into the actual movement actions for the player.  I setup some vector based verbs to figure out the rooms I need to be spawning based on the direction the player is moving (on a planet a player can move in any cardinal direction).

This guide will hopefully be expanded as time goes on and I am able to write more examples.

Monday, December 24, 2012

Fun Changes 12/24/12


Whilst things have been quiet on the home front, things have been busy elsewhere-
We've been doing a lot of detailed changes in order to both balance the game more and expand content available to players, notably that of 'superior' weapons which come with a (!) suffix. These weapons are assigned a number of 'points' during generation and these are randomly spent on various stats on the weapon to improve it over a non-superior weapon of the same type. Note that these 'superior' suffixes are not mutually exclusive with existing weapon prefixes so you could find a 'sawn-off m78a1 plasma rifle (!)' or an 'artillery judge-brand pistol (!)' with crazy-high stats and mad damage output.
Here's a list of a portion of the things that have been done:

- Superior weapons now come in six delicious flavors (levels), ranging through cyan, green, blue, purple, yellow and red. Each of these levels have different improvement levels and higher level superiority is exponentially more difficult to acquire in comparison to a lower level.
- Superior weapons now appear in your inventory and on the ground with their suffix correctly shown.
- Superior weapons now generate with more 'points' to spend depending on how high the quality of the weapon is (higher quality means better stats).
- Attacks will now hit bodyparts rather than ambiguously hitting a target somewhere on their body, if they have a body.
- Hackable treasure containers such as those found in pirate bases will now spawn items within a quality range rather than quality 0 which sucked.
- Respawn matrices such as the Kerkove organic regeneration matrix will now display a fun message whenever you respawn at the matrix, thanking you for your patronage/telling you not to die again/etc.
- Civilians bearing a paramedic AI package will now use any medical supplies they are carrying (such as bandages and medicare health injectors) before they use their standard equipment, so they will use any health injectors and top-tier bandages you give them in order to improve their healing abilities.
- The ammo capacity modification of weapons during superior weapon generation has been changed in order to scale with the weapon's standard ammo capacity (weapons with high ammo capacity will gain more, whereas weapons with small ammo capacity will gain less) and weapons with an ammo capacity of 1 will have their superiority 'points' spent in other stats.
- Civilian building construction now works, if you enable civilian building rights then construction sites will appear in the 3x3 section around your sector center (including the center tile) and these construction sites will slowly be completed and then finish regularly.
- Diseases such as spore cough now pay attention to if you're wearing a gas mask or headgear bearing a rebreather module and do not affect people wearing such things.
- Explosives set off inside vehicles will now damage the containing vehicle (frag grenades and such will do little to harm the vehicle, but a pile of proximity charges will make a royal mess of things).
- Sector centers now bear sensors to warn civilians during attacks from vehicles, warning them to take shelter inside the sector center or to man turrets in order to repel the vehicle threat. The civilians manning turrets may also be able to identify the individual controlling the attacking vehicle and attack them if they leave their vehicle.
- Various new consumables are available to players.
- You can now construct tractor beam modules, which can be installed in solar carriers to drag ships inside the integral hangar.
- You can now use drug injectors on both yourself and other people.
- Bandages and injectors now employ a medical skill roll to reduce the duration of their use (the more medical skills you have, the shorter the average time it takes for you to use a bandage or injector on someone).
- NPC factions have received various updates which allow players to operate under them, allow them to perform ground assaults on locations, man turrets and use them to attack, reload vehicle weapons and perform planet travel to inside-a-building/vehicle travel without fault.

There's a bunch of other stuff I'd like to share, but some of it's secret and the rest I'm just too lazy to report B).

Wednesday, December 19, 2012

Updates 12/19/12

* Enabled web access to the random movie poster generator: tinyurl.com/wayfarposters
* Fixed a long standing bug with password resets
* ASecretiveMan added tractor beam modules for starships
* In game changelog added to website
* Server status added to website
* A new issue of drillbit, thanks to Aphteroid: