diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..dbc12db --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-07-28 - Fast voxel access with chunk caching and bitwise operations +**Learning:** In highly localized tight loops (like chunk meshing or frequent voxel collision checks in games like Shardfall), repeating dictionary lookups (`Map.get`) for chunk boundaries is extremely expensive. Profiling shows that caching the `_lastChunk` used during voxel lookups skips almost all `Map.get` calls because consecutive queries are nearly always within the same chunk. Combining this with replacing `Math.floor(x / 16)` and remainder operations with fast bitwise shifts (`x >> 4`) and masks (`x & 15`) dramatically reduces overhead for the fundamental `getBlock`/`setBlock` bottleneck in JS voxel engines. +**Action:** When optimizing tight voxel or grid lookup loops (especially millions of times per frame in a browser), cache the last-accessed spatial bucket to avoid map lookups, and ensure grid access logic is implemented purely via inline bitwise arithmetic. diff --git a/shardfall-v12.html b/shardfall-v12.html index a0d5aec..e61531a 100644 --- a/shardfall-v12.html +++ b/shardfall-v12.html @@ -785,18 +785,22 @@

if(!c){ c=genChunk(cx,cz); world.chunks.set(k,c); } return c; } +// ⚡ Bolt: Cache last chunk & use bitwise ops for fast voxel access (reduces map lookups) +let _lastChunk=null; function getBlock(x,y,z){ if(y<0) return B.BEDROCK; if(y>=WH) return B.AIR; x=Math.floor(x); y=Math.floor(y); z=Math.floor(z); - const c=ensureChunk(Math.floor(x/CH),Math.floor(z/CH)); - return c.blocks[cidx(x-c.cx*CH,y,z-c.cz*CH)]; + const cx=x>>4, cz=z>>4; + let c=_lastChunk; + if(!c||c.cx!==cx||c.cz!==cz){ c=ensureChunk(cx,cz); _lastChunk=c; } + return c.blocks[(((x&15)<<4)|(z&15))<<7|y]; } const solidAt=(x,y,z)=>BLOCKS[getBlock(x,y,z)].solid; function setBlock(x,y,z,id,noSave,noFluidReaction){ if(y<1||y>=WH) return; x=Math.floor(x); y=Math.floor(y); z=Math.floor(z); - const cx=Math.floor(x/CH), cz=Math.floor(z/CH); - const c=ensureChunk(cx,cz), lx=x-cx*CH, lz=z-cz*CH; + const cx=x>>4, cz=z>>4; + const c=ensureChunk(cx,cz), lx=x&15, lz=z&15; const posKey=bkey(x,y,z), ci=cidx(lx,y,lz); const oldId=c.blocks[ci], oldLevel=world.water.get(posKey)??8; c.blocks[ci]=id;