
A first-person puzzle game built around seamless world-switching — the player shifts instantly between an ancient Arab city and a futuristic counterpart shaped by the same cultural roots. Set in a high-fidelity, realistic environment, the prototype pushes UE5's lighting, rendering, and world-streaming systems to their limits. Developed in 6 weeks part-time by a cross-discipline team, the game took 1st place at the Arab Youth Gaming Hackathon, supported by Futuregames and the Arab Youth Center.
void UWorldSwitchComponent::ExecuteSwitch()
{
if (bTransitionInProgress) return;
bTransitionInProgress = true;
// Capture current world state before swap
SnapshotActorStates(ActiveLayer);
EWorldLayer TargetLayer = (ActiveLayer == EWorldLayer::Ancient)
? EWorldLayer::Futuristic
: EWorldLayer::Ancient;
// Stream in target, stream out current via Data Layers
SetDataLayerState(LayerAssets[ActiveLayer], EDataLayerState::Unloaded);
SetDataLayerState(LayerAssets[TargetLayer], EDataLayerState::Activated);
ActiveLayer = TargetLayer;
RestoreActorStates(ActiveLayer);
PlaySwitchFX(GetOwner()->GetActorLocation());
bTransitionInProgress = false;
}void UWorldSwitchComponent::SnapshotActorStates(EWorldLayer Layer)
{
TArray<AActor*> LayerActors;
GetActorsInLayer(Layer, LayerActors);
for (AActor* Actor : LayerActors)
{
if (IWorldStateful* Stateful = Cast<IWorldStateful>(Actor))
{
FLayerState& State = LayerStateCache[Layer][Actor];
State.bIsActive = Actor->IsActorTickEnabled();
State.Transform = Actor->GetActorTransform();
State.CustomData = Stateful->SerializeState();
}
}
}void ALayerPuzzleGate::OnLayerActivated(EWorldLayer NewLayer)
{
// Each gate tracks requirements per-layer independently
const FPuzzleRequirement& Req = Requirements[NewLayer];
if (Req.IsMet())
{
SetGateState(EGateState::Open);
BroadcastGateCleared(NewLayer);
}
else
{
SetGateState(EGateState::Locked);
UpdateHUD_RequirementsLeft(Req.CountRemaining());
}
}