docs: Add The Trinity official Minecraft skins

- Frost Wizard skin for Frostystyle (Michael) - cyan/ice theme
- Fire Emissary skin for Gingerfury (Meg) - orange/fire theme
- Arcane Catalyst skin for unicorn20089 (Holly) - purple/arcane theme
- All skins use light skin tones with element-colored glowing eyes
- Detailed armor/robe designs with overlay layers for depth
- Includes 3D skin viewer HTML tool for previewing before upload
- Comprehensive README with usage instructions and design philosophy

All three skins represent The Trinity's Fire/Frost/Arcane elements.

Signed-off-by: Claude <claude@firefrostgaming.com>
This commit is contained in:
Claude
2026-03-28 01:34:01 +00:00
parent 2d6d8b1151
commit 273a3f521d
5 changed files with 779 additions and 0 deletions

View File

@@ -0,0 +1,154 @@
# The Trinity - Minecraft Skins
**Official Minecraft character skins for The Trinity founders.**
Created: March 27, 2026
Format: 64x64 PNG with overlay layers
Compatible: Minecraft Java Edition (all versions with skin support)
---
## The Three Skins
### ❄️ Frost Wizard - Frostystyle (Michael)
**File:** `frost-wizard-frostystyle.png`
**Element:** Frost/Ice
**Primary Color:** #00E5FF (Electric Cyan - Frost Primary)
**Model:** Steve (classic/wider arms)
**Role:** The Wizard - Technical lead, infrastructure, Path of Frost leader
**Design Features:**
- Black hair
- Cyan/frost armor with ice crystal patterns
- Detailed snowflake accents throughout
- Frost crown overlay with icicle pattern
- Cyan glowing eyes
- Gray boots with frost accents
- Light skin tone
---
### 🔥 Fire Emissary - Gingerfury (Meg)
**File:** `fire-emissary-gingerfury.png`
**Element:** Fire/Passion
**Primary Color:** #FF3D00 (Deep Orange/Red - Fire Primary)
**Model:** Alex (slim arms)
**Role:** The Emissary - Community manager, social lead, Path of Fire leader
**Design Features:**
- Ginger/red hair (warm red-orange tones)
- Fire gradient armor (yellow→orange→red)
- Flame crown with upward flames
- Fire symbols and flame patterns throughout
- Warm glowing orange eyes
- Friendly smile
- Golden amber boots (#FFD600 - Fire Accent)
- Light skin tone
---
### ⚡ Arcane Catalyst - unicorn20089 (Holly)
**File:** `arcane-catalyst-unicorn20089.png`
**Element:** Arcane/Magic
**Primary Color:** #A855F7 (Purple - Official Arcane color)
**Model:** Alex (slim arms)
**Role:** The Catalyst - Lead Builder, creative authority, bridge between Fire and Frost
**Design Features:**
- Purple/violet hair (deep purple tones)
- Arcane gradient armor (light→bright→dark purple)
- Crystal crown with mystical energy
- Arcane rune and symbol patterns throughout
- Purple glowing eyes
- Central arcane crystal on chest
- Light purplish-gray boots
- Light skin tone
---
## How to Use These Skins
### Option 1: Upload to Minecraft.net
1. Go to: https://www.minecraft.net/en-us/msaprofile/mygames/editskin
2. Click "Choose File"
3. Select the skin PNG file
4. Choose model (Steve or Alex as noted above)
5. Click "Upload"
### Option 2: Use in Multiplayer Servers
Once uploaded to your Minecraft.net profile, the skin will automatically appear on all servers.
### Option 3: Preview Before Uploading
Use the included `minecraft_skin_viewer.html` tool (in this directory or docs/tools/) to preview skins in 3D before uploading.
---
## Design Philosophy
Each skin represents one element of The Trinity:
- **Frost (Cyan)** - Technical precision, systems, infrastructure
- **Fire (Orange/Red)** - Passion, community, warmth
- **Arcane (Purple)** - Balance, creativity, catalytic force
All three skins:
- Use light skin tones (requested preference)
- Feature glowing eyes in their element color
- Include detailed overlay layers for depth
- Have element-specific armor/robe designs
- Are built on proper Minecraft skin template (64x64)
---
## File Specifications
- **Resolution:** 64x64 pixels
- **Format:** PNG with transparency
- **Color Mode:** RGBA
- **Layers:** Base layer + Overlay layer (second skin layer enabled)
- **Compatible:** Minecraft Java Edition 1.8+
---
## Customization
These skins can be customized using:
- **Nova Skin Editor:** https://minecraft.novaskin.me/
- **Miners Need Cool Shoes:** https://www.needcoolshoes.com/
- **Skindex:** https://www.minecraftskins.com/
When editing, preserve:
- The element color schemes (Frost/Fire/Arcane)
- The glowing eye aesthetic
- The overall Trinity branding
---
## Usage Rights
These skins are official Firefrost Gaming branding assets.
**Permitted Use:**
- The Trinity members (Michael, Meg, Holly) for personal Minecraft profiles
- Firefrost Gaming marketing materials
- Community showcases and promotional content
- Server branding and displays
**Not Permitted:**
- Commercial redistribution
- Modification and claiming as original work
- Use by non-Trinity members claiming to be The Trinity
---
## Version History
| Version | Date | Changes |
|---------|------|---------|
| 1.0 | 2026-03-27 | Initial Trinity skins created |
---
**Fire + Frost + Arcane = The Trinity** 🔥❄️⚡
*"For children not yet born"* 💙

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,625 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Firefrost Gaming - Minecraft Skin Viewer</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}
.header {
text-align: center;
color: white;
margin-bottom: 30px;
}
.header h1 {
font-size: 2.5em;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
}
.header p {
font-size: 1.1em;
opacity: 0.9;
}
.container {
background: white;
border-radius: 20px;
padding: 30px;
box-shadow: 0 10px 40px rgba(0,0,0,0.3);
max-width: 1200px;
width: 100%;
}
.controls {
margin-bottom: 20px;
display: flex;
gap: 15px;
flex-wrap: wrap;
align-items: center;
}
.file-input-wrapper {
position: relative;
overflow: hidden;
display: inline-block;
}
.file-input-wrapper input[type=file] {
position: absolute;
left: -9999px;
}
.file-input-wrapper label {
display: inline-block;
padding: 12px 24px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 8px;
cursor: pointer;
font-weight: 600;
transition: transform 0.2s;
}
.file-input-wrapper label:hover {
transform: translateY(-2px);
}
.preset-buttons {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.preset-btn {
padding: 10px 20px;
border: 2px solid #667eea;
background: white;
color: #667eea;
border-radius: 8px;
cursor: pointer;
font-weight: 600;
transition: all 0.2s;
}
.preset-btn:hover {
background: #667eea;
color: white;
}
.preset-btn.frost {
border-color: #00E5FF;
color: #00E5FF;
}
.preset-btn.frost:hover {
background: #00E5FF;
color: white;
}
.preset-btn.fire {
border-color: #FF3D00;
color: #FF3D00;
}
.preset-btn.fire:hover {
background: #FF3D00;
color: white;
}
.preset-btn.arcane {
border-color: #A855F7;
color: #A855F7;
}
.preset-btn.arcane:hover {
background: #A855F7;
color: white;
}
#viewer-container {
width: 100%;
height: 600px;
background: linear-gradient(to bottom, #87CEEB 0%, #E0F6FF 100%);
border-radius: 10px;
position: relative;
overflow: hidden;
}
.info {
margin-top: 20px;
padding: 15px;
background: #f8f9fa;
border-radius: 8px;
font-size: 0.9em;
color: #666;
}
.info strong {
color: #333;
}
.animation-controls {
margin-top: 15px;
padding: 15px;
background: #f0f0f0;
border-radius: 8px;
}
.animation-controls label {
margin-right: 15px;
font-weight: 600;
}
.animation-controls select {
padding: 8px 12px;
border-radius: 5px;
border: 1px solid #ccc;
font-size: 1em;
}
</style>
</head>
<body>
<div class="header">
<h1>🔥❄️ Firefrost Gaming 🔥❄️</h1>
<p>Minecraft Skin Viewer - The Trinity</p>
</div>
<div class="container">
<div class="controls">
<div class="file-input-wrapper">
<input type="file" id="skinInput" accept="image/png" />
<label for="skinInput">📁 Upload Skin PNG</label>
</div>
<div class="preset-buttons">
<button class="preset-btn frost" onclick="loadPreset('frost')">❄️ Frost Wizard</button>
<button class="preset-btn fire" onclick="loadPreset('fire')">🔥 Fire Emissary</button>
<button class="preset-btn arcane" onclick="loadPreset('arcane')">⚡ Arcane Catalyst</button>
</div>
</div>
<div class="animation-controls">
<label for="animationSelect">Animation:</label>
<select id="animationSelect" onchange="changeAnimation()">
<option value="idle">Idle (Standing)</option>
<option value="walk">Walking</option>
<option value="run">Running</option>
<option value="wave">Waving</option>
</select>
</div>
<div id="viewer-container"></div>
<div class="info">
<strong>Controls:</strong> Click and drag to rotate • Scroll to zoom • Right-click drag to pan<br>
<strong>Tip:</strong> Upload any 64x64 Minecraft skin PNG or try the Trinity presets!
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
// Three.js scene setup
let scene, camera, renderer, skinMesh;
let animationTime = 0;
let currentAnimation = 'idle';
// Initialize the 3D scene
function init() {
const container = document.getElementById('viewer-container');
// Scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0x87CEEB);
// Camera
camera = new THREE.PerspectiveCamera(
50,
container.clientWidth / container.clientHeight,
0.1,
1000
);
camera.position.set(0, 16, 40);
camera.lookAt(0, 16, 0);
// Renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(container.clientWidth, container.clientHeight);
container.appendChild(renderer.domElement);
// Lighting
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(10, 20, 10);
scene.add(directionalLight);
// Ground plane
const groundGeometry = new THREE.PlaneGeometry(100, 100);
const groundMaterial = new THREE.MeshStandardMaterial({
color: 0x90EE90,
side: THREE.DoubleSide
});
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = Math.PI / 2;
ground.position.y = 0;
scene.add(ground);
// Mouse controls
let isDragging = false;
let previousMousePosition = { x: 0, y: 0 };
let rotation = { x: 0, y: 0 };
renderer.domElement.addEventListener('mousedown', (e) => {
isDragging = true;
});
renderer.domElement.addEventListener('mousemove', (e) => {
if (isDragging && skinMesh) {
const deltaMove = {
x: e.offsetX - previousMousePosition.x,
y: e.offsetY - previousMousePosition.y
};
rotation.y += deltaMove.x * 0.01;
rotation.x += deltaMove.y * 0.01;
// Clamp vertical rotation
rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, rotation.x));
}
previousMousePosition = { x: e.offsetX, y: e.offsetY };
});
renderer.domElement.addEventListener('mouseup', () => {
isDragging = false;
});
// Zoom with mouse wheel
renderer.domElement.addEventListener('wheel', (e) => {
e.preventDefault();
camera.position.z += e.deltaY * 0.05;
camera.position.z = Math.max(20, Math.min(80, camera.position.z));
});
// Handle window resize
window.addEventListener('resize', () => {
const width = container.clientWidth;
const height = container.clientHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
});
// Animation loop
animate();
}
// Create Minecraft character from skin texture
function createMinecraftCharacter(skinTexture) {
// Remove old mesh if exists
if (skinMesh) {
scene.remove(skinMesh);
}
const group = new THREE.Group();
// Minecraft skin texture
skinTexture.magFilter = THREE.NearestFilter;
skinTexture.minFilter = THREE.NearestFilter;
const skinMaterial = new THREE.MeshStandardMaterial({
map: skinTexture,
transparent: true
});
// Head (8x8x8)
const headGeo = new THREE.BoxGeometry(8, 8, 8);
const head = new THREE.Mesh(headGeo, skinMaterial);
head.position.y = 24;
// UV mapping for head
setHeadUVs(headGeo);
group.add(head);
// Body (8x12x4)
const bodyGeo = new THREE.BoxGeometry(8, 12, 4);
const body = new THREE.Mesh(bodyGeo, skinMaterial);
body.position.y = 14;
setBodyUVs(bodyGeo);
group.add(body);
// Arms (4x12x4 each)
const armGeo = new THREE.BoxGeometry(4, 12, 4);
const rightArm = new THREE.Mesh(armGeo, skinMaterial);
rightArm.position.set(-6, 14, 0);
setRightArmUVs(rightArm.geometry);
group.add(rightArm);
const leftArm = new THREE.Mesh(armGeo, skinMaterial);
leftArm.position.set(6, 14, 0);
setLeftArmUVs(leftArm.geometry);
group.add(leftArm);
// Legs (4x12x4 each)
const legGeo = new THREE.BoxGeometry(4, 12, 4);
const rightLeg = new THREE.Mesh(legGeo, skinMaterial);
rightLeg.position.set(-2, 6, 0);
setRightLegUVs(rightLeg.geometry);
group.add(rightLeg);
const leftLeg = new THREE.Mesh(legGeo, skinMaterial);
leftLeg.position.set(2, 6, 0);
setLeftLegUVs(leftLeg.geometry);
group.add(leftLeg);
// Store body parts for animation
group.userData = {
head: head,
body: body,
rightArm: rightArm,
leftArm: leftArm,
rightLeg: rightLeg,
leftLeg: leftLeg
};
skinMesh = group;
scene.add(group);
}
// UV mapping functions for each body part
function setHeadUVs(geometry) {
const uvs = geometry.attributes.uv.array;
// Front, back, top, bottom, right, left faces
// Simplified UV mapping for head (8,8 to 16,16 area)
const faceUVs = [
[8/64, 8/64, 16/64, 16/64], // front
[24/64, 8/64, 32/64, 16/64], // back
[8/64, 0/64, 16/64, 8/64], // top
[16/64, 0/64, 24/64, 8/64], // bottom
[0/64, 8/64, 8/64, 16/64], // right
[16/64, 8/64, 24/64, 16/64] // left
];
for (let i = 0; i < 6; i++) {
const [x1, y1, x2, y2] = faceUVs[i];
const offset = i * 8;
uvs[offset + 0] = x1; uvs[offset + 1] = 1 - y2;
uvs[offset + 2] = x2; uvs[offset + 3] = 1 - y2;
uvs[offset + 4] = x1; uvs[offset + 5] = 1 - y1;
uvs[offset + 6] = x2; uvs[offset + 7] = 1 - y1;
}
geometry.attributes.uv.needsUpdate = true;
}
function setBodyUVs(geometry) {
const uvs = geometry.attributes.uv.array;
const faceUVs = [
[20/64, 20/64, 28/64, 32/64], // front
[32/64, 20/64, 40/64, 32/64], // back
[20/64, 16/64, 28/64, 20/64], // top
[28/64, 16/64, 36/64, 20/64], // bottom
[16/64, 20/64, 20/64, 32/64], // right
[28/64, 20/64, 32/64, 32/64] // left
];
for (let i = 0; i < 6; i++) {
const [x1, y1, x2, y2] = faceUVs[i];
const offset = i * 8;
uvs[offset + 0] = x1; uvs[offset + 1] = 1 - y2;
uvs[offset + 2] = x2; uvs[offset + 3] = 1 - y2;
uvs[offset + 4] = x1; uvs[offset + 5] = 1 - y1;
uvs[offset + 6] = x2; uvs[offset + 7] = 1 - y1;
}
geometry.attributes.uv.needsUpdate = true;
}
function setRightArmUVs(geometry) {
const uvs = geometry.attributes.uv.array;
const faceUVs = [
[44/64, 20/64, 48/64, 32/64],
[52/64, 20/64, 56/64, 32/64],
[44/64, 16/64, 48/64, 20/64],
[48/64, 16/64, 52/64, 20/64],
[40/64, 20/64, 44/64, 32/64],
[48/64, 20/64, 52/64, 32/64]
];
for (let i = 0; i < 6; i++) {
const [x1, y1, x2, y2] = faceUVs[i];
const offset = i * 8;
uvs[offset + 0] = x1; uvs[offset + 1] = 1 - y2;
uvs[offset + 2] = x2; uvs[offset + 3] = 1 - y2;
uvs[offset + 4] = x1; uvs[offset + 5] = 1 - y1;
uvs[offset + 6] = x2; uvs[offset + 7] = 1 - y1;
}
geometry.attributes.uv.needsUpdate = true;
}
function setLeftArmUVs(geometry) {
const uvs = geometry.attributes.uv.array;
const faceUVs = [
[36/64, 52/64, 40/64, 64/64],
[44/64, 52/64, 48/64, 64/64],
[36/64, 48/64, 40/64, 52/64],
[40/64, 48/64, 44/64, 52/64],
[32/64, 52/64, 36/64, 64/64],
[40/64, 52/64, 44/64, 64/64]
];
for (let i = 0; i < 6; i++) {
const [x1, y1, x2, y2] = faceUVs[i];
const offset = i * 8;
uvs[offset + 0] = x1; uvs[offset + 1] = 1 - y2;
uvs[offset + 2] = x2; uvs[offset + 3] = 1 - y2;
uvs[offset + 4] = x1; uvs[offset + 5] = 1 - y1;
uvs[offset + 6] = x2; uvs[offset + 7] = 1 - y1;
}
geometry.attributes.uv.needsUpdate = true;
}
function setRightLegUVs(geometry) {
const uvs = geometry.attributes.uv.array;
const faceUVs = [
[4/64, 20/64, 8/64, 32/64],
[12/64, 20/64, 16/64, 32/64],
[4/64, 16/64, 8/64, 20/64],
[8/64, 16/64, 12/64, 20/64],
[0/64, 20/64, 4/64, 32/64],
[8/64, 20/64, 12/64, 32/64]
];
for (let i = 0; i < 6; i++) {
const [x1, y1, x2, y2] = faceUVs[i];
const offset = i * 8;
uvs[offset + 0] = x1; uvs[offset + 1] = 1 - y2;
uvs[offset + 2] = x2; uvs[offset + 3] = 1 - y2;
uvs[offset + 4] = x1; uvs[offset + 5] = 1 - y1;
uvs[offset + 6] = x2; uvs[offset + 7] = 1 - y1;
}
geometry.attributes.uv.needsUpdate = true;
}
function setLeftLegUVs(geometry) {
const uvs = geometry.attributes.uv.array;
const faceUVs = [
[20/64, 52/64, 24/64, 64/64],
[28/64, 52/64, 32/64, 64/64],
[20/64, 48/64, 24/64, 52/64],
[24/64, 48/64, 28/64, 52/64],
[16/64, 52/64, 20/64, 64/64],
[24/64, 52/64, 28/64, 64/64]
];
for (let i = 0; i < 6; i++) {
const [x1, y1, x2, y2] = faceUVs[i];
const offset = i * 8;
uvs[offset + 0] = x1; uvs[offset + 1] = 1 - y2;
uvs[offset + 2] = x2; uvs[offset + 3] = 1 - y2;
uvs[offset + 4] = x1; uvs[offset + 5] = 1 - y1;
uvs[offset + 6] = x2; uvs[offset + 7] = 1 - y1;
}
geometry.attributes.uv.needsUpdate = true;
}
// Animation function
function updateAnimation() {
if (!skinMesh) return;
const parts = skinMesh.userData;
animationTime += 0.05;
// Reset rotations
Object.values(parts).forEach(part => {
part.rotation.set(0, 0, 0);
});
switch(currentAnimation) {
case 'walk':
parts.rightArm.rotation.x = Math.sin(animationTime) * 0.5;
parts.leftArm.rotation.x = -Math.sin(animationTime) * 0.5;
parts.rightLeg.rotation.x = -Math.sin(animationTime) * 0.5;
parts.leftLeg.rotation.x = Math.sin(animationTime) * 0.5;
break;
case 'run':
parts.rightArm.rotation.x = Math.sin(animationTime * 2) * 0.8;
parts.leftArm.rotation.x = -Math.sin(animationTime * 2) * 0.8;
parts.rightLeg.rotation.x = -Math.sin(animationTime * 2) * 0.8;
parts.leftLeg.rotation.x = Math.sin(animationTime * 2) * 0.8;
skinMesh.position.y = Math.abs(Math.sin(animationTime * 2)) * 2;
break;
case 'wave':
parts.rightArm.rotation.z = -Math.PI / 2;
parts.rightArm.rotation.x = Math.sin(animationTime * 3) * 0.3;
break;
case 'idle':
default:
// Gentle breathing/idle motion
skinMesh.position.y = Math.sin(animationTime * 0.5) * 0.3;
parts.rightArm.rotation.x = Math.sin(animationTime * 0.3) * 0.05;
parts.leftArm.rotation.x = -Math.sin(animationTime * 0.3) * 0.05;
break;
}
}
// Animation loop
function animate() {
requestAnimationFrame(animate);
if (skinMesh) {
updateAnimation();
}
renderer.render(scene, camera);
}
// Load skin from file
document.getElementById('skinInput').addEventListener('change', (e) => {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (event) => {
const loader = new THREE.TextureLoader();
loader.load(event.target.result, (texture) => {
createMinecraftCharacter(texture);
});
};
reader.readAsDataURL(file);
}
});
// Load preset skins
function loadPreset(type) {
const paths = {
'frost': 'frost-wizard-skin-proper.png',
'fire': 'fire-emissary-meg-skin.png',
'arcane': 'arcane-catalyst-holly-skin.png'
};
// Note: In a real deployment, these would need to be accessible
// For now, show a message
alert(`To view ${type} skin:\n\n1. Download the ${type} skin PNG\n2. Click "Upload Skin PNG"\n3. Select the downloaded file`);
}
// Change animation
function changeAnimation() {
const select = document.getElementById('animationSelect');
currentAnimation = select.value;
animationTime = 0;
}
// Initialize on page load
window.addEventListener('load', init);
</script>
</body>
</html>