05 Jul, 2010, Hades_Kane wrote in the 1st comment:
Votes: 0
I did some searching on google and some searching through the site but wasn't able to come up with any information on converting a ROM to using an unlimited bits system, other than links to places no longer working.

I recall people saying this is a tiresome process, but I'm interested in taking a look to see what it would take. Anyone have a link to a guide or snippet or whatnot that would be of any help?

Thanks!

(PS: This might be a good addition to the articles section)
05 Jul, 2010, JohnnyStarr wrote in the 2nd comment:
Votes: 0
Are you using gcc or g++?
I would rather use an std::map<T> going forward on my project than messing with pure bits. Not that they aren't great, but
computers are so much faster than the Diku days ya know?
05 Jul, 2010, Runter wrote in the 3rd comment:
Votes: 0
Some code I worked on for a while. A number of people have had success on various codebases.

[link=file]1015[/link]

It comes with some of the methods that would be required to get such a thing working properly. Like a way to read/write them as a string. There's a C and C++ version. This is the C link.

And another one I would recommend.

[link=file]2640[/link]


I seem to remember the parts that confuse people being the saving/loading. In rom it's just straight integers so there's no special process to save and load that field. It gets more annoying when you're trying to do it for *everything* that uses a flag. Like the flags on exits, items, rooms, characters, and so on. It's much easier to target one specific thing and get it where you want it. Like getting the flags for players where you want them, then working on something else.
06 Jul, 2010, Kline wrote in the 4th comment:
Votes: 0
JohnnyStarr said:
I would rather use an std::map<T> going forward on my project than messing with pure bits.


Can you elaborate why for me? I'm certainly not a C++ rockstar but I've been using bitsets and just converting them to a string value on save/load for easier maintainability and moving the # values without disrupting the game. Is this what you'd achieve with a map, sans the extra save/load routines?
06 Jul, 2010, David Haley wrote in the 5th comment:
Votes: 0
I have a C++ version lying around too; if you're interested I can dig it up. But most people seem more comfortable with C, which is why I put that version up. (As a result, I cleaned up the C version a bit too.)

Quote
I would rather use an std::map<T> going forward on my project than messing with pure bits. Not that they aren't great, but
computers are so much faster than the Diku days ya know?

I would use a std::set myself, where a bit is considered to be 'true' if it is in the set, and false otherwise.

Well, actually, I wouldn't use a std::set either, because the interface is slightly cumbersome; in particular, it is annoying to test if an element is in the set. I would use a wrapper around a std::set – well, I would actually use a wrapper around true bit vectors (similar to what Runter linked to but in C++), but basically the interface would all be relatively simple. (std::map objects suffer from similar annoyances of interface.)
06 Jul, 2010, JohnnyStarr wrote in the 6th comment:
Votes: 0
After looking into it, I agree with David. I'm spoiled from Ruby's Hash class. I assumed you could do boolean arithmetic with the [ ] operators.

if ch.flag[:drunk] && ch.flag[:broke]
ch.send "You've had enough buddy"
else
mob.give_more_beer(ch)
end


I was hoping the map would return false if the element didn't exist. I guess you would have to use something like:

mapIt = ch->flags.find(FLG_DRUNK);
if (mapIt != ch->flags.end())


Which sucks.
06 Jul, 2010, Kline wrote in the 7th comment:
Votes: 0
That does suck. Is there any compelling reason against std::bitset, though? if( thing.test(value) ) seems the simplest of options so far…
06 Jul, 2010, Runter wrote in the 8th comment:
Votes: 0
You must know the size of bitset at compile and as far as I know the memory is always in use regardless of the bits being set or not. Those are two compelling reasons for why it may not be appropriate if you have a lot of bits and a lot of masks in memory. It probably won't matters for most projects.
06 Jul, 2010, Hades_Kane wrote in the 9th comment:
Votes: 0
I appreciate the responses and advice, I'll take a look at the stuff provided and see if I can get something going from that.

I don't think I was using the right keywords in my search on the site when I was looking for some files :p
06 Jul, 2010, JohnnyStarr wrote in the 10th comment:
Votes: 0
Probably a bit late on this one, but are really running out of bits? Or is it something that you see happening in the future?
I've obviously not added as much content as you, so it's good to know in advance.

EDIT:

about what was discussed with maps and sets:

Couldn't you just overload the [ ] operator to return null if the map has no member at(N)
06 Jul, 2010, David Haley wrote in the 11th comment:
Votes: 0
I ran out of bits on standard Diku bitvectors, yes (32 and 64 bit).

Quote
Couldn't you just overload the [ ] operator to return null if the map has no member at( N )

You could write your own subclass of std::set, but you really don't want to change the semantics of the public interface because it could cause serious breakage in the rest of the STL code.

It would be easier to do something like I suggested and just write your own wrapper on top of the more primitive data structure. (The STL containers are more like container building blocks, IMHO, than APIs meant to be easy to use.)
06 Jul, 2010, Runter wrote in the 12th comment:
Votes: 0
@JS
You mean :drunk or :broke. :)
06 Jul, 2010, JohnnyStarr wrote in the 13th comment:
Votes: 0
Runter said:
@JS
You mean :drunk or :broke. :)


if mob.is_not_a_horrible_person?
if ch.flag[:drunk] && ch.flag[:broke]

else
if ch.flag[:broke] || ch.flag[:drunk] || ch.flag[:ugly]

end
06 Jul, 2010, Hades_Kane wrote in the 14th comment:
Votes: 0
JohnnyStarr said:
Probably a bit late on this one, but are really running out of bits? Or is it something that you see happening in the future?
I've obviously not added as much content as you, so it's good to know in advance.


Hehe… let's see…

I have 5 ACT_ flags left
3 immunity flags left
0 affect flags
1 item type
0 room flags
0 player flags
1 COMM flag

I already added a second set of room flags, and was doing the same for players when I thought it might be time to start looking at adding the unlimited thing. I already have weeded out and removed a lot of stock flags when I was running low, have been conservative in adding more, and have used the comm flags and such in place of when it would have been more appropriate to have been a player flag instead.

So yeah…
07 Jul, 2010, JohnnyStarr wrote in the 15th comment:
Votes: 0
wow, I see what you mean.

If you are currently restricted to gcc, I was thinking a Binary Search Tree might be an efficient alternative. You could just use an enum to make a list
of integers which would be the value stored in each tree node. It wouldn't help with size, but it would be faster than a linear search. In Big-O Notation
it's O(log n) vs. O(n) The downside is that the growth (in memory) would be exponential, but you would definitely have all the flags you could ever want.
07 Jul, 2010, Runter wrote in the 16th comment:
Votes: 0
I don't think search time is going to matter here. n is always going to be a relatively small number. If anything is worthwhile it is reducing memory, but even that isn't really. My advice is doing whatever is easiest to write, read, and maintain and focusing on programmer efficiency here.
07 Jul, 2010, David Haley wrote in the 17th comment:
Votes: 0
Wait… uh… no, don't go to binary search trees… A measly 10-byte bitvector gives you 80 flags. You want 1,000 flags? You only need 125 bytes. You want a binary search tree? You'll have to spend 12 bytes (or 20 on a 64-bit machine) just to get a single node with 32 flags.

Nobody is doing linear search here, by the way. Testing if a given flag is set is a constant-time operation. You certainly aren't traversing the flag set. So using a BST would actually be slowing things down.

It's also very easy to make a dynamically growing byte-based bitvector. It's as simple as a growing array, really. Let's not get carried away over-engineering things here. :wink:
07 Jul, 2010, JohnnyStarr wrote in the 18th comment:
Votes: 0
Actually, I didn't say anything about boolean arithmetic using linear search. I was just saying if you were going to use integers as flags, a BST would be faster than just a list of flags, and then
having to iterate through each one to see if IS_SET.

I also said "the growth would be exponential". :biggrin:
07 Jul, 2010, David Haley wrote in the 19th comment:
Votes: 0
Quote
Actually, I didn't say anything about boolean arithmetic using linear search. I was just saying if you were going to use integers as flags, a BST would be faster than just a list of flags, and then having to iterate through each one to see if IS_SET.

Right, and that's what I'm saying; finding if a given bit is set doesn't require you to traverse the integers one by one, you need merely jump to the correct byte (bit_num/8, using integer division) and then jump to the correct bit (using bit shifts).
Perhaps you mean that you would keep a list of active flags, instead of a full list of active/inactive flags? In that case, yes, if it was just an unsorted list representation, you would need to step through it linearly.


Also, BST growth isn't exponential. In fact, it's linear. For a tree with n nodes, you have n values plus 2n pointers to nodes. Therefore, assuming that sizeof(value) =~ sizeof(pointer), space requirements are 3n. (Well, also note that you can represent a binary tree using an array and thereby eliminate the pointer overhead, but of course this makes growing the tree more expensive.)
17 Jul, 2010, Rarva.Riendf wrote in the 20th comment:
Votes: 0
Another easy solution:
As an example you have AFFECT that use flags in char_data
Just add an AFFECT_2 field.
Duplicate affect code everywhere it needs to (not that many places)
tada, done, off course if you really need THAT many flags added…better find another solution.
0.0/38