• Another Frame.js question

    From Kirkman@VERT/GUARDIAN to All on Tue Jun 9 15:29:46 2015
    To Deuce or echicken or whoever,ããLately I've been playing with using frames like tiles. In a 132x60 terminal, Iãcreate an 8x3 grid of frames. Each frame is 16x16 characters. This dimension isãconvenient because it lets me adapt 16x16 pixel RPG sprites and tiles intoãANSI.ããAnyway, back to the point. I've got the tile map working. I can move a spriteãaround it. But the latency when moving a sprite around the map is pretty high.ããThe routine works like this:ãã * Figure out where you are on the master map and store those coordinates.ãã * Using those coords, iterate over the frame grid and check tile types.ãã - If a frame needs the same tile as it had before, don't updateãã - If the frame needs a new tile, .load() it, then .draw()ãã * After iterating over all frames, .cycle() the parent frameãããChecking to see if the tile is the same as before helps some with the latency,ãbut I have a feeling there's a way to reduce the latency much more.ããMany of my tiles have repeated information. For example, there are a lot ofãsolid green blocks since they are grassy.ããWhen I .load() a new ANS or BIN file into a frame, does Frame.js just replaceãall data and redraw every character in the entire frame? Or does it check theãnew data against the old data to see if there are characters it can skipãrepainting?ããã--JoshãããBTW - I posted a video showing an early version of this tile map idea here:ããhttp://breakintochat.com/blog/2015/05/26/ansi-tile-map/ãã////--------------------------------------------------ãBiC -=- http://breakintochat.com -=- bbs wiki and blogãã---ã þ Synchronetã
  • From Kirkman@VERT/GUARDIAN to All on Wed Jun 10 15:59:49 2015
    When I .load() a new ANS or BIN file into a frame, does Frame.js just replaceã>all data and redraw every character in the entire frame? Or does it check theã>new data against the old data to see if there are characters it can skipã>repainting?ããOkay, after some testing, I am pretty sure that frame.load() will require every character in the frame to be redrawn.ããI cooked up my own routine to work around this. I set up a frame that serves as a temporary holder. When I'm updating all the tile frames, I no longer .load() the data straight into each tile frame. Instead, I load the tile graphic into the holder frame. Then I iterate over the holder frame and compare each character with the corresponding character in the target tile frame. If they are different, then I .setData() on that character in the tile frame. Once all this is finished, .cycle() the entire screen.ããI wrote some debug code to measure how long each screen redraw was taking. Before my optimizations, the average screen refresh was about 0.67 seconds. After the optimizations, they are down to 0.23 seconds. So it has made a pretty big difference.ããHere's the code if anyone cares:ãã// Get the name of this tile type's BIN fileãvar tileFile = this._map[mY][mX].getFile();ã// empty the tileHolderãthis._tileHolder.invalidate();ã// Load new tile graphic into tile holderãthis._tileHolder.load(js.exec_dir '/tiles/' tileFile, this._mapTileW, this._mapTileH);ã// Iterate over all characters in this frameãfor (var a=0; a<this._mapTileW; a ) {ã for (var b=0; b<this._mapTileH; b ) {ã var newChar = this._tileHolder.getData(a,b);ã var oldChar = this._tiles[x][y].getData(a,b);ã if ( newChar.attr !== oldChar.attr || newChar.ch !== oldChar.ch) {ã this._tiles[x][y].clearData(a,b);ã this._tiles[x][y].setData(a,b,newChar.ch,newChar.attr);ã }ã
    }ã}ã// mark this tile for updatingãthis._tiles[x][y].cycle();ãã---ã þ Synchronetã
  • From echicken@VERT/ECBBS to Kirkman on Thu Jun 11 00:53:26 2015
    Re: Another Frame.js questionã By: Kirkman to All on Tue Jun 09 2015 15:29:46ãã Ki> - If the frame needs a new tile, .load() it, then .draw()ãã Ki> When I .load() a new ANS or BIN file into a frame, does Frame.js justã Ki> replace all data and redraw every character in the entire frame? Or doesããI'd have to check to be sure, but I suspect this is the case.ãã Ki> it check the new data against the old data to see if there are charactersã Ki> it can skip repainting?ããThe .load() process will slow things down somewhat, and I think that .draw()ãwill force a total redraw of the frame. This is probably where a good chunk ofãthe slowness is coming from.ããHow many different kinds of tiles are there? If each is saved as an individualã.bin or .ans, you might try combining them all into a single spritesheet. Loadãthe entire spritesheet into each 16x16 frame, then scroll the frame toãdifferent x/y offsets as needed to reveal the desired portion of the largerãgraphic. This would cut out the .load() and .draw() calls, as .cycle() (whichãI assume is being called regularly on the overall parent frame) should takeãcare of redrawing all child frames as needed.ãã---ãechickenãelectronic chicken bbs - bbs.electronicchicken.com - 416-273-7230ã þ Synchronet þ electronic chicken bbs - bbs.electronicchicken.comã
  • From echicken@VERT/ECBBS to Kirkman on Thu Jun 11 00:56:53 2015
    Re: Another Frame.js questionã By: Kirkman to All on Wed Jun 10 2015 15:59:49ãã Ki> Before my optimizations, the average screen refresh was about 0.67ã Ki> seconds. After the optimizations, they are down to 0.23 seconds. So it hasã Ki> made a pretty big difference. ããThat's a good improvement. You might still try the spritesheet method Iãdescribed previously and see if it helps at all - or makes things worse. :Dãã---ãechickenãelectronic chicken bbs - bbs.electronicchicken.com - 416-273-7230ã þ Synchronet þ electronic chicken bbs - bbs.electronicchicken.comã
  • From Kirkman@VERT/GUARDIAN to echicken on Wed Oct 14 11:10:18 2015
    Re: Another Frame.js questionã> By: Kirkman to All on Tue Jun 09 2015 15:29:46ã>ã>How many different kinds of tiles are there? If each is saved as an individualã>.bin or .ans, you might try combining them all into a single spritesheet. Loadã>the entire spritesheet into each 16x16 frame, then scroll the frame toã>different x/y offsets as needed to reveal the desired portion of the largerã>graphic. This would cut out the .load() and .draw() calls, as .cycle() (whichã>I assume is being called regularly on the overall parent frame) should takeã>care of redrawing all child frames as needed.ããI finally got around to trying your suggested tileset approach, and I ran into a a couple roadblocks. Let me explain.ããI'm taking a 132 char x 60 char canvas and dividing it into an 8x3 grid of frames. Each frame holds a 16 char x 16 char tile.ããIn my test code, I'm iterating over each frame and .load()ing my tileset. The tileset is 128x112. I have tried various versions of this tileset, as an ANSI file, a BIN file, with SAUCE or without. No matter what, I always run out of memory.ããAdditionally, when I try to debug the errors, Frame.js is giving the wrong data dimensions for my tileset files. As I said, the tileset is 128x112, but if I call .data_width and .data_height after .load()ing, I get 17x832 for the .ANS version or 129x112 for the BIN.ããI don't *think* I'm asking too much of the system memory-wise, but maybe I'm wrong. If you have a minute could you take a look and tell me if you have any thoughts on the out-of-memory issue, or the wrong data dimensions?ããMy test code is here: https://gist.github.com/Kirkman/0853cad3deaad373f000#file-1tileset-test-jsããThe out-of-memory errors can be seen here (They are slightly different depending on whether you load the ANS or BIN version of the tileset):ãhttps://gist.github.com/Kirkman/0853cad3deaad373f000#file-2errors-txtããThe debugging info is here:ãhttps://gist.github.com/Kirkman/0853cad3deaad373f000#file-3debugging-txtããYou can download the ANS and BIN version of the tileset here:ãhttp://breakintochat.com/files/misc/debug/16x16_tileset.ansãhttp://breakintochat.com/files/misc/debug/16x16_tileset.binãã--Joshãã---ã þ Synchronetã
  • From Digital Man@VERT to Kirkman on Wed Oct 14 22:10:13 2015
    Re: Another Frame.js questionã By: Kirkman to echicken on Wed Oct 14 2015 11:10 amãã > > Re: Another Frame.js questionã > > By: Kirkman to All on Tue Jun 09 2015 15:29:46ã >ã > >How many different kinds of tiles are there? If each is saved as anã > individualã > >.bin or .ans, you might try combining them all into a single spritesheet.ã > Loadã > >the entire spritesheet into each 16x16 frame, then scroll the frame toã > >different x/y offsets as needed to reveal the desired portion of the largerã > >graphic. This would cut out the .load() and .draw() calls, as .cycle()ã > (which >I assume is being called regularly on the overall parent frame)ã > should take >care of redrawing all child frames as needed.ã >ã > I finally got around to trying your suggested tileset approach, and I ranã > into a a couple roadblocks. Let me explain.ã >ã > I'm taking a 132 char x 60 char canvas and dividing it into an 8x3 grid ofã > frames. Each frame holds a 16 char x 16 char tile.ã >ã > In my test code, I'm iterating over each frame and .load()ing my tileset.ã > The tileset is 128x112. I have tried various versions of this tileset, as anã > ANSI file, a BIN file, with SAUCE or without. No matter what, I always runã > out of memory.ã >ã > Additionally, when I try to debug the errors, Frame.js is giving the wrongã > data dimensions for my tileset files. As I said, the tileset is 128x112, butã > if I call .data_width and .data_height after .load()ing, I get 17x832 forã > the .ANS version or 129x112 for the BIN.ã >ã > I don't *think* I'm asking too much of the system memory-wise, but maybe I'mã > wrong. If you have a minute could you take a look and tell me if you haveã > any thoughts on the out-of-memory issue, or the wrong data dimensions?ããI don't really know anything about frame.js (except vaguely that it exists), soãI can't really help specifically with that, but regarding the memory usage: youãcan allocate more memory to the JS runtime via your configurationã(JavaScriptMaxBytes in http://wiki.synchro.net/config:sbbs.ini#global). Theãdefualt is 8Mbytes, which logically, should be enough.ããIf a script is performing a lot of string manipulation, it might need to useãthe new(is) js.flatten_string() method to reduce unnecessary memoryãconsumption.ããOther methods of scope manipulation can encourage garbage collection. You canãread/print the js.gc_attempts property to make sure garbage collection isãrunning and possibly manipulate js.gc_interval to make it happen more often.ãIt's certainly possible that there is a bug in the current code in regards toãJS memory usage/garbage collection.ãã digital manããSynchronet "Real Fact" #24:ãThe Digital Dynamics company ceased day-to-day opperations in late 1995.ãNorco, CA WX: 75.1øF, 72.0% humidity, 3 mph SE wind, 0.00 inches rain/24hrsã---ã þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.netã
  • From echicken@VERT/ECBBS to Kirkman on Thu Oct 15 00:47:27 2015
    Re: Another Frame.js questionã By: Kirkman to echicken on Wed Oct 14 2015 11:10:18ãã Ki> I don't *think* I'm asking too much of the system memory-wise, but maybeã Ki> I'm wrong. If you have a minute could you take a look and tell me if youã Ki> have any thoughts on the out-of-memory issue, or the wrong dataã Ki> dimensions? ããBy default, Synchronet places some tight limits on how much memory can be usedãby javascript modules. See JavaScriptMaxBytes and JavaScriptContextStack inãsbbs.ini. I believe that the idea here is to save people from their ownã(inadvertently) memory-hungry code. These values are fairly reasonable forãmore typical BBS modules.ããIf you find that you actually need to allow JS modules to use more memory, youãcan bump these values up. On a test BBS, I got around the 'Out of memory'ãerror when running your script by bumping the ContextStack value up to 512Kãfrom the default 16K. (That's quite a jump, but then again on my main BBS Iãhave these values set higher, I don't recall by how much.) Some rough mathãsuggests that if every character cell in your 128x112 graphic was occupied, andãrepeated over 24 frames, you might need more than that. The overhead of theãFrame objects would need to be allowed for as well.ãã Ki> Additionally, when I try to debug the errors, Frame.js is giving the wrongã Ki> data dimensions for my tileset files. As I said, the tileset is 128x112,ã Ki> but if I call .data_width and .data_height after .load()ing, I get 17x832ã Ki> for the .ANS version or 129x112 for the BIN. ããI generally use .BIN files for loading into frames. The data_width of 129 inãthis case suggests that something is slightly off (by one) in the way thatãFrame is reporting this. At a glance, it looks like Frame is adding 1 to thisãvalue ... for reasons I do not know. I'll ask mcmlxxix if he remembers whyãit's doing this. For now, just subtract 1 from your data_width, and that's theãreal number.ããThe data_width of 17 for the .ANS file would be a two-part issue. Again,ãdata_width would actually be 16 in this case, which is the width of the frameãin question. Apparently when loading a .ANS file, Frame wraps the loadedãcontent to the width of the frame. I can't imagine why, but maybe there's aãreason - so I won't change it just yet and will just suggest that you use .BINãinstead.ãã---ãechickenãelectronic chicken bbs - bbs.electronicchicken.com - 416-273-7230ã þ Synchronet þ electronic chicken bbs - bbs.electronicchicken.comã
  • From Kirkman@VERT/GUARDIAN to echicken on Thu Oct 15 09:58:23 2015
    If you find that you actually need to allow JS modules to use more memory, youã>can bump these values up. On a test BBS, I got around the 'Out of memory'ã>error when running your script by bumping the ContextStack value up to 512Kã>from the default 16K. (That's quite a jump, but then again on my main BBS Iã>have these values set higher, I don't recall by how much.) Some rough mathã>suggests that if every character cell in your 128x112 graphic was occupied, andã>repeated over 24 frames, you might need more than that. The overhead of theã>Frame objects would need to be allowed for as well.ããThanks, I didn't realize these settings were configurable in SBBS. I think I will try to stick to Synch's default settings for memory. ããIt occurs to me that I can combine my frame "re-painting" method with the tilesheet method: Make one invisible "holder" frame that loads the entire tileset at the beginning. Then on each redraw, copy data out of the holder to paint those characters that have changed in the visible frames. By loading only one copy of the tileset, I should have no memory issues, and I'll also get the benefit of no longer constantly loading individual tile BIN files.ãã>I generally use .BIN files for loading into frames. The data_width of 129 inã>this case suggests that something is slightly off (by one) in the way thatã>Frame is reporting this. At a glance, it looks like Frame is adding 1 to thisã>value ... for reasons I do not know. ã>ã>The data_width of 17 for the .ANS file would be a two-part issue. Again,ã>data_width would actually be 16 in this case, which is the width of the frameã>in question. Apparently when loading a .ANS file, Frame wraps the loadedã>content to the width of the frame.ããI thought data_width and _height properties were supposed to be the true dimensions of the loaded image, since you can use offset to scroll that image around in the frame. But, yeah, until that's sorted, I'll stick to BINs.ãã--Joshãã---ã þ Synchronetã
  • From echicken@VERT/ECBBS to Kirkman on Thu Oct 15 14:38:22 2015
    I thought data_width and _height properties were supposed to be the true dimensions of the loaded image, since you can use offset to scroll that image around in the frame. But, yeah, until that's sorted, I'll stick to BINs.

    Yes, that's what they are supposed to be. The problem is that Frame is returning is internal cursor to the start of the line once it reaches the viewable width of its canvas, regardless of whether the image it's loading told it to do so (with a crlf or a positioning sequence, say.) Data that should be getting set outside of the viewable area is instead being moved down to the next line, and wrapping on and on like that (which explains the high number you're seeing for data_height.)

    ---
    echicken
    electronic chicken bbs - bbs.electronicchicken.com - 416-273-7230ãã---ã þ Synchronet þ electronic chicken bbs - bbs.electronicchicken.comã