why does the jump action masking work but not the boost aciton masking static const torch::Tensor getJumpMask(const torch::Device& device, int actionAmount) {
	static std::vector<int64_t> jumpIndices = { 32, 33, 36, 37, 40, 41, 54, 55, 56, 57, 60, 61, 74, 75, 78, 79, 83 };
	torch::Tensor jumpMask = torch::zeros(actionAmount, device); // Use actionAmount
	for (const auto& idx : jumpIndices) {
		if (idx < actionAmount) { // Prevent out-of-bounds
			jumpMask[idx] = 1;
		}
	}
	return jumpMask;
}

static const torch::Tensor getBoostMask(const torch::Device& device, int actionAmount) {
	static std::vector<int64_t> boostIndices = { 14, 15, 18, 19, 22, 23, 25, 27, 29, 33, 35, 37, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89 };
	torch::Tensor boostMask = torch::zeros(actionAmount, device); // Use actionAmount
	for (const auto& idx : boostIndices) {
		if (idx < actionAmount) { // Prevent out-of-bounds
			boostMask[idx] = 1;
		}
	}
	return boostMask;
}


torch::Tensor GetOutput(torch::Tensor input) {
	try {
		if (input.dim() < 2) {
			input = input.unsqueeze(0);
		}

		torch::Tensor initialOut = seq->forward(input);
		auto logits = policyHead->forward(initialOut);

		//auto boostFractions = input.select(1, BOOST_FRACTION_OBS_INDEX);
		//std::cout << "Boost Fraction Values: " << boostFractions << std::endl;

		auto noFlip = (input.select(1, FLIP_AVAILABLE_OBS_INDEX) < 0.5f).unsqueeze(1);
		auto noBoost = (input.select(1, BOOST_FRACTION_OBS_INDEX) <= 0.0f).unsqueeze(1);
		//std::cout << "No Boost Mask: " << noBoost << std::endl;

		logits = logits.addcmul(noFlip, getJumpMask(device, actionAmount), MASK_VALUE);
		logits = logits.addcmul(noBoost, getBoostMask(device, actionAmount), MASK_VALUE);

		return torch::nn::functional::softmax(
			logits / temperature,
			torch::nn::functional::SoftmaxFuncOptions(-1)
		);
	}
	catch (std::exception& e) {
		RG_ERR_CLOSE("Exception: " << e.what());
	}RLGSC::DiscreteAction::DiscreteAction() {
	Action a = {};

	constexpr float
		// Boolean input
		R_B[] = { 0, 1 },

		// Float input (hint: you can add partial inputs here)
		R_F[] = { -1, 0, 1 };

	// TODO: Use std permutations here or whatever			

	// Ground
	for (float throttle : R_F) {
		for (float steer : R_F) {
			for (float boost : R_B) {
				for (float handbrake : R_B) {
					// Prevent useless throttle when boosting
					if (boost == 1 && throttle != 1)
						continue;

					actions.push_back(
						{
							throttle, steer, 0, steer, 0, 0, boost, handbrake
						}
					);
				}
			}
		}
	}

	// Aerial
	for (float pitch : R_F) {
		for (float yaw : R_F) {
			for (float roll : R_F) {
				for (float jump : R_B) {
					for (float boost : R_B) {
						// Only need roll for sideflip
						if (jump == 1 && yaw != 0)
							continue;

						// Duplicate with ground
						if (pitch == roll && roll == jump && jump == 0)
							continue;

						// Enable handbrake for potential wavedashes
						float handbrake = (jump == 1) && (pitch != 0 || yaw != 0 || roll != 0);

						actions.push_back(
							{
								boost, yaw, pitch, yaw, roll, jump, boost, handbrake
							}
						);
					}
				}
			}
		}
	}

	static std::once_flag onceFlag;
	std::call_once(onceFlag, 
		[=] {
			RG_LOG("DiscreteAction(): Lookup table built, action count: " << actions.size());
		}
	);
}
}