Brendan Lally wrote:

  I just don't really see what we get by having to do it via a purely request
basis.  I can't really see the client not sending a request when things change.

I can, that's why I started off with the status values. If a client
only shows spell names, or only names and denied status, they would
only request a new copy of the list on status 4 or 4 & 2 respectively.

  If there is the potential of client only sending requestinfo based on what
changed, that could also be done with a push approach (setup spellmon val, and
based on val determines what events we send spell updates.

This could work, but requires a new command in the protocol.

I don't know why it would require a new command. the setup command is not true/false values, it is setting some variable to whatever value.

 So a 'setup spellmon 6' is perfectly valid.

And to push the data, the same command could be used - it'd just need to be clarified that spellist would represent updates to existing data. Or the spellist command could send optional params to denote what it is updating.


  the other advantage of push is we can be more bandwidth efficient.  If a
player learns a new spell, only need to send that spell down the line, and not
all the spells if done on a pull approach.

I thought about that, but I can't see how it can be done without the
server storing the spell list for each player, which is a fairly ugly
way to implement things. (the only other thing I could think of is to
abuse the spell objects, and set an update value for each one (added,
removed, changed costs, changed damage, etc)

 Same way it is done for most objects - you send it at the time of the event.

So in server/apply.c, in learn_spell, you'd make a call to send_spellist() when the player learns a spell.

This is how most all of the object updates for player inventory are currently done - the update is sent in the code that makes the change - we don't hold the results and send them later.


2) I wonder if more spell info should be sent.  For example, base damage values,
lore information, etc.  If we only send spells on push, bandwidth shouldn't be
that costly, and it then gives the player more info to choose spells (fireball,
24 dam, ...).

Lore and damage seem reasonable, although then the question is, should
that be base damage or effective damage? Both of these values have
issues, effective damage may not do as much damage as stated (even
before resistance) owing to quirks in how each spell propagates, if
base damage is sent, then you need to send a lot more data and
hardcode the calculation. (more on that below)

For damage, we obviously can't take into account resistances of creatures. So it'd be basic damage - if the spell does more, like cones, because of multiple effects on top of each other, we don't factor that, as you can't really know for sure how that will work out (likewise for fireballs - damage would vary greatly based on where the creature is in the effect). The lore info could note those increased effects.


Related, I think it'd be easier all around to send the spell path
information as a bitmask - saves some bandwidth, and the bitmasks values should
be pretty stable (can't remember last time a new spell path was added, and even
then, the client could just display something like 'unknown' or whatever)

This could work, although currently the clients have no information
about spellpaths.
This could be added, although maybe then a request_info spellpaths
would be better to initialise it? (this way clients couldn't fall out
of sync, and there is no restriction on adding new paths).

Perhaps, adding requesting adds complication, but not that much. At the same time, there is a lot of communication that is defined stable. IF someone were to add another stat for example, that would require some significant changes - the client isn't designed for dynamic stat information.

At some level, it could be nice for the server to somehow note what current client version is and tell the player if their client is out of date. So if the client is out of date, they'd know to go update it - that'd be good for reasons beyond just spellpaths.

But hardcoding them or doing via requestinfo both work. Note of course the spell path info in this case is really the bitmask to name mapping. For all spell calculations itself, the client wouldn't really care (player bitmask is attuned 4, denied 24, repelled 1. This spells path is 16, so it is denied to the player, etc). It doesn't need to know what spell path 16 is to make those calculations.

But that is one reason why I say giving the client hte numbers is easier - it makes handling easier. Otherwise, what I'm sure will happen is at some point someone will come up with code in the client that takes the spellpaths and converts them into bitmasks, etc.

If I've learned one thing through lots of client/server programming, almost always best to send the raw data and let the client figure out what it means vs having the server try to figure out what it thinks the data should look like and send that processed data to the client.


3) Related to point #2, I wonder if it would be 'easier' to just send the base
values for costs that the server users to calculate real cost.

more consistant in terms of data sent in a single iteration. but
SP_level_spellpoint_cost - the function that does this server side,
calls on about half a dozen other values, all of which the client
would need to know, and some of which
(settings.spellpoint_level_depend for example) are quite obscure. If
ever the method used to calculate cost changed, then this would fail
hopelessly. I don't think a commitment to keep the same spell costing
rate can be made, therefore hardcoding it into clients is a bad idea.

well, settings.spellpoint_level_depend determines if spellpoint costs differ - it is either an on/off value.

 Looking at other values:
 Since the spell is linked to a skill, the client does know the skill level.
The client also will know the spell level (one of the most importent bits of the spell).
 As per notes above, it would also know the spell paths.
To figure out actual sp costs, it would need the sp/maxsp and grace/maxgrace values. the PATH_SP_MULT macro is perhaps the most variable. However, since that macro has values hard coded in (not pulling it from settings or anyplace else), probably relatively hard coded.

 All that said, one could see something like a C->S: requestinfo spell_conf,
in which the server responds with those values. But that does make things more complicated. But I don't think those values have changed in 5+ years, so I'd call them relatively stable also.



  Otherwise, whenever the player equips an item that changes their spellpaths,
you get the case of potentially all the spells changing in value.  Level changes
can also effect costs, and that is likely to happen when you really don't want
more data sent down, eg, in combat.

This would be where the logic behind letting the client decide when to
request the information comes into play.

But I don't really see how the client can make any real intelligent decision on that. It would basically seem to me that the client will request a spell dump if the spells have changed and it matches why it wants updates.

I can't see the client really being able to know that the player is in combat and thus now is a bad time to request all that data.

I'd think at best the client could perhaps decide 'at most, I'll request spell info every 10 seconds' or something. But then you'll get the case where a player equips something that makes them attuned, goes to cast the spell, and is confused because the client is still showing old data in terms of spell cost and damage.

This may seem trivial, but when it happens, I'm sure bugs will be filed and people complain.


The only change needed for that to really
work would be to send down the players current spellpaths in the stats command.

This seems like quite a good idea, it is simpler and yet more powerful
than the status I have been using.

  Thus, the only time in this case you really need to send spell information is
when the player learns a new spell.  That said, it does complicate the client a 
bit.

I'm more concerned with how it complicates the server, it will mean
that each spell will need to track its status independently.

See note above. You'd just inject the appropriate send spell data command wherever the player can learn a spell. And in fact, the number of places a player can learn a spell is limited- in fact, I think it all leads back to do_learn_spell(), and all the data that is needed to send the data to the client is there (player object, spell object, etc).


It might be possible to pick an unused value in the spell objects, and
use this to hold states, and then iterate over them with a diff like
syntax.

so we might have

spellupdate
!spark shower:1:176:Electricity:0:5:0:Sparkshower is a cone of
electrical energy.
Creatures caught within the cone take magical and electrical damage.
+holy word:1:170:Turning:0:0:4::
-burning hands:1:174:Fire:1:4:0::
(icidentally, these last two do not have msg's)

In this case then, every line altering a spell would start with + - or
! to add, remove or modify a spell respectively, any line not starting
with one of these characters, would be the next line of the msg
associated with the previous spell.

This could still lead to a lot of traffic at login, although maybe
that is preferable than a lot of traffic during combat.

 Right now, I believe it is basically a requirement that spell names be unique.

This, it can be assumed (within the protocol) that if a spellupdate contains a spell name that the client already knows about, it is just and update for that spell. If it contains info it doesn't know about, it is a new spell.

Right now, other than DM action, there is no way to lose a spell. But for that, might just be easiest to do something like 'spellremove ....', and just like do_learn_spell() being the only place to add a spell, the only place to remove a spell is probably just a few places so wouldn't be hard to do.

In terms of bandwidth, I wonder if it is reasonable to do some form of caching of the message info, eg, the client have a spell file that contains the info it got. Instead of the server sending the message text each time, it sends a checksum of the message data. The client could load the spell up from its history file and see if the checksum match - if so, use the one in the history file, if not, request info from server.

_______________________________________________
crossfire mailing list
[email protected]
http://mailman.metalforge.org/mailman/listinfo/crossfire

Reply via email to