import React, { useState, useEffect, useRef } from 'react'; import { Wheat, User, LogOut, Gamepad2, Sprout, Hand, Terminal, Trophy, Users } from 'lucide-react'; // --- SOUND EFFECTS --- const useClickSound = () => { const playClick = () => { try { const audioCtx = new (window.AudioContext || (window as any).webkitAudioContext)(); const oscillator = audioCtx.createOscillator(); const gainNode = audioCtx.createGain(); oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(800, audioCtx.currentTime); oscillator.frequency.exponentialRampToValueAtTime(100, audioCtx.currentTime + 0.1); gainNode.gain.setValueAtTime(0.3, audioCtx.currentTime); gainNode.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.1); oscillator.connect(gainNode); gainNode.connect(audioCtx.destination); oscillator.start(); oscillator.stop(audioCtx.currentTime + 0.1); } catch (e) { // Ignore audio errors } }; return playClick; }; // --- DATA TYPES --- interface UserData { username: string; cornbread: number; streak: number; lastClaim: number; // Timestamp pfpSeed: number; inventory: Record; id: string; } interface ActivityLog { id: string; message: string; timestamp: number; type: 'poke' | 'claim' | 'gacha'; } const CROPS = [ { id: 'grass', name: 'Dry Grass', rarity: 'Common', color: 'text-green-600', chance: 0.40 }, { id: 'corn_stalk', name: 'Corn Stalk', rarity: 'Common', color: 'text-green-600', chance: 0.35 }, { id: 'wheat', name: 'Wild Wheat', rarity: 'Uncommon', color: 'text-blue-500', chance: 0.15 }, { id: 'golden_corn', name: 'Golden Corn', rarity: 'Rare', color: 'text-purple-500', chance: 0.09 }, { id: 'ancient_seed', name: 'Ancient Seed', rarity: 'Legendary', color: 'text-yellow-500', chance: 0.01 }, ]; // --- FAKE NETWORK (SIMULATION) --- // Since we have no server, we simulate other users doing things const BOT_NAMES = ['~gl3bmon3y', '~milady', '~remilia_fan', '~beanstalk', '~corn_lord', '~bit_farmer']; const BOT_ACTIONS = [ 'claimed daily rations!', 'found Golden Corn!', 'poked the server!', 'is resting...', 'harvested Dry Grass.', 'lost their streak.' ]; // --- AUTH COMPONENT --- const AuthScreen = ({ onLogin }: { onLogin: (user: UserData) => void }) => { const [username, setUsername] = useState(''); const [isRegistering, setIsRegistering] = useState(false); const playClick = useClickSound(); const handleAuth = (e: React.FormEvent) => { e.preventDefault(); playClick(); // Check Local Storage const existing = localStorage.getItem(`user_${username}`); if (isRegistering) { if (existing) { alert("User already exists locally. Please login."); return; } const newUser: UserData = { username, id: Math.random().toString(36).substr(2, 9), cornbread: 0, streak: 0, lastClaim: 0, pfpSeed: Math.floor(Math.random() * 1000), inventory: {} }; localStorage.setItem(`user_${username}`, JSON.stringify(newUser)); localStorage.setItem('currentUser', username); onLogin(newUser); } else { if (!existing) { alert("User not found on this device."); return; } localStorage.setItem('currentUser', username); onLogin(JSON.parse(existing)); } }; return (

REMILIA

OFFLINE MODE v2.0

setUsername(e.target.value)} placeholder="Enter Username" required />
); }; // --- MAIN APP COMPONENTS --- const ProfileCard = ({ user }: { user: UserData }) => { const avatarUrl = `https://api.dicebear.com/7.x/pixel-art/svg?seed=${user.pfpSeed}&backgroundColor=3e2b20`; return (
Avatar
ID: {user.id}

{user.username}

~ Local Farmer

Cornbread Balance
{user.cornbread}
Current Streak
{user.streak} days
Inventory
{Object.entries(user.inventory || {}).length === 0 && ( Storage Empty. Go pick crops. )} {Object.entries(user.inventory || {}).map(([key, count]) => (
{key} x{count}
))}
); }; const DailyConsole = ({ user, onUpdate }: { user: UserData, onUpdate: (u: UserData) => void }) => { const [status, setStatus] = useState('System Ready...'); const [loading, setLoading] = useState(false); const playClick = useClickSound(); const handleClaim = async () => { setLoading(true); playClick(); setStatus('Analyzing timestamp...'); // Simulate network delay setTimeout(() => { const now = Date.now(); const lastClaimTime = user.lastClaim || 0; const hoursSince = (now - lastClaimTime) / (1000 * 60 * 60); if (hoursSince < 24) { setStatus(`ERROR: Cool-down active. Wait ${Math.ceil(24 - hoursSince)} hours.`); setLoading(false); return; } let newStreak = user.streak; if (hoursSince > 48 && lastClaimTime !== 0) { newStreak = 1; setStatus('Streak Lost! Resetting to 1.'); } else { newStreak += 1; } const reward = 50 + (newStreak * 5); const updatedUser = { ...user, cornbread: user.cornbread + reward, streak: newStreak, lastClaim: now }; onUpdate(updatedUser); setStatus(`SUCCESS: Acquired ${reward} Cornbread. Streak: ${newStreak}`); setLoading(false); }, 1500); }; return (
{/* Console Screen */}

DAILY RATION

{loading ? 'PROCESSING...' : status}

Current Supply: {user.cornbread} CB
{/* Controls */}
); }; const CropPicker = ({ user, onUpdate }: { user: UserData, onUpdate: (u: UserData) => void }) => { const [logs, setLogs] = useState([]); const [isGathering, setIsGathering] = useState(false); const playClick = useClickSound(); const bottomRef = useRef(null); const COST = 20; const gatherCrops = () => { playClick(); if (user.cornbread < COST) { setLogs(prev => [...prev, `> ERROR: Insufficient Cornbread. Need ${COST}.`]); return; } setIsGathering(true); setLogs(prev => [...prev, `> Initiating gathering sequence... (-${COST} CB)`]); setTimeout(() => { // 1. Determine yield (1-5 items) const yieldCount = Math.floor(Math.random() * 5) + 1; const foundItems: string[] = []; const newInventory = { ...user.inventory }; for (let i = 0; i < yieldCount; i++) { const roll = Math.random(); let cumulative = 0; let selectedCrop = CROPS[0]; for (const crop of CROPS) { cumulative += crop.chance; if (roll <= cumulative) { selectedCrop = crop; break; } } foundItems.push(selectedCrop.name); newInventory[selectedCrop.name] = (newInventory[selectedCrop.name] || 0) + 1; } const updatedUser = { ...user, cornbread: user.cornbread - COST, inventory: newInventory }; onUpdate(updatedUser); setLogs(prev => [ ...prev, `> Sequence complete. Found:`, ...foundItems.map(item => ` + ${item}`) ]); setIsGathering(false); }, 2000); }; useEffect(() => { bottomRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [logs]); return (
CAM_01 [LIVE]
{isGathering ? (
SCANNING FIELD...
) : (
SECTOR CLEAR
Ready to gather
)}
HARVEST LOG v1.0
{logs.length === 0 &&
Waiting for input...
} {logs.map((log, i) => (
{log}
))}
); }; const ActivityFeed = ({ currentUser, addActivity }: { currentUser: UserData, addActivity: (msg: string) => void }) => { const [activities, setActivities] = useState([]); const playClick = useClickSound(); // Initial fake history useEffect(() => { setActivities([ { id: '1', message: '~system initialized', timestamp: Date.now() - 100000, type: 'poke' }, { id: '2', message: '~gl3bmon3y joined the farm', timestamp: Date.now() - 50000, type: 'poke' }, ]); }, []); // Bot Generator: Adds fake events to make it feel alive useEffect(() => { const interval = setInterval(() => { if (Math.random() > 0.7) { const botName = BOT_NAMES[Math.floor(Math.random() * BOT_NAMES.length)]; const action = BOT_ACTIONS[Math.floor(Math.random() * BOT_ACTIONS.length)]; const newLog: ActivityLog = { id: Math.random().toString(), message: `${botName} ${action}`, timestamp: Date.now(), type: 'poke' }; setActivities(prev => [newLog, ...prev].slice(0, 50)); } }, 5000); // New fake event every ~5 seconds return () => clearInterval(interval); }, []); const handlePoke = () => { playClick(); const newLog: ActivityLog = { id: Math.random().toString(), message: `${currentUser.username} poked the server!`, timestamp: Date.now(), type: 'poke' }; setActivities(prev => [newLog, ...prev].slice(0, 50)); addActivity("Poked the server"); }; return (

Global Net (SIM)

{activities.map(act => (
{new Date(act.timestamp).toLocaleTimeString()} {act.message}
))}
); }; // --- APP SHELL --- export default function App() { const [user, setUser] = useState(null); const [view, setView] = useState<'profile' | 'cornbread' | 'crops'>('profile'); const playClick = useClickSound(); // Initial load useEffect(() => { const savedName = localStorage.getItem('currentUser'); if (savedName) { const savedUser = localStorage.getItem(`user_${savedName}`); if (savedUser) { setUser(JSON.parse(savedUser)); } } }, []); // Save on update const handleUpdateUser = (updatedUser: UserData) => { setUser(updatedUser); localStorage.setItem(`user_${updatedUser.username}`, JSON.stringify(updatedUser)); }; const handleLogout = () => { localStorage.removeItem('currentUser'); setUser(null); }; if (!user) return ; return (
{/* Top Bar */} {/* Main Layout */}
{/* Left Column: Content */}
{/* Mobile Nav */}
{[ { id: 'profile', icon: User, label: 'Profile' }, { id: 'cornbread', icon: Gamepad2, label: 'Rations' }, { id: 'crops', icon: Sprout, label: 'Crops' }, ].map(item => ( ))}
{view === 'profile' && } {view === 'cornbread' && } {view === 'crops' && }
{/* Right Column: Global Chat/Activity */}
{}} />
); }