
Posted June 13, 2025 by SteelCycloneStudios
#velocity puck #indie game dev #3D air hockey #web game #browser game #steel cyclone studios #html5 game #javascript #three.js
Welcome back, puck-slingers! In this fourth devlog, weโre excited to showcase new gameplay systems and visual polish that bring Velocity Puck closer to our vision of a fast-paced, character-driven 3D air hockey experience.
Hereโs whatโs new:
Previously, character selection was hard-coded or minimal. Now, weโve moved it to a fully integrated in-game menu using HTML/CSS paired with JavaScript event listeners. The UI is intuitive and sleek:
Access the menu using the hamburger icon (โฐ) in the top-left.
Tap Characters to choose between:
Classic ๐ฅ
Robot ๐ค
Ninja ๐ฅท
Alien ๐ฝ
Each selection visually highlights your choice and updates the paddle styling or switches to a custom 3D character.
In the HTML:
html <div id="characterMenu" class="character-grid"> <div class="characterBtn selected" data-character="classic">...</div> ... </div>
In the JavaScript:
js
document.querySelectorAll('.characterBtn').forEach(btn => {
btn.addEventListener('click', function() {
...
updateCharacterStyle(character);
});
});
The updateCharacterStyle() function applies color changes or activates character models (like the robot).
You can now play as a fully 3D animated Robot Paddle Character imported from a GLTF model!
The robot appears in place of the classic paddle when selected.
Integrated with lighting and shadows.
Scaled and positioned dynamically to follow player input.
js
loader.load('...RobotExpressive.glb', function(gltf) {
robotModel = gltf.scene;
robotModel.scale.set(1.5, 1.5, 1.5);
robotModel.visible = false;
scene.add(robotModel);
});
This loads the robot using Three.jsโs GLTFLoader. Once loaded, it's added to the scene but hidden until selected from the menu.
When playing as the robot, animations respond to player actions:
Idle: When standing still.
Walking: When moving the paddle.
Punch: When hitting the puck.
These are handled using Three.jsโs AnimationMixer, with smooth transitions using .fadeIn() and .fadeOut().
js
function updateRobotAnimation(newPosition) {
...
if (isMovingNow && !isRobotMoving) {
currentAnimation = robotModel.animations['Walking'];
...
} else if (!isMovingNow && isRobotMoving) {
currentAnimation = robotModel.animations['Idle'];
...
}
}
And on puck impact:
js
function playPunchAnimation() {
currentAnimation = robotModel.animations['Punch'];
...
}
These functions are triggered based on mouse or touch movement and puck collisions.
The index.html file functions as the main entry point for the game. It does the following:
html <script type="importmap"> ... "three": "<a href="https://unpkg.com/three@0.158.0/...">https://unpkg.com/three@0.158.0/...</a>" </script>
Sidebar-based navigation with character and color customization.
Toggle options for theme, pause, and new game.
Loads 3D table, walls, puck, paddles.
Configures lights and shadows.
Adds camera and user controls via OrbitControls.
Tracks score, handles puck physics, AI movement, goal detection.
Updates character animations based on user input.
Fully supports both mouse and mobile/touch inputs.
Coming up in the next updates:
Multiplayer support.
Enhanced character variety with unique abilities.
Character voice SFX and UI polish.
Thanks for reading! ๐ You can play the updated build right now on our [itch.io page]. Donโt forget to let us know what you think of the robot character โ and what kind of fighters you'd like to see on the puck table next!
โ Jordon McClain
Steel Cyclone Studios ๐ฅ