Chatgpt and Programming

Associate
Joined
3 Oct 2014
Posts
1,756
Has anyone used ChatGPT for programming, it has helped me solve two problems today. One using an obscure library to link into an API from an unrelated website.
It would have taken ages to piece it all together manually.

An example just off the creating a bash script and appending some text to a file, then asking it to do it a different way.


1Z5ibfX.png
 
Last edited:
Commissario
Joined
16 Oct 2002
Posts
2,830
Location
In the radio shack
I asked it to write something for me in Python for the Pi and it was spot on, even loading the appropriate libraries for me to access the GPIO pins I wanted to. It's rather clever.
 
Associate
OP
Joined
3 Oct 2014
Posts
1,756
Does it write code and test it 'virtually' before spitting out an answer?

Don't think it tests it but it should be on the user to do so, just like when you get an answer from StackOverflow.

Its a great tool to build the core of what you want and you can tweak it.
 
Last edited:
Soldato
Joined
20 Apr 2015
Posts
4,097
Location
.
Don't think it tests it but it should be on the user to do so, just like when you get an answer from StackOverflow.

Its a great tool to build the core of what you want and you can tweak it.

Hmmm, this is really interesting. Could it do mods to games or find the cause of game crashes?
 
Soldato
Joined
17 Jan 2016
Posts
8,771
Location
Oldham
That's pretty cool that it can write code like that.

I wonder in the future if a version will ever get to the stage of being asked to create a game and you can specify everything and it would mod it as it went along.
 
Soldato
Joined
20 Dec 2004
Posts
15,845
write a simple unreal engine subsystem
Sure! Here is an example of a simple Unreal Engine subsystem that logs a message to the screen every time it is updated:

C++:
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
#include "Engine/Engine.h"

class FMySubsystem : public FDefaultGameModuleImpl
{
public:
 virtual void StartupModule() override
    {
UE_LOG(LogTemp, Warning, TEXT("MySubsystem has started!"));
    }

 virtual void ShutdownModule() override
    {
UE_LOG(LogTemp, Warning, TEXT("MySubsystem has shut down."));
    }

 virtual bool IsGameModule() const override
    {
return true;
    }
};

IMPLEMENT_PRIMARY_GAME_MODULE(FMySubsystem, MySubsystem, "MySubsystem");

This subsystem can be added to your game by adding it to the DefaultEngine.ini file in the [/Script/Engine.Engine] section:

C++:
[/Script/Engine.Engine]
+ActiveGameModules=MySubsystem

When the game starts, the subsystem will output the message "MySubsystem has started!" to the log, and when the game shuts down, it will output the message "MySubsystem has shut down."
Well, not a bad effort, but it's fundamentally misunderstood the problem, as what it has done is create a Module called FMySubsystem, rather than create a USubSystem.

The code works though, kinda impressive it knows the Unreal API.
 
Soldato
Joined
20 Dec 2004
Posts
15,845
I asked for a USubSystem, not a module


I apologize for the mistake. Here is an example of a simple Unreal Engine subsystem that logs a message to the screen every time it is updated:
Copy code

C++:
#include "CoreMinimal.h"

#include "Modules/ModuleManager.h"

#include "Engine/Engine.h"

#include "Subsystems/GameInstanceSubsystem.h"



class FMySubsystem : public FGameInstanceSubsystem

{

public:

virtual void Initialize(FSubsystemCollectionBase& Collection) override

{

UE_LOG(LogTemp, Warning, TEXT("MySubsystem has initialized!"));

}



virtual void Deinitialize() override

{

UE_LOG(LogTemp, Warning, TEXT("MySubsystem has deinitialized."));

}



virtual void Update(FWorldContext& WorldContext) override

{

UE_LOG(LogTemp, Warning, TEXT("MySubsystem is being updated."));

}

};

This subsystem can be added to your game by adding it to the DefaultEngine.ini file in the [/Script/Engine.Engine] section:
Copy code
C++:
[/Script/Engine.Engine]
+GameInstanceSubsystems=MySubsystem
When the game starts, the subsystem will output the message "MySubsystem has initialized!" to the log, and when the game shuts down, it will output the message "MySubsystem has deinitialized." Every time the subsystem is updated, it will output the message "MySubsystem is being updated."
Ok, it got there. Default to GameInstanceSubsystem, interestingly.
 
Last edited:
Soldato
Joined
20 Dec 2004
Posts
15,845
Impressive! I'll probably use this to stub stuff out

write an Unreal UWorldSubsystem that can record a list of actors and call an update method on each one every frame


Certainly! Here is an example of an Unreal Engine UWorldSubsystem that maintains a list of AActor objects and calls the Update() method on each one every frame:
C++:
#include "Engine/World.h"
#include "GameFramework/Actor.h"
#include "MySubsystem.generated.h"

UCLASS()
class UMySubsystem : public UWorldSubsystem
{
GENERATED_BODY()

public:
UMySubsystem();

virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual void Deinitialize() override;
virtual void Update(FWorldContext& WorldContext) override;

void AddActor(AActor* Actor);
void RemoveActor(AActor* actor);

private:
TArray<AActor*> Actors;
};

UMySubsystem::UMySubsystem()
{
}

void UMySubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
Super::Initialize(Collection);
}

void UMySubsystem::Deinitialize()
{
Super::Deinitialize();
}

void UMySubsystem::Update(FWorldContext& WorldContext)
{
for (AActor* actor : Actors)
{
actor->Update();
}
}

void UMySubsystem::AddActor(AActor* actor)
{
Actors.Add(actor);
}

void UMySubsystem::RemoveActor(AActor* actor)
{
Actors.Remove(actor);
}
 
Soldato
Joined
20 Dec 2004
Posts
15,845
Intrigued, I gave it a more challenging example.

write an Unrealengine UWorldSubsystem that tracks a list of actors in a spatial grid and implements an avoidance algorithm

C++:
#include "WorldSubsystem.h"
#include "GameFramework/Actor.h"
#include "Components/StaticMeshComponent.h"
#include "Math/UnrealMathUtility.h"

// Forward declare the avoidance algorithm function
FVector Avoid(const AActor& Actor, const TArray<AActor*>& neighbors);

class FAvoidanceSubsystem : public UWorldSubsystem
{
public:
    // Initializes the subsystem with the given grid size and cell size
    void Initialize(float gridSize, float cellSize)
    {
        GridSize = gridSize;
        CellSize = cellSize;
        NumCells = FMath::CeilToInt(gridSize / cellSize);
        Cells.SetNum(NumCells * NumCells);
    }

    // Adds the given actor to the subsystem's tracking list
    void AddActor(AActor& actor)
    {
        Actors.Add(&actor);
        UpdateActorCell(actor);
    }

    // Removes the given actor from the subsystem's tracking list
    void RemoveActor(AActor& actor)
    {
        Actors.Remove(&actor);
        UpdateActorCell(actor, true);
    }

    // Updates the actor's position in the grid
    void UpdateActor(AActor& actor)
    {
        UpdateActorCell(actor, true);
        UpdateActorCell(actor);

        // Find the actor's neighbors in the grid
        TArray<AActor*> neighbors;
        FindNeighbors(actor, neighbors);

        // Apply the avoidance algorithm to the actor
        FVector avoidance = Avoid(actor, neighbors);

        // Update the actor's velocity based on the avoidance vector
        UStaticMeshComponent* mesh = actor.FindComponentByClass<UStaticMeshComponent>();
        if (mesh)
        {
            mesh->AddImpulse(avoidance);
        }
    }

private:
    // Updates the actor's position in the grid by adding or removing it from the appropriate cell
    void UpdateActorCell(AActor& actor, bool bRemove = false)
    {
        FVector location = actor.GetActorLocation();
        int x = FMath::FloorToInt(location.X / CellSize);
        int y = FMath::FloorToInt(location.Y / CellSize);
        int index = y * NumCells + x;

        if (bRemove)
        {
            Cells[index].Remove(&actor);
        }
        else
        {
            Cells[index].Add(&actor);
        }
    }

    // Finds the actors that are neighbors to the given actor in the grid
    void FindNeighbors(const AActor& actor, TArray<AActor*>& neighbors)
    {
        FVector location = actor.GetActorLocation();
        int x = FMath::FloorToInt(location.X / CellSize);
        int y = FMath::FloorToInt(location.Y / CellSize);

        for (int i = -1; i <= 1; i++)
        {
            for (int j = -1; j <= 1; j++)
            {
                int xIndex = x + i;
                int yIndex = y + j;
                if (xIndex >= 0 && xIndex < NumCells && yIndex >= 0 && yIndex < NumCells)
                {
                    int index = yIndex * NumCells + xIndex;
                    for (AActor* neighbor : Cells[index])
                    {
                        if (neighbor != &actor)
                        {
                            neighbors.Add(neighbor);
                        }
                    }
                }
            }
        }
    }

    // The size of the grid
    float GridSize;

    // The size of each cell in the grid
    float CellSize;

    // The number of cells in each row/column of the grid
    int NumCells;

    // The actors being tracked by the subsystem
    TArray<AActor*> Actors;

    // The grid cells, which contain the actors within them
    TArray<TArray<AActor*>> Cells;
};

// Example implementation of the avoidance algorithm
FVector Avoid(const AActor& actor, const TArray<AActor*>& neighbors)
{
    FVector avoidance = FVector::ZeroVector;

    for (const AActor* neighbor : neighbors)
    {
        FVector direction = actor.GetActorLocation() - neighbor->GetActorLocation();
        float distance = direction.Size();
        if (distance < 200.0f)
        {
            avoidance += direction.GetSafeNormal() * (200.0f - distance);
        }
    }

    return avoidance;
}

It's not the most elegant code in the world, or efficient, some sloppy stuff like uninitialised members, but I'd probably progress a junior candidate coming up with that as an interview task.
I gave it a couple of follow up prompts to tidy it up and optimise a bit....ended up with some decent code.

Wild!
 
Last edited:
Caporegime
Joined
29 Jan 2008
Posts
58,912
Copilot is worth a look too and is more specific to code.

Does it write code and test it 'virtually' before spitting out an answer?

No, and that is an issue, it's predicting text and will give you wrong answers too.

Certainly very useful to help with productivity or for initially taking a look at some way of doing things, could replace searching stack overflow etc.. but definitely exercise some skepticism with the answers.

It's rather clever but it's going to raise a load of issues in academia.

Perhaps more so in the US where things are more coursework-heavy, it's not necessarily writing A-grade essays yet but it could certainly be used to cheat.

The easy solution is to move towards 100% exams and in-class tests etc.. for summative assessments and use coursework for formative assessments only; compulsory to submit and to gain a passing grade in but doesn't affect the final module grade providing that's been fulfilled.
 
Associate
Joined
6 Jan 2023
Posts
2
Location
London
been using it as a more directed search for programming problem. Although not 100% reliable, it's amazing (and scary) how well it works.

Not sure what the landscape will look like in a decade. Perhaps less explicit writing of code and more prompting and reviewing will become the norm.
 
Soldato
Joined
18 Oct 2002
Posts
4,892
I find it really good for creating test data e.g. you can paste in a table schema and tell it to create an insert statement to generate x number of rows.
or use it to optimise code, its good that it not only gives you the answer but it also explains it.
 
Soldato
Joined
18 Oct 2002
Posts
14,153
Location
West Midlands
Used it to write a few long winded Powershell scripts that I couldn't be bothered to investigate first at any great length, the worked great so I am happy with that as a time saver.
 
Soldato
Joined
28 Sep 2008
Posts
14,129
Location
Britain
No. It's only useful for beginner stuff and can't do more advanced programming techniques. I actually had to correct it at least twice yesterday when it was trying to use an invalid resource attribute.
 
Back
Top Bottom