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

Recent

Welcome to TinyPortal. Please login or sign up.

Recent posts

#11
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
#12
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...
#13
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>

#14
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?
#15
Support / "Session verification failed" ...
Last post by joecool85 - March 26, 2026, 04:26:23 PM
I usually log in through the "User" menu block in TinyPortal, but since updating to TP 3.0.3, this fails with a "Session verification failed" message.  Any ideas?

Site is ssguitar.com and I have SMF 2.1.7 installed.
#16
Chit chat / Re: OMG
Last post by Zerocchi - March 23, 2026, 01:02:33 AM
Quote from: @rjen on March 22, 2026, 05:53:41 PMWhy do you miss it! It is still here!

Yup. I was really happy the first time I found this place. Current web is such an uninteresting mess  :-\
#17
Chit chat / Re: OMG
Last post by @rjen - March 22, 2026, 05:53:41 PM
Why do you miss it! It is still here!
#18
Chit chat / Re: OMG
Last post by Zerocchi - March 22, 2026, 09:52:40 AM
Really miss this kind of portal. Thanks everyone for keeping this up.
#19
Chit chat / Re: OMG
Last post by lurkalot - March 10, 2026, 01:34:13 AM
Look at the stats. It's not uncommon for the guest count to exceed 1642

Online ever: 8,223 (February 19, 2025

#20
Chit chat / Needs addressing this Lurk
Last post by Kernal - March 10, 2026, 12:18:31 AM
 :)

This website is proudly hosted on Crocweb Cloud Website Hosting.