// Ulicraft landing — pixel components, live status, copy-IP, scroll reveals, tweaks
const { useState, useEffect, useRef, useCallback } = React;
/* ---------- pixel art helpers ---------- */
// 8x8 creeper face
const CREEPER = [
"00000000",
"01100110",
"01100110",
"00011000",
"00111100",
"00111100",
"00100100",
"00000000",
];
function Creeper() {
const cells = CREEPER.join("").split("");
return (
{cells.map((c, i) => )}
);
}
// 7x7 feature glyphs
const GLYPHS = {
shield: ["0111110","1111111","1111111","1111111","0111110","0011100","0001000"],
diamond:["0001000","0011100","0111110","1111111","0111110","0011100","0001000"],
orb: ["0011100","0111110","1111111","1111111","1111111","0111110","0011100"],
heart: ["0110110","1111111","1111111","1111111","0111110","0011100","0001000"],
};
function PixelIcon({ glyph, gold }) {
const cells = GLYPHS[glyph].join("").split("");
return (
{cells.map((c, i) => (
))}
);
}
/* ---------- copy to clipboard ---------- */
function copyText(text) {
try {
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(text);
return;
}
} catch (e) {}
const ta = document.createElement("textarea");
ta.value = text;
ta.style.position = "fixed";
ta.style.opacity = "0";
document.body.appendChild(ta);
ta.select();
try { document.execCommand("copy"); } catch (e) {}
document.body.removeChild(ta);
}
function IpChip({ ip }) {
const [copied, setCopied] = useState(false);
const onCopy = () => {
copyText(ip);
setCopied(true);
clearTimeout(onCopy._t);
onCopy._t = setTimeout(() => setCopied(false), 1600);
};
return (
▸ {ip}
{copied ? "Copied!" : "Copy IP"}
);
}
/* ---------- live player count ---------- */
function useLivePlayers(base = 37, max = 100) {
const [n, setN] = useState(base);
useEffect(() => {
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
const id = setInterval(() => {
setN((p) => {
const step = Math.floor(Math.random() * 5) - 2;
return Math.max(base - 6, Math.min(max - 4, p + step));
});
}, 2600);
return () => clearInterval(id);
}, [base, max]);
return n;
}
/* ---------- floating pixel dust ---------- */
function Dust({ on }) {
if (!on) return null;
const bits = Array.from({ length: 16 }, (_, i) => i);
return (
{bits.map((i) => {
const size = 3 + (i % 3) * 2;
const st = {
position: "absolute",
left: ((i * 61) % 100) + "%",
bottom: "-20px",
width: size + "px",
height: size + "px",
background: i % 4 === 0 ? "var(--gold)" : "var(--accent)",
opacity: 0.18 + (i % 3) * 0.06,
imageRendering: "pixelated",
animation: `rise ${13 + (i % 7) * 3}s linear ${i * 0.7}s infinite`,
};
return ;
})}
);
}
/* ---------- server-list status panel ---------- */
function ServerListPanel({ players, max, version }) {
return (
Ulicraft
Java {version}
⛏ Season 3 · Survival SMP · whitelist open
);
}
/* ---------- scroll reveal (fail-safe: visible at rest, .anim added when in view) ---------- */
function useReveal() {
useEffect(() => {
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
let els = [...document.querySelectorAll(".reveal")];
let stop = false;
const tick = () => {
if (stop) return;
const vh = window.innerHeight;
for (let i = els.length - 1; i >= 0; i--) {
const r = els[i].getBoundingClientRect();
if (r.top < vh * 0.9 && r.bottom > 0) {
els[i].classList.add("anim");
els.splice(i, 1);
}
}
if (els.length) requestAnimationFrame(tick);
else stop = true;
};
requestAnimationFrame(tick);
return () => { stop = true; };
}, []);
}
/* ============================================================ */
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"heroLayout": "centered",
"mood": "grass",
"headFont": "pixelify",
"serverIp": "play.ulicraft.net",
"tagline": "Hardcore survival, built to last.",
"particles": true
}/*EDITMODE-END*/;
const HEAD_FONTS = {
pixelify: "'Pixelify Sans', system-ui, sans-serif",
"8bit": "'Press Start 2P', monospace",
silkscreen: "'Silkscreen', system-ui, sans-serif",
};
const FEATURES = [
{ glyph: "shield", gold: false, h: "Grief-proof claims",
p: "Lock down your base with golden-shovel land claims. Your builds stay yours — even while you're offline." },
{ glyph: "diamond", gold: true, h: "Zero pay-to-win",
p: "The store sells cosmetics and nothing else. Every diamond is earned in-game, never bought." },
{ glyph: "orb", gold: false, h: "A living world",
p: "Seasonal map resets, custom bosses, and community events keep the overworld worth logging into." },
{ glyph: "heart", gold: true, h: "Real community",
p: "A whitelisted, moderated server with an active Discord. Toxicity meets the ban hammer, fast." },
];
function App() {
const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
const players = useLivePlayers(37, 100);
const peak = 84;
const version = "1.21.4";
// guarantee pixel head fonts are downloaded before first paint settles
useEffect(() => {
if (!document.fonts || !document.fonts.load) return;
["600 32px 'Pixelify Sans'", "700 32px 'Pixelify Sans'",
"400 32px 'Press Start 2P'", "400 32px 'Silkscreen'", "700 32px 'Silkscreen'"]
.forEach((f) => document.fonts.load(f).catch(() => {}));
}, []);
// apply mood / hero / font to
useEffect(() => {
const r = document.documentElement;
r.setAttribute("data-mood", t.mood);
r.setAttribute("data-hero", t.heroLayout);
r.setAttribute("data-head", t.headFont);
r.style.setProperty("--font-head", HEAD_FONTS[t.headFont] || HEAD_FONTS.pixelify);
}, [t.mood, t.heroLayout, t.headFont]);
useReveal();
return (
<>
{/* NAV */}
{/* HERO */}
Java Edition · Survival SMP · Season 3
{t.tagline}
A whitelisted Java SMP with land claims, seasonal events, and zero pay-to-win.
Grab the IP, fire up your launcher, and stake your claim.
{players} playing now
Java {version}
No mods required
{/* STATUS */}
Server Status
Live, and waiting for you.
This is exactly what you'll see in your multiplayer list.
{[
{ k: <>{players}
/100 >, l: "Players Online" },
{ k: <>{peak}>, l: "Peak Today" },
{ k: <>99.9
% >, l: "Uptime" },
{ k: <>20.0
tps >, l: "Performance" },
].map((s, i) => (
))}
{/* FEATURES */}
What makes it Ulicraft
Built for players who stay.
No reset roulette, no whales buying god gear. Just a server that respects your time.
{FEATURES.map((f, i) => (
))}
{/* HOW TO JOIN */}
How to Join · 3 Steps
From zero to spawning in.
Ulicraft runs on Minecraft: Java Edition. Here's the whole path, start to finish.
{/* STEP 1 */}
1
Account
Get Minecraft: Java Edition
Create a free Microsoft account, then buy and download Minecraft: Java & Bedrock
Edition from minecraft.net. Already own Java Edition? Skip straight to step 2.
{/* STEP 2 */}
2
Launcher
Download & set up the launcher
Install the official Minecraft Launcher, sign in with your Microsoft account, and select
the Latest Release ({version}) profile.
Download the launcher for Windows, macOS, or Linux.
Sign in → pick Latest Release → press Play once to finish installing.
Optional: allocate 4–6 GB RAM under Installations → More Options for smoother play.
{/* STEP 3 */}
3
Connect
Join the Ulicraft server
In Minecraft, open Multiplayer → Add Server . Name it Ulicraft,
paste the address below, hit Done , then double-click the server to join.
Whitelisted server — apply in our Discord first to get added.
{/* FOOTER */}
{/* TWEAKS */}
setTweak("heroLayout", v)} />
setTweak("mood", v)} />
setTweak("headFont", v)} />
setTweak("tagline", v)} />
setTweak("serverIp", v)} />
setTweak("particles", v)} />
>
);
}
ReactDOM.createRoot(document.getElementById("root")).render( );