Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

MMORPG kit - draft document in progress, for discussion purposes only

ZHugh Becquerel
Registered User
Join date: 24 Oct 2003
Posts: 68
11-23-2003 05:41
MMORPG kit - draft document in progress, for discussion purposes only

I want to create something like Everquest, only anyone can extend it, and possibly modify it.

This is extremely similar to DarkLife and there may well be collaboration/exchange/complete fusion for various parts or the whole.

Here is a high-level strategic view of the project. This post will be edited as time goes on making it the Reference.


Goal of the project:

Create an MMORPG toolkit and context for creating an MMORPG-style environment


Philosophy of the project

Anyone can create a zone and add it to the MMORPG. Ideally anyone can add content and the system will integrate this seamlessly into the game. Ideally I can create a single avatar, with corresponding health, money, XP, and use him/her across all integrated zones.


How this would work - High level view

Each player will have an attachment that represents everything about them.

A set of API modules facilitate development of monsters, weapons and so on.

Between zones, a floating exchange-rate could be implemented for money and XP.

By using modular scripts that communicate using a well-defined Linked Messages interface we will move any secret-secret stuff into what will hopefully be a tiny tiny script/module, leaving anyone free to generate their own monsters, weapons and avatar types!



Deliverables

Documentation
- The project design (this post, will evolve iteratively)

Example implementations:
- Example monster (open except core)
- Example avatar token (open except core)
- Example weapon (open except core)
- Example spell implementation (open except core)

Core script modules:

These modules could be freely available (open) but would be closed prior to actual instantiation in the game world in order to lock them, eg with channel number.

- Zone exchange rate implementation modules: enforces XP and Money exchange-rates (locked module)
- Generic monster module(s): integrates a monster into the MMORPG (locked module)
- Generic weapon module(s): integrates a weapon into the MMORPG (locked module)
- Generic avatar module(s): integrates an avatar into the MMORPG (locked module)

Helper modules/systems:

- Zone exchange rate caculator system: calculates XP and Money exchange-rates (open modules)

MMORPG Library:

A set of modules that could be incorporated into monsters, weapons and avatars that provide functional abstraction and facilitate the rapid generation of these objects.

- Weapon API module: placeholder
- Monster API module: eg provides code for moving, pathing, basic AI and behavior
- Avatar API module: placeholder


How this would be used

Joe decides he wants to make a dungeon. He gets hold of copies of copies of the core, live modules and adds them to his weapons, monsters, and avatar token. He adds in the MMORPG Library API modules, and writes surrounding wrapper code to customize how his zone behaves.

People come and visit the zone. Hopefully. They play for a while and accumulate experience and money in this zone.

As time goes on, the system learns how easy it is to get xp and money in this zone and can compare this to other zones, in order to generate exchange rates.

The exchange rates set the equivalent xp and level as one moves between zones.

Now the MMORPG just got bigger! People can choose where they are going to level. Zones that are a posteriorae hard to level in get assigned a favorable exchange rate, and visa versa.

Priorities

Stuff to create a dungeon zone is priority 1.
Stuff to provide zone inter-compatibility is priority 2.

Risks

Risks outstanding for creating dungeon zone:

- Risk that unable to create convincing and fun monsters -> risk outstanding, prototype in progress
- Risk that convincing and fun monsters will be too resource intensive -> risk outstanding, awaiting results of prototyping
- Risk that demise of project owner would kill off existing implemented dungeons -> very low because all modules open in their non-instantiated form.

Risks outstanding for inter-zone compatibility:

- Risk that unable to implement xp equivalence detection
- Risk that unable to implement financial equivalence detection
- Risk that unable to implement object equivalence dection

- Risk that unable to implement xp interchange mechanism
- Ditto for finance
- Ditto for objects

-> risks for inter-zone compatibility will be looked at in more detail once technology for creating dungeon zones in place

Risks with Status=Closed

Make a sword to hit people -> prototyped, works ok
Make a sword to hit objects -> prototyped, works ok
Store life points and stuff, kill avatar as required -> prototyped, works ok

Details and Discussion

This section will provide implementation details.

Zone addition/modification

In order for the exchange rate system to work, we need to implement systems to handle zone modification. Worst case, we lock zones against modification and have all modifications as adds followed by deletes.

Use of objects between zones

To be decided.

Security

There is the possibility that a channel number, or other secure protocol parameter, will become widely-known at some point, compromising the stability of the game world.

To mitigate this we need to consider methods to:
- modify the channel number, or equivalent, throughout the effected gameworld
- segment the gameworld to limit the damage caused by any single breach.

As far as channel numbers, we might consider using a different channel per zone. The zone designer designates the appropriate channel number.

If the zone designer owns all objects in his/her zone, we can have the objects respond to a change_channel request, as long as it comes from his/her id.

In an initial project implementation, each avatar is local to the zone. In future updates, we might choose to conserve this, and to provide gateway systems to seamlessly move between zones. That allows us to shut down a compromised zone by removing it from the gateways systems.

Detailed Design - modules

Note: draft, for discussion purposes only

Introduction

We can split the required functionalities as follows:
- secure comms (in-channel shouts)
- receive damage
- receive effects
- send damage
- send effects
- stats (life, money...)
- AI (for monsters)
- movement (for monsters and possibly for avatars)
- control interface (for avatars)

We need to consider for each module the extent to which:
- it must be easily updatable
- it should be stable wrt changes
- it should be secure/locked wrt players and wrt zone designers

For the effects/damage modules, we basically need that we can flexibly add new weapons and effects into the game, whilst all objects already in the game will respond appropriately to them.

To this effect, we will split the damage/effect modules into receive and send. The send modules will be fairly flexible and can change with time. The receive modules must be very stable wrt new attacks.

Dynamically loaded scripts were considered but not retained for now because of the load they would impose on the sim motors.

Module design

Damage/effect receive modules will respond to six primitive attack types:
- directdamage(amount)
- damageovertime(amount, duration)
- movespeed(percent, duration) (can be more or less than 100%)
- attackspeed(percent, duration)
- attackpower(percent, duration)
- sensorpower(percent, duration)

Damage/effect send modules will use these primitives to create a range of attack types.

Projectiles can be implemented within this framework because the receive modules dont need to know with what they are being attacked, just the amount of damage inflicted.

The receive modules will be using Listens to sense attacks. Since scripts/modules are not threaded the listen must exit immediately, without undue delay, ie no llSleeps, and delegation to other events/scripts as necessary.

A stats module will store current avatar state, ie Life, Money, Movespeed, AttackSpeed, AttackPower, SensorPower.

Detailed design as at 24 November 2003:<==

Following systems will be created:

- CombatSystems GRI (GRI = "Game Rules Instantiation";)
- Weapon/spell system
- Shield system
- Money system

Following modules will be created:

CombatSystems GRI system:
- Stats module
- Receive dmg module
- Send dmg module

Shield system:
- shield module

Weapon/spell system:
- weapon module

Money:
- money module

Money

Money will be stored as objects in your inventory. This makes life really easy for the developers. You can convert your money from different types at the bank. Money will communicate with other modules, ie GRI stuff, over ChannelMoney.

Shield System

Shields will work by replying to PROTECTIONPING messages. The shield module enforces their being worn as an attachment. The CombatSystem GRI will do periodic pings to work out how much armor you are wearing. Shield modules will send an INVCHNG message on attach and detach.

Shield will communicate with the CombatSystem GRI via ChannelShield.

Shield types

We will have the following shield types:

- AC (vs melee attacks)
- MR (vs magic attacks)
- Projectile (vs projectile attacks)

Note that shields are not linked to the CombatSystem GRI. All communications is via inter-object communiation (initially shouts)

Weapons/magic staves

Weapons/magic staves are separate objects from the CombatSystem GRI.

They are worn as attachmnets, and the weapon module enforces this.

Weapons will attack by being asked to do so by the player (via takecontrols or channel 0 or whatever).

Weapons cant directly attack anything, because they run on a separate channel, ChannelWpn. What they do is send an attack message to the CombatSystems GRI SendDmg module, which will validate it and broadcast it to the appropriate victim.

We will pipe weapons messages via the CombatSystems GRI to provide a certain amound of centralized validation, eg we can turn off certain rogue weapons, control cooldown and so on.

AS far as cooldown, two possibilities:

- global cooldown. EAch weapon has a cooldown associated with it, that it sends in its attack message to the CS GRI. The CS GRI blocks all further attacks, from any of this players weapons, until CoolDown has elapsed.
- Weapon specific cooldown. Certain weapons can bypass the global cooldown and be fired simultaneously

Weapons will send the following information in their attack message:
- attack type (DirectDamage, Reduce MoveSpeed, etc...)
- power
- duration
- attack substrate (magic/melee/projectile), which is used to trade off against shield types

Weapons can have a recharge time, and can have a limited ammunition/number of charges. Weapons are responsible for enforcing this.

DoTs

DoTs will be instantiated by firing an object at the target that "sticks" to him her for the duration of the effect. This can be visible (like a poison dart/arrow), or not. This makes life easy for the damage send/receive modules.

CombatSystems GRI Modules

The juicy bit, the core of the system!

There will be 3 or 4 base modules, which may be fusioned or fissioned as time goes on. Concretely these are scripts embedded in a single attached object, such as a bracelet.

The attached object is termed the "GRI Tag" and must be worn to take part in the game. If you take it off, you're out, and may be ejected from the land. To rejoin, just put it back on, but there will probably be a small delay during this respawn.

The GRI modules are:

- receive damage module
- send damage module
- stats module
- and possibly a secure comms module

Now you've seen the other systems, you can imagine what these will do, but read this anyway.

Receive damage module:
- responsible for receiving ATTACK messages from other Actors via the SecureComms module
- validates the ATTACK messages against currently cached shield stats, to generate actual damage inflicted.
- sends SUBSTRACTSTAT linked messages to the Stats module
- listens for STATCHANGE linked messages from the Stats modules and handles the Death condition

Handling the Death condition in the STATCHANGE event makes this work within an async comms framework.

The following damage can be received:

- DirectDamage (health stat)
- Mana (mana stat)
- AttackSpeed (AttackSpeed stat)
- AttackPower (AttackPower stat)
- AttackRange (AttackRange stat)

Send damage module:

- receives ATTACK messages from the weapons system (different attachment) on ChannelWeapon.
- modules them for currently cached attackspeed, attackpower and attackrange stats
- forwards them to the SecureComms module for onward transmission to the unfortunate target
- may or may not enforce global cooldown timing

This is a one-way pipeline and will work just fine with async comms.

Stats module

This stores the stats for the player.

Stats include:
- Health
- Mana
- AttackSpeed
- MoveSpeed

and probably AC, MR and Projectile Armor

To work within the async module comms framework, the stats module will send a broadcast linked message every time a stat changes, and other modules will cache the stats they are interested in. Coupling is minimal to the extent that the modules only cache what they're interestd in, so can add new stats variables without having to rebuild the entire GRI.

SecureComms module

Responsible for inter-Actor communication on ChannelInterActor.

It's a separate module becuase:
- means we can abstract the current shout system from the other modules, and migrate easily to direct object-to-object communication when we get it
- makes changing the ChannelInterActor number really easy
- it will encapsulate encryption and other stuff if we need

Other systems not covered here:

Monster AI. A module that can be placed in monsters to make them fun to kill.

Monster Move Module. Separate or fusioned with the Monter AI Module. Provides routines for making Monsters move about.

Other points

Sourceforge

Now possible. Good. For now, Alternative Scripting Library is fine. I think we had enough publicity for a while :-) Maybe we can wait a couple of months for people to get used to the idea of SL and then make another Slashdot article?

Concepts

XP

There will be no XP. If you want to be tougher, buy better equipment!!!

Monster drops

You will get given money and / or equipment if you do something cool, like finish a mission. Killing rabbits will get you squat. Working as a team will get you really decent stuff.

Your rights to use this design:

You can freely use and derive from this design as long as this does doesn't affect my ability or rights to use and/or derive from the design myself, here or in any other game or on any other platform, to the extent to which this is enforceable.

Obviously if you send me derivatives, it will help me make future stuff.
Dionysus Starseeker
Mostly Harmless
Join date: 31 Dec 1969
Posts: 764
11-23-2003 09:05
What would keep someone from creating a +9999999999 sword and only charging $1 for it?
_____________________
Life beyond Second Life? Nah...

"...you will get as many answers as people you ask." -- Kenichi Chen *hehe... yep*
Mezzanine Peregrine
Senior Member
Join date: 14 Nov 2003
Posts: 113
11-23-2003 13:11
In my opinion, SL has too many limitations to 'compete' with MMORPGs.

What I mean is, its not explicitly designed for dungeon hacking slaying exping camping style things, and the scripting, and other tools, while powerful, are not powerful enough... or at least, are not made for THAT kind of thing...

My point is that you can make a rough estimation of another MMORPG within SL, but the other MMORPG will be smoother, look better, have more detail, more complexity, more depth, more items, etc etc, it will simply be better, because the other MMORPG runs on an engine that is DESIGNED explicitly to do what it does.

For example, dark life has something good going in that it mimics some of the aspects of some of the MMORPGs out there. However, each additional aspect to mimic is exponentially harder than the last, because this engine just wasn't designed for that sort of thing. And many, many things it just CANNOT do as of yet (Maybe in the future).

Before a real MMORPG game can be devised in SL that could actually 'compete' with the dedicated MMORPGs out there, there are many graphical / scripting updates that would need to be done, including animations of objects, PERSISTANT script data, and so on.

HOWEVER

Let me not be a voice of doom here!

As a programmer myself, I must add the following.

One does not know what features to add to an engine until one knows what its intended usage is!

So it may be very beneficial to plan out a MMORPG system. And plan it out fully - that is, do not bind yourself by the limitations of Second Life - plan it out as if you are making your own game engine that can do what is required. Trying to crow bar it into CURRENT SL is going to make it suck - or at least, not be AS GOOD as the MMORPGs it tries to mimic....

So plan it out as if you are free to implement anythign you can think of.

Then try to get Linden Labs to implement the necessary features into SL that will allow you to do it.
Ryen Jade
This is a takeover!
Join date: 21 Jun 2003
Posts: 1,329
11-23-2003 17:41
*opens dictionary*

MMO-RPG In Second-Life: N, "See Akar and Darklife"
Ama Omega
Lost Wanderer
Join date: 11 Dec 2002
Posts: 1,770
11-23-2003 18:08
Dionysus hit the key flaw.

Unfotunatly more control is needed.

I would recomend switching to a more closed method.

Create the closed core modules for weapons, monsters people.

Create an api for modifiing those core modules. Very similar to what you say above, except these core modules should handle much more than communications.

For example lets say that a weapon can have the following properties:
- Blunt damage
- Sharp damage
- Range damage
- Magic damage
- Accuracy
- Stat boost

You decide that for each 'level' of weapon the designer gets 2 points to place. Value and cost are assigned to the weapon automatically. So using the api a player would say the weapon is level 3 and say where the 6 points go. Stat boost could be flexible enough to effect any stat. This would allow players to design the weapons they chose, but the price/value of the weapon would be determined by the power of the weapon essentially and not randomly.

The same should go for the monsters. Define the level of the monster which gives the designer X points to distribute among speed, accuracy, smarts, defence, offence etc. The XP given for the monster would be determined by the level chosen.

There would still be great flexibility in visual design and statistical design, and yet nothing would 'break' the game. Just make sure there are enough places to distribute the points. :D
_____________________
--
010000010110110101100001001000000100111101101101011001010110011101100001
--
Haney Linden
Senior Member
Join date: 3 Oct 2002
Posts: 990
Games within SL
11-23-2003 18:20
I agree with Mezz that SL won't soon compete with specialized MMORPG's in production value. And making games within SL is going to be challenging.

However, SL offers a couple of opportunities that specialized games don't:

1. The cool think about SL is that you can do a bunch of different thing with friends, sports, shooting, triva, in addition to building and selling. Even if the questing is not as smooth as Everquest, it is fun and can add another dimension to the relationships you have in SL.

2. SL also offers the chance to use game design as a form of self-expression. How often outside of SL do you get to hang out with the person who designed the game you are enjoying?
Mezzanine Peregrine
Senior Member
Join date: 14 Nov 2003
Posts: 113
11-23-2003 18:37
Yes - my main point was that while you can currently make a pseudo-MMORPG in Second Life, it can't have nearly the depth and features of a born-and-bred 'real' MMORPG.

And getting even close to one of them gets exponentially hard.

And some things are completely impossible.

So instead of designing an MMORPG to live in the limitations of the SL engine, consider designing a MMORPG which would be much, much better, and could be implemented in SL "if only" it had a few key features.

If you could figure out exactly what key features SL lacks in order to make a kickass MMORPG that actually can somewhat compete with the 'real' ones, then there you've got some key features to put on the suggestion board that will benefit everyone.
Carnildo Greenacre
Flight Engineer
Join date: 15 Nov 2003
Posts: 1,044
11-23-2003 22:45
From: someone
Originally posted by Dionysus Starseeker
What would keep someone from creating a +9999999999 sword and only charging $1 for it?


You could add a routine that takes an item's attributes and computes a minimum price for it. A designer could give an item a higher price, but not a lower one.
Mark Busch
DarkLife Developer
Join date: 8 Apr 2003
Posts: 442
11-24-2003 08:26
MMORPG's like everquest or FFXI are made by teams of professional programmers, graphics designers and a lot of other specialized people who get paid for their work.
I know a lot of people somehow think they could make the same quality games as that, only if they tried. But unfortunatly they are wrong.

Creating games is a real hard job. I think the Lindens know that too, and even if you come with some good looking design for a game (something that everyone can put together) I don't think they are going to put extra key features in SL, so you might really really maybe be good enough to create that. It's also much harder to do games in SL because you have a speed limitation and a memory limitation.

First try actually making a part of the game, and I do not mean the special effects or the design of the environment, but really the core features of the game.
That is how I did it with darklife. I created a backpack with stats , a weapon and a shield, and a monster that was 1 box.
But you could fight it, level up and die etc. and I showed that to Linden and Ama.
From that they knew that my game idea could actually be done (and I could do it) so they gave me support.
But I think it's probably a bad idea to come up with some kind of huge design document and expect Lindens to add new features to SL, for you to TRY (and probably fail) to do your amizingly, better then EQ, MMORPG in SL.
Before you start, the final version of DarkLife has about 17 scripts (only for the backpack), which is about 2500 lines of codes, and I did very much optimize my code for speed and memory usage, which made it very hard. Anyway that is just the backpack, then you have the shops, the weapons, the monsters, the gold, the lootbag, the shrine etc. etc. It also got to have very secure coding, so people can't cheat by repeatedly clicking on gold, or whatever weird things you can do in SL. And that made it another step harder.
Believe me I am a professional programmer and making this game in SL with it's small memeory and speed is a HELL of a job. If you just learned how to script just forget about trying something like this... start way smaller!
Also another thing what won't work: if you are not a scripter don't go making a game design and hire a scripter to create it, because 1 the scripter will lack the motivation to completly finish it (I have seen this happen inside and outside SL very much), and 2 if you can't script you also have no idea of the limitations of the scripting language so your idea is most likely to have impossible features in it.
You really want to start a big project?
If you are a scripter, think of the game you want to make, make sure it can be done within the limitations of LSL, and make sure YOU can actually do it. Don't count to much on other people, if the game is your idea YOU are the one who's going to have to do it. Also don't count on extra features that you think will appear in some future version of SL. You have no idea when and if they will come, and if you have to wait to long you probably lose interest in your idea.
If you are not a scripter, find a good one, and discuss your game together! listen to the scripter, he/she probably knows more about what is a good idea and what not.
The make the core of your game first, don't start on all fancy designs etc. just use some boxes and try to proof to yourself (and later the sponsors) that your idea works. If you have done that you probably have to motivation to continue and you will get support somewhere along the way. Don't ask for support if you have nothing to show for...

sorry fot the negative response, but I do think I actually know what I'm talking about, I have a lot of amateur projects expirience, and ofcourse, I made DarkLife using the method I described.
ZHugh Becquerel
Registered User
Join date: 24 Oct 2003
Posts: 68
11-24-2003 13:02

Mezzanine Peregrine
Senior Member
Join date: 14 Nov 2003
Posts: 113
11-24-2003 13:53
You know your MMORPG is balanced when every class is asking you to nerf every other class.
Aizndor Kothari
Junior Member
Join date: 21 Nov 2003
Posts: 8
11-25-2003 03:39
For a different point of view:

In general I find that it works best if you first find what can be done in the system that you are working in, and then design the game from scratch to make the most of this system.

Therefore I think it would be best to forget about anything that has ever been in any MMORPG or RPG, and then decide what you want to make and how to fit it into the system.

Therefore there is no need to try to compete with commercial MMORPGs, since the limitations of your capabilities are already intrinsic in your design, finding you a niche of your own.

For an example, see Ville Mönkkönen's games. They have great graphics, but work within his own limits, and he creates great games of types that are unique enough that no commercial versions exist.

If you look at independant game developers in general you'll find that there are entire genres of games that are only developed by independants.
Aizndor Kothari
Junior Member
Join date: 21 Nov 2003
Posts: 8
11-25-2003 03:48
I have to agree that the design document at the top is too ambitious. I know from experience that a big plan must be divided into little steps.

And while it's true that a game is probably well balanced if everyone is complaining about everyone else being to strong, a much better way to prove it is using mathematics.

This brings another thing though, some aspects of modern games are mathematically incapable of being balanced. While I can't remember any examples at the moment, anybody who does the mathematics behind building the algorithm for calculating items/monsters/stats balance should be able to spot these quickly enough and replace them with balancable equivalents.
Mark Busch
DarkLife Developer
Join date: 8 Apr 2003
Posts: 442
11-25-2003 05:37
While LSL has it's limitations to memory/speed, some other things are not limited, for example objects :)
We can make as many monsters as we want, as many weapons, as many potions, as many spells. Also the PvP and share/help functions in the final version could make it really fun for a long time, because people you play never act the same. I don't think that many players of Everquest or Ultima Online would play those game so long if they couldn't fight eachother.
Plus I already thought of another cool features I could put in when people get bored with the final version of DarkLife.
We might not be able to compete with other MMORPG's, but we can also think of features that are NOT in any other MMORPG's yet, which could make the game interesting even if you already played a dozen of other MMORPG's.
The aim of creating games in SL is probably not to compete with any existing game, but to have fun creating it, and let other people have fun playing it, and also inspiring other people to create games as well.
Ama Omega
Lost Wanderer
Join date: 11 Dec 2002
Posts: 1,770
11-25-2003 09:31
First, why does it have to be as good as EQ or other 'professional' MMORPGs? It never can be of course - they run on specialized servers with specialized OSs networked in specialized ways to work with clients designed specially for the MMORPG. You sacrifice in SL because of the flexibility of the system.

That doesn't mean a MMORPG isn't worth trying to build or can't be effectively done. Mark at the least has shown that isn't true.

I myself have had in my head a seperate MMORPG idea for a while now and I may share my design at some point in the near future in case anyone else thinks its cool.

Also as a side note, the vast majority of EQ players can not PVP.
_____________________
--
010000010110110101100001001000000100111101101101011001010110011101100001
--
ZHugh Becquerel
Registered User
Join date: 24 Oct 2003
Posts: 68
Shield Module build 0001
11-25-2003 14:26
Parameters:

ChannelShield - secure comms with CombatSystems GRI
AC - melee armour
MR - magic resistance
ProjArmour - projectile armor

Your rights to usage and derivation:

You can use this code and derive from it freely as long as you dont affect my ability or rights to do the same, for this code, here or in any other game/platform.

CODE

integer ChannelShield = 5;

integer MR = 0;
integer AC = 10;
integer ProjArmour = 5;

SendInvChangedMessage()
{
llWhisper( ChannelShield, "INVCHANGE" );
}

default
{
state_entry()
{
llListen( ChannelShield, llKey2Name( llGetOwner() ), llGetOwner(), "" );
}
on_rez( integer param )
{
}
attach( key id )
{
// this covers both attach and detach
SendInvChangedMessage();
}
listen( integer channel, string name, key id, string message )
{
if( message == "PROTECTIONPING" )
{
llWhisper( ChannelShield, llGetObjectName() + "-=-" + (string)AC + "-=-" + (string)ProjArmour + "-=-" + (string)MR );
}
}
}
ZHugh Becquerel
Registered User
Join date: 24 Oct 2003
Posts: 68
Weapon module build 0001
11-25-2003 14:47
Parameters:
- ChannelWpn
- AttackType ("DirectDamage", "ManaDamage", "MoveSpeedIncrease", "AttackSpeedIncrease" or "AttackRangeIncrease" )
- AttackVector ("MELEE", "MAGIC", or "PROJECTILE" )
- AttackPower
- CoolDown (in seconds)

Your rights to usage and derivation:

You can use this code and derive from it freely as long as you dont affect my ability or rights to do the same, for this code, here or in any other game/platform.

CODE

integer ChannelWpn = 4;

string AttackType = "DirectDamage";
string AttackVector = "MELEE";
integer AttackPower = 20;
float CoolDown = 0.5;

string PlayerName;
key Playerid;

float LastAttack = 0;
integer have_permissions = FALSE;
integer Message2displayed = FALSE;

TellPlayer( string Message )
{
llWhisper(0,PlayerName + ", " + Message );
}

TellOwner( string Message )
{
// llInstantMessage( Playerid, Message );
}

GenericInit()
{
Playerid = llGetOwner();
PlayerName = llKey2Name( Playerid );
PlayerName = llGetSubString( PlayerName, 0, llSubStringIndex( PlayerName, " ") );

TellPlayer( "Switch to mouselook to attack!" );
llRequestPermissions(llGetOwner(),
PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS);
llPreloadSound( "swordhit" );
llPreloadSound( "swing1" );

Message2displayed = FALSE;
llSetTimerEvent(5.0);
}

default
{
state_entry()
{
GenericInit();
}
on_rez(integer startparam)
{
GenericInit();
}

timer()
{
llSay(0, "Use me wisely, " + PlayerName + "!");
llSetTimerEvent(0.0);
Message2displayed = TRUE;
}
run_time_permissions(integer perms)
{
if(perms & (PERMISSION_TAKE_CONTROLS))
{
llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT | CONTROL_UP | CONTROL_DOWN | CONTROL_ML_LBUTTON, TRUE, TRUE);
have_permissions = TRUE;
}
}

attach(key attachedAgent)
{
if (attachedAgent != NULL_KEY)
{
Playerid = llGetOwner();
llRequestPermissions(Playerid,
PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS);
}
else
{
if (have_permissions)
{
llReleaseControls();
have_permissions = FALSE;
}
}
}

control(key name, integer levels, integer edges)
{
if ( ((edges & CONTROL_ML_LBUTTON) == CONTROL_ML_LBUTTON)
&&((levels & CONTROL_ML_LBUTTON) == CONTROL_ML_LBUTTON) )
{
if( LastAttack < llGetTimeOfDay() - CoolDown )
{
LastAttack = llGetTimeOfDay();
llSensor("","",SCRIPTED,2.0,PI/4);
llStartAnimation("sword_strike_R");
llPlaySound("swing1",1.0 );
}
}
}

sensor(integer num_detected)
{
integer TargetFound = FALSE;
key Targetid;
string TargetName;

TargetFound = FALSE;

integer i;
i = 0;
while( TargetFound == FALSE && i < num_detected )
{
if( llDetectedType(i) == SCRIPTED || llDetectedType(i) == AGENT )
{
TargetFound = TRUE;
Targetid = llDetectedKey(i);
TargetName = llDetectedName(i);
}
i++;
}

if( TargetFound )
{
llWhisper( ChannelWpn, "ATTACK" + "-=-" + (string)Targetid + "-=-" + AttackType + "-=-" + AttackVector + "-=-" + (string)AttackPower + "-=-" + (string)CoolDown );
llPlaySound( "swordhit", 1.0);
}
}

}
ZHugh Becquerel
Registered User
Join date: 24 Oct 2003
Posts: 68
CombatSystems GRI - Stats module build 0001
11-25-2003 15:09
CombatSystems GRI - Stats module build 0001

Parameters:
This stores parameters for the GRI so no particular parameters, but you probably want to set initial values here (optional because you could do this from other modules).

No channel number because this only communicates with other modules in the CombatSystem GRI Tag object.

Your rights to usage and derivation:

You can use this code and derive from it freely as long as you dont affect my ability or rights to do the same, for this code, here or in any other game/platform.

CODE

integer Life = 100;
integer AttackSpeed = 100; // percent of norm
integer MoveSpeed = 100; // percent of norm
integer Mana = 100;
integer AttackRange = 100; // percent of norm

SendStat( string StatName )
{
if( StatName == "Life" )
{
llMessageLinked( LINK_SET, 0, "STATUPDATE-=-Life-=-" + (string)Life, "" );
}
else if( StatName == "AttackSpeed" )
{
llMessageLinked( LINK_SET, 0, "STATUPDATE-=-AttackSpeed-=-" + (string)AttackSpeed, "" );
}
else if( StatName == "MoveSpeed" )
{
llMessageLinked( LINK_SET, 0, "STATUPDATE-=-MoveSpeed-=-" + (string)MoveSpeed, "" );
}
else if( StatName == "Mana" )
{
llMessageLinked( LINK_SET, 0, "STATUPDATE-=-Mana-=-" + (string)Mana, "" );
}
else if( StatName == "AttackRange" )
{
llMessageLinked( LINK_SET, 0, "STATUPDATE-=-AttackRange-=-" + (string)AttackRange, "" );
}
}

BroadcastStats()
{
SendStat( "Life" );
SendStat( "AttackSpeed" );
SendStat( "MoveSpeed" );
SendStat( "Mana" );
SendStat( "AttackRange" );
}

integer GetStat( string StatName )
{
if( StatName == "Life" )
{
return Life;
}
else if( StatName == "AttackSpeed" )
{
return AttackSpeed;
}
else if( StatName == "MoveSpeed" )
{
return MoveSpeed;
}
else if( StatName == "Mana" )
{
return Mana;
}
else if( StatName == "AttackRange" )
{
return AttackRange;
}
return 0;
}

SetStat( string StatName, integer StatValue )
{
if( StatName == "Life" )
{
Life = StatValue;
}
else if( StatName == "AttackSpeed" )
{
AttackSpeed = StatValue;
}
else if( StatName == "MoveSpeed" )
{
MoveSpeed = StatValue;
}
else if( StatName == "Mana" )
{
Mana = StatValue;
}
else if( StatName == "AttackRange" )
{
AttackRange = StatValue;
}
SendStat( StatName );
}

default
{
state_entry()
{
}
link_message( integer sendernum, integer num, string message, key id )
{
list Arguments;
Arguments = llParseString2List( message, ["-=-"], [] );

string Command;
Command = llList2String( Arguments, 0 );

string StatName;
StatName = llList2String( Arguments, 1 );

integer StatValue;
StatValue = (integer)llList2String( Arguments, 2 );

integer CurrentStat;

if( Command == "SETSTAT" )
{
SetStat( StatName, StatValue );
}
else if( Command == "RAISESTAT" )
{
CurrentStat = GetStat( StatName );
SetStat( StatName, CurrentStat + StatValue );
}
else if( Command == "MINSTAT" )
{
// MinStat( StatName, StatValue );
}
else if( Command == "MAXSTAT" )
{
// MaxStat( StatName, StatValue );
}
else if( Command == "PINGSTATS" )
{
BroadcastStats();
}
}
}
ZHugh Becquerel
Registered User
Join date: 24 Oct 2003
Posts: 68
CombatSystem GRI - SendDmg module build 0001
11-25-2003 15:28
CombatSystem GRI - SendDmg module build 0001

Parameters:
- specify ChannelWpn, which should be the same as wot you put for the Weapon itself.

You add this module to the CombatSystems GRI tag, along with the stats module, the receivedmg module (to be posted) and the securecomms module.

Your rights to usage and derivation:

You can use this code and derive from it freely as long as you dont affect my ability or rights to do the same, for this code, here or in any other game/platform.

CODE

integer ChannelWpn = 4;

integer AttackPower = 100;
integer AttackSpeed = 100;
integer AttackRange = 100;

default
{
state_entry()
{
llListen( ChannelWpn, llKey2Name( llGetOwner() ), llGetOwner(), "" );
}
listen( integer channel, string name, key id, string message )
{
list Arguments;
Arguments = llParseString2List( message, ["-=-"],[] );

string Command;
Command = llList2String( Arguments, 0 );

if( Command == "ATTACK" )
{
key Target;
string AttackType;
string AttackVector;
integer Power;
float CoolDown;

Target = llList2String( Arguments, 1 );
AttackType = llList2String( Arguments, 2 );
AttackVector = llList2String( Arguments, 3 );
Power = (integer)llList2String( Arguments, 4 );
CoolDown = (float)llList2String( Arguments, 5 );

// Need to add stuff to handle AttackRange here...
// Maybe Send Weapon range from weapon to SendDmg module over ChannelWpn?

Power = ( Power * AttackPower )/ 100;
CoolDown = ( CoolDown * 100 ) / AttackSpeed;
llMessageLinked( LINK_SET, 0, "SENDSECURECOM-=-ATTACK-=-" + (string)Target + "-=-" + AttackType + "-=-" + AttackVector + "-=-" + (string)Power, "" );
}
}
link_message( integer sendernum, integer num, string message, key id )
{
list Arguments;
Arguments = llParseString2List( message, ["-=-"],[] );

string Command;
Command = llList2String( Arguments, 0 );

if( Command == "STATUPDATE" )
{
string StatName;
integer StatValue;
StatName = llList2String( Arguments, 1 );
StatValue = (integer)llList2String( Arguments, 2 );
if( StatName == "AttackSpeed" )
{
AttackSpeed = StatValue;
}
else if( StatName == "AttackRange" )
{
AttackRange = StatValue;
}
else if( StatName == "AttackPower" )
{
AttackPower = StatValue;
}

}
}
}
ZHugh Becquerel
Registered User
Join date: 24 Oct 2003
Posts: 68
CombatSystems GRI - SecureComms module build 0001
11-25-2003 15:39
CombatSystems GRI - SecureComms module build 0001

Parameters:
- channel number for inter actor communication (talk with other avatars/monsters to attack them and be attacked)

Your rights to usage and derivation:

You can use this code and derive from it freely as long as you dont affect my ability or rights to do the same, for this code, here or in any other game/platform.

CODE

integer ChannelInterActor = 1;

default
{
state_entry()
{
llListen( ChannelInterActor, "","","" );
}

listen( integer channel, string name, key id, string message )
{
llMessageLinked( LINK_SET, 0, message, "RECEIVEDSECURECOM-=-" + message );
}
link_message( integer sendernum, integer num, string message, key id )
{
list Arguments;
Arguments = llParseString2List( message, ["-=-"],[] );

string Command;
Command = llList2String( Arguments, 0 );

if( Command == "SENDSECURECOM" )
{
string MessageToSend;
MessageToSend = llGetSubString( message, llStringLength( "SENDSECURECOM") ,1000);
llShout( ChannelInterActor, MessageToSend );
}
}
}
Mark Busch
DarkLife Developer
Join date: 8 Apr 2003
Posts: 442
11-25-2003 19:04
Can you show these scripts in action???
Mark Busch
DarkLife Developer
Join date: 8 Apr 2003
Posts: 442
11-26-2003 03:56
just a quick speed/memory tip:

using channel numbers instead of the -=- is probably a better way to tell what type of message it is.
It's faster and uses less memory...
ZHugh Becquerel
Registered User
Join date: 24 Oct 2003
Posts: 68
CombatSystems GRI - ReceiveDmg module build 0001
11-26-2003 11:57
CombatSystems GRI - ReceiveDmg module build 0001

Parameters:
- ChannelShield Make sure this is the same as wot is on your shields
- DeathTime: how long people should stay dead, in seconds

All other parameters are automatically read from shields, the stats module and so on.

This completes the CombatSystems GRI modules, and completes all high-risk modules from the Detailed Definitions of 24 November.

To do:
- unit testing
- integration testing
- docs

Your rights to usage and derivation:

You can use this code and derive from it freely as long as you dont affect my ability or rights to do the same, for this code, here or in any other game/platform.

CODE

integer ChannelShield = 4;

integer DeathTime = 40;

integer AC = 0;
integer MR = 0;
integer ProjArmour = 0;

integer NewAC = 0;
integer NewMR = 0;
integer NewProjArmour = 0;

integer PingInProgress = FALSE;
integer PingSent = 0;

TellPlayer( string Message )
{
llWhisper( 0, Message );
}

PingProtection()
{
if( !PingInProgress )
{
PingSent = (integer)llGetWallclock();
NewAC = 0;
NewMR = 0;
NewProjArmour = 0;
llWhisper( ChannelShield, "PROTECTIONPING" );
PingInProgress = TRUE;
llSetTimerEvent( 10.0 );
}
}

ReduceStat( string StatName, integer Amount )
{
llMessageLinked( LINK_SET, 0, "RAISESTAT-=-" + StatName + "-=-" + "-" + (string)Amount, "" );
}

SetStat( string StatName, integer Value )
{
llMessageLinked( LINK_SET, 0, "SETSTAT-=-" + StatName + "-=-" + "-" + (string)Value, "" );
}

ProcessDirectDamage( string AttackVector, integer Power )
{
integer Damage;
if( AttackVector == "MELEE" )
{
Damage = ( Power * 100 ) / ( 100 + AC );
}
else if( AttackVector == "MAGIC" )
{
Damage = ( Power * 100 ) / ( 100 + MR );
}
else if( AttackVector == "PROJECTILE" )
{
Damage = ( Power * 100 ) / ( 100 + ProjArmour );
}
ReduceStat( "Life", Damage );
}

ProcessAttack( string AttackType, string AttackVector, integer Power )
{
if( AttackType == "DirectDamage" )
{
ProcessDirectDamage( AttackVector, Power );
}
else if( AttackType == "ManaDamage" )
{
}else if( AttackType == "IncreaseMoveSpeed" )
{
}else if( AttackType == "IncreaseAttackSpeed" )
{
}else if( AttackType == "IncreaseAttackRange" )
{
}
}

EnforceDeathCondition()
{
TellPlayer( "You are dead. Please wait...");
// llShout( Channel, "KILLED" +"-=-" + (string)llFrand(1000.0) + "-=-" + (string)Attackerid + "-=-" + (string)Playerid );

llMessageLinked( LINK_SET, 0, "DEATHCONDITIONON", "" );
llStartAnimation( "dead" );
llMoveToTarget( llGetPos(), 0.2 );

llSleep((float)DeathTime);

llStopAnimation("dead");
llStopMoveToTarget();
llMessageLinked( LINK_SET, 0, "DEATHCONDITIONOFF", "" );

TellPlayer( "Ressurection completed" );
// llShout( Channel, "RESURRECTED-=-" + (string)llFrand(1000.0) +"-=-" + (string)Playerid +"-=-" ) ;

SetStat( "Life", 100 );
}

default
{
state_entry()
{
llListen( ChannelShield, llKey2Name( llGetOwner()), llGetOwner(),"" );
PingProtection();
}
on_rez( integer param )
{
PingProtection();
}
listen( integer channel, string name, key id, string message )
{
list Arguments;
Arguments = llParseString2List( message, ["-=-"], [] );

string Command;
Command = llList2String( Arguments, 0 );

if( Command == "PROTECTIONRESPONSE" )
{
NewAC = NewAC + (integer)llList2String( Arguments, 2 );
NewMR = NewMR + (integer)llList2String( Arguments, 3 );
NewProjArmour = NewProjArmour + (integer)llList2String( Arguments, 4 );
}
else if( Command == "INVCHANGE" )
{
PingProtection();
}
}
timer()
{
if( PingInProgress )
{
if( llAbs( (integer)llGetWallclock() - PingSent ) > 10 )
{
AC = NewAC;
MR = NewMR;
ProjArmour = NewProjArmour;
PingInProgress = 0;
llSetTimerEvent(0.0);
}
}
}
link_message( integer sendernum, integer num, string message, key id )
{
list Arguments;
Arguments = llParseString2List( message, ["-=-"], [] );

string Command;
Command = llList2String( Arguments, 0 );

if( Command == "RECEIVEDSECURECOM" )
{
if( llList2String( Arguments, 1 ) == "ATTACK" )
{
key Target;
Target = (key)llList2String( Arguments, 2 );
if( Target == llGetOwner() )
{
string AttackType;
string AttackVector;
integer Power;

AttackType = llList2String( Arguments, 3 );
AttackVector = llList2String( Arguments, 4 );
Power = (integer)llList2String( Arguments, 5 );
ProcessAttack( AttackType, AttackVector, Power );
}
}
}
else if( Command == "STATUPDATE" )
{
if( llList2String( Arguments, 1 ) == "Life" )
{
if( (integer)llList2String( Arguments, 2 ) <= 0 )
{
EnforceDeathCondition();
}
}
}
}
}
ZHugh Becquerel
Registered User
Join date: 24 Oct 2003
Posts: 68
11-26-2003 14:17
(for info, the avatar Hugh Perkins will be taking over this project)