A collection of things that don't really matter https://www.riptor.com Mostly useless content from the Pacific Northwest Tue, 28 Oct 2025 14:38:39 +0000 en-US hourly 1 https://wordpress.org/?v=6.9 Claude https://www.riptor.com/2025/10/28/claude/ Tue, 28 Oct 2025 14:38:39 +0000 https://www.riptor.com/?p=198 Continue reading Claude ]]> I started tinkering with Claude Code and I’ve found it to be an excellent rubber duck. You know, like the rubber duck you have on your monitor that you talk to and explain your code and ponder the meaning of it all?

Claude is like the rubber duck but you can get a response back that will almost always be helpful. It might not be the right answer but I have yet to find a case where it doesn’t put me on the right track to the answer I need. And sometimes I even ask Claude to implement something for me, say, a method for checking if a point is inside a wedge.

Is AI going to make us all irrelevant? Hardly. It’s going to make some of us really good at what we do. Potentially more productive too. Don’t buy into the hype. Take the scientific approach. Test the waters. See what it can do and where the edges start to fray. I am very satisfied with Claude Code. Your mileage may vary. Find one that works for you.

]]>
Debuggery https://www.riptor.com/2021/05/29/debuggery/ Sat, 29 May 2021 15:25:00 +0000 https://www.riptor.com/?p=185 Continue reading Debuggery ]]> I was having a terrible time finding if a sword slash hit a barrel or not… which, it clearly did not because the barrel did not trigger a collision. After numerous attempts to figure out what was going on, I started on a path to debug … well … the path the collider was on! So I wrote a script.

I’m using box colliders since everything I’m doing does not require precision. This makes it easy to script up something to highlight the path my colliders have been on.

The code is below. I tossed an MIT license on it so you can use it however you like. You can add it to any game object that has a box collider or add it to an empty object in your scene and reference a box collider. You could even adapt the script to use some other collider if you like.

/**
 * MIT License
 *
 * Copyright (c) 2021 Josiah Olivieri
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

/**
 *
 * this is used to debug the path a box collider proceeds on as the game is played. i am hoping it 
 * proves useful in debugging whether a target is hit or not in combat.
 */
public class DebugColliderPath : MonoBehaviour {

    public bool debugTrail = false;

    public BoxCollider boxCollider;
    public float captureRate = 0.5f;
    public int maxPoints = 10;
    public bool connected = false;
    public Color trailColor = new Color( 1.0f, 0.75f, 0.0f );

    private List<List<Vector3>> debugPath = new List<List<Vector3>>();
    private float lastTimeDebugTrail;

    void Start() {
        if (debugTrail && boxCollider == null) {
            boxCollider = GetComponent<BoxCollider>();
        }
    }

    void FixedUpdate() {
        if (debugTrail) {
            if ( boxCollider == null || boxCollider.gameObject == null ) {
                debugTrail = false;
                return;
            }

            if (Time.time - lastTimeDebugTrail < captureRate)
                return;

            lastTimeDebugTrail = Time.time;

            Vector3 center = boxCollider.center;
            Vector3 boxSize = boxCollider.size / 2.0f;

            List<Vector3> points = new List<Vector3>();
            for (int i = 0; i < 8; i++) {
                Vector3 extents = boxSize;

                extents.Scale( new Vector3( ( i & 1 ) == 0 ? 1 : -1, ( i & 2 ) == 0 ? 1 : -1, ( i & 4 ) == 0 ? 1 : -1 ) );

                Vector3 localPos = center + extents;
                Vector3 globalPos = boxCollider.transform.TransformPoint( localPos );

                points.Add( globalPos );
            }

            debugPath.Add( points );

            if (debugPath.Count > maxPoints)
                debugPath.RemoveAt( 0 );
        }
    }

#if UNITY_EDITOR
    void OnDrawGizmos() {

        if ( debugTrail ) {
            if (boxCollider == null || boxCollider.gameObject == null) {
                debugTrail = false;
                return;
            }

            GUIStyle style = new GUIStyle();
            style.richText = true;
            style.fontSize = 12;

            Color trails = new Color(trailColor.r, trailColor.g, trailColor.b, 0.0f );
            
            float alpha = 0.0f;
            float inc = 1.0f / (float)maxPoints;
            int n = 0;
            if ( debugPath.Count < 1 )
                return;

            var lastPoints = debugPath[0];
            foreach (var points in debugPath) {
                Gizmos.color = trails;

                for ( int i=0; i<7; i++ ) {
                    for ( int j=i+1; j<8; j++ ) {
                        Gizmos.DrawLine( points[i], points[j] );
                    }
                }

                if ( connected ) {
                    Gizmos.color = new Color( trails.b, trails.r, trails.g, alpha );
                    for ( int i=0; i<7; i++ ) {
                        Gizmos.DrawLine( points[i], lastPoints[i] );
                    }
                }
                
                UnityEditor.Handles.Label( points[0], "<color=white>p" + n + "</color>", style );
                n++;

                alpha = alpha + inc; 
                if ( alpha > 1.0f ) alpha = 1.0f;
                trails.a = alpha;
                lastPoints = points;
            }
        }
    }
#endif
}

That’s all for this week. This little example was fun to work on but it also proved useful. (I found that the animation was key-framed to the side of the barrel and past the barrel… so I turned on animate physics and it seems like things… barrels… are breaking correctly now!)

]]>
Routines https://www.riptor.com/2021/05/23/routines/ Sun, 23 May 2021 18:00:00 +0000 https://www.riptor.com/?p=182 Continue reading Routines ]]> I really don’t have anything useful to say.

Our country is overflowing with distrust, hate, and inequity.

Our world is plagued and forever changed.

Humans need to be willing to be influenced by new facts and perspectives.

I want to add some writing time to my daily or weekly routine. With all that is going on outside of my tiny pocket of the world I will need to find something that I care to share with others. I will likely put some effort into a side project and share the progress here. It’s not anything that matters in the broader spectrum of the current events, but I will share regardless.

I had a project awhile back (2017?) that I started… I made the art (2d vector sprites, animated with Spine) and built in Unity. I recently took all the 2d code and ported it to 3d to make a side-scrolling dungeon crawling adventure that uses 3d scenes and models with a 2d feel. I’ll keep tinkering with this project and share updates from time to time.

]]>
Updated https://www.riptor.com/2020/11/15/updated/ Sun, 15 Nov 2020 21:36:03 +0000 https://www.riptor.com/?p=165 Continue reading Updated ]]> I haven’t been doing a good job housekeeping my website. I recently discovered I was running a very old version of Ubuntu so it was time to dust off some linux skills and get crackin’ at porting my site to a new image.

One of the most tedious things about setting up a new site is making sure you have everything covered. I don’t have a script to automagically port one site to another. Instead, I’m going to dig through my bash history and capture everything I just did here.

On the new machine:

$ sudo mkdir /proj
$ sudo mount /dev/xvdf /proj # I have a virtual disk 
$ sudo adduser user
$ sudo usermod -aG admin user
$ sudo usermod -aG sudo user
$ sudo apt upgrade
$ sudo apt-get install apache2
$ sudo apt-get install php libapache2-mod-php php-cli php-mysql php-gd php-imagick php-tidy php-xmlrpc
$ sudo apt-get install mysql-server mysql-client
$ sudo systemctl start mysql
$ sudo mysql -u root 
> create database nameofwpdb;
> create user 'wpuser'@'%' identified by 'password';
> create user 'wpuser'@'localhost' identified by 'password';
> grant all on nameofwpdb.* to 'wpuser'@'%' with grant option;
> grant all on nameofwpdb.* to 'wpuser'@'localhost' with grant option;
> flush privileges;

On the old machine:

$ sudo tar czf ~/tmp/www.tgz /www
$ sudo tar czf ~/tmp/etc.tgz /etc
$ sudo tar czf ~/tmp/home.tgz /home
$ mysqldump -u root -p nameofwpdb > ~/tmp/nameofwpdb.dump
$ scp ~/tmp/www.tgz user@newhost:/home/user/
$ scp ~/tmp/etc.tgz user@newhost:/home/user/
$ scp ~/tmp/home.tgz user@newhost:/home/user/
$ scp ~/tmp/nameofwpdb.dump user@newhost:/home/user/

And back on the new machine:

$ mysql -u wpuser -p nameofwpdb < ~/nameofwpdb.dump
$ mkdir ~/unpack ; cd ~/unpack
$ tar zxf ../www.tgz
$ tar zxf ../etc.tgz
$ tar zxf ../home.tgz
$ # put the home directory back in order
$ mv home/user/.bashrc ~/ ; mv home/user/.profile ~/
$ mv home/user/* ~/
$ sudo mkdir /www
$ sudo chown www-data:www-data /www
$ mv www/* /www
$ sudo chgrp -R www-data /www/
$ cd /etc/apache2/mods-enabled
$ sudo ln -s ../mods-available/rewrite.load .
$ sudo ln -s ../mods-available/socache_shmcb.load .
$ sudo ln -s ../mods-available/ssl.conf .
$ sudo ln -s ../mods-available/ssl.load .
$ cd ../sites-available
$ sudo cp ~/unpack/etc/apache2/sites-available/* .
$ cd ../sites-enabled
$ # I did some symlinking of my sites here
$ cd ..
$ cp ~/unpack/etc/apache2/IPList.conf . # this is my ip block list for my sites
$ sudo mv ~/unpack/etc/letsencrypt/ /etc
$ sudo chown -R root:root /etc/letsencrypt
$ sudo apt-get install certbot
$ sudo hostnamectl set-hostname --static pokemonname
$ sudo vi /etc/cloud/cloud.cfg # set preserve_hostname = true
$ sudo reboot
$ sudo apt-get install python3-certbot-apache
$ sudo certbot renew --dry-run

And lastly, a few links I used along the way:

https://aws.amazon.com/premiumsupport/knowledge-center/linux-static-hostname-rhel7-centos7/

https://dev.mysql.com/doc/refman/8.0/en/creating-accounts.html

]]>
Friday post for the new year https://www.riptor.com/2020/01/03/friday-post-for-the-new-year/ Sat, 04 Jan 2020 06:40:55 +0000 https://www.riptor.com/?p=158 Continue reading Friday post for the new year ]]> I thought I might try a series of posts on Fridays this year. Maybe not every Friday, but as we used to say… a post will be here on A Friday.

Lots of things going on lately, chief among them is I started a new job. Really happy I did and you can hit up my LinkedIn profile if you’re curious where I went, whether I’m happy about the move, or if we’re hiring. (here’s a hint: I’m very happy about I love the new gig)

I’ll make the first one brief. I’m not really sure what I’ll cover in these posts yet. I could cover some technical bits (like how I’m ramping up at work – doing bug fixes by first creating end-to-end tests that confirm the bug, and implementing the fix!) or I could talk about some social agenda bits that are going on around the Pacific North West (you should consider supporting Hope Link). I could talk about hobbies I don’t have enough time to do such as painting, brewing, … or guitar. Or I might even cover a video game or two (the new Pokemon for Switch is just great btw).

I’ll leave it here for now. The exercise is to just get posts going.

]]>
Day / Night cycle https://www.riptor.com/2018/04/29/day-night-cycle/ Mon, 30 Apr 2018 04:38:34 +0000 https://www.riptor.com/?p=145 Continue reading Day / Night cycle ]]> I just managed to swing a day to night cycle in Unity and it only took me … 30 minutes! and it’s beautiful to boot.  I’m using some assets from Synty Studios which turned me on to an awesome, and totally free, post processing stack that looks great in the day to night cycle.

  1. Basic Setup

a. Find the SM_Generic_SkyDome in the POLYGON_Renderbox assets. You’ll put this in your scene and it will be hooked up later to the script that manages the transitions.

b. Add a directional light to the scene. It doesn’t really matter what color you use, we’ll set those up later in our script.

c. Run the game and make sure everything looks nifty.

2. New Script

Create a new script named DayNightTransitionManager and attach it to an empty object in the scene.

    public class DayNightTransitionManager : MonoBehaviour {

        public Light light;

        public List<Material> materials;
        public List<Color> colors;
        public float timeBetweenCycles = 60.0f;
        public float transitionTime = 20.0f;

        public MeshRenderer rend;

        private float lastCycle = 0.0f;
        private int pointer = 0;
        private int next = 1;
        private int max = 0;

        private bool inTransition = false;

        void Start() {
            lastCycle = Time.time;
            max = materials.Count;

            rend.material = materials[ 0 ];
            light.color = colors[ 0 ];
        }

        void Update() {

            if ( !inTransition ) {
                if ( Time.time - lastCycle > timeBetweenCycles ) {
                    inTransition = true;
                    lastCycle = Time.time;

                    Debug.Log( "DayNight moving to transition phase" );
                }
            } else {

                float amount = Mathf.Clamp( ( Time.time - lastCycle ) / transitionTime, 0.0f, 1.0f );
                rend.material.Lerp( materials[ pointer ], materials[ next ], amount );
                light.color = Color.Lerp( colors[ pointer ], colors[ next ], amount );

                if ( Time.time - lastCycle > transitionTime ) {
                    inTransition = false;
                    lastCycle = Time.time;

                    rend.material = materials[ next ];
                    light.color = colors[ next ];

                    next = ( next + 1 ) % max;
                    pointer = ( pointer + 1 ) % max;

                    Debug.Log( "DayNight moving out of transition phase" );
                }
            }

        }
    
    }

 

3. Connecting it all up

a. Drag your Directional Light into the Light field in the inspector.

b. Drag the SkyDome object into the Rend field in the inspector.

c. I set the materials and colors sizes to 4, and added the following elements to materials:

Skydome_Day
Skydome_Sunset
Skydome_Night
Skydome_EarlyMorning

d. I used the following colors for each stage:

#FFF4D6FF
#FCC88500
#35388000
#FA240000

4. Enjoy!

]]>
Going Secure https://www.riptor.com/2018/03/27/going-secure/ Wed, 28 Mar 2018 04:01:14 +0000 https://www.riptor.com/?p=139 Continue reading Going Secure ]]> I setup an SSL-enabled Apache server on Lightsail today in 15 minutes. I would have spent less time on it if I had gone directly to Let’s Encrypt, but I’ll share the steps in case anyone wants a quick-and-easy SSL-enabled web server. I’m using Ubuntu 16.04.3 LTS so… you’re mileage may vary.

  1. Add the certbot repo:

    sudo add-apt-repository ppa:certbot/certbot

  2. Update:

    sudo apt-get update

  3. Install the certbot:

    sudo apt-get install python-certbot-apache

  4. Modify your site conf for SSL:

    sudo vi /etc/apache2/sites-enabled/000.example.conf

    ..
    <IfModule mod_ssl.c>
    <VirtualHost *:443>
    ServerAdmin webmaster@example.com
    ServerName example.com
    ServerAlias www.example.com
    ..

  5. Run the certbot:

    sudo certbot --apache -d example.com -d www.example.com

After that you agree to some terms, answer some questions (my shortcut for this is A, N, Enter, 2), and BOOM! You have an SSL-enabled web server too! You might not even need steps 2 and 4 but I did ’em anyway and it didn’t hurt.

]]>
Up and running with Lightsail https://www.riptor.com/2018/02/04/up-and-running-with-lightsail/ Mon, 05 Feb 2018 04:14:20 +0000 http://www.riptor.com/?p=135 Continue reading Up and running with Lightsail ]]> It happened yet again… I went back to the billing console in AWS and I realized my reserved instance was no longer reserved… my bill was double. Yay.

So I opted to check out Lightsail. It’s an AWS service that makes virtual private servers on the cloud easy. I opted for a relatively small instance to run my website and now I’m only paying $10 a month. I went with an Ubuntu image and it was easy to move all my bits from my previous reserved instance over to Lightsail. Now I’m not going to worry about my monthly bill surprising me next time!

]]>
Slow progress https://www.riptor.com/2017/11/28/slow-progress/ Tue, 28 Nov 2017 15:42:25 +0000 http://www.riptor.com/?p=133 Continue reading Slow progress ]]> I finally started to look at Node.js. I’ve never truly enjoyed JavaScript but the new spec makes the language feel pretty modern and there are plenty of editors out there that make editing a breeze.

I decided to stand up a simple server with a NoSQL solution behind it. This was very simple. I used tutorials from the Node.js site as well as a few from w3schools. Before I knew it I was sending my metric data from my dungeon platform game to a server that captured the metrics and shoved ’em in a collection.

I still need to do something with the data but I’m making progress again. The next step is to handle some auth (or a simple challenge for the client / server) and some input validation to ensure what I’m reading is meant for the service. I also haven’t quite worked out how to gather the data out of mongo and make it useful but there’s always something else to work on.

]]>
Pico Disaster https://www.riptor.com/2017/08/22/pico-disaster/ Tue, 22 Aug 2017 14:39:55 +0000 http://www.riptor.com/?p=126 Continue reading Pico Disaster ]]> I wanted to get a fresh hop going this year as last year our kitchen went kaput and I couldn’t use those hops. So this year… I was ready. I harvested a full bowl of hops (with the help of Gigi), I dried them out, I stopped after work at the brew store to build a nice Czech Pilsner (minus the hops!)… and I was ready for a brew day on Saturday.

The Pico had been giving me some flow issues in the last batch. I got an error #1 a few times until I got all the connections worked out (or temp sensors warmed up). It wasn’t that big a deal as the batch started and finished brewing properly and all was well.

So this batch, I had one issue with an error #1 during the warm up and it was ready to go after that. Until I went to check on it after dinner… the mash was spewing water everywhere. I had to stop the cycle, rush towels in, and cleaned up the biggest mess I’ve seen in awhile.

I’ve only had my Pico two years now… here’s hoping it’s an easy fix but the way I’m dealing with support I’m quite concerned that out-of-warranty on an emergent product means out-of-luck. I guess I’ll have to investigate one of these if that’s the case.

]]>