Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Sign in to follow this  
gggmork

annoying questions you should ignore

Recommended Posts

Suppose I draw a bunch of polygons in doombuilder with some shared sides/points. LineA shares a point with lineB, sectorM shares a line with sectorN, etc. This implies that there should be a list of unique 'real' points and a list of unique 'real' lines SOMEwhere, and each sector should have either a reference or an index to that 'real' line (so 2 sectors can 'point' to the same line). NEWAYZ, well like 'global variables are bad' supposedly in OOP right? So putting a big list of real points out there in global land is maybe bad? Perhaps I should make another class called GlobalData() or something with a big list of all the 'real' points/lines/sectors inside that class, then have stuff reference stuff inside that class.

Does original doom really use 'references' or do sectors share lines etc by having the same index to a line object in a list/array?
For example, in python's omgifol:
myEditor.linedefs[25].vx_a
is an INDEX to the vertex in the vertexes list, not a reference to that vertex.

Another thing (just for curiosity mostly cuz I'll never get good enough to do this), a WAD file is ultimately essentially a single big binary number right? I read the doom wiki on it and no need to textwall details like 'little endian' or whatever, the point is just that if I maybe use python to read a WAD file, is it just essentially a question of changing the right bits in a single big binary number to, say, move vertex #127 on map 23 left 4 pixels?

Its amazing how constipated my brain is in thinking about complicated programming stuff. I think its too visual-oriented to think in 'code', or too retarded. Maybe if I bang on the side of my tilted head, my brain can urinate all my idiocy out of my ear, seems plausible. Like I drew a rectangle in doombuilder and filled it with random polygons, drew little pictures in paint etc and am staring at this stuff forever going 'wtf happens if I X'. No, that's giving me too much credit.. I usually don't progress past 'wtf' to any specific question. No hope in answering a question you can't even ask!

Doom data is weird, like a sector seems like it should be made of lines and/or points.. but doom sectors are just flats and heights basically. Sidedefs point TO sectors but sectors don't point to anything, seemingly making them hard to code with. For example, lots of doom action lines say 'sector raise to lowest adjacent sector'. How is a sector that references nothing going to find its lowest adjacent sector.. um.. loop through every linedef.. find only the sidedefs that reference that sector.. go back to the linedef and find its opposite sidedef.. find that sidedef's sector.. ta da! maybe!

I actually selected the 'DUMB' message icon instead of having it default to that.

Share this post


Link to post

When I started writing DB2, I tried both the references approach and the indexed approach. DB1 used the indexed approach, but that was not programmed object-oriented and DB2 really is. I found that the references approach is much more efficient in this case. You always have to update certain references when something is removed or otherwise changed in the map, but once you got that right, this is no big deal anymore. (Also, with the indexed approach you have to update certain indices when anything is removed, see horrible DB1 code) The benefit of the references approach is that traversing data structures is much fast (probably due to less table lookup overhead).

Also, DB2 has 'backward' references. A sector keeps a list of its sidedefs and a vertex keeps a list of attached linedefs. This also helps with traversing data structures as you don't need to 'scan' all linedefs to find out which ones belong with a certain vertex.

This doesn't mean you should do this as well, it really depends on what you need to get done, but this is just my 2 cents.

Share this post


Link to post

Yeah, doing it the index way and then deleting an item, thus shifting all the indexes after it down 1 when other things were 'pointing' to those indexes sounds like a real headache. Alternately each item could have an id# so when you delete something the id stays the same.

I'm just trying to do something like automatically fill a somewhat large rectangle with many sub rectangles of randomly varying sizes (I think I'll stick to rectangles instead of more complex polygons for now...).. make lots of these pieces, and paste them around next to eachother automatically, making the heights so you can walk from piece to piece and texture stuff automatically etc. Its confusing to think 'how to I select/point to/get the item I want' just using code instead of pointing right at it with a mouse to select it. When you point at a line/point/sector and click you just get the item nearest to the mouse instead of worrying about what things are named I guess. Luckily no 2 points in doom can have the same x/y data, so the data kinda IS each item's unique name (if multiple points could have the same data, ie. be on top of eachother, then finding point (24,48) could find TWO points or something, like having both points named "Bob" or something, erg.

I guess I'll try the references approach since that worked for you, but ultimately I have to later convert the final map creation back to big lists and indexes to 'feed' the data to the way omgifol wants it. Its too confusing to even mentally prove that would be possible.. probably, coding is like building something with legos using only your feet while blindfolded and its a crapshoot whether the pieces in your bucket are even capable of forming what you intend. I'll probably make a clunky hacky wannabe (that word passed spell checking..) parasite on top of omgifol instead of edit that code directly because its hard to understand, if I end up doing anything at all.

Share this post


Link to post
gggmork said:

...thus shifting all the indexes after it down 1...

Or just move the last item to the removed index, then you only have to update those indices.

Share this post


Link to post
gggmork said:

Does original doom really use 'references' or do sectors share lines etc by having the same index to a line object in a list/array?


On-disk, all structures reference each other via indexes, and that puts some funny limits on how many sectors, lines, vertexes etc. there might be in a map, because those indexes are usually stored as 16-bit integers, and what's worse, vanilla doom code interprets them as signed in most cases, so there can only be 32K lines, 32K sectors, 32K vertexes etc. unless you use a limit-removing port with proper map-reading extensions in place.

However, once read into memory, most on-disk map structures are converted to slightly different ones, which use proper references (or pointers), so the index/reference dichotomy only exists between disk/memory format.

Ideally, an editor should work with the less restrictive and easier to update one, aka references, even though they have to be converted into indexes for PWAD distribution.

gggmork said:

the point is just that if I maybe use python to read a WAD file, is it just essentially a question of changing the right bits in a single big binary number to, say, move vertex #127 on map 23 left 4 pixels?


Yeah, it's possible, but like all sorts of binary formats, it will be very hard to locate the right bits without a knowledge of what every other bit in the file is, something that you can't really do unless you properly read the PWAD's header, locate its "table of contents", and know where each lump starts/ends. The only programs operating in the way you described are binary patchers, which assume a very specific version of a file.

Share this post


Link to post

Ha ha, putting the last item to the removed index sounds like a much better solution.
I guess even lower than 32k sectors because the lines/vertexes will max out first. I still have to learn precise 'under the hood' definitions of pointer vs reference vs index. Interesting to know a wad could potentially be edited as a big binary number (I don't know much about files so thought a wad might have a maze of 'folders' inside it or something.. it kinda does anyway because some of the bits represent a 'directory'). I just quickly searched how to read/write binary files with python:
http://linux.byexamples.com/archives/478/python-writing-binary-file/
but will probably keep using omgifol for the time being instead.

Share this post


Link to post

Everything on a computer can be treated as a binary number. That's because, fundamentally, it is a binary number.

This has some interesting ramifications...

Share this post


Link to post
Gez said:

Everything on a computer can be treated as a binary number


Sure, but it makes more sense to know e.g. that a vertex is organized in 10-byte groups ("data stuctures") and that it contains 16-bit field corresponding to x,y coord etc. and is stored in a structure with all other lumps which starts at a certain byte offset from the beginning of the file, rather than "change bits #2234234, #7324324 and #2342343 of the binary number 1110010010101...........(a fuckload of digits).....1101 for no apparent reason :-p

As I said, only file-patching programs operate in that fashion, that's why they are so inflexible and will crap out if the target file is different than what the patch was designed to fix by even one bit, even if the file's contents may be totally equivalent from a functional point of view.

Share this post


Link to post
gggmork said:

Its too confusing to even mentally prove that would be possible.. probably, coding is like building something with legos using only your feet while blindfolded and its a crapshoot whether the pieces in your bucket are even capable of forming what you intend.

Well, it indeed shouldn't be like this, but sadly it's what everyone does. See this; I don't have anything significant to add.

Share this post


Link to post
tempun said:

See this


Nice read, thanks for the link (the domino puzzle solution was interesting).

If I want to fill a rectangular area with randomly shaped sectors, I'm suspecting it might be easier to first pack it with orderly triangles (or squares). Then randomly merge multiple small triangles together to get bigger more complex shapes.

Share this post


Link to post

Yeah, they already are; I just never bother to put stuff on idgames with an official 'permissions' type text, mostly because of the weird 'ftp' stuff I don't want to figure out. Use in any way, no need to even 'credit' me.

While this is bumped I might as well say some stuff about my fail program which is currently a toppling mess of unfixability. (program is meant to make rectangular areas that are packed with randomly shaped polygons.

First I figured out that giving each element in a list/array an id, instead of using its index directly as its id, is FAIL. Because you have to loop through and FIND the id, which means lots of complex loop structures that waste time and confuse. (I know references were recommended but it was an experiment)

Second, I figured out how to do 'fake' object oriented programming using procedural/imperative, which maybe everyone else knows about but is new to me (oop is probably better, but I'm experimenting). For example, this is a FUNCTION, not a class, yet it returns data that is kinda object-like.

def newVertex(x,y,linedefIds):
    global vertexIdCounter
    vertex = {'x':x, 
              'y':y,
              'linedefIds':list(linedefIds),
              'id':vertexIdCounter}
    vertexIdCounter+=1
    return vertex
ie. just use dictionaries (aka hashes I think) as the fake class attributes, whatever.

Third I thought of 3 algorithms to pack a rectangular area with polygons (I wanted all lines snapped to 45 degree increments and all vertexes snapped to 64 grid).
First, is just draw one at a time, tracing over whatever other shared sides of existing polygons. Seemed too hard, didn't bother.
Second is first pack the rectangle with a bunch of small squares or triangles, then 'merge' larger polygons out of that. Might work but didn't really try.
Third, which seemed to work but the whole program toppled over in failitude before I knew for sure, is to focus on the lines; start with the rectangle, then meander a line randomly through to divide that into 2 sectors, repeat n times. So the line/path kinda automatically draws 2 sectors at once without having to worry much about their hairy connections to other sectors.

Also all lines were split into 32 length increments, so its easier to test whether the meandering path hits an existing point (rather than testing if its between points etc).

Whatever it sucks and doesn't work. Probably need to redo using oop and references and focus on sectors as the main object units.

Share this post


Link to post

Here's another doombuilder 2 question:

You can draw the biggest possible large square (65536) and view at 100% scale with 'view floor textures' selected and press arrow keys to move the camera around. And you can see all the pixels in the floor/etc.

This implies that there is a single enormous 65536 pixel 'surface' (aka picture) in memory, probably with a camera rectangle for zooming in/out.

Well in stupid ass pygame (for python) I tried to replicate this zooming, and the biggest surface it can handle is probably only about 4096 before SDL (which pygame is a 'wrapper' for) complains that the surface is too big or the program might freeze. So sigh, what, do you have to dice a would-be huge surface into a grid of smaller surfaces or something? Or does pygame just suck and c/etc can handle large surfaces?

I was happy I actually got something working (like it zoomed toward where the mouse was pointed, like how DB does it, which was a miracle because I suck at programming/math, even managed to draw grid lines afterward (so the pixels of the picture get bigger when you zoom but grid line thickness stays same 1-pixel wide at any scale)). But like usual some hurdle completely blocks me.

Share this post


Link to post
gggmork said:

Well in stupid ass pygame (for python) I tried to replicate this zooming, and the biggest surface it can handle is probably only about 4096 before SDL (which pygame is a 'wrapper' for) complains that the surface is too big or the program might freeze. So sigh, what, do you have to dice a would-be huge surface into a grid of smaller surfaces or something? Or does pygame just suck and c/etc can handle large surfaces?



If you think a minute about the actual size of the surface you tried to create it should be obvious why it can't work.

Share this post


Link to post

The important thing is that in DB2, the "enormous surface" isn't texture-mapped on a 1-texel-per-pixel ratio. The floor textures are typically (especially in vanilla) 64x64 texels, tiled. That takes a lot less space in memory.

Furthermore, DB2 uses DirectX, so the most annoying parts of rendering are outsourced to the video hardware.

Share this post


Link to post
Graf Zahl said:

If you think a minute about the actual size of the surface you tried to create it should be obvious why it can't work.


Maybe obvious to a smart person. I made a 4096 image in mspaint.exe and drew thin 1x pixel pencil lines easily, but Tried a 8192 image, and it crashed, instead of taking 4 times longer which would seem more intuitive.
Also I did a test in pygame, instead of making one 65536 surface, I made 64 1024 surfaces which should be the same amount of pixels overall. The one 65536 surface crashes or makes errors, but the 64 1024s are all created and blitted to the screen with a random color in maybe 1.5 seconds.

Graf Zahl said:

The important thing is that in DB2, the "enormous surface" isn't texture-mapped on a 1-texel-per-pixel ratio. The floor textures are typically (especially in vanilla) 64x64 texels, tiled. That takes a lot less space in memory.

Furthermore, DB2 uses DirectX, so the most annoying parts of rendering are outsourced to the video hardware.


First time I've heard of 'texel'. I assume that's like when you zoom really close and it gets blocky, each 'block' is a texel is sort of like a pixel scaled up to a bigger size (taking a block of pixels to represent a single pixel).
But at 100% scale it sure looks like a 1-1 ratio; you can see every detail of the floor texture. You mean its really some sort of anti aliasing blend of neighboring pixels or something. Like its 'real' width isn't 65536, but much smaller?
Maybe you're saying that instead of a huge 65536 pixel area, it really just has ONE 64x64 floor texture and the same texture is somehow repeated over and over without redundant duplication of that same texture over a large area.

Well I'm probably too dumb to implement all this 'texel' complexity so maybe I should just make like a 2048x2048 area, with smaller thumbnail images of the floor, then just pretend its 65536 long, like multiply by 32 when you click somewhere etc. As if I'll get all this stuff to work anyway.

Share this post


Link to post
gggmork said:

I made a 4096 image in mspaint.exe and drew thin 1x pixel pencil lines easily, but Tried a 8192 image, and it crashed, instead of taking 4 times longer which would seem more intuitive.

It's just programmers who wrote it can't be arsed to make it work

gggmork said:

Also I did a test in pygame, instead of making one 65536 surface, I made 64 1024 surfaces which should be the same amount of pixels overall. The one 65536 surface crashes or makes errors, but the 64 1024s are all created and blitted to the screen with a random color in maybe 1.5 seconds.

65536*65536=4294967296, but 64*1024*1024 is only 67108864

gggmork said:

First time I've heard of 'texel'. I assume that's like when you zoom really close and it gets blocky, each 'block' is a texel

yes, it just means "texture element", a pixel of a texture.

gggmork said:

Maybe you're saying that instead of a huge 65536 pixel area, it really just has ONE 64x64 floor texture and the same texture is somehow repeated over and over without redundant duplication of that same texture over a large area.

Yes. Exactly. Look in docs for pygame to find how to make textures repeat/tile/whatever it's called. If it can't, toss it and find something that can.

Share this post


Link to post
tempun said:

65536*65536=4294967296, but 64*1024*1024 is only 67108864

Oops, I only did one row, I tried again * 64 again and it indeed ran out of memory doing 1024 areas.

tempun said:

Look in docs for pygame to find how to make textures repeat/tile/whatever


My guess is make one 64x64 surface, then lots of references to that same surface each with a unique xy coordinate, and zoom this whole thing as a grid of 64x64 block references instead of 1 big picture.
But then if you change one 64x64 block, they all change because they reference the same thing. So if you draw new diagonal lines, cutting some blocks into 2 or more pieces and give different floor textures to each piece, you have to treat those broken/diced blocks as unique non-references (or all other blocks will break into pieces too).
And if you draw like a 27 degree line that spans 50 blocks (with a different floor texture on each side), each block is a separate thing, so you'd have to dice each block individually which might look like funky jagged line pieces instead of a smooth line over many blocks.
I guess I could try that but it seems difficult/complex. Thanks for the help.

edit: actually I could maybe use references to each pixel in each texture instead of references to each big texture block, then it might be easier to dice up when lines divide texture blocks with different floors on each side.

By the way, inverted y axises are so stupid... trigonometry math/omgifol and doom require a normal y axis, and pygame is built with an inverted y axis. Its like a grid system from hell crashing into itself where you have to think for a minute to even know which way is up.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  
×