Log In  
Follow
magic_chopstick

expint(): Counting To Eleventy-Bajillion In PICO-8 With Exponential Integers (v 1.01)

Cart #mcg_expint_test-2 | 2025-06-03 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
2

Overview

Hello, everyone! I'm back with another Quick 'n' Dirty code snippet: extreme range, low precision Exponential Integers!

expint() lets you easily work with extremely large numbers at low precision in PICO-8. You can create them, add to them, "spend" from them, display them in a friendly format, and save/load them using a single 32-bit data slot.

expint() is particularly well-suited to games where you need to track very large amounts of points or money, like incremental games/idle clickers, large-scale exploration games, and other places where 32k just isn't gonna cut it.

Update: Version 1.01

  • Fixed weirdness with the print() function
  • Shaved a few tokens off, to boot

The Snippet And Its Use

Install

Paste the following snippet into your cart:

[hidden]

function expint(new_sig, new_exp) 
	local num = {}

	function num._step_up(steps)
		while steps > 0 do
			num.sig \= 10
			num.exp += 1
			steps -= 1
			if num.sig == 0 then -- we've lost all precision; for whatever we're doing, this number is as good as zero
				num.exp += steps
				steps = 0
			end
		end
	end

	function num._norm()
		while num.sig >= 10000 do
			num._step_up(1)
		end
		while num.sig < 1000 and num.exp > 0 do
			num.sig *= 10
			num.exp -= 1
		end
	end

	function num.add(val, sig)
		local to_add = expint(val, sig) -- be non-destructive with arithmetic; copy info into another expint to protect precision
		to_add._step_up(num.exp-to_add.exp) -- instead of doing any logic, just run step_up 
		num._step_up(to_add.exp-num.exp) -- on both the numbers. It'll only affect one of them.
		num.sig += to_add.sig
		num._norm()
	end

	function num.spend(val, sig)
		-- if val < num, subtracts val from num and returns true
		-- otherwise, returns false
		local to_spend = expint(val, sig)
		if to_spend.exp > num.exp or to_spend.exp == num.exp and num.sig < to_spend.sig then
			return false -- to_spend is greater than num; can't make the spend
		end
		to_spend._step_up(num.exp-to_spend.exp) -- instead of doing any logic, just run step_up 
		num._step_up(to_spend.exp-num.exp) -- on both the numbers. It'll only affect one of them.
		num.sig -= to_spend.sig
		num._norm()
		return true
	end

	function num.print()
--		local suffixes = split("K,m,g,T,P,E,Z,Y,R,Q") -- SI suffixes
		local suffixes = split("K,m,b,t,qU,qI,sX,sP,oC,nO,dE") -- number suffixes
		local return_string = num.sig
		if num.sig > 1000 then
			local modval = num.exp%3+1
			local suffix = num.exp\3+1
			if suffix > #suffixes then
				return_string = sub(return_string,1,1).."."..sub(return_string, 2).."X10^"..(num.exp+3)
			else
				return_string = sub(return_string, 1, modval).."."..sub(return_string, modval+1)..suffixes[suffix]
			end
		end
		return return_string
	end

	function num.save(cart_slot)
		dset(cart_slot, num.sig | num.exp>>16)
	end

	function num.load(cart_slot)
		num.sig = dget(cart_slot)\1
		num.exp = dget(cart_slot)<<16
	end

	num.sig = new_sig
	num.exp = new_exp or 0

	-- handle special cases: input can also be either an integer in string format or a table (assume it's another expint()!)
	if type(new_sig) == "string" then
		num.sig = tonum(sub(new_sig, 1, 4))
		num.exp = max(#new_sig-4, 0)
	elseif type(new_sig) == "table" then
		num.sig = new_sig.sig
		num.exp = new_sig.exp
	end

	num._norm()
	return num
end

[ Continue Reading.. ]

2
2 comments



Cart #mcg_endlessshipstoy-1 | 2025-05-17 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
4

Update 1!

This is still very much a toy, but it's very close to "done" for purposes of the larger game. Ships are stronger, but so are your weapons–and you can do more than just deal direct damage now!

Of note in this update:

  • Added module modifiers!
    • heal
    • hack (disable enemy die)
    • ion (extra damage to shields and set enemy die to one)
    • burn (stackable damage over time)
    • trap (sets a trap on an enemy die that does damage when used)
  • Improved crew (dice)!
    • Crew now have names
    • Crew may have non-standard roll possibilities (including a wildcard roll!)
    • Crew can have modifiers, much like modules

[ Continue Reading.. ]

4
6 comments




The Quick 'N' Dirty Galaxy Generator builds off of my my Quick 'N' Dirty Planet Generator by adding procedurally generated planets, routes, names, and governments to create a nice, compact little galaxy to explore. Right now, it's just a toy, but you can probably see where I'm planning to go with this!

Version 0.2 update: Saving Things!

  • Added auto-saving and auto-loading of the galaxy and the current state of your exploration. Reload your browser and pick right back up where you left off!
  • Fixed a bug where the same governments and government colors were chosen over and over
  • Fixed a bug where governments could take over the capitals of other governments during generation

[ Continue Reading.. ]

12
6 comments




Hello, everyone! I'm back with another Quick 'N' Dirty cart!

This time, I've put together a little planet generation and rendering system I'm looking to use in a bigger project. From the cart's intro comments:

This is a very very work-in progress planet generator. I'm not (yet) going for huge 
amounts of complexity or variation in my texture generator. Rather, right now, I'm
working to make as *performant* a planet generator and renderer as I reasonably can.

To generate terrain, I'm using the diamond-square algorithm to rende a 64x128 pixel
heightmap on the bottom half of the sprite sheet, which is mapped to the bottom half
of the PICO-8 map. To help ensure that we're not impacting performance, I've added some
break logic to the rendering routine that lets us stop processing once we hit a
certain CPU threshold, spreading the work across a few frames. This is fast enough that
planets render in well under a second, even with the added overhead of the break
logic.

Of note here is that planet generation is entirely deterministic and stems from a
single seed value. If you want to build a galaxy of planets, all you need to do is
store a number per planet and re-render them on the fly.

To render, I'm relying on tline to draw a linearly-banded UV map that reads from the
bottom half of PICO-8's map and draws a series of horizontal tlines across the unit
circle. At higher rotation rates, this is very obviously not an accurate way to draw
a sphere, but it *is* a blazingly *fast* way to do it, and at slow enough rotation
rates, it's good enough to fool the casual observer. Rendering times increase as the
planet grows, but even when the planet takes up most of the screen it only eats about
30% of the standard update cycle's CPU time.

Future improvements will be focused on adding some good variety to the planets being 
generated, along with features like polar regions and wind/precipitation-based biome
coloring.

Arrow keys to zoom and control the speed of rotation; O/Z to generate a new planet.

Have fun!

8
4 comments



Cart #mcg_agntsekr_1_02-1 | 2024-05-03 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
16

Agent Seeker

A PICO-8 Spy Hunter demake/remake/homage

Overview

Agent Seeker is a fast-paced, reflex-taxing game built in the style of the original Spy Hunter, one of the greatest video games ever created. [no citation needed]

Drive your heavily-customized luxury sports car down an endless roadway, protecting innocent motorists from a rogue's gallery of menacing enemy agents. Use machine guns, oil slicks, smoke screens, flamethrowers, and armor-piercing cannons to stop as many enemy agents as you can!

Controls

Arrow keys/D-Pad: Drive (l/r to steer, up for gas, down for brake)
Z key / O button: fire machine guns (front-facing, infinite ammunition)

[ Continue Reading.. ]

16
6 comments