TP-Docs
HTML5 Icon HTML5 Icon HTML5 Icon
TP on Social Media

Recent

Welcome to TinyPortal. Please login or sign up.

Recent posts

#1
Support / Re: "Session verification fail...
Last post by @rjen - April 17, 2026, 04:24:25 PM
Not yet, I confirmed the issue, but did not find a fix yet
#2
Support / Re: "Session verification fail...
Last post by joecool85 - April 17, 2026, 03:22:47 PM
Quote from: @rjen on March 30, 2026, 08:06:48 PMSeeing the same thing, must be something that changed in TP3.0.3, will check

Hi rjen, any update on this?
#3
Chit chat / Re: Hog roast sausage`s tonigh...
Last post by Sledge - April 10, 2026, 02:00:25 PM
Some places you might get the side eye for putting ketchup on a hot dog. Especially a sausage, lol. Mustard goes on a weenie.  :idiot2:
#4
Block Codes / Re: Automated Blocks
Last post by Sledge - April 10, 2026, 01:47:55 PM
Great script Kernal. Thanks!
#5
Support / Re: Frontpage breadcrumbs
Last post by @rjen - March 31, 2026, 05:12:10 AM
Confirmed, the page is working as intended. The breadcrumbs are removed on the page=... URL's. Not the Frontpage.

You can check the article page: https://forum.craftylion.com/index.php?page=9

The article setting is not intended to affect the breadcrumbs on the frontpage. That would require another setting, a frontpage specific one, which is not included in TinyPortal.
#6
Support / Re: Frontpage breadcrumbs
Last post by kimba - March 30, 2026, 09:13:34 PM
Link to my forum: http://forum.craftylion.com
SMF version: Latest
TP version: Latest
Theme name and version: Default

As you can see, the breadcrumbs says "Crafty Lion - Lion's Haven (Camp Phase) ►  Forum" when it's clearly on the frontpage.
#7
Support / Re: "Session verification fail...
Last post by @rjen - March 30, 2026, 08:06:48 PM
Seeing the same thing, must be something that changed in TP3.0.3, will check
#8
Support / Re: Frontpage breadcrumbs
Last post by @rjen - March 30, 2026, 08:01:33 PM
I am not sure what you are seeing. Can you share a link to the frontpage of your site?

The article settings to set the breadcrumbs typically works on the article page. The page with url: ../index.php?page=...

The frontpage normally shows a very short breadcrumb which only shows the forum name itself: that is not controlled by the article setting.

Maybe what you are seeing is related to the SMF version, TP version or theme.
It would help of you provide these details too...
#9
Block Codes / Re: Space invader game
Last post by Kernal - March 30, 2026, 05:20:39 PM
Made a bit of a upgrade blowing up space invaders and also added blowing up bases too this is a fun project and can be added to a tiny portal block for time out invaders, Oh i forgot to add that I've also added rapid fire just keep the space bar pressed or fire button to rapid fire the invaders!

Everyone`s welcome to add to this code to complete the ultimate Tinyportal space invader game be fun get involved add upgrades to the code and I'll work with you to update the game too, I`ve also added rapid fire with bases exploding on invader contact.

<html lang="en">
<head>
<meta charset="UTF-8">
<title>Space Invaders - TinyPortal</title>
<style>
  body { margin:0; font-family:monospace; background:black; color:#00ff66; text-align:center; }
  canvas { background:black; border:6px solid #00ff66; box-shadow:0 0 30px #00ff66 inset; display:block; margin:0 auto; }
  #startScreen {
    position:absolute; top:0; left:0; width:100%; height:100%;
    background:black; color:#00ff66; display:flex;
    flex-direction:column; justify-content:center; align-items:center;
  }
  #startScreen h1 { font-size:48px; margin:0; }
  #startScreen p { font-size:24px; margin:5px 0 30px; }
  #pressStart { font-size:20px; margin-top:20px; }
  #gameContainer { display:none; }
  #muteBtn { position:absolute; top:10px; right:10px; width:80px; height:35px; font-size:16px; }
  #highscore { font-size:16px; margin-bottom:5px; }
  button { width:60px; height:40px; margin:5px; font-size:18px; }
</style>
</head>
<body>

<div id="startScreen">
  <h1>SPACE INVADERS</h1>
  <p>Kernal Coded - TinyPortal 2026</p>
  <div id="pressStart">PRESS START</div>
</div>

<div id="gameContainer">
  <div id="highscore">High Score: 0 &nbsp;&nbsp; Kernal Coded For TinyPortal</div>
  <canvas id="game" width="360" height="440"></canvas>
  <div>
    <button id="leftBtn">⬅</button>
    <button id="fireBtn">🔥</button>
    <button id="rightBtn">➡</button>
  </div>
  <p>⬅ ➡ Move | HOLD FIRE | R Restart</p>

  <audio id="bgMusic" src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3" loop autoplay></audio>
  <button id="muteBtn">🔊 Mute</button>
</div>

<script>
const startScreen = document.getElementById("startScreen");
const pressStart = document.getElementById("pressStart");
const gameContainer = document.getElementById("gameContainer");
const bgMusic = document.getElementById("bgMusic");
const muteBtn = document.getElementById("muteBtn");

let blink = true;
setInterval(() => {
  pressStart.style.visibility = blink ? 'visible' : 'hidden';
  blink = !blink;
}, 500);

document.addEventListener("keydown", startGame);
document.addEventListener("click", startGame);
function startGame() {
  startScreen.style.display = "none";
  gameContainer.style.display = "block";
  draw();
  document.removeEventListener("keydown", startGame);
  document.removeEventListener("click", startGame);
}

muteBtn.onclick = () => {
  if(bgMusic.paused){ bgMusic.play(); muteBtn.textContent="🔊 Mute"; }
  else{ bgMusic.pause(); muteBtn.textContent="🔇 Unmute"; }
};

const canvas = document.getElementById("game");
const x = canvas.getContext("2d");
const leftBtn = document.getElementById("leftBtn");
const rightBtn = document.getElementById("rightBtn");
const fireBtn = document.getElementById("fireBtn");

const stars=[];
for(let i=0;i<80;i++) stars.push({x:Math.random()*360,y:Math.random()*440,r:Math.random()*2+1,speed:Math.random()*0.5+0.2});
function drawStars(){ x.fillStyle="white"; stars.forEach(s=>{ x.fillRect(s.x,s.y,s.r,s.r); s.y+=s.speed; if(s.y>440){ s.y=0; s.x=Math.random()*360 } }); }

let player={x:170,y:400,w:24,h:12,s:4};
let bullets=[], enemyBullets=[], invaders=[], explosions=[], shields=[], ufo=null;
let keys={}, firing=false, lastShot=0, fireDelay=120;
let level=1, score=0, dir=1, speed=0.6, gameOver=false;

const alien1=["00111100","01111110","11011011","11111111","01111110","01000010"];
const alien2=["00111100","01111110","11111111","11011011","11111111","00100100"];
const ship=["00100","01110","11111"];
const ufoSprite=["00111100","01111110","11111111","01111110"];

let anim=0, animTick=0;

const A=new (window.AudioContext||window.webkitAudioContext)();
function beep(f,d=0.1){ let o=A.createOscillator(),g=A.createGain(); o.connect(g);g.connect(A.destination); o.frequency.value=f;o.start();o.stop(A.currentTime+d) }

function drawSprite(s,xp,yp,sc,col){ x.fillStyle=col; for(let r=0;r<s.length;r++) for(let d=0;d<s[r].length;d++) if(s[r][d]=="1") x.fillRect(xp+d*sc,yp+r*sc,sc,sc); }
function makeInvaders(){ invaders=[]; for(let r=0;r<5;r++) for(let c=0;c<10;c++) invaders.push({x:40+c*28,y:50+r*26,a:true}); }
function makeShields(){ shields=[]; for(let i=0;i<3;i++) shields.push({x:50+i*90,y:340,hp:40}); }
function drawShields(){ x.fillStyle="#00ff66"; shields.forEach(s=>{ for(let i=0;i<s.hp;i++) x.fillRect(s.x+(i%8)*4,s.y+Math.floor(i/8)*4,3,3) }); }
function movePlayer(){ if(keys["ArrowLeft"]||keys["TouchLeft"]) player.x-=player.s; if(keys["ArrowRight"]||keys["TouchRight"]) player.x+=player.s; player.x=Math.max(0,Math.min(336,player.x)) }
function shoot(){ let now=Date.now(); if(firing && now-lastShot>fireDelay){ bullets.push({x:player.x+11,y:player.y}); lastShot=now; beep(800,0.05) } }

function updateBullets(){
  bullets.forEach(b=>b.y-=5);
  enemyBullets.forEach(b=>b.y+=3);

  bullets.forEach(b=>{
    // INVADERS
    invaders.forEach(i=>{
      if(i.a && b.x>i.x && b.x<i.x+16 && b.y>i.y && b.y<i.y+16){
        i.a=false;
        score+=10;
        explode(i.x,i.y);
        b.y=-100;
      }
    });

    // 🚀 UFO HIT FIX
    if (ufo && b.x > ufo.x && b.x < ufo.x + 32 && b.y > ufo.y && b.y < ufo.y + 16) {
      score += 100;
      explode(ufo.x, ufo.y);
      ufo = null;
      b.y = -100;
      beep(1200, 0.2);
    }

    // SHIELDS
    shields.forEach(s=>{
      if(s.hp>0 && b.x>s.x && b.x<s.x+32 && b.y>s.y && b.y<s.y+32){
        s.hp--;
        b.y=-100;
      }
    });
  });

  enemyBullets.forEach(b=>{
    if(b.x>player.x && b.x<player.x+24 && b.y>player.y){
      explode(player.x,player.y);
      gameOver=true;
    }
    shields.forEach(s=>{
      if(s.hp>0 && b.x>s.x && b.x<s.x+32 && b.y>s.y && b.y<s.y+32){
        s.hp--;
        b.y=999;
      }
    });
  });

  bullets=bullets.filter(b=>b.y>0);
  enemyBullets=enemyBullets.filter(b=>b.y<440);
}

function alienShoot(){ let alive=invaders.filter(i=>i.a); if(alive.length && Math.random()<0.02+(level*0.01)){ let s=alive[Math.floor(Math.random()*alive.length)]; enemyBullets.push({x:s.x+8,y:s.y+12}); beep(400,0.05); } }
function moveInvaders(){ let edge=false; invaders.forEach(i=>{ if(!i.a) return; i.x+=dir*speed; if(i.x<10||i.x>320) edge=true; shields.forEach(s=>{ if(s.hp>0 && i.y+16>=s.y && i.x+16>s.x && i.x<s.x+32){ s.hp--; i.a=false; explode(i.x,i.y); } }); if(i.y+16>=player.y) gameOver=true; }); if(edge){ dir*=-1; invaders.forEach(i=>i.y+=10) } }
function explode(xp,yp){ for(let i=0;i<12;i++) explosions.push({x:xp,y:yp,vx:Math.random()*4-2,vy:Math.random()*4-2,l:20}); beep(300,0.1) }
function drawExplosions(){ explosions.forEach(e=>{ x.fillStyle="yellow"; x.fillRect(e.x,e.y,2,2); e.x+=e.vx;e.y+=e.vy;e.l--; }); explosions=explosions.filter(e=>e.l>0) }
function drawBullets(){ x.fillStyle="cyan"; bullets.forEach(b=>x.fillRect(b.x,b.y,4,10)); x.fillStyle="orange"; enemyBullets.forEach(b=>x.fillRect(b.x,b.y,3,8)) }
function drawUFO(){ if(ufo){ ufo.x+=2; drawSprite(ufoSprite,ufo.x,ufo.y,2,"red"); if(ufo.x>400) ufo=null; } }
function spawnUFO(){ if(!ufo && Math.random()<0.002){ ufo={x:-40,y:25}; } }

function draw(){
  x.clearRect(0,0,360,440);
  drawStars();
  movePlayer();
  shoot();
  updateBullets();
  moveInvaders();
  alienShoot();
  spawnUFO();
  drawUFO();

  animTick++;
  if(animTick>20){ animTick=0; anim=(anim+1)%2 }

  invaders.forEach(i=>{ if(i.a) drawSprite(anim?alien1:alien2,i.x,i.y,2,"white") });

  drawSprite(ship,player.x,player.y-6,4,"#00ff66");
  drawBullets();
  drawShields();
  drawExplosions();

  x.font = "14px monospace";
  x.fillStyle = "#00ff66";
  x.fillText("Score " + score, 10, 20);
  x.fillText("Level " + level, 280, 20);

  if(!invaders.some(i=>i.a)){ level++; speed+=0.2; makeInvaders(); makeShields(); }
  if(gameOver) reset();

  requestAnimationFrame(draw);
}

function reset(){ score=0; level=1; speed=0.6; bullets=[]; enemyBullets=[]; explosions=[]; makeInvaders(); makeShields(); gameOver=false }

document.addEventListener("keydown", e=>{ keys[e.key]=true; if(e.key===" ") firing=true; if(e.key==="r") reset() });
document.addEventListener("keyup", e=>{ keys[e.key]=false; if(e.key===" ") firing=false });
leftBtn.ontouchstart=()=>keys["TouchLeft"]=true; leftBtn.ontouchend=()=>keys["TouchLeft"]=false;
rightBtn.ontouchstart=()=>keys["TouchRight"]=true; rightBtn.ontouchend=()=>keys["TouchRight"]=false;
fireBtn.ontouchstart=()=>firing=true; fireBtn.ontouchend=()=>firing=false;

makeInvaders();
makeShields();
</script>
</body>

#10
Support / Frontpage breadcrumbs
Last post by kimba - March 29, 2026, 11:10:12 PM
I've just added TinyPortal to my forum and created a frontpage article. However, the breadcrumb above the article still shows the forum link even though I unchecked the "Display breadcrumb navigation" in the article's edit page.

How do I get rid of the forum link?

This website is proudly hosted on Crocweb Cloud Website Hosting.