avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • Tuesday May 24, 2022, 11:32 pm
  • Proudly celebrating 15+ years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - Deozaan [ switch to compact view ]

Pages: [1] 2 3 4 5 6 ... 19next
Living Room / April Fools!
« on: April 01, 2022, 01:50 AM »
Hey all,

This is just a reminder that it's April 1st, so there will likely be a lot of headlines, announcements, emails, etc., that you shouldn't believe. If something seems off about something you read, keep this in mind.

I'm mentioning it here because I got a silly email from Windscribe VPN saying they were bought out. But it came in the early afternoon on March 31 my local time, so I didn't realize for a while that it was an April Fools joke, and I was really puzzled. I thought this kind of thing from soulless corporations was "cute" and fun ~15 years ago because it made them seem like they were more friendly and had a personality, but I've really grown annoyed by it over the years. I don't want corporations to have a personality. I don't want to be "friends" with a company. I just want them to provide the service they say they provide and otherwise stay out of my way.

But that's just me being a curmudgeon, I suppose.

General Software Discussion / Mount a Disc Image from Context Menu?
« on: December 18, 2021, 01:54 AM »
Hi all,

I deal with disc images semi-frequently, and one thing that I've found very helpful in the past is to be able to just right-click the ISO (or other format) image and select "Mount Disc Image" and it would automatically mount it as a virtual drive. Then I could view/copy the files I needed and then eject/unmount the drive and be on my way when I was finished.

I was under the impression that it had become a standard Windows 10 feature. But I've just noticed that I no longer have that context menu option, and I can't remember what utility I may have had installed in the past to enable it.

Does anyone have any ideas or suggestions on how to get this feature back?

N.A.N.Y. 2022 / NANY 2022 Release: Progress Bar and Jam (PB&J)
« on: November 24, 2021, 03:38 AM »
NANY 2022 Entry Information

Application Name Progress Bar and Jam (PB&J)
Version 1.211126.0
Short Description A countdown timer and progress bar for game jams
Supported OSes Windows, Linux, Mac
Web Page This is it
Download Link Download on Keybase
System Requirements
  • Modern Windows, Linux, or MacOS
  • x86_64 architecture CPU
Version History
  • v1.211126.0
    - Add custom icon
  • v1.211124.0
    - Use event name for window title
  • v1.211123.0
    - Initial release
    - Set event name, start and end times
    - Precision settings
    - Font settings
Author Deozaan

I have been using mouser's Progress Bars of Life (PBOL) for many years as a good visual indicator for how much time I have left while doing game jams. I have also been nagging mouser to fix PBOL's docked mode (and weird precision issues) for years, to better suit my wants/needs for game jams.

Here's what PBOL looks like:

Progress Bars Of Life - Large.png

Here's what I want it to look like:

Progress Bars Of Life - Minimal.png

But after years of not getting what I want from mouser, I finally went full Thanos.

I'll do it myself.jpg

  • Displays a customizable title for the event
  • Displays a progress bar showing how far into the event you are
  • Displays a countdown timer showing how long until the event starts/ends or how long it has been over
  • Configurable amount of precision (how many units of time to display)
  • Optional monospace font
  • Optional dyslexic font

Planned Features
No other features planned

PBOD - Roboto.png PBOD - RobotoMono.png PBOD - Dyslexic.png PBOD - DyslexicMono.png

Unzip and run.

Using the Application
Launch the app once to generate the config file.
Edit the config file as you see fit.
Re-launch the app to load the new configuration.
Panic as your deadline approaches.

It should be mostly "portable" so you can just delete the files wherever you unzipped it to, but it might write some logs to your user path under Deozaan/PB&J (or PBandJ).

Don't actually panic.

Known Issues

Living Room / Exploiting Glitches to Win Games Quickly (Speedruns)
« on: November 16, 2021, 02:07 AM »
There have been a couple of similar posts on this subject already, see the one about beating Castlevania: Symphony of the Night with assembly code here (along with a couple other videos about Super Mario World) or the one about the race to conquer Mario Kart's Choco Mountain in seconds here, but I'm creating a more generic thread here which any future similar video (or article) can be posted to.

To start off the thread, here's a video of how speedrunners beat a trial version of The Legend of Zelda: Ocarina of Time which would automatically reset after 5 minutes had elapsed. The methods used in this one is similar to the above linked Castlevania video, where the speedrunner performs certain actions in the game to rewrite parts of system/game memory to get the desired result.

Super Smash Bros. Brawl contains a timed demo of Zelda: Ocarina of Time, with only 5 minutes of playtime. Defeating Ganon and beating the game sounds completely impossible in the demo! However, speedrunners have found a way. Here's how they did it.

How Speedrunners Beat the Brawl Ocarina of Time Demo

DC Gamer Club / Ludum Dare 49: October 1st-4th, 2021
« on: September 15, 2021, 02:07 PM »
Ludum Dare 49 is almost here! It begins in about 2 weeks.

Unfortunately I have scheduling conflicts this time around, so I don't plan on participating.

But theme suggestions are currently open, which means that anyone who is interested can submit up to 3 themes, even if they're not participating. You just need to register a free account to be able to do so. If you'd like to suggest a theme, you may do so here:

See previous posts on DonationCoder about Ludum Dare:

Ludum Dare 48 - (My team made Let's Go Deeper for LD48)
Ludum Dare 47 - (My team made Chrono Crash for LD47)
Ludum Dare 46 - (My team made Defendeer for LD46)
Ludum Dare 45 Reviews - A thread about LD45 games
Ludum Dare 41 - (My team made It's Not Lupus! for LD41)
Ludum Dare 2017 Thread - A thread about games from LD37 and LD38
Ludum Dare 33 - A thread about LD33 games
Ludum Dare 32 - (I made Time Bomb during LD32)
Ludum Dare 31 - (I made Worm Wars during LD31)
Ludum Dare 30 - (I made Planetary Devourers during LD30)
Ludum Dare 29 - (I made It Came From... Beneath!! during LD29)
Ludum Dare [29] topic for other games - A thread about LD29 games
Ludum Dare 23 - (I made Be Tiny, World! during LD23)
Ludum Dare - Game Programming Challenges

Developer's Corner / Clean Code - Uncle Bob (YouTube Playlist)
« on: September 08, 2021, 12:07 PM »
I came across this playlist of videos of "Uncle Bob" lecturing about writing clean code. It looks like the full lecture/seminar is about 9 hours in total. I just finished the first video and am finding it interesting enough that I want to continue with the series.

And if you decide to watch it, don't be put off the whole thing by how annoying or useless the first ~3:30 minutes of introductions at the beginning of the first video appear to be. In fact, it may be best just to skip them. Use the chapters/timestamps to get to the right spot. :Thmbsup:

Oh, and one more word of warning: Unfortunately the video editor kind of sucked at their job and didn't always show the feed from the most useful camera. For example, sometimes Uncle Bob is showing or talking about his slides but the camera is zoomed in for a close up on his face instead of showing us the projector screen. :(

Great lecture (so far), shoddy video editing work.

Developer's Corner / Constructing a minimal Sudoku puzzle
« on: July 28, 2021, 10:35 AM »
Hi all,

I've been working on programming a Sudoku game and I've run into a problem with my code that I've been unable to solve for the past few days and realize I need some fresh eyes on the problem. This may not be the best place to ask about this, but as best as I can tell this problem requires a bit of an in-depth explanation and I don't really feel comfortable asking on other sites that may be more closely aligned with the specific area of inquiry, but where I have not really established myself as part of the community. And maybe it could be asked more succinctly, but unfortunately for anyone who reads this, I tend to be overly verbose in an effort to make sure I'm explaining myself clearly. So here goes.

First of all, I assume the reader is familiar with Sudoku puzzles and understands the basic rules. But I figure I should establish some Sudoku terminology (mostly from Peter Norvig), so we're all speaking the same language here.

Square: A place where a number goes. A Sudoku puzzle is made up of 81 squares arranged in a 9x9 grid.
Row: Nine squares arranged horizontally (9x1), in which the numbers 1 through 9 can only appear once.
Column: Nine squares arranged vertically (1x9), in which the numbers 1 through 9 can only appear once.
Box: Nine squares arranged in a 3x3 grid, in which the numbers 1 through 9 can only appear once.
Unit: Any nine squares that compose a row, column, or box. Each square is a member of exactly 3 units.
Peers: Any squares that share a unit are considered peers. Each square has exactly 20 peers.
Given: The "freebie" clues that are known at the start of the puzzle.
Minimal Puzzle: A Sudoku puzzle that has the fewest amount of givens possible, while still only having one unique solution.

And here's a crude diagram showing a minimal puzzle with some of the above terminology highlighted:

Sudoku Terminology.png

So what I'm trying to accomplish is making a game that can generate an infinite number of Sudoku puzzles (well, as many of the 6,670,903,752,021,072,936,960 possible puzzles as a player might want/be able to play). It turns out that generating solutions is easy. You can sort of just make it up as you go along. The part I'm having trouble with is going from the solution to the minimal puzzle.

In other words, in order to present the player with a puzzle to solve, I want to go from something like what's on the left to something like what's on the right:

Code: Text [Select]
  1. 1 2 7 | 4 5 8 | 3 6 9     . . . | . . . | . 6 .
  2. 5 3 9 | 6 7 2 | 1 8 4     . 3 . | . . 2 | . . .
  3. 6 4 8 | 9 3 1 | 7 2 5     . . . | . 3 . | . . .
  4. ------+-------+------     ------+-------+------
  5. 3 1 5 | 7 8 6 | 4 9 2     . . . | 7 . 6 | . . .
  6. 4 8 2 | 3 1 9 | 6 5 7     . 8 2 | . 1 . | . . .
  7. 9 7 6 | 2 4 5 | 8 3 1     9 . 6 | . 4 . | . . .
  8. ------+-------+------     ------+-------+------
  9. 8 9 4 | 5 6 7 | 2 1 3     8 9 4 | 5 . 7 | . . 3
  10. 2 6 3 | 1 9 4 | 5 7 8     . . . | 1 . . | 5 7 8
  11. 7 5 1 | 8 2 3 | 9 4 6     . 5 . | . . . | . . .

I've written code that accomplishes it. In fact, the above puzzle was generated by my code. But it's far too slow, and unpredictably so, to be useful in a real-time game. Sometimes it only takes a couple of seconds to generate a puzzle, which in itself is too slow. But other times it takes up to a few minutes. And in a few cases it has taken so long that I've been too impatient to let it finish. I'm coding this in GDScript, which is a custom language created for Godot, but which is very similar to Python.

I'm storing the solution of the 9x9 grid in a special kind of one-dimensional array in GDScript called a PoolIntArray, which is passed by value instead of reference. It would look like this as a traditional array:

Code: Python [Select]
  1. var answer := [
  2.         1, 2, 7, 4, 5, 8, 3, 6, 9,
  3.         5, 3, 9, 6, 7, 2, 1, 8, 4,
  4.         6, 4, 8, 9, 3, 1, 7, 2, 5,
  5.         3, 1, 5, 7, 8, 6, 4, 9, 2,
  6.         4, 8, 2, 3, 1, 9, 6, 5, 7,
  7.         9, 7, 6, 2, 4, 5, 8, 3, 1,
  8.         8, 9, 4, 5, 6, 7, 2, 1, 3,
  9.         2, 6, 3, 1, 9, 4, 5, 7, 8,
  10.         7, 5, 1, 8, 2, 3, 9, 4, 6,
  11. ]

I also have a similar array of booleans, called "givens" which indicates if a particular square is a given or not.

I then follow a method I read about in a paper called Sudoku Puzzles Generating: from Easy to Evil (link to archive, since original link is dead) which the authors refer to as "digging holes" in the puzzle, and offer this flowchart as part of their explanation:

Digging Strategy.png

I'll summarize my understanding and (attempted) implementation as follows:

  • Order a list of all the squares to "dig" however you see fit. (I just shuffle an array of all the squares)
  • For each square in the list, attempt to dig the known value N. This means to set the value as "unknown" or "empty" (represented internally by the number 0).
  • With the newly dug square, attempt to solve the puzzle with all possible values (1-9) other than N.
  • If you find a solution, it means the puzzle is no longer unique (it has multiple solutions), so the square is considered a given and must display the value N to maintain uniqueness.
  • If you don't find a solution, the square can remain "dug" and you continue iterating the list to dig more holes.
  • Once you've iterated the entire list, you should have dug out all squares that are not essential to maintaining the uniqueness of the puzzle, which results in a minimal puzzle.

Here's the code which I think does what I described above:

Code: Python [Select]
  1. # digs a solved grid to find a minimal puzzle
  2. func find_givens() -> void:
  3.         # make a list of all 81 indices of the grid
  4.         var dig_list := []
  5.         for idx in 81:
  6.                 dig_list.push_back(idx) # push_back() just adds elements to the end of an array
  7.         # randomize the order of squares we "dig"
  8.         dig_list.shuffle()
  9.         # prepare some variables we'll be using repeatedly
  10.         var nums = answer # grab a copy of the answer so we don't make changes to it
  11.         var v : int # temporarily stores the "dug" value in case we need to replace it
  12.         var coords := Vector2() # x,y coordinates
  13.         # iterate the randomized list
  14.         for i in dig_list:
  15.                 # don't attempt to dig a square that is known to be a given
  16.                 if given[i] == true:
  17.                         # sanity check: this code should never actually be reached
  18.                         continue
  19.                 # store the current value of the digit
  20.                 v = nums[i]
  21.                 for n in range(1, 10): # iterate the numbers 1-9
  22.                         # skip if this is the square's original value
  23.                         if n == v:
  24.                                 continue
  25.                         # dig the value and try finding other solutions
  26.                         nums[i] = 0
  27.                         # get the (x, y) coords for this square
  28.                         coords = index_to_coord(i) # convert the index (0-80) to x,y coordinates as if on a 9x9 grid
  29.                         # change the value at this square to something else, if possible
  30.                         if is_possible(nums, coords.y, coords.x, n):
  31.                                 # N could legally be placed in this square
  32.                                 nums[i] = n
  33.                                 # try to find a solution to the puzzle with this new value in this square
  34.                                 if solve(nums) > 0:
  35.                                         # we found a solutions, which means the puzzle is no longer unique
  36.                                         # so put the value back
  37.                                         nums[i] = v
  38.                                         # mark this square as a given
  39.                                         given[i] = true
  40.                                         # don't attempt further numbers for this square
  41.                                         break

And here's the code for the if_possible() function, which is used to determine if a value n could legally be placed in the square located at (x,y) in a 9x9 grid. Or in other words, it makes sure that no other peer of the square (x,y) has the value n:

Code: Python [Select]
  1. # returns true if no peers have the value n
  2. func is_possible(grid, y : int, x : int, n : int) -> bool:
  3.         for i in 9:
  4.                 # check if n already exists in current row (9x1)
  5.                 if grid[coord_to_index(y, i)] == n:
  6.                         return false
  7.                 # check if n already exists in current column (1x9)
  8.                 if grid[coord_to_index(i, x)] == n:
  9.                         return false
  10.         # integer math here means (5 / 3) * 3 is the same as 1 * 3
  11.         var x0 : int = (x / 3) * 3
  12.         var y0 : int = (y / 3) * 3
  13.         # check if n already exists in current box (3x3)
  14.         for i in 3:
  15.                 for j in 3:
  16.                         if grid[coord_to_index(y0 + i, x0 + j)] == n:
  17.                                 return false
  18.         # as far as we know, n is a legal value for this square
  19.         return true

And finally, the code used to attempt to find a solution to the puzzle. I think this is where my trouble lies. This function basically just brute-forces the grid, attempting every possible value in every unknown square, looking for a solution, with backtracking when it reaches a dead-end. Initially I had it naively starting at element 0 of the array and looping through them in order, but this is obviously very inefficient and leads to a lot of duplicated efforts due to backtracking. It seemed to work, and generated minimal puzzles which usually had about 24-26 givens. But as mentioned previously, it was pretty slow.

So then I attempted to sort the list of squares to solve by the number of possible values that were legal to place there, starting with those which had the least possible solutions. This increases chances of success, but even in the event of a failure (dead-end) it cuts out a huge number of the possible solutions we'd have to check.

Oh, and since it's recursive, I have it keep track of and return how many solutions it has found so that it can immediately jump all the way back down the stack once a solution has been found.

Code: Python [Select]
  1. func solve(grid, solutions := 0) -> int:
  2.         # this is a dictionary whose key will be the (x,y) coordinate
  3.         # and the value will be the number of possibilities for that coordinate
  4.         var possibilities = {}
  5.         # loop through every element in the grid
  6.         for i in grid.size():
  7.                 # get the (x,y) coordinates for this index
  8.                 var coord = index_to_coord(i)
  9.                 # start with the assumption that each square has 0 possibilities (i.e., the square's value is known)
  10.                 possibilities[coord] = 0
  11.                 # if it's not zero, then it's considered "solved" already
  12.                 if not grid[i] == 0:
  13.                         continue
  14.                 # check how many values are possible here
  15.                 for n in range(1, 10): # iterate the numbers 1-9
  16.                         if is_possible(grid, coord.y, coord.x, n):
  17.                                 possibilities[coord] += 1
  18.         # sorted_list is an array whose elements will contain the index of the squares grid,
  19.         # sorted by the number of possibilities
  20.         var sorted_list := []
  21.         for n in range(1, 10): # iterate the numbers 1-9
  22.                 # loop through each element in possibilities
  23.                 for coord in possibilities.keys(): # remember that each key is an (x,y) coordinate
  24.                         if possibilities[coord] == n:
  25.                                 # add this square to the sorted list of squares to solve
  26.                                 sorted_list.push_back(coord_to_index(coord.y, coord.x))
  27.         # now iterate through the sorted list and try solving
  28.         for i in sorted_list:
  29.                 var coord = index_to_coord(i)
  30.                 if grid[i] == 0:
  31.                         for n in range(1, 10): # iterate the numbers 1-9
  32.                                 if is_possible(grid, coord.y, coord.x, n):
  33.                                         grid[i] = n
  34.                                         solutions += solve(grid, solutions)
  35.                                         if solutions > 0:
  36.                                                 return solutions
  37.                                         else:
  38.                                                 grid[i] = 0
  39.                         # none were possible, we've reached a dead end
  40.                         return solutions
  41.         # if we got this far then we've solved it!
  42.         solutions += 1
  43.         return solutions

And again, this seems to work... kind of. I mean, it is (usually) noticeably faster than when I was naively brute-forcing without sorting. But (1) it's still too slow, taking at least a couple of seconds to complete, and (2) the "minimal" puzzles its generating can't actually be minimal. Doing it the naïve way, I was getting minimal puzzles with about 24-26 givens on average, the puzzles this is generating consistently have almost twice as many, usually in the 44-46 range. But it has been proven that the least amount of givens a unique puzzle could have is as low as 17 and the highest amount of givens a minimal unique puzzle can have is 39. So something is definitely wrong. Here's an example:

Code: Text [Select]
  1. . . . | . 5 9 | . 3 4
  2. 2 1 . | . . 6 | . 5 7
  3. 9 . . | 3 . 7 | . 6 .
  4. ------+-------+------
  5. . 9 . | . . 3 | 8 4 2
  6. 5 . 8 | 7 . 2 | 3 . 9
  7. . . 2 | 1 9 . | . . .
  8. ------+-------+------
  9. . 2 . | 8 7 1 | 4 . .
  10. 1 . 7 | 9 . . | 5 . 6
  11. . 3 9 | 6 2 . | 7 8 .

Oh, and for completeness, here is the code for a couple of helper functions that are used in a few places in the code above:

Code: Python [Select]
  1. # returns an index for an 81-element array based on x,y coordinates of a 9x9 grid
  2. func coord_to_index(y : int, x : int) -> int:
  3.         return (y * 9) + x
  6. # returns the x,y coordinates of a square on a 9x9 grid based on 81-element array index
  7. func index_to_coord(i : int) -> Vector2:
  8.         var coord := Vector2()
  9.         coord.x = i % 9
  10.         # integer division
  11.         coord.y = i / 9
  12.         return coord

I tried adding tons of comments everywhere to make sure it was clear what the code was (supposed to be) doing. If anyone here takes the time to read this, parse/understand the code, and offer helpful suggestions/solutions, I'd appreciate it. Mostly I think I just needed a break from the coding and thought that maybe the process of writing this all out would be a form of Rubber Duck debugging.

I know I'm doing something wrong because I'm not getting minimal puzzles anymore. So help figuring out why that's happening would be much appreciated. But perhaps a more helpful response would explain what else I'm doing wrong that is making this so slow. My understanding is that most minimal puzzles should be solved/generated in milliseconds at most, and that it should be fairly rare to come across a puzzle that takes a few seconds and even rarer to come across one that takes minutes or longer. I've tried benchmarking my code by generating 100 puzzles and averaging the time it takes to do each step, and I can't even do that because while it "only" takes a few seconds at best for each puzzle, it often takes up to a few minutes. But the clincher is that in every attempt at generating 100 puzzles in a row there's (at least) one that takes so long that I've never had the patience to find out exactly how long it would take to complete. I can't remember for sure, but I think I've left it running on a single puzzle for over an hour before aborting the process and trying to adjust the code to speed it up.

What am I doing wrong? And where? Please don't say "everything/everywhere" :D

DC Gamer Club / Valve Announces Steam Deck: A Handheld PC
« on: July 17, 2021, 12:48 AM »

Valve have announced a new, portable PC with built-in gamepad which looks very much like the Nintendo Switch. It will come with a custom version of SteamOS installed, designed to run games using your Steam library. But it's a full PC, meaning it can also be docked to a TV or monitor and other peripherals (keyboard, mouse, other gamepads) using a USB hub or Bluetooth. And you could even install Windows or other Linux distributions on it.

All the internal hardware of the various models is the same except for the internal storage, which results in a 64 GB (eMMC) model for $400, a 256 GB (NVMe) model for $530, and a 512 GB (even faster NVMe than the 256) model for $650 which also has an anti-glare screen. That said, all three will include a MicroSD slot to allow for even more storage.

Here's a pretty good video overview of all the pertinent details.

Reserving requires a $5 deposit (which will be put toward the final price once you purchase) and will put you on the waiting list, which currently appears to be full until Q2-Q3 of 2022 depending on which model you want.

I decided to reserve one even though I'm still on the fence about it, because at this point I'll have about a year to cancel if I change my mind.

For more details and to reserve one for yourself, see:

On July 6th, 2021, the Linux Foundation announced the public availability of the Open 3D Engine (O3DE) open-source project and the formation of the Open 3D Foundation.

As a founding partner in O3DE, Amazon Web Services and the AWS Lumberyard team has been working on this effort for awhile, preparing the code and tools for a developer-centric initial release.


Amazon is contributing its Lumberyard game engine to open source, and it will be known as the Open 3D Engine.

The Linux Foundation will oversee the project and form the Open 3D Foundation to accelerate collaboration with game developers to enhance the triple-A game engine.

So what’s changed? Is this Lumberyard with an open-source license?

In short, a lot! Yes, it’s open source, under the permissive Apache 2.0 license. And no, O3DE is very different than the artist formerly known as Lumberyard. We leaned heavily on our Lumberyard experiences, iterated, and improved O3DE for eventual collaboration and creative control. We kept the parts that customers loved most about Lumberyard and significantly revamped the rest. We aimed to build an engine that could stand the test of time in an open source world. Because game engines tend to be monolithic, we leaned heavily toward becoming modular with extensibility, embracing open standards tooling from the onset. However, we remained unsatisfied, so we added a new prefab system, a new build system, an extensible UI, many new cloud capabilities, numerous math library optimizations, new networking capabilities, and far too many performance improvements to mention here. Also, for good measure, we even added a whole new PBR renderer capable of forward+ and deferred rendering with ray tracing and GI support!


General Software Discussion / Windows 11 Announced
« on: June 24, 2021, 03:26 PM »
Well, I had heard the rumors and even the "confirmations" of the leaks, but I had assumed that the "Windows 11" moniker was just an internal name since Microsoft has said that Windows 10 would be the last version of Windows ever. But it seems they're actually calling it Windows 11.

They had a big, hour long presentation today, which I didn't watch. But I did watch this trimmed down to about 7-minutes version from the Verge:

This may be a little niche, or too specific to my situation, but I'm having some troubles and figured I'd ask if anyone here had experience or insight on how to resolve them. No worries if this is too specific. I don't expect anyone here to go through the trouble of setting up GitLab and SourceTree just to help me out, though I wouldn't put it past some of you people to be that awesomely helpful. ;)

A Brief-ish History:
Ten years ago a thread started here on some relatively new distributed version control systems called Git and Mercurial (Hg). At the time when I researched them, I wanted to use Git but it wasn't easy to get working on Windows, so I ended up using Hg. So for about the past ten years I've become an old fart, set in my ways, thumbing my nose at Git while more or less happily using Hg with BitBucket and TortoiseHg. That is, until last year when BitBucket dropped support for Hg repositories. :(

For a little while I remained stubborn and hosted my own RhodeCode server but it wasn't ideal because I actually collaborate with at least one other person on a somewhat regular basis and my ISP's upload speed isn't that great and my internet connection kept dropping out frequently, so it wasn't very reliable for others to connect to and use.

As a result, this past December I decided to bite the bullet and convert all my repositories to Git and start using Git from then on. And after doing some research I decided I'd rather be using GitLab than GitHub. So I first used a feature of GitHub to import my Mercurial repositories from my personal RhodeCode server and convert them to Git automatically. Then I used a feature of GitLab to import my GitHub repositories to GitLab.

While I was still using Hg, I was alternating between using TortoiseHg and SourceTree to manage my repositories. That is, I primarily used TortoiseHg, but I felt SourceTree had better integrated using development branches more easily. When I made the move to Git, I obviously had to drop TortoiseHg, but I decided to just keep using SourceTree, which supports both Git and Hg (for now... Atlassian owns BitBucket and SourceTree).

I think I got it all configured and had it working in December so that I could connect with GitLab and push/pull to/from my repositories. But then this year I've kind of taken a break from my usual thing and have just been doing little experiments that I never felt were big or important enough for version control. But now I'm starting to get back into wanting version control and I've run into a problem where I can't seem to get SourceTree to work with GitLab anymore.

The Problem:
Somehow I was able to successfully create a new remote repository from SourceTree, but then I immediately got an error when it tried to push my local repo to it. The error looks something like this:

remote: HTTP Basic: Access denied
remote: You must use a personal access token with 'read_repository' or 'write_repository' scope for Git over HTTP.
remote: You can generate one at
fatal: Authentication failed for ''

GitLab has something called "personal access tokens" (PAT) which can be used in place of your password to authenticate third-party apps to work with your account. The UI doesn't make it very clear (IMO) which scopes are needed, and which scopes include the privileges of other scopes, etc. So, while the PAT I created from December had only the "api" scope, the error message says I need "read_repository" and/or "write_repository" so I created a new PAT with all the scopes.

All the things.png

It didn't help. I still get the same error.

I tried changing the URL to use SSH instead of HTTPS, but then it just asks me to load a ppk file which supposedly contains my SSH key. I don't have one of those. Or at least not the right one. I found one on my PC which I thought might be the right one, but when I load it, it just asks me for the SSH password over and over again. So it seems that the password I have stored in my password manager for GitLab SSH key does not match whatever SSH key is in that ppk file.

I do have my SSH private key stored in my password manager, but the putty agent (pageant) which SourceTree uses seems to require PPK format instead of... whatever format I have it stored as. It starts with "-----BEGIN OPENSSH PRIVATE KEY-----" whereas the random PPK file I found where I thought my GitLab SSH key would be starts with "PuTTY-User-Key-File-2: ssh-rsa"

GitLab PATs.png

So here I am with two PATs that don't seem to work anymore. Somehow I have saved an incompatible SSH key/password in my password manager. I swear I had this all working fine in December and I don't know what changed in the interim. And I don't know if it's a classic case of PEBCAK, or if GitLab's PATs aren't working right, or if SourceTree is not working properly. I just want to be able to push to and pull from my GitLab repos from SourceTree!

That said, I'm mostly just sticking with SourceTree because I'm already familiar with it and because it's free. If there's an alternative (and free) Git GUI client that works well with GitLab and runs on Windows which would solve my problem, I'd be happy to hear your recommendations on that front, as well. :Thmbsup:

Finished Programs / Program to play inaudible sound continuously
« on: April 09, 2021, 06:39 PM »
Old solutions for new problems....

I had an old Pentium I computer with a combo modem/soundcard that had issues staying connected to the internet when a system sound played (system would lock up just long enough to kick me offline), unless there was sound continuously flowing through the soundcard at all times. This meant playing music all the time, and usually keeping the speakers turned off if I didn't want to hear it, till I came across a small app capable of playing continuous low frequency tones that my cheap speakers were unable to produce. (25 Hz did the trick)

Flash forward to a couple of days ago, when a screwy Windows feature update, which I am unable to uninstall, messed up my bluetooth, so that no matter how I have the hardware settings configured, it turns Bluetooth off (to save power) when it thinks it is not in use. This is very BAD for a bluetooth mouse. I reported here about this issue in this thread, and was avoiding reinstalling that update for as long as possible, but Microsoft managed to automatically cram it down my throat when I recently rebooted my machine, despite having updates paused till some time in January.

BUT I noticed it doesn't cut off my mouse if I have sound playing through my bluetooth headphones. So, I am back to using that very old app, to generate a continuous 10 Hz tone, just so I can use my mouse.

I had to use the system volume mixer to set the volume of this app at a very low level, since my bluetooth headphones are capable of producing audible sound generated from this app, at even the lowest (10 Hz) setting.

Do you have a link to that app, app?

About 6 months ago I moved my entire PC setup into another room, and when I plugged in my speakers to the power source (a surge protector), they made a very loud POP sound, and ever since then none of the audio jacks on my PC work. So now I've got a bluetooth speaker connected to my PC, but it has the unfortunate problem of taking half a second to "warm up" (or catch up?) whenever some audio is played for the first time after a few seconds of silence. And it's like it receives and plays that first half-second of audio all at once, making an unpleasant (and relatively loud) popping or crackling sound in the speaker as it begins to play audio.

I figure if I could trick it into thinking it is constantly playing audio, then it would stay "awake" and not have this issue. Then I remembered you mentioned playing an inaudible, low frequency sound to help with your BT issues and so here I am, asking about it. :D

DC Gamer Club / Ludum Dare 48: April 23rd-26th, 2021
« on: April 06, 2021, 12:49 AM »
Ludum Dare 48 is approaching fast! It begins three Fridays from now.

To be honest, I'm not especially motivated to participate this time, but it's kind of historic in that it's the 48th event of that which used to be called "LD48" due to its origin as a 48-hour game jam before being rebranded as "LDJam" a few years ago. So I feel I can't miss out on being a part of LD48. That said, I've never actually done the 48-hour "compo" and have always participated in the more laid-back 72-hour jam. Anyway, this time I'll be participating in the 72-hour jam as part of a team once again, so that should lighten the load.

Right now theme suggestions are open. Anyone can submit up to 3 themes, even if they're not participating. You just need to register a free account to be able to do so. If you'd like to suggest a theme, you may do so here:

EDIT: My team made Let's Go Deeper for LD48.

See previous posts on DonationCoder about Ludum Dare:

Ludum Dare 47 - (My team made Chrono Crash for LD47)
Ludum Dare 46 - (My team made Defendeer for LD46)
Ludum Dare 45 Reviews - A thread about LD45 games
Ludum Dare 41 - (My team made It's Not Lupus! for LD41)
Ludum Dare 2017 Thread - A thread about games from LD37 and LD38
Ludum Dare 33 - A thread about LD33 games
Ludum Dare 32 - (I made Time Bomb during LD32)
Ludum Dare 31 - (I made Worm Wars during LD31)
Ludum Dare 30 - (I made Planetary Devourers during LD30)
Ludum Dare 29 - (I made It Came From... Beneath!! during LD29)
Ludum Dare [29] topic for other games - A thread about LD29 games
Ludum Dare 23 - (I made Be Tiny, World! during LD23)
Ludum Dare - Game Programming Challenges

General Software Discussion / Deozaan's To-do List
« on: March 19, 2021, 03:38 AM »
I've recently started learning how to use the Godot Engine. It's a game engine, but it can be used for non-game apps as well. As a means of familiarizing myself with Godot, I have been working on some simple projects.

I made another non-game app: a simple to-do list.

To-do List.png

Considering it's my second complete project in Godot, I expect there are probably some bugs.

Jotti says it's clean.
VirusTotal says it's clean.

You can download it from my Keybase:

Just thought I'd share with anyone here who might be interested. :Thmbsup:

Oh, and right now I only have a Windows build available for download. But if anyone is interested in Linux or MacOS builds, let me know and I can supply those as well.

General Software Discussion / Deozaan's Simple Text Editor
« on: March 19, 2021, 03:27 AM »
I've recently started learning how to use the Godot Engine. It's a game engine, but it can be used for non-game apps as well. As a means of familiarizing myself with Godot, I have been working on some simple projects.

The first one I made is a simple text editor. I started out just following a tutorial series on YouTube and then I added a few more features until I lost interest and was ready to move on to something else.

Simple Text Editor - Hello World.png

Considering it's my first complete project in Godot, I expect there are plenty of bugs. And I certainly don't expect it to compete with the likes of Notepad++, or even Microsoft Notepad, for that matter.

Jotti says it's clean.
VirusTotal says it's clean.

You can download it from my Keybase:

Just thought I'd share with anyone here who might be interested. :Thmbsup:

Oh, and right now I only have a Windows build available for download. But if anyone is interested in Linux or MacOS builds, let me know and I can supply those as well.

I've had a portable .exe of Auslogics Disk Defrag Portable sitting in a folder on my PC for years, and frequently used it. The most recent time I used it a few days ago, out of nowhere Windows Defender marked it as malicious. I went into Windows Security center and told it to allow/restore it, but after I rebooted my computer today for the most recent Windows Update, it's gone! That leads me to two questions:

#1: Is it feasible that this portable app has had some hidden trojan all these years and only now is it being properly picked up by anti-virus scanners, or is it most likely just a sudden false positive? I uploaded the file to Jotti and VirusTotal before it disappeared, and there were several AVs flagging it as malicious. So it's not just Windows Defender acting up. Again, this is a file I've had for years. It's not like I just downloaded a new or updated version that changed the code.

#2: Does anyone know how to restore a file that Windows Defender got rid of? I don't see the usual "allow" or "restore" options in Windows Security. In fact, Windows Security tells me that it failed to remediate the problem. I'm attaching relevant screenshots if it helps to see what I'm seeing.

Windows Security - Removed or Restored.png

Windows Security - Remediation Incomplete.png

EDIT: Nevermind about #2. I had a backup in my Dropbox folder.

General Software Discussion / Earning More with Cryptocurrency
« on: March 04, 2021, 01:05 PM »
I'm posting this in response to some interest shown by others on this site when I briefly mentioned in another thread I was using a Raspberry Pi to earn a little bit of cryptocurrency. The relevant bits of that thread are quoted here:

It's not making me rich, but it's earning me a decent amount of money simply for keeping a device running/connected that I'm already leaving running/connected 24/7 anyway as my personal media server and whatnot.

You buried the lede. What is that, and how does it work? Maybe on a new thread. That sounds interesting...

Considering I have two RasPi 4B's on 24/7 running Docker services, (and spare 2B, 3B, & 3B+), I'm also interested in this. :P

Before I get into the details, I need to make some clarifications and disclaimers:

First of all, I should clarify that my definition of "a decent amount of money" is really not a lot. There's been a recent boom in cryptocurrency starting around the new year, and even at the recent all-time highs I've only gained maybe up to $250 value over the past month from what I'm doing with my RasPi. Usually it's significantly lower than that. Nothing I'll mention in this post should be taken as a way to get rich quick. It's more about slowly increasing your wealth over the long term. Like gaining interest in some kind of savings account.

I also need to admit that I very much oversimplified what I'm doing with the RasPi. It's not as simple as buying $50-100 worth of RasPi hardware/accessories, installing some software, and then running it and forgetting all about it while raking in the cash.

And finally, the big disclaimer: This is not financial advice. Do your own research. Don't "invest" more than you can afford to lose. Et cetera.

Okay, let's get to the fun stuff.

Earn More Cryptocurrency Through Staking

Have you heard of staking (proof of stake, or PoS)? It's like mining but without all the crazy electricity demands. It has an initial financial demand instead. It feels more similar to earning interest on money you already have.

In contrast to traditional proof of work (PoW) mining blockchains, which have everybody in a fierce competition frantically hashing as quickly as possible to be the first person to mine a block and propagate it to the network, PoS blockchains assign people their turns to mine in a raffle-like manner based on how much of the coin has been staked. Everyone knows their turn well in advance of when it actually needs to be done, so you keep your "mining" hardware connected to the chain (or at least connect it early enough that it can catch up to the current state of the chain), wait your turn, and then it mines a block when it's your turn. It's all very orderly and relatively cordial. It's more of a cooperation than a competition. There's no need to constantly be maxing out your CPU/GPU/ASIC 24/7 because you know in advance exactly when it will be your turn to produce a block. This means that the hardware requirements are (or can be) much lower in PoS blockchains than what is typically required for PoW blockchains. Some chains can even have low enough requirements that blocks can be produced with a Raspberry Pi.


I've been using my RasPi with the Tezos blockchain (the coins are called tez, with XTZ as the symbol). Tezos is a lot like Ethereum in terms of functionality, but it has a built-in governance model, which basically means that upgrades (or changes) to the protocol are voted on and passed by the "community" on the blockchain itself. The purpose of that is to avoid instances of conflict and division such as the schism(s) and several resulting forks of Bitcoin (e.g. Bitcoin Cash) due to disagreements on what the purpose and future of Bitcoin ought to be.

Mining in Tezos is called baking, and as I said earlier, there is an initial up-front financial cost to become a baker. The baker has to lock up some collateral, essentially saying "I promise I won't do anything wrong, and if I do, I will forfeit this collateral." The collateral is unlocked, along with the baking rewards, about 2 weeks later. To register as a baker in Tezos, you need to have a minimum of 8,000 tez in your account or delegated to your account. A baker should earn somewhere in the 5-8% range (annually) from block rewards. If we use the lower bound of 5% of 8,000 tez then that's 400 tez in a year, or about $125 per month at the current price of about $3.80 for 1 tez.

Speaking of current prices, 8,000 tez costs about $30,000 USD right now. That obviously is (or can be) prohibitively expensive for many people wanting to become bakers or earn "interest" on their cryptocurrency. But fear not! You may have noticed that I mentioned the possibility of having funds delegated to your account. This means that if you can convince other people to delegate their funds to your account, you can start baking even if you don't personally own 8,000 tez. What this also means is that you can delegate your funds to a baker and have them bake on your behalf. Bakers typically charge a fee of somewhere in the range of 5-20% (with 10-15% seeming to be most common). Or in other words, if your delegated funds earned a total of 50 tez, a baker with a 10% fee would keep 5 and send you 45.

A few important points about Tezos: Funds you delegate to a baker are still in your possession with your private key. They can't be seized, stolen, or lost by the baker. You are essentially delegating the "rights" of your coins for use in baking and on-chain governance (voting). But you still maintain full ownership of the coins and can change your delegate at any time. Additionally, Tezos uses a Liquid Proof of Stake protocol, which means that delegated funds are never locked up. You can spend or transfer them at any time. Only the baker's personal funds are locked up (and potentially forfeited) during the baking process. But the baker is also not required by the protocol to send you any part of the rewards earned. From the point of view of the protocol, the baker takes on all the risk and therefore earns all of the reward. So it's up to you to make sure your baker is paying you according to your agreement with them, and if not, delegate to another baker who will honor their agreements. The vast majority of bakers are trustworthy but of course you'll always find a few people scamming others when there is the opportunity to do so.

I initially bought a RasPi 3B+ for baking on Tezos but at the time there was no official 64-bit OS for it (due to it only having 1 GB of RAM) and shortly thereafter some Tezos upgrades required 64-bit support so I couldn't use it anymore. But with the release of the RasPi model 4 with more RAM came official support for a 64-bit OS, and Tezos definitely uses a lot of RAM anyway, so I'd recommend a 4GB+ RasPi at a minimum (I have the 8GB model).

All of this has been very specific to Tezos because that's what I'm using my Raspberry Pi for. But there are other PoS blockchains out there, such as Cardano (ADA), which also allow you to earn more through staking your funds to another block producer, though I'm not familiar with Cardano's requirements (in terms of minimum stake or hardware) for becoming a block producer yourself. And if you weren't aware, Ethereum also has plans to transition from using PoW to using a PoS algorithm soon™.

In summary:

  • If you use a PoS cryptocurrency, look into staking your coins to increase your holdings!
  • If you have enough coins to become a block producer, and you have the hardware and technical knowledge/experience, look into doing that so you can keep 100% of the reward rather than paying someone else a fee to do it for you.

The above is nice and all, but there's always the risk that the cryptocurrency could drastically go down in value. It's no use to have 5% more of a cryptocurrency that has dropped 95% in value! So now I'm going to talk about something I've recently discovered that has the possibility of much lower risk.

Earn More Cryptocurrency by Providing Liquidity

At the beginning of the year, I looked at my savings account with my bank and noticed that my interest rate had fallen (again). When I first created the account about 10-15 years ago, my interest rate was above 3%. Now it's around 0.3%. So pathetic.

I started looking into cryptocurrency-related alternatives and discovered something really amazing. There are cryptocurrency apps/services that are offering 3-12% annual interest on various cryptos, depending on a variety of factors. But what stood out to me was that the cryptos with the highest interest rate also tend to be the "safer" stablecoins. One such stablecoin is USD Coin (USDC) which, as its name suggests, has its value tied to the dollar. In other words, there's no volatility in USDC's price. You can always buy and sell 1 USDC for $1 USD (on Coinbase).

I quickly realized that meant I could be earning over 10% APY on the money in my savings account rather than the 0.3% my bank was paying me. I may have done the math wrong, but I calculated that I could earn as much interest in a single month using one of these apps that my bank would pay me over the course of three years!

Here's how it works:

  • You provide liquidity to the service by depositing some funds to your account.
  • The service makes fully collateralized loans to others. (I'm no financial expert, but this seems like a virtually risk-free loan to me.)
  • Eventually the loan is repaid, with interest.
  • The service shares a significant portion of that interest with you.

This sounds very much like the traditional fiat banking system, with two exceptions: Banks tend to engage in risky lending because they know they will be bailed out if anything catastrophic happens to them. Also, banks are much more stingy and share very little of the profit with you, the liquidity provider.

Celsius Network

I've been using the Celsius Network to earn 10.51% APY on USDC. They make payments every Monday. I've earned over half as much in 3 weeks using Celsius as I earned from my bank in all of 2020, even though I had 2-3 times as much money in my savings account than what I've put into Celsius. It's nice! I'm not getting rich quick, but at least I'm earning something! And they have options for non-USA residents to earn even higher interest rates.

If this interests you enough to sign up, you can also create an account using my referral link and we'll both gain $30 worth of BTC after you make your first transfer of $200 or more.

And after you've signed up, you can enter the promo code WEB40 in the app to get another $40 worth of BTC after making a transfer of $200 or more (in a single transaction) and keeping it in the app for 30 days. Or in other words, if you use my referral link, you can get $70 worth of BTC. (often abbreviated as CDC from "crypto dot com") has similar liquidity/interest features, though I find I prefer the rates on Celsius. But CDC also has a nifty pre-paid Visa card you can get which has some nice bonuses, such as earning 1-8% back as crypto, or even complete reimbursement (in crypto) for some purchases such as Spotify, Netflix, or even Amazon Prime subscriptions. If you use my referral code then we'll both get $25 worth of cryptocurrency once you've met certain criteria, which I believe is to deposit about $400 worth of crypto into your account and stake it, which is incidentally also how you qualify for the first non-free tier of the Visa card bonuses.

I'm kind of a miser who doesn't like spending money (because money is usually tight) but I got the lowest non-free Visa card tier and have been kind of excited/happy when I spend money with it now, knowing that I'm earning a little back in a form (cryptocurrency) that may be worth much more in the future than it's worth now. But it's also such a small amount that if it goes down in value (even to nothing) then I'm not really any worse off than if I had just paid cash for things.


After interest was shown in what I use my RasPi for, I thought it would be a good opportunity to also share my recent discoveries of other ways to earn a little more cryptocurrency. I apologize for taking so long to write this after the initial interest was shown. I know that brevity is not one of my strengths, especially when talking about something like cryptocurrency, which has a lot of minor, but in my opinion important, technical details. That said, I've still chosen to leave some things out so that I'm not wasting time explaining every little thing if no one reading this is going to be interested in doing anything I talk about. If you have questions, ask, and I'll respond to the best of my knowledge and ability.

Hi all,

I have a few Raspberry Pis functioning as media servers or whatnot, including running other things (such as self-hosted version control) that require an external internet connection or allow other people connect to my devices remotely. But the problem is that my modem frequently stops communicating with the outside world and the only fix seems to be to reboot it. Otherwise it will happily sit there for hours without an internet connection and never self-recover.

If I'm home when it happens, it's annoying to have the frequent interruptions to streaming Netflix or YouTube or whatever, but it's not a huge ordeal to fix it. I just walk over and pull the power cord and plug it back in. But when I'm not home, which is ostensibly when I really need my internet to be reliable for accessing my files/devices, I obviously can't remotely reboot the modem. So hours go by without an internet connection at home because no one is around to reboot the modem.

What would be nice would be to have a "smart" power switch that could detect the lack of an internet connection, cut and restore power to an external device (the modem) and then wait a few minutes for the modem to finish rebooting before going back into internet connection detection mode and being ready to do it all again if/when necessary.

If something like this already exists and is fairly inexpensive, I'd love to hear about it. Otherwise, I'm thinking it must be possible somehow as a kind of DIY Raspberry Pi project. And as mentioned, I already have a few Raspberry Pis sitting around that I could use if needed.

Does anyone have any tips or suggestions--or even better: links to hardware and/or instructions--on how to get the desired result of rebooting my modem any time it loses its connection to the internet, so I don't have to babysit it all the time or be afraid of leaving my house for extended periods of time?


Living Room / Share Your 2020 Top Ten List(s)!
« on: January 24, 2021, 10:14 PM »
A little over a year ago mouser started a thread about sharing our top ten lists of something from the year that just wrapped up, which was 2019. So I thought I'd try to continue the tradition by asking people to share their top ten list(s) of things from 2020.

Although, it looks like mouser already beat me to the punch by sharing some videos of his top ten board games of various categories. Though those aren't necessarily specifically about 2020.

Brevity is not my strong point, as evidenced by my post in last year's top ten thread. So even though I'm still working on writing up my list, I thought I'd extend the invitation to others to share their lists in the meantime.

Coding Snacks / [Solved] Adjust Subtitle (SRT) Timestamps
« on: December 20, 2020, 02:26 AM »
Hi all,

I've got a movie that would be pretty tame (PG in the USA) were it not for the fact that inexplicably it has about 30 seconds of nudity in a scene that has absolutely no bearing on any part of the film. Okay, I said the reason was inexplicable, but it's a French film, so I guess it should go without saying. Anyway, in an effort to make it more family friendly, I've ripped the DVD and cut out the scene with nudity. But, seeing as it's a French film, and I don't speak French, now all the timings for the subtitles are off by a significant enough amount that it's hard to follow.

Actually, editing the file made me lose the subtitles, but I downloaded new ones (in SRT format).

The idea of manually adjusting the time for each line of text that appears is just far too daunting a task for me to even begin. Surely there must be some way to do this automatically? Or perhaps someone who is knowledgeable with Regular Expressions can whip something up for me that will find all timestamps, do a calculation on them, and then replace them with the new values?

Here are my requirements:

  • Allow me to enter the "start time" or the time after which all future timestamps should be modified. Or in other words, don't modify the timestamps for anything before this time.
  • Allow me to enter an adjustment amount by which to modify the timestamps. The timestamps are down to the millisecond precision level, FYI.
  • Allow me to press "Go" and have it do its work.
  • Bonus points if it erases any subtitles that may exist in the resulting "limbo zone" (the time between the "start time" and the "start time + adjustment amount" time) and double bonus points if it also renumbers any following subtitles to compensate for deleted ones.
  • Either present me with the changed text in a textarea I can copy to my clipboard or allow me to output the text to a file of my choosing (so I can choose to keep the original file if I want). Or, essentially, don't destroy any data without my explicit consent.

I actually don't need all of that. If it just let me enter the amount to shift every timestamp by, with precision down to one second, I would happily work with that. I'd be able to run it on the file and then copy and paste everything after the "start time" from the new times over the original times, and manually edit out the relatively few "limbo zone" subtitles.

Thanks in advance! :Thmbsup:

As part of their Winter Sale, GOG have sent out a newsletter with a little puzzle: Spot the 7 differences between the images to get discounts on games.

Play for yourself with the link above, or save yourself time by clicking the spoiler below.

I spotted the differences, here are the discounts, which all expire Dec 23, 2020, 6:59 AM (not sure which time zone):

GOG Presents.png
90% Off:
Syberia 2
Syberia 3
85% Off:
Banner Saga
Cat Quest
80% Off:
Overlord 2
Jazz Jackrabbit Collection
The Incredible Machine Mega Pack
75% Off:
Slime Rancher
This War of Mine
Summer & Winter: Olympic Challenge
55% Off:
Costume Quest
Icewind Dale Enhanced Edition
Space Pirates and Zombies (SPAZ)
FAR: Lone Sails
35% Off:
Heart of the Woods
30% Off:
Cthulhu Saves Christmas

Hi all,

I've gathered a bit of a sound library which has grown so large over the years that it makes it hard to know what I have, and where. I'd like some software that can help me quickly browse and preview the sound files. Bonus points if it can help me organize (and tag?) the files as well.

When I say "sound library" I don't mean music for personal enjoyment. I mean sound effects, jingles, voice tracks, or audio tracks for video games (or just videos, I suppose).

Surely people who do video editing for a living have some software that helps manage sound libraries. Any suggestions out there for what I can use?

Compatibility with Windows is needed. Preferably free/open source, but I'm open to affordable paid options if you have experience with them and feel they're worth it. This is mostly for hobby stuff, so expensive professional software is probably not feasible for my use case.

Thanks in advance.

It seems Apple is surreptitiously undermining their users' privacy in a hidden "rules for thee but not for me" whitelist of their own apps on macOS Big Sur.

The new macOS release, Big Sur, has made headlines due to Apple’s decision to place 56 of its own apps, including FaceTime, Apple Maps, and Apple Music Library, on an undocumented, unannounced “exclusion list.” This means these apps can bypass firewalls and, potentially, VPNs that function on a per-app basis without the users’ knowledge or consent, undermining macOS devices’ security and privacy.

Apple Big Sur Tweet.png


General Software Discussion / MOVED: 3D Arrow
« on: November 17, 2020, 10:44 AM »

Living Room / Downloading Blender Open Movie "Sintel (2010)" in 4K
« on: October 24, 2020, 09:27 PM »
Hi all,

I'm trying to download the Open Movie made/funded by the Blender Foundation called Sintel from here:

I'm trying to get the 4K (mkv) version, which is about 4.2GB. At first it downloads really fast, telling me it will complete in about 20 minutes. But after I've gotten about 250MB into it, it then seems to throttle my download speed to about 64 kbps and says it will take 20 hours to complete. Is anyone else here able to download it at a speedy rate?

Or perhaps someone else is better able to search the internets than I have been to find a working torrent I can use to relieve of the burden of having to serve the file to me?

Pages: [1] 2 3 4 5 6 ... 19next