Angband.oook.cz
Angband.oook.cz
AboutVariantsLadderForumCompetitionComicScreenshotsFunniesLinks

Go Back   Angband Forums > Angband > Development

Reply
 
Thread Tools Display Modes
Old September 13, 2015, 20:41   #1
TricksterWolf
Scout
 
Join Date: Sep 2012
Posts: 43
TricksterWolf is on a distinguished road
Lightbulb Reworking the entire magic system (yay)!

This is a thread where I will dump questions I have while I am reworking the entire magic system.

I have a situation where I want characters to have racial and class-based magic, with potential overlap between the two, and access to more than one realm of magic. The caster armor weight limit and mana stat will be determined by class.

I'm pulling all the magic information into the "books" themselves and front-loading all of it with a spell parser and a "book" parser instead of saving it with the player's class data. Each "book" will have a realm, and outside of a "book" the language will be generalized to "item", "magical feat", etc. The player will have the caster armor limit, mana stat, lowest-level "spell", total "spells" possible, and list of "spells" they can "cast" in a single struct.

I don't think it will be hard to calculate and cache the lowest-level "spell" a character can perform or the total number of "spells" a character can have: I should be able to min and sum those at birth.

It currently looks like there's a hard limit of 98 spells total in the game. Is that because it's using a signed byte? Is 'byte' a signed or unsigned byte? I'd like to pump that sucker up above 255 if possible, so would changing spell_order to a u16b* be sufficient, as I suspect...? Breaking savefiles is (obviously) not a problem.
TricksterWolf is offline   Reply With Quote
Old September 13, 2015, 22:19   #2
debo
Veteran
 
debo's Avatar
 
Join Date: Oct 2011
Location: Toronto, Canada
Posts: 2,364
debo is on a distinguished road
Quote:
Originally Posted by TricksterWolf View Post
This is a thread where I will dump questions I have while I am reworking the entire magic system.

I have a situation where I want characters to have racial and class-based magic, with potential overlap between the two, and access to more than one realm of magic. The caster armor weight limit and mana stat will be determined by class.

I'm pulling all the magic information into the "books" themselves and front-loading all of it with a spell parser and a "book" parser instead of saving it with the player's class data. Each "book" will have a realm, and outside of a "book" the language will be generalized to "item", "magical feat", etc. The player will have the caster armor limit, mana stat, lowest-level "spell", total "spells" possible, and list of "spells" they can "cast" in a single struct.

I don't think it will be hard to calculate and cache the lowest-level "spell" a character can perform or the total number of "spells" a character can have: I should be able to min and sum those at birth.

It currently looks like there's a hard limit of 98 spells total in the game. Is that because it's using a signed byte? Is 'byte' a signed or unsigned byte? I'd like to pump that sucker up above 255 if possible, so would changing spell_order to a u16b* be sufficient, as I suspect...? Breaking savefiles is (obviously) not a problem.
Haven't looked at source but usually people #define 'byte' to be 'unsigned char', which tells the compiler to make things basically behave like a bitpattern iirc. You should be able to find it in whatever .h file is the "here's all my shared crap".

This means that you should have up to 255, unless 'byte' is for some reason 'signed char'. If it's just 'char' I think you're also sort of fine but that type is really only intended to store data that is read via some encoding (e.g. ascii), iirc.

There doesn't seem much reason in 2015 to not have this be some sort of integer type, so your plan sounds reasonable

Edit: Even if it's a "signed byte" (a ridiculous concept), you still have up to 127.
__________________
Glaurung, Father of the Dragons says, 'You cannot avoid the ballyhack.'
debo is offline   Reply With Quote
Old September 13, 2015, 23:09   #3
Nick
Vanilla maintainer
 
Nick's Avatar
 
Join Date: Apr 2007
Location: Canberra, Australia
Age: 54
Posts: 7,841
Donated: $60
Nick will become famous soon enough
Quote:
Originally Posted by TricksterWolf View Post
It currently looks like there's a hard limit of 98 spells total in the game. Is that because it's using a signed byte? Is 'byte' a signed or unsigned byte? I'd like to pump that sucker up above 255 if possible, so would changing spell_order to a u16b* be sufficient, as I suspect...? Breaking savefiles is (obviously) not a problem.
Why do you think 98 is the limit? I don't think there is a limit in 4.0.

Interesting ideas, btw
__________________
One for the Dark Lord on his dark throne
In the Land of Mordor where the Shadows lie.
Nick is offline   Reply With Quote
Old September 14, 2015, 02:23   #4
TricksterWolf
Scout
 
Join Date: Sep 2012
Posts: 43
TricksterWolf is on a distinguished road
Quote:
Originally Posted by Nick View Post
Why do you think 98 is the limit? I don't think there is a limit in 4.0.

Interesting ideas, btw
It should be 99 actually.

The magic number 99 is used as a marker in spell_order* to denote a spell that has never been learned so that it will be skipped when forgetting spells. This implies a player with 100 spells will end up marking a spell as "never learned" in the spell_order, which will cause you to forget only the first 99 spells you learn rather than the most recent spells (among other potentially more serious errors). This is more of an issue for my build because the spell information is no longer going to be stored with the player at all, so I'll want spell_order* to range over all spells in the entire game for simplicity.

I've fixed this by defining PY_SPELL_NEVER_LEARNED to 65000 (instead of using hard-coded 99 as the cap for spells remembered) and changing it to a u16b. This inflates savefiles by a couple of kilobytes, but means I should be safe for up to 65000 spells.

And it seems to work so far. The big changes I'm working on now are as follows:

struct player_magic (loaded from both race.txt and class.txt into player)
. int spell_first (lv of 1st spell over all spell sources/realms)
. int spell_weight (by class)
. int mana_stat (by class; casting stat may be different!)
. byte *spell_level (req. lv for all spells cast by THIS character, 0 if can't)
. byte *spell_mana (mana for each spell; 0 is possible)
. byte *spell_fail (base fail-rate for spells cast by THIS character)
. byte *spell_flags (moved from player. to player->magic.)
. u16b *spell_order (moved from player. to player->magic.)

struct magic_book (loaded from books.txt, probably into obj_kind)
. int tval
. int sval
. int num_spells
. int *spell_index (must contain at least one spell: spell 0 determines book realm)

struct magic_spell (loaded from spells.txt into new m_info var)
. int index
. char *name
. int spell_realm
. char *text
. struct effect *effect (as before)

in obj-util.c:
. struct magic_spell *m_info

I'm probably adding magic_book to obj_kind (best guestimate), and player_magic is replacing class_magic in player. So it will be player->magic. instead of player->class->magic. essentially, and global m_info will hold all the spell information.

The big work during birth will be carefully updating the level and fail rates for spells so that the character gets the best level and fail rate from any overlapping items.

I'm removing sexp entirely in favor of just using (spell_level+1)*(spell_mana+1) to determine exp gain the first time a spell is cast (at all, not per book).

EDIT: I'm updating this as I change stuff around.

Last edited by TricksterWolf; September 14, 2015 at 17:01.
TricksterWolf is offline   Reply With Quote
Old September 14, 2015, 13:07   #5
PowerWyrm
Prophet
 
PowerWyrm's Avatar
 
Join Date: Apr 2008
Posts: 2,666
PowerWyrm is on a distinguished road
The "99" marker is for illegible spells and that's now obsolete with the refactored spell system. I bet it can be removed easily.
__________________
PWMAngband variant maintainer - check http://powerwyrm.monsite-orange.fr (or http://www.mangband.org/forum/viewforum.php?f=9) to learn more about this new variant!
PowerWyrm is offline   Reply With Quote
Old September 14, 2015, 16:34   #6
TricksterWolf
Scout
 
Join Date: Sep 2012
Posts: 43
TricksterWolf is on a distinguished road
Quote:
Originally Posted by PowerWyrm View Post
The "99" marker is for illegible spells and that's now obsolete with the refactored spell system. I bet it can be removed easily.
Yes, but the problem remains when you hit 256. If my 255th spell is Magic Missile and my 256th spell is Fireball, I'll forget Magic Missile first. Spells may work past 255 but spell-forgetting-order won't because it's stored in a byte. That's what I changed.

EDIT: Also, I think I want illegible spells now that I'm refactoring the system so spell information is not repeated endlessly in class data. I think the current system of repeating spell information is a mess and it makes class.txt a horrendous pain to read.

Last edited by TricksterWolf; September 20, 2015 at 20:28.
TricksterWolf is offline   Reply With Quote
Old September 20, 2015, 05:08   #7
TricksterWolf
Scout
 
Join Date: Sep 2012
Posts: 43
TricksterWolf is on a distinguished road
Post

To ask the above less confusingly, perhaps.

I don't understand how here:

Code:
static enum parser_error parse_spell_name(struct parser *p) {
    struct magic_spell *next = parser_priv(p);
    struct magic_spell *spell = mem_zalloc(sizeof *spell);
    spell->name = string_make(parser_getstr(p, "name"));
    spell->next = next;
    parser_setpriv(p, spell);
    return PARSE_ERROR_NONE;
}
...parser_priv(p) successfully gives me a pointer to the next spell yet-to-be-parsed, yet here:

Code:
static errr finish_parse_spell(struct parser *p) {
    m_info = parser_priv(p);
    parser_destroy(p);
    return 0;
}
...parser_priv(p) gives me a pointer back to the initial spell after all the spells have been parsed. How can I access the last spell in the list in a way that will let me set its next field to NULL?

Or more directly, is there some way I can check *p in the very beginning to see if I've parsed the final spell in my spell.txt file...?
TricksterWolf is offline   Reply With Quote
Old September 20, 2015, 14:21   #8
TricksterWolf
Scout
 
Join Date: Sep 2012
Posts: 43
TricksterWolf is on a distinguished road
Alright, I've decided I'm probably going to use z_info->s_max to keep track of the total spell number, because 0) I can't figure out how to get the parser to hoof me a reference to the final spell parsed without an ugly hack, and 1) it looks like z_info->s_max is totally unused, which is weird.

Oh, parser. You are so magical.

EDIT: It's working, though for some reason my spells are loaded into m_info in reverse order.

I should probably be doing some cleanup, like declaring an array of magic_spell and copying the spell data in and attaching m_info to the array. I don't think it matters, though, because I never use m_info once all of the objects have been parsed (the objects have a separate linked list of magic spells with pointers copied from m_info).

Last edited by TricksterWolf; September 20, 2015 at 20:05.
TricksterWolf is offline   Reply With Quote
Old September 20, 2015, 21:22   #9
TricksterWolf
Scout
 
Join Date: Sep 2012
Posts: 43
TricksterWolf is on a distinguished road
Is there a simple way to flush the debug() buffer? It's usually several hundred characters behind where it should be.
TricksterWolf is offline   Reply With Quote
Reply

Tags
byte, magic, savefile, spell, u16b


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Mk build system? CJNyfalt Development 11 March 25, 2015 08:25
Resist system Jungle_Boy Development 65 August 30, 2011 04:10
Yay INT2BYTE! PaulBlay Development 2 May 3, 2009 11:59
Export entire message log to text file PaulBlay Vanilla 2 February 28, 2009 20:24
Magic system thoughts Mangojuice Variants 16 November 13, 2008 03:51


All times are GMT +1. The time now is 06:02.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.