Development Diary serves as a running update log that highlights ongoing improvements, feature additions, fixes, optimizations, and refinements across its web applications, giving readers a clear view of what’s new, what’s changed, and how each application continues to evolve over time.
lw-loading class to both html and body, locking page overflow until the loader finishes. Once the page fully loads, the overlay fades out, is removed from the page, and scrolling is restored automatically.
.htaccess rules, incomplete file references were reduced, and unnecessary 404 handling was minimized. This helped make the website cleaner, easier to troubleshoot, and less wasteful with server resources. For a growing site like Lemon Web Solutions, this kind of cleanup is not just about speed. It is about stability, better resource control, and making sure the server spends its effort serving real visitors instead of repeatedly processing broken or outdated requests.
var MAX_PAGES = 5;
function perPage() {
return window.matchMedia("(max-width: 768px)").matches ? 4 : 8;
}
function totalPagesFor(key) {
var total = state[key].data.length;
return Math.max(1, Math.min(MAX_PAGES, Math.ceil(total / perPage())));
}
The update also keeps the game lists better organised by preventing titles from overlapping between the Most Played and Trending Games sections. This means games that are already highlighted as popular will not be repeated again in the trending area, giving other active games a better chance to be discovered. The pagination styling was also refined so the buttons remain clearly visible on light backgrounds, with cleaner page controls and no unnecessary “Page 1 of 5” text. I also tested slide animation for page changes, but removed it in the end because the simpler static transition feels cleaner, faster, and more suitable for a game browsing page. This works well with the existing Lemon Web Games JavaScript structure, which already separates the game grids into sections such as mp-grid, ra-grid, rg-grid, and tg-grid.
// Loop through last 7 days of logs
for ($i = 0; $i < 7; $i++) {
$date = date('Y-m-d', strtotime('-' . $i . ' days'));
$logFile = $logsDir . '/game_clicks-' . $date . '.log';
if (!file_exists($logFile)) continue;
$fh = fopen($logFile, 'r');
while (($line = fgets($fh)) !== false) {
$parts = explode(' | ', trim($line), 5);
if (count($parts) < 3) continue;
$ip = trim($parts[1]);
$game = trim($parts[2]) ?: 'Unknown';
if (!isset($result[$game])) {
$result[$game] = ['plays'=>0,'users'=>0,'_ips'=>[]];
}
$result[$game]['plays']++;
$ipHash = substr(hash('sha1', $ip), 0, 12);
if (!isset($result[$game]['_ips'][$ipHash])) {
$result[$game]['_ips'][$ipHash] = true;
$result[$game]['users']++;
}
}
fclose($fh);
}
col-md-9 content column and is instead output as a separate detached block that gets moved above the entire row containing both the main component and the right sidebar, which fixes the issue of the right-position module appearing behind the hero. I also kept the hero visible only on the clean /lemon-blog URL with no query string, increased the hero showcase from 3 to 4 articles, made the hero content use the wider 1150px layout, added a separate stylized category selector inside the hero while hiding the original selector whenever the hero is shown, kept the original selector and placement when the hero is hidden, set the hero video to fill the background as requested, and ensured the normal blog grid skips the posts already featured in the hero so the same articles are not repeated immediately below.
EmulatorJS 4.2.3 files are loaded correctly.
#random-games, including the correct #rg-grid target, so the section renders in the same 4-column desktop and 2-column mobile grid with identical spacing, card styling, hover behavior, thumbnail handling, and pill metadata styling.
(btn btn-default btn-success), aligning it to the left, and removing the horizontal divider above it so the footer feels lighter and more modern.
“Syntax error, unrecognized expression: /”, which happened because the Zo2 mega menu script was treating the menu link’s href value as a CSS selector. When a link had href="/" (or any normal URL), the code attempted to run jQuery('/'), which is not a valid selector, causing the click handler to crash. The fix was simple: add a guard so the smooth-scroll animation only runs for in-page anchor links that start with # (for example #about), and let normal links like / navigate as usual. After updating site.scripts.js with this check (and preventing default only for anchors), the console error disappeared and menu behavior became stable again.
color-scheme: dark; in my page styling, and that caused Chrome to render the input text in white, which blended badly with the game’s light input background. The fix was simple and immediate: I removed the color-scheme setting completely, and the textbox returned to normal with readable text again.
<style>
.lw-kill-fullscreen-prompt{
display:none !important;
visibility:hidden !important;
pointer-events:none !important;
height:0 !important;
width:0 !important;
overflow:hidden !important;
opacity:0 !important;
}
</style>
<script>
(function () {
function isIOS() {
var ua = navigator.userAgent || '';
var iOS = /iP(hone|od|ad)/.test(ua);
var iPadOS = (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
return iOS || iPadOS;
}
if (!isIOS()) return;
// Disable fullscreen on iOS to stop auto re-fullscreen (blocks on-screen keyboard).
function noopResolved(){ return Promise.resolve(); }
try {
var EP = Element.prototype;
if (EP.requestFullscreen) EP.requestFullscreen = noopResolved;
if (EP.webkitRequestFullscreen) EP.webkitRequestFullscreen = noopResolved;
if (EP.msRequestFullscreen) EP.msRequestFullscreen = noopResolved;
} catch(_) {}
try {
if (document.exitFullscreen) document.exitFullscreen = noopResolved;
if (document.webkitExitFullscreen) document.webkitExitFullscreen = noopResolved;
} catch(_) {}
// Kill the green "Tap here to go fullscreen" prompt even if it gets injected later.
function killGreenPrompt(root){
var wanted = 'tap here to go fullscreen';
var scope = root || document;
var nodes = scope.querySelectorAll('button, a, div, span, p');
for (var i=0;i<nodes.length;i++){
var el = nodes[i];
var t = (el.textContent || '').trim().toLowerCase();
if (t === wanted){
try { el.classList.add('lw-kill-fullscreen-prompt'); } catch(_) {}
try { el.style.display = 'none'; } catch(_) {}
try { el.remove(); } catch(_) {}
}
}
}
killGreenPrompt(document);
var mo = new MutationObserver(function(muts){
for (var i=0;i<muts.length;i++){
var m = muts[i];
if (m.addedNodes && m.addedNodes.length){
for (var j=0;j<m.addedNodes.length;j++){
var n = m.addedNodes[j];
if (n && n.nodeType === 1) killGreenPrompt(n);
}
}
}
});
try {
mo.observe(document.documentElement, { childList:true, subtree:true });
} catch(_) {}
})();
</script>
/lemon-blog/tags/*, I revised the thresholds so the module now scales progressively starting at 2250px (show 1 item), then increases the visible post count in stepped ranges (2715px = 2, 3180px = 3, and so on) up to a hard cap of 30, all based on the overall #eb height. For /lemon-blog/search/*, I added stricter logic: if the #eb height is below 2715px, the entire module (including the header module title) is fully hidden; once it reaches 2715px and above, it starts showing posts progressively (2715px = 1, 3180px = 2, 3645px = 3, etc.) with a cap of 29. On all other pages, the original height-mapping logic stays unchanged, so Lemon Blog existing behaviour remains intact everywhere else.
WebAssembly.Memory configuration, my application is still "greedy" for more space than the browser can safely provide, leading to the "Cannot enlarge memory" error.
PersistentSymbols.ini file. Specifically, reducing tex_iNormalSize, tex_iAnimationSize, and tex_iEffectSize to a value of 1 restricts the size of my loaded assets, while adding explicit caps like tex_iMaxMemSize = 128 prevents my engine from bloating. Additionally, lowering the maximum memory cap in my JavaScript to around 1.8 GB and disabling ALLOW_MEMORY_GROWTH ensures my engine hits its own internal "Out of Memory" handlers—which can trigger resource flushing—rather than hitting the 32-bit integer wall and crashing my entire browser session.
TextDecoder fails to interpret the resulting corrupted strings. This produces the "The encoded data was not valid for encoding utf-8" error and the appearance of broken characters, proving that I cannot simply "out-allocate" this architectural limitation as the engine's fundamental data handling breaks down entirely once the 2 GB boundary is breached.
.google-auto-placed, ins.adsbygoogle, and related wrappers or iframes) is forced not to render, preventing ads from overlapping my logo, navigation, or top banner. I chose this approach because it keeps the layout stable and clean without disabling AdSense site-wide, so the header remains an “ad-free zone” while the rest of the site can continue monetizing normally.
[sdl]
fullscreen=true
output=overlay
autolock=true
sensitivity=100
waitonerror=false
priority=higher,normal
mapperfile=mapper.txt
usescancodes=true
[dosbox]
memsize=16
[cpu]
core=dynamic
cputype=486_slow
cycles=fixed 7000
[render]
frameskip=0
aspect=false
scaler=normal2x
[midi]
mpu401=intelligent
mididevice=default
midiconfig=
[mixer]
nosound=false
rate=22050
blocksize=2048
prebuffer=10
[sblaster]
sbtype=sbpro2
irq=5
dma=1
hdma=0
mixer=true
oplmode=auto
oplrate=22050
[dos]
xms=true
ems=false
umb=true
keyboardlayout=auto
vga_render_per_scanline =off
[joystick]
joysticktype=auto
timed=true
autofire=false
swap34=false
buttonwrap=true
[serial]
serial1=dummy
serial2=dummy
serial3=disabled
serial4=disabled
[ipx]
ipx=true
[autoexec]
echo off
mount c .
c:
start.exe
If anyone knows a good setting for this game, please please please please please reach out to me and share to me the config file pleaseeee..
<script>
(function () {
const heading = document.getElementById("responsive-heading");
if (!heading) return;
const url = window.location.href.toLowerCase();
const routes = [
{ match: "lemon-blog?cat=application-development", title: "APP DEVELOPMENT" },
{ match: "lemon-blog?cat=cybersecurity", title: "CYBERSECURITY" },
{ match: "lemon-blog?cat=designs-artworks", title: "DESIGN & ARTWORKS" },
{ match: "lemon-blog?cat=games", title: "GAMES" },
{ match: "lemon-blog?cat=general-information", title: "GENERAL INFO" },
{ match: "lemon-blog?cat=guitar-covers", title: "GUITAR COVER" },
{ match: "lemon-blog?cat=mobile-development", title: "MOBILE DEV" },
{ match: "lemon-blog?cat=news", title: "NEWS" },
{ match: "lemon-blog?cat=personal-blog", title: "PERSONAL BLOG" }
];
let matched = false;
for (let i = 0; i < routes.length; i++) {
if (url.indexOf(routes[i].match) !== -1) {
heading.innerHTML = "<strong>" + routes[i].title + "</strong>";
matched = true;
break;
}
}
if (!matched && url.indexOf("lemon-blog") !== -1) {
heading.innerHTML = "<strong>LEMON BLOG</strong>";
}
})();
</script>
Not a major update, but a beautification code nevertheless...
<video id="example"></video>
<script>
(function () {
var started = false;
function startVideo() {
if (started) return;
started = true;
var v = document.getElementById("example");
if (v) {
v.muted = true;
v.play().catch(function(){});
}
document.removeEventListener("touchstart", startVideo);
document.removeEventListener("click", startVideo);
}
document.addEventListener("touchstart", startVideo, { passive: true });
document.addEventListener("click", startVideo, { passive: true });
})();
</script>
This is merely a note to myself in the future when uploading video as i tend to forgot for IOS users.
Lemon Web Solutions specializes in high-performance desktop and web software across Windows, macOS, Linux, and the browser—primarily in C++, C#, WPF, .NET, Node.js, and Java.