Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,7 @@ npm-debug.log
dev.secret.exs

priv/static/uploads

games/punderplay/zig-cache/
games/punderplay/zig-out/
games/punderplay/.zigmod
23 changes: 23 additions & 0 deletions games/punderplay/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Punderplay

### build

Install [`zigmod`](https://github.com/nektro/zigmod#download) and run:

```sh
# from the `punderplay` directory
zigmod fetch
zig build
# use ./zig-out/bin/punderplay.wasm
```

### Testing

Run unit tests via `zig build test`

Execute functions in the game:

```sh
# currently this just echoes out the input after deserializing & reserializing
extism call zig-out/bin/punderplay.wasm init_game --input '{"player_ids": ["steve", "ben"]}' | jq .
```
27 changes: 27 additions & 0 deletions games/punderplay/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const std = @import("std");
const deps = @import("deps.zig");

pub fn build(b: *std.build.Builder) void {
const mode = b.standardReleaseOptions();
const target = b.standardTargetOptions(.{ .default_target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding } });
const exe = b.addExecutable("punderplay", "src/main.zig");
exe.setTarget(target);
exe.setBuildMode(mode);
deps.addAllTo(exe);
exe.install();

const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}

const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);

const exe_tests = b.addTest("src/test.zig");
exe_tests.setBuildMode(mode);

const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&exe_tests.step);
}
86 changes: 86 additions & 0 deletions games/punderplay/deps.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// zig fmt: off
const std = @import("std");
const builtin = @import("builtin");
const Pkg = std.build.Pkg;
const string = []const u8;

pub const cache = ".zigmod/deps";

pub fn addAllTo(exe: *std.build.LibExeObjStep) void {
checkMinZig(builtin.zig_version, exe);
@setEvalBranchQuota(1_000_000);
for (packages) |pkg| {
exe.addPackage(pkg.pkg.?);
}
var llc = false;
var vcpkg = false;
inline for (comptime std.meta.declarations(package_data)) |decl| {
const pkg = @as(Package, @field(package_data, decl.name));
for (pkg.system_libs) |item| {
exe.linkSystemLibrary(item);
llc = true;
}
for (pkg.frameworks) |item| {
if (!std.Target.current.isDarwin()) @panic(exe.builder.fmt("a dependency is attempting to link to the framework {s}, which is only possible under Darwin", .{item}));
exe.linkFramework(item);
llc = true;
}
inline for (pkg.c_include_dirs) |item| {
exe.addIncludePath(@field(dirs, decl.name) ++ "/" ++ item);
llc = true;
}
inline for (pkg.c_source_files) |item| {
exe.addCSourceFile(@field(dirs, decl.name) ++ "/" ++ item, pkg.c_source_flags);
llc = true;
}
vcpkg = vcpkg or pkg.vcpkg;
}
if (llc) exe.linkLibC();
if (builtin.os.tag == .windows and vcpkg) exe.addVcpkgPaths(.static) catch |err| @panic(@errorName(err));
}

pub const Package = struct {
directory: string,
pkg: ?Pkg = null,
c_include_dirs: []const string = &.{},
c_source_files: []const string = &.{},
c_source_flags: []const string = &.{},
system_libs: []const string = &.{},
frameworks: []const string = &.{},
vcpkg: bool = false,
};

fn checkMinZig(current: std.SemanticVersion, exe: *std.build.LibExeObjStep) void {
const min = std.SemanticVersion.parse("null") catch return;
if (current.order(min).compare(.lt)) @panic(exe.builder.fmt("Your Zig version v{} does not meet the minimum build requirement of v{}", .{current, min}));
}

pub const dirs = struct {
pub const _root = "";
pub const _f0fex8nt61gp = cache ++ "/../..";
pub const _hybfpvr9c5u2 = cache ++ "/git/github.com/extism/zig-pdk";
};

pub const package_data = struct {
pub const _f0fex8nt61gp = Package{
.directory = dirs._f0fex8nt61gp,
};
pub const _hybfpvr9c5u2 = Package{
.directory = dirs._hybfpvr9c5u2,
.pkg = Pkg{ .name = "extism-pdk", .source = .{ .path = dirs._hybfpvr9c5u2 ++ "/src/main.zig" }, .dependencies = null },
};
pub const _root = Package{
.directory = dirs._root,
};
};

pub const packages = &[_]Package{
package_data._hybfpvr9c5u2,
};

pub const pkgs = struct {
pub const extism_pdk = package_data._hybfpvr9c5u2;
};

pub const imports = struct {
};
64 changes: 64 additions & 0 deletions games/punderplay/src/game.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const std = @import("std");
const Plugin = @import("extism-pdk").Plugin;

pub const Player = []const u8;
pub const Judge = Player;
pub const Scores = std.StringHashMap(u8);
pub const Round = struct {
winner: Player,
winning_pun: []const u8,
judge: Judge,
prompt: [2]u8,
};

const Game = struct {
allocator: std.mem.Allocator,
current_judge: Judge,
players: []Player,
scores: Scores,
rounds: std.ArrayList(Round),

const Self = @This();

pub fn init(allocator: std.mem.Allocator, players: []Player) Self {
// pick a player from the set of current players to act as the judge.
// initialize the scores for each player.
var scores = std.StringHashMap(u8).init(allocator);
for (players) |player| {
scores.put(player, 0) catch unreachable;
}
return Self{
.allocator = allocator,
.current_judge = players[0],
.players = players,
.scores = scores,
.rounds = std.ArrayList(Round).init(allocator),
};
}

pub fn deinit(self: *Self) void {
self.scores.deinit();
self.rounds.deinit();
}
};

const verbs = "watering.cataloging.hunting.wanting.holding.taping.integrating.worrying.loving.spending.fitting.bating.risking.normalizing.restructuring.costing.programming.touching.towing.altering.marketing.yelling.crushing.beholding.agreeing.fencing.sparkling.wiping.sparking.slaying.copying.melting.appraising.complaining.leading.telling.crashing.subtracting.normalizing.grabbing.wrecking.thanking.forming.answering.overhearing.wriggling.rin.ing.admitting.bruising.making.pumping.melting.bumping.dragging.consisting.accepting.dropping.smelling.recognizing.facing.deciding.deserting.riding.ensuring.frightening.shading.flapping.washing.completing.heaping.snoring.draining.clothing.detailing.initiating.dispensing.diagnosing.paddling.sin.ing.promising.handling.planing.separating.thriving.shrinking.scrubbing.confusing.spotting.scattering.noticing.upgrading.piloting.estimating.showing.reigning.folding.contracting.blushing.broadcasting.speaking.slipping.squashing.pecking.hanging.returning.receiving.landing.injecting.fleeing.cheering.sniffing.sleeping.clin.ing.breeding.searching.carving.meaning.attaching.affording.nesting.undergoing.passing.entertaining.longing.enjoying.fighting.wrestling.unfastening.drawing.supposing.knotting.greasing.producing.spinning.squashing.asking.projecting.enduring.adopting.fancying.conducting.conceiving.guessing.mating.overthrowing.regulating.determining.bearing.devising.abiding.piloting.hearing.rhyming.retrieving.servicing.integrating.preaching.rubbing.clarifying.agreeing.striking.wobbling.groaning.speeding.filling.repairing.pining.launching.sneaking.shaping.breathing.spoiling.living.recruiting.proposing.pedaling.wrecking.replacing.operating.trying.licensing.discovering.overdoing.rinsing.camping.displaying.muddling.pricking.nesting.processing.counseling.consolidating.shivering.numbering.removing.sliding.referring.rin.ing.representing.risking.inspecting.assisting.enhancing.administering.identifying.enacting.skipping.shaking.spoiling.spelling.selecting.shopping.causing.reflecting.photographing.withstanding.evaluating.breaking.visiting.creeping.feeding.loading.graduating.combing.tickling.catching.dividing.squealing.breathing.fixing.floating.logging.chewing.carrying.hurting.sacking.expressing.getting.forbidding.sawing.moaning.grinding.ruining.hurrying.balancing.exploding.spilling.welcoming.eliminating.acceding.classifying.smiling.assuring.settling.scheduling.perceiving.moaning.shooting.reconciling.faxing.executing.decaying.marrying.stin.ing.investigating.enacting.caring.questioning.proving.rescuing.filming.shopping.separating.identifying.leading.laying.speeding.tracing.identifying.alerting.sacking.remaining.activating.interesting.boasting.imagining.putting.controlling.disliking.addressing.solving.fleeing.agreeing.shining.fancying.wrin.ing.fading.accelerating.establishing.curling.attacking.guaranteeing.deceiving.patting.applauding.noting.pressing.kneeling.hitting.scheduling.presiding.repeating.prescribing.arising.slaying.adding.fitting.snoring.shaking.sewing.inspecting.educating.manipulating.belonging.giving.participating.agreeing.doubting.misunderstanding.following.trotting.writing.clin.ing.interesting.damming.correlating.plugging.attending.retiring.beholding.understanding.walking.pinpointing.photographing.braking.soaking.folding.remembering.slin.ing.borrowing.rocking.allowing.filming.obeying.coiling.cycling.untidying.shrinking.preferring.stirring.fixing.attending.baking.saying.rotting.learning.governing.confessing.reminding.utilizing.bruising.dramatizing.knowing.puncturing.shearing.suggesting.achieving.heading.sliding.punching.greeting.gazing.swin.ing.spending.occurring.sneezing.creating.sparking.hiding.stitching.promoting.changing.snowing.taking.lying.reading.responding.bouncing.baking.pecking.multiplying.conserving.challenging.losing.sowing.fooling.marketing.informing.spilling.matching.speaking.dealing.detecting.rating.screwing.bruising.interlaying.phoning.ensuring.binding.stoping.scattering.weighing.participating.editing.letting.publicizing.preparing.financing.shearing.checking.writing.exciting.firing.bombing.disliking.restoring.eating.fighting.answering.balancing.sending.blotting.amusing.disagreeing.innovating.relying.correcting.confronting.judging.reducing.entertaining.arguing.selecting.stamping.parking.naming.noticing.doing.chopping.banging.engineering.trusting.describing.delegating.cheating.lending.mistaking.squeaking.winding.comparing.adapting.cracking.correlating.scolding.blushing.scraping.buzzing.existing.improvising.praising.splitting.distributing.curing.overdoing.mapping.progressing.activating.feeding.forgiving.dressing.manning.polishing.smoking.reconciling.knowing.tugging.being.causing.shutting.preventing.disappearing.presenting.banging.explaining.crossing.predicting.converting.sighing.designing.fooling.bursting.decorating.battling.hearing.sensing.meaning.presetting.chasing.overdrawing.classifying.charging.parting.polishing.planting.sniffing.fearing.commanding.formulating.bruising.distributing.officiating.seeking.offending.harming.computing.realigning.touring.containing.revising.surprising.helping.pleading.overflowing.reinforcing.nodding.matching.barring.ascertaining.budgeting.allowing.lightening.presetting.deceiving.collecting.slitting.becoming.collecting.cleaning.extending.boiling.overthrowing.obeying.working.painting.dealing.protecting.mugging.flin.ing.updating.referring.skiing.discovering.blinking.spelling.calling.curling.dealing.quitting.shaking.meaning.diverting.smiling.facilitating.satisfying.rolling.siting.asking.holding.blowing.kneeling.assuring.defining.disproving.recruiting.diagnosing.whispering.coughing.lasting.racing.sprouting.acquiring.stitching.heading.soothsaying.parking.splitting.programming.starting.including.knitting.making.jumping.staining.sensing.nominating.regulating.receiving.lasting.boxing.preceding.inventing.increasing.implementing.radiating.relaxing.guarding.brushing.heaping.killing.objecting.confronting.keeping.vexing.accomplishing.orienteering.sinking.repairing.instituting.coughing.preaching.juggling.trading.frying.lightening.scaring.hypothesizing.insuring.sealing.shoeing.grinning.ranking.teaching.coaching.creeping.rising.rubbing.bowing.systemizing.jamming.performing.framing.delaying.quitting.experimenting.smashing.leveling.skipping.sealing.breeding.blinking.beginning.owing.clearing.breaking.growing.guaranteeing.numbering.formulating.standing.verbalizing.executing.shaking.foreseeing.delighting.sneaking.hooking.pasting.objecting.coloring.setting.instructing.generating.measuring.glueing.reconciling.challenging.avoiding.missing.attaining.forecasting.tipping.sharing.bleaching.addressing.proofreading.intending.parting.queueing.crushing.sucking.monitoring.overcoming.copying.restructuring.chewing.casting.tying.ignoring.painting.examining.doubling.doubting.wishing.helping.spiting.wending.thrusting.splitting.muddling.confusing.liking.recognizing.designing.sending.reconciling.inducing.keeping.unifying.excusing.buzzing.joking.forgiving.conserving.budgeting.scratching.initiating.bumping.stamping.suspending.leveling.liking.scribbling.stinking.exhibiting.structuring.rating.queueing.belonging.fearing.broadcasting.hurrying.packing.brushing.glueing.tricking.wandering.bathing.inventorying.expanding.launching.reinforcing.soothing.communicating.predicting.simplifying.pressing.living.exceeding.spotting.disapproving.calculating.spotting.strapping.correcting.rotting.owing.bursting.encouraging.unpacking.cutting.originating.sketching.consisting.causing.affording.impressing.producing.hammering.sensing.scratching.borrowing.transforming.modifying.killing.besetting.lightening.spreading.mediating.sketching.wobbling.staring.adopting.strapping.laying.buying.biding.boasting.possessing.solving.expecting.covering.matching.accepting.rejecting.drying.mattering.blessing.cheering.hugging.wrapping.curing.attempting.meeting.sprin.ing.dressing.using.alighting.speeding.conceiving.meddling.losing.stimulating.clearing.forgetting.rocking.appreciating.rejoicing.increasing.rising.eating.critiquing.depending.spraying.keeping.researching.slapping.requesting.claiming.harassing.betting.crying.mending.irritating.concentrating.summarizing.enforcing.exercising.handwriting.supplying.acquiring.purchasing.lecturing.competing.compiling.beating.binding.bleeding.encouraging.charging.tutoring.kissing.testing.fetching.soothsaying.ending.arriving.sipping.appearing.nominating.praying.arranging.overdrawing.hiding.leaving.entering.maintaining.zooming.investigating.tempting.satisfying.suggesting.flowing.extracting.covering.treating.reigning.handling.bathing.upholding.facilitating.swelling.mending.slipping.paddling.mugging.belonging.pinpointing.wailing.pinching.excusing.occurring.ordering.preparing.assessing.parking.transforming.timing.grating.reflecting.groaning.snowing.shutting.checking.organizing.finding.digging.curving.filling.smoking.folding.releasing.locking.finalizing.installing.radiating.crawling.doing.admiring.telephoning.challenging.contracting.puncturing.deserving.owning.peeling.scorching.dispensing.resolving.plugging.disappearing.hypothesizing.parking.interrupting.exhibiting.rejoicing.reorganizing.bouncing.misunderstanding.choosing.deserving.killing.critiquing.mattering.realizing.swimming.passing.transforming.caring.bowing.professing.pinching.appraising.reminding.publicizing.reaching.leaning.knitting.typing.expecting.delivering.choking.seeing.licking.flapping.clarifying.symbolizing.stealing.trapping.drafting";

test "init game" {
const input = "[\"alice\", \"bob\"]";
var stream = std.json.TokenStream.init(input);
const players = try std.json.parse([]Player, &stream, .{ .allocator = std.testing.allocator });
defer std.json.parseFree([]Player, players, .{ .allocator = std.testing.allocator });

var game = Game.init(std.testing.allocator, players);
defer game.deinit();

try std.testing.expectEqualStrings(game.current_judge, "alice");
try std.testing.expect(game.players.len == 2);
var iter = game.scores.iterator();
while (iter.next()) |entry| {
try std.testing.expect(entry.value_ptr.* == 0);
}
try std.testing.expect(game.scores.count() == 2);
try std.testing.expect(game.rounds.items.len == 0);
}
65 changes: 65 additions & 0 deletions games/punderplay/src/main.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const std = @import("std");
const extism_pdk = @import("extism-pdk");
const Plugin = extism_pdk.Plugin;
const json = std.json;

const game = @import("game.zig");

pub fn main() void {}

const allocator = std.heap.wasm_allocator;

const GameConfig = struct {
player_ids: []game.Player,
};

fn initGame(config: GameConfig, plugin: *Plugin) i32 {
const data = json.stringifyAlloc(allocator, config, .{}) catch unreachable;
plugin.output(data);
return 0;
}

const LiveEvent = struct {
player_id: []const u8,
event_name: []const u8,
value: EventPayload,
};

const EventPayload = struct {
prompt_id: usize,
pun: []const u8,
};

fn handleEvent(event: LiveEvent) i32 {
_ = event;
return 0;
}

const Assigns = struct {};

fn renderView(data: Assigns) i32 {
_ = data;
return 0;
}

export fn init_game() i32 {
var plugin = Plugin.init(allocator);
const input = plugin.getInput() catch unreachable;
defer allocator.free(input);

var stream = json.TokenStream.init(input);
const config = json.parse(GameConfig, &stream, .{ .allocator = allocator }) catch unreachable;
defer json.parseFree(GameConfig, config, .{ .allocator = allocator });

return initGame(config, &plugin);
}

// export fn handle_event(input: []const u8) i32 {
// const event = json.parse(LiveEventEvent, input, .{}) catch unreachable;
// return handleEvent(event);
// }

// export fn render(input: []const u8) i32 {
// const assigns = json.parse(Assigns, input, .{});
// return render(assigns);
// }
6 changes: 6 additions & 0 deletions games/punderplay/src/test.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const test_main = @import("main.zig");
const test_game = @import("game.zig");

test {
@import("std").testing.refAllDecls(@This());
}
2 changes: 2 additions & 0 deletions games/punderplay/zigmod.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
2
git https://github.com/extism/zig-pdk commit-0ee480666df11ad5c3b4fe2cfa47c68da4a7aa73
6 changes: 6 additions & 0 deletions games/punderplay/zigmod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
id: f0fex8nt61gpyoimsjcmtpd4ukxh0f2hbts0zgtjntvclua0
name: punderplay
license: BSD-3
description: Pun-based game for GameBox demo
root_dependencies:
- src: git https://github.com/extism/zig-pdk